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