Skip to main content

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [List Home]
Re: [platform-ant-dev] Eclipse 2.1.0 AntRunner regression from 2.0.0


You are doing something wrong but you are not stupid...classloaders give me headaches as well :-)

Your AntLogger is getting loaded by the "wrong" class loader so the instanceof check fails.  In 2.1, the order of loading classes changed: first plugin loaders are queried for a class, and then the URLs on the Ant runtime classpath are used to resolve the class.
See http://bugs.eclipse.org/bugs/show_bug.cgi?id=33664 for all the details.

The fix:
you need separation from the classes of your plugin and the classes in your some-ant.jar. Your extra classpath JAR must not be a plug-in library and your AntLogger can reference any class available for the plugin but plug-in classes must not access the logger.
This was recommended in 2.0 but it is "enforced" in 2.1.
It is outlined in the Help provided within Eclipse under the Platform Plug-in Developers Guide > Platform Ant support.

HTH
Darins



Štěpán Roh <rohs@xxxxxxxxxxxxx>
Sent by: platform-ant-dev-admin@xxxxxxxxxxx

04/24/03 11:05 AM
Please respond to platform-ant-dev

       
        To:        platform-ant-dev@xxxxxxxxxxx
        cc:        
        Subject:        [platform-ant-dev] Eclipse 2.1.0 AntRunner regression from 2.0.0



Hello, I have a problem with AntRunner. I'm embedding Ant in my code using
following construct:

AntRunner ant = new AntRunner();
ant.addBuildLogger(AntLogger.class.getName());
ant.setBuildFileLocation(SOME_PATH);
ant.setArguments("-Dbuild.compiler=" + SOME_COMPILER);
ant.run(SOME_MONITOR);

AntLogger is a special build logger which integrates Ant logs into the rest of
the system.

Both are in the same plugin, AntRunnerWrapper is in some.jar, AntLogger in
some-ant.jar. Both are mentioned in plugin.xml.

I also defined these extensions:

  <extension
        point="org.eclipse.ant.core.extraClasspathEntries">
     <extraClasspathEntry
           library="some-ant.jar"/>
  </extension>
  <extension
        point="org.eclipse.ant.core.antTasks">
     <antTask
           library="some-ant.jar"
           name="SOME_TASK"
           class="SOME_CLASS">
     </antTask>
  </extension>

When I run the code I get:

org.eclipse.core.runtime.CoreException[1]:
com.disnetsoft.builder.core.ant.AntLogger which was specified to perform
logging is not an instance of org.apache.tools.ant.BuildLogger.
       at
org.eclipse.ant.internal.core.ant.InternalAntRunner.createLogger(InternalAntRunner.java:659)
       at
org.eclipse.ant.internal.core.ant.InternalAntRunner.addBuildListeners(InternalAntRunner.java:192)
       at
org.eclipse.ant.internal.core.ant.InternalAntRunner.run(InternalAntRunner.java:522)
       at
org.eclipse.ant.internal.core.ant.InternalAntRunner.run(InternalAntRunner.java:367)
       at java.lang.reflect.Method.invoke(Native Method)
       at org.eclipse.ant.core.AntRunner.run(AntRunner.java:335)
       at MY_CODE
--- Nested Exception ---
java.lang.ClassCastException: com.disnetsoft.builder.core.ant.AntLogger
       at
org.eclipse.ant.internal.core.ant.InternalAntRunner.createLogger(InternalAntRunner.java:655)
       at
org.eclipse.ant.internal.core.ant.InternalAntRunner.addBuildListeners(InternalAntRunner.java:192)
       at
org.eclipse.ant.internal.core.ant.InternalAntRunner.run(InternalAntRunner.java:522)
       at
org.eclipse.ant.internal.core.ant.InternalAntRunner.run(InternalAntRunner.java:367)
       at java.lang.reflect.Method.invoke(Native Method)

        at org.eclipse.ant.core.AntRunner.run(AntRunner.java:335)
       at MY_CODE

AntLogger is of course instance of org.apache.tools.ant.BuildLogger.

The exact same code worked in Eclipse 2.0.0, but is not working in Eclipse
2.1.0. If I replace libraries in plugins org.apache.ant and
org.eclipse.ant.core with those from Eclipse 2.0.0 everything works (which is
not a big surprise).

I tried to debug it (and, trust me, this classpath and reflection hell is
giving me headaches) and it looks like AntLogger and its interface
BuildLogger are normally loaded from plugins they belong to, but it is then
casted to BuildLogger from different ClassLoader. This is the relevant part
from InternalAntRunner (as presented in Eclipse 2.1.0):

private BuildLogger createLogger() {
       if (loggerClassname == null) {
                buildLogger= new DefaultLogger();
        } else if (!"".equals(loggerClassname)) { //$NON-NLS-1$
// ...snip...
buildLogger = (BuildLogger) (Class.forName(loggerClassname).newInstance());
// ...snip...
        }
        return buildLogger;
}

I had an impression that BuildLogger in InternalAntRunner is actually loaded
from jar file on Ant's classpath, but now I'm not as sure as I was, but it is
the only reason I can think of.

Am I doing something wrong, am I stupid? Please tell me.

Thanks.

Stepan Roh
rohs@xxxxxxxxxxxxx

_______________________________________________
platform-ant-dev mailing list
platform-ant-dev@xxxxxxxxxxx
http://dev.eclipse.org/mailman/listinfo/platform-ant-dev



Back to the top