This is an automated email from the ASF dual-hosted git repository.

remm pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/tomcat-jakartaee-migration.git


The following commit(s) were added to refs/heads/master by this push:
     new b89a835  Validate changes by the class transformer
b89a835 is described below

commit b89a835d5bca7e67e4ba0decf7e4e712c3b6aef5
Author: remm <r...@apache.org>
AuthorDate: Thu Mar 25 18:01:07 2021 +0100

    Validate changes by the class transformer
    
    When converting in the class transformer, the opportunity exists to try
    to load the classes to verify that the rewrite makes more sense than the
    original.
    Inspired by the problem posed by JSTL in the Tomcat examples webapp [or
    any other webapp that would include EE specification classes that happen
    to match the profile used].
---
 CHANGES.md                                         |  1 +
 .../apache/tomcat/jakartaee/ClassConverter.java    | 52 +++++++++++++++++++++-
 2 files changed, 52 insertions(+), 1 deletion(-)

diff --git a/CHANGES.md b/CHANGES.md
index 1e2c314..669b1b2 100644
--- a/CHANGES.md
+++ b/CHANGES.md
@@ -3,6 +3,7 @@
 ## 0.3.0 (in progress)
 
 - Fix [#14](https://github.com/apache/tomcat-jakartaee-migration/issues/14). 
Do not migrate `javax.xml.(registry|rpc)` namespaces. (mgrigorov)
+- The class transformer will now validate that its rewrite exists in the 
runtime environment (remm)
 
 ## 0.2.0
 
diff --git a/src/main/java/org/apache/tomcat/jakartaee/ClassConverter.java 
b/src/main/java/org/apache/tomcat/jakartaee/ClassConverter.java
index d3fbaae..1ef8993 100644
--- a/src/main/java/org/apache/tomcat/jakartaee/ClassConverter.java
+++ b/src/main/java/org/apache/tomcat/jakartaee/ClassConverter.java
@@ -101,7 +101,57 @@ public class ClassConverter implements Converter, 
ClassFileTransformer {
         ByteArrayInputStream inputStream = new 
ByteArrayInputStream(classfileBuffer);
         ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
         try {
-            convert(className, inputStream, outputStream, profile);
+            ClassParser parser = new ClassParser(inputStream, "unknown");
+            JavaClass javaClass = parser.parse();
+
+            boolean converted = false;
+
+            // Loop through constant pool
+            Constant[] constantPool = 
javaClass.getConstantPool().getConstantPool();
+            // Need an int as the maximum pool size is 2^16
+            for (int i = 0; i < constantPool.length; i++) {
+                if (constantPool[i] instanceof ConstantUtf8) {
+                    ConstantUtf8 c = (ConstantUtf8) constantPool[i];
+                    String str = c.getBytes();
+                    String newString = profile.convert(str);
+                    // Object comparison is deliberate
+                    if (newString != str) {
+                        // Since this is runtime conversion, the idea is to 
only convert to
+                        // Jakarta EE specification classes that exist in the 
container 
+                        String[] split = newString.split(";");
+                        for (String current : split) {
+                            int pos = current.indexOf("jakarta/");
+                            if (pos >= 0) {
+                                boolean found = false;
+                                try {
+                                    
loader.loadClass(current.substring(pos).replace('/', '.'));
+                                    found = true;
+                                } catch (Exception e) {}
+                                if (!found) {
+                                    // Cancel the replacement as the 
replacement does not exist
+                                    String originalFragment = 
current.replace("jakarta/", "javax/");
+                                    newString = newString.replace(current, 
originalFragment);
+                                }
+                            }
+                        }
+                        if (newString != str) {
+                            c = new ConstantUtf8(newString);
+                            constantPool[i] = c;
+                            converted = true;
+                        }
+                    }
+                }
+            }
+
+            if (logger.isLoggable(Level.FINE)) {
+                if (converted) {
+                    logger.log(Level.FINE, 
sm.getString("classConverter.converted", className));
+                } else if (logger.isLoggable(Level.FINEST)) {
+                    logger.log(Level.FINEST, 
sm.getString("classConverter.noConversion", className));
+                }
+            }
+
+            javaClass.dump(outputStream);
         } catch (IOException e) {
             throw new IllegalClassFormatException(e.getLocalizedMessage());
         }

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org
For additional commands, e-mail: dev-h...@tomcat.apache.org

Reply via email to