Community
Participate
Working Groups
when 1/ Ant is run in the same JRE 2/ a user Ant task has Java code 3/ the user Java code causes a class to be loaded then the Ant plugin uses the BundleClassLoader before using org.eclipse.ant.internal.core.AntClassLoader if the class the Java code loads happens to exist in a plugin, then the wrong version of the class is loaded. The attached testcase loads org.apache.commons.logging.LogFactory. It fails under RAD where there are more plugins using various versions of commons-logging.jar. To demonstrate the behaviour that would lead to a failure under Eclipse you need to run both a JVM and Eclipse classloader trace with the .options file. I will also attach a sample trace.
Also noticed that when searching for the user Ant Task Java class, the plugin loads org/apache/tools/ant/AntClassLoader, but then uses the BundleClassLoader to search for the user Ant Task. I think this means that if the user had their own version of a standard Ant task in their user project directory, the Ant Plugin would not load it when running in the Eclipse JRE.
Created attachment 29432 [details] testcase
Created attachment 29435 [details] .options to enable classloader traces
Created attachment 29436 [details] classloader trace search for AntTaskTest and the LogFactory to see how the user Ant Task and the LogFactory class used by AntTaskTest are loaded.
Comment on attachment 29435 [details] .options to enable classloader traces Here is the startup command line used to produce the trace: D:\e302\eclipse>\rad60\eclipse\jre\bin\java -cp startup.jar -verbose:class org.e clipse.core.launcher.Main -data \testcase\02543756\e302 -debug > trace3.out 2>&1
Command Line used to generate the classloader trace D:\e302\eclipse>\rad60\eclipse\jre\bin\java -cp startup.jar -verbose:class org.e clipse.core.launcher.Main -data \testcase\02543756\e302 -debug > trace3.out 2>&1
Thank you for the bug report but this is working as designed. I agree this can lead to problems but it was the design decision made so that the plugin classloaders could be consulted and the plugin dependency chain used for correct classloading when the Ant task is using plugin classes. If there are other possibilities I am open to consideration. The Ant classloader is coded to always load the Apache Ant classes at runtime. Is there any chance you can create your Ant task in a plugin that has a dependancy chain that does not include the incorrect versions of LogFactory?
Hi Darin, thanks for your quick response. We're relieved to finally have the right component to deal with this issue. I agree entirely that the BundleClassLoader is needed - perhaps to allow the user to run Eclipse Ant Tasks for example. The issue is just that the user project should be searched ahead of the plugins. I.e. it's just an ordering issue. The trace indicates: [Loaded java.net.URLClassLoader$5 from D:\ies601\eclipse\jre\lib\core.jar] [Loading superclass and interfaces of java/net/URLClassLoader$5] [Preparing java/net/URLClassLoader$5] [Loaded org.apache.commons.logging.LogFactory from file:D:/testcase/02543756/ies601/testanterror/lib/commons-logging-1.0.2.jar] the LogFactory class itself indicates it was loaded by org.eclipse.ant.internal.core.AntClassLoader i.e. that if there is no plugin conflict that org.eclipse.ant.internal.core.AntClassLoader ends up (correctly) loading LogFactory from the user version of the jar in the user project. My suggestion is simply that the Ant plugin invoke the org.eclipse.ant.internal.core.AntClassLoader before the bundle classloader. p.s. I now realise that org.eclipse.ant.internal.core.AntClassLoader is a different classloader than org.apache.tools.ant.loader.AntClassLoader2 which appears earlier in the trace. Both of them are not the BundleClassLoader and if the Ant plugin can invoke org.apache.tools.ant.loader.AntClassLoader2 before the BundleClassLoader then hopefully it can also invoke org.eclipse.ant.internal.core.AntClassLoader before the BundleClassLoader.
I totally agree that it is just a choice of ordering. In the past, the AntClassLoader used to load classes first and then consult the plugin classloaders. See bug 33664 and bug 33117 for the reason for the change to the current design. Simply put, there are problems with both implementations.
Hi Darin, Thanks again. This is very helpful in getting to the root issue. I don't understand the defects you pointed to enough to make any constructive suggestions on the AntClassLoader first side. From the AntClassLoader last perspective, the Modify Attributes and Launch Dialog > Classpath dialog needs to disallow user classes ahead of the Ant Home (Default) library. In fact it really should display the plugin dependency chain that will be searched first by the BundleClassLoader and only allow user classes after that when running in the same JRE. This would also serve to document the AntClassLoader last implementation. I realize this is a spinoff from the original issue and would be glad to open a new defect for this if that's more convenient.
There are some (minor) improvements in the classpath display in 3.1 but still does not really address the issues you have pointed out. We should consider displaying the plugin dependency to truly allow the user to understand the classpath. The Ant component is not receiving alot of attention in the 3.2 cycle...mostly critical bugs and minor tweaks. I am not convinced this is in either category unfortunately.
Hi Darin, This is more important in RAD than in Eclipse because there are more plugins in the BundleClassLoader search Path on RAD. We have had 2 separate reports of a customer collision with org.apache.commons.logging.LogFactory on RAD 6.0.1. In many cases this will work by luck because many of the RAD plugins ship the same level of LogFactory that the customer is using. The exact BundleClassLoader search path seems to depend on the exact configuration of the RAD machine and varies. (This has meant we could not recreate this problem on all machines which has added to the resolution time.) So there likely many customer Ant tasks that are loading org.apache.commons.logging.LogFactory from an unexpected location and it just happens to work. A helpful stepping stone to a full display of the plugin classpath when running in the same JRE would be simply to 1/ restrict the default entries on the Classpath pane to only ones that will not be loaded by the bundle classloader. This would remove most if not all of the default entries. 2/ add words on the pane to make it clear that the user classpath will be appended to the plugin classpath 3/ document how the user can calculate the Ant plugin classpath - this may already exist
Thanks Greg. I agree we should investigate how we can at least make it easier for the user to understand the classpath within the 3.2 timeframe.
Is a possible "fix" for this problem to find the problematic plugin with the "incorrect" commons logging and set that plugin to not re-export the common logging jars?
Consider for 3.3
No further enhancements are planned for 3.3
Nothing we can do for 3.3.1
Please assess this bug for the 3.4 release. We have a customer defect waiting on this enhancement.
Has any progress been made on this?
No work is planned for 3.4
Looking at comment 13, it seems that the summary for this bug is incorrect: Classloaders do work as designed, but the request is for improving the way how the UI displays the classloader. Would it make sense to change the summary accordingly?
This bug hasn't had any activity in quite some time. Maybe the problem got resolved, was a duplicate of something else, or became less pressing for some reason - or maybe it's still relevant but just hasn't been looked at yet. If you have further information on the current state of the bug, please add it. The information can be, for example, that the problem still occurs, that you still want the feature, that more information is needed, or that the bug is (for whatever reason) no longer relevant.