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 <[email protected]>
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: [email protected]
For additional commands, e-mail: [email protected]