Skip to main content

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [List Home]
Re: [transformer-dev] Question about package rename scope

Thank you, BJ!

Yes, string constant javax.servlet.LocalStrings is correctly transformed to jakarta.servlet.LocalStrings, and java.util.ResourceBundle.getBundle now looks for jakarta.servlet.LocalStrings, but it is nowhere to be found on the class path ... Remember in this scenario, I don't have any of the jakarta jar files on the class path (yet).

Jan

On Monday, April 29, 2024 at 03:53:20 PM GMT+2, BJ Hargrave via transformer-dev <transformer-dev@xxxxxxxxxxx> wrote:


Transformer already has the capability to transform string constants in class files as well as package names. So, you will need to make sure the proper string constant transformations occur when processing the class file.

 

See https://github.com/eclipse/transformer/blob/43e34f863c57031e66979a2faf238904a4151eb0/org.eclipse.transformer.jakarta/src/main/resources/org/eclipse/transformer/jakarta/jakarta-direct.properties#L16 where the specific string you reference is included in a list of string constant transformations.

 

-- 


BJ Hargrave
Senior Technical Staff Member, IBM // office: +1 386 848 1781
Open Source Development // mobile: +1 386 848 3788
hargrave@xxxxxxxxxx

 

 

 

From: transformer-dev <transformer-dev-bounces@xxxxxxxxxxx> on behalf of jan luehe via transformer-dev <transformer-dev@xxxxxxxxxxx>
Date: Monday, April 29, 2024 at 03:03
To: BJ Hargrave via transformer-dev <transformer-dev@xxxxxxxxxxx>
Cc: jan luehe <janluehe@xxxxxxxxx>
Subject: [EXTERNAL] Re: [transformer-dev] Question about package rename scope

Hi BJ, while the jakarta classes are not yet available on our class path, I have started looking into Option 2, which is about “preloading” the jakarta classes "by asking the class loader to define the jakarta class with the transformed class

ZjQcmQRYFpfptBannerStart

This Message Is From an External Sender

This message came from outside your organization.

 

ZjQcmQRYFpfptBannerEnd

Hi BJ,

 

while the jakarta classes are not yet available on our class path, I have started looking into Option 2, which is about “preloading” the jakarta classes "by asking the class loader to define the jakarta class with the transformed class file of the javax class".

 

This looks promising and all goes well until jakarta.servlet.GenericServlet (defined from the transformed byte code of javax.servlet.GenericServlet) is initialized, which throws this error:

 

Caused by: java.util.MissingResourceException: Can't find bundle for base name jakarta.servlet.LocalStrings, locale en_US

        at java.base/java.util.ResourceBundle.throwMissingResourceException(ResourceBundle.java:2045)

        at java.base/java.util.ResourceBundle.getBundleImpl(ResourceBundle.java:1683)

        at java.base/java.util.ResourceBundle.getBundleImpl(ResourceBundle.java:1586)

        at java.base/java.util.ResourceBundle.getBundleImpl(ResourceBundle.java:1549)

        at java.base/java.util.ResourceBundle.getBundle(ResourceBundle.java:858)

        at jakarta.servlet.GenericServlet.<clinit>(GenericServlet.java:51)

        ... 18 more

 

This is because the original javax.servlet.GenericServlet has this static initializer code:

 

private static final String LSTRING_FILE = "javax.servlet.LocalStrings";

private static ResourceBundle lStrings = ResourceBundle.getBundle(LSTRING_FILE);

 

I have to check if and how we could trick the class loader (java.util.ResourceBundle) into loading the old javax.servlet.LocalStrings, when the transformed jakarta.servlet.GenericServlet requests jakarta.servlet.LocalStrings - which does not exist anywhere on the class path ...

 

If you have any ideas, please do let me know. :)

 

Thank you!

 

Jan

 

On Thursday, April 11, 2024 at 09:35:02 PM GMT+2, jan luehe via transformer-dev <transformer-dev@xxxxxxxxxxx> wrote:

 

 

Thank you, BJ!

 

That's exactly the point: when the class name changes, you need to transform before the class load request and not during the class load. Well said!

 

Thank you for highlighting both alternatives! The first alternative, which is what my current integration approach relies on, sounds much more straightforward: It does require that the Jakarta classes already be available on the class path, but that's our ultimate goal anyway! Our main use case for the transformer is dealing with third-party dependencies that have not been migrated yet.

 

Thank you!

 

Jan

 

On Thursday, April 11, 2024 at 07:36:28 PM GMT+2, BJ Hargrave via transformer-dev <transformer-dev@xxxxxxxxxxx> wrote:

 

 

If there is an application class which references a javax class and you are transforming it during class loading to reference a jakarta class, then after returning the transformed class file, the class will be loaded and then reference the jakarta class. In this scenario, I would image you already have the jakarta classes already accessible for class loading and things will work fine.

 

If you also want to have the transformer convert the javax class to a jakarta class, then you have to “preload” the jakarta class by asking the class loader to define the jakarta class with the transformed class file of the javax class. That is, when the class name changes, you need to transform before the class load request and not during the class load. You could do this preload during the transformation of the other application class since you can observe which javax classes it references and then transform and preload them all.

 

Good luck! 😊

 

-- 


BJ Hargrave
Senior Technical Staff Member, IBM // office: +1 386 848 1781
Open Source Development // mobile: +1 386 848 3788
hargrave@xxxxxxxxxx

 

 

 

From: transformer-dev <transformer-dev-bounces@xxxxxxxxxxx> on behalf of jan luehe via transformer-dev <transformer-dev@xxxxxxxxxxx>
Date: Thursday, April 11, 2024 at 10:57
To: BJ Hargrave via transformer-dev <transformer-dev@xxxxxxxxxxx>
Cc: jan luehe <janluehe@xxxxxxxxx>
Subject: [EXTERNAL] Re: [transformer-dev] Question about package rename scope

One possible solution that I could think of would be to exempt these types of classes (e.g., javax/servlet/ServletException) from transformation, because eventually, they will no longer be loaded once they have been replaced by their Jakarta-equivalents

ZjQcmQRYFpfptBannerStart

This Message Is From an External Sender

This message came from outside your organization.

 

ZjQcmQRYFpfptBannerEnd

One possible solution that I could think of would be to exempt these types of classes (e.g., javax/servlet/ServletException) from transformation, because eventually, they will no longer be loaded once they have been replaced by their Jakarta-equivalents (e.g., jakarta/servlet/ServletException) on the class path ...

 

Jan

 

On Thursday, April 11, 2024 at 04:44:48 PM GMT+2, jan luehe via transformer-dev <transformer-dev@xxxxxxxxxxx> wrote:

 

 

Thank you, BJ, for your prompt response!

 

I think I understand what's going on. I have integrated the transformer into our org.eclipse.osgi.internal.hookregistry.ClassLoaderHook subclass, by implementing:

 

public byte[] processClass(String name, byte[] classbytes, ClasspathEntry classpathEntry, BundleEntry entry, ClasspathManager manager)

 

to call into the transformer and return the possibly transformed classbytes.

 

This works great for any class that is not getting renamed as part of the transformation, but if the class itself is subject to renaming, I run into an issue because the class name passed to ClassLoader.loadClass (e.g., javax/servlet/ServletException) no longer matches the renamed class (jakarta/servlet/ServletException), resulting in this error:

 

Caused by: java.lang.NoClassDefFoundError: jakarta/servlet/ServletException (wrong name: javax/servlet/ServletException)

        at java.base/java.lang.ClassLoader.defineClass1(Native Method)

        at java.base/java.lang.ClassLoader.defineClass(ClassLoader.java:1017)

        at org.eclipse.osgi.internal.loader.ModuleClassLoader.defineClass(ModuleClassLoader.java:283)

        at org.eclipse.osgi.internal.loader.classpath.ClasspathManager.defineClass(ClasspathManager.java:716)

        at org.eclipse.osgi.internal.loader.classpath.ClasspathManager.findClassImpl(ClasspathManager.java:639)

        at org.eclipse.osgi.internal.loader.classpath.ClasspathManager.findLocalClassImpl(ClasspathManager.java:607)

        at org.eclipse.osgi.internal.loader.classpath.ClasspathManager.findLocalClassImpl(ClasspathManager.java:582)

        at org.eclipse.osgi.internal.loader.classpath.ClasspathManager.findLocalClass(ClasspathManager.java:566)

        at org.eclipse.osgi.internal.loader.ModuleClassLoader.findLocalClass(ModuleClassLoader.java:335)

        at org.eclipse.osgi.internal.loader.BundleLoader.findLocalClass(BundleLoader.java:397)

        at org.eclipse.osgi.internal.loader.BundleLoader.findClass0(BundleLoader.java:500)

        at org.eclipse.osgi.internal.loader.BundleLoader.findClass(BundleLoader.java:416)

        at org.eclipse.osgi.internal.loader.ModuleClassLoader.loadClass(ModuleClassLoader.java:168)

        at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:579)

 

Do you have any suggestion for how to make this scenario work as well? 

 

Jan

 

 

On Thursday, April 11, 2024 at 03:35:02 PM GMT+2, BJ Hargrave via transformer-dev <transformer-dev@xxxxxxxxxxx> wrote:

 

 

Transformer does not need the old or new packages on the classpath to transform. It uses the information in the transformation rules to determine the mapping from old package names to new package names and processes the class files in the artifact being transformed. This is primarily done by mutating the constant pool in the class file to use the new names instead of the old names.

 

-- 


BJ Hargrave
Senior Technical Staff Member, IBM // office: +1 386 848 1781
Open Source Development // mobile: +1 386 848 3788
hargrave@xxxxxxxxxx

 

 

 

From: transformer-dev <transformer-dev-bounces@xxxxxxxxxxx> on behalf of jan luehe via transformer-dev <transformer-dev@xxxxxxxxxxx>
Date: Thursday, April 11, 2024 at 06:25
To: transformer-dev@xxxxxxxxxxx <transformer-dev@xxxxxxxxxxx>
Cc: jan luehe <janluehe@xxxxxxxxx>
Subject: [EXTERNAL] [transformer-dev] Question about package rename scope

Is my assumption correct that in order for the transformer to be able to apply the package rename rules at https://github.com/eclipse/transformer/blob/main/org.eclipse.transformer.jakarta/src/main/resources/org/eclipse/transformer/jakarta/jakarta-renames.properties,

ZjQcmQRYFpfptBannerStart

This Message Is From an External Sender

This message came from outside your organization.

 

ZjQcmQRYFpfptBannerEnd

Is my assumption correct that in order for the transformer to be able to apply the package rename rules at https://github.com/eclipse/transformer/blob/main/org.eclipse.transformer.jakarta/src/main/resources/org/eclipse/transformer/jakarta/jakarta-renames.properties, the target packages of the renames ("newPackageName", e.g., jakarta.servlet), must already exist on the class path of the hosting app, so that the renamed references can be correctly resolved? 

 

For example, if the hosting app still has jakarta.servlet-api-4.0.4.jar (which provides the "old" javax.servlet) on its class path, then the rename rule from javax.servlet to jakarta.servlet will fail. 

 

In other words, only class references to "currentPackageName" will be renamed (e.g, "Foo implements javax.servlet.Servlet"), but not the class definitions themselves ("package javax.servlet; public interface Servlet { ... }").

 

Could you please confirm? Thank you!

_______________________________________________
transformer-dev mailing list
transformer-dev@xxxxxxxxxxx
To change your delivery options, retrieve your password, or unsubscribe from this list, visit
https://dev.eclipse.org/mailman/listinfo/transformer-dev

_______________________________________________
transformer-dev mailing list
transformer-dev@xxxxxxxxxxx
To change your delivery options, retrieve your password, or unsubscribe from this list, visit
https://dev.eclipse.org/mailman/listinfo/transformer-dev

_______________________________________________
transformer-dev mailing list
transformer-dev@xxxxxxxxxxx
To change your delivery options, retrieve your password, or unsubscribe from this list, visit
https://dev.eclipse.org/mailman/listinfo/transformer-dev

_______________________________________________
transformer-dev mailing list
transformer-dev@xxxxxxxxxxx
To change your delivery options, retrieve your password, or unsubscribe from this list, visit
https://dev.eclipse.org/mailman/listinfo/transformer-dev

_______________________________________________
transformer-dev mailing list
transformer-dev@xxxxxxxxxxx
To change your delivery options, retrieve your password, or unsubscribe from this list, visit
https://dev.eclipse.org/mailman/listinfo/transformer-dev

Back to the top