Bug 3158

Summary: "java" task has got problems with loading classes on Java1.4
Product: Ant Reporter: Andreas Schildbach <apache.org>
Component: Core tasksAssignee: Ant Notifications List <notifications>
Status: RESOLVED FIXED    
Severity: normal CC: jesse.glick, jrspm, kohlhaas, thorsten.sommermann
Priority: P3 Keywords: JDK1.4
Version: 1.4   
Target Milestone: ---   
Hardware: PC   
OS: All   
Attachments: demonstration of the (maybe) bug
The targer "run_fail" demonstrates failure to load a resource. The target "run_ok" forks a new VM and successfully finds the resource.
Bug report
Java test that fails when not forked
build.xml file for myTest.java

Description Andreas Schildbach 2001-08-17 09:49:46 UTC
when i use the java task to execute a class, i frequently have got problems to 
load classes. for example: when i do a Class.forName(), a 
java.lang.NoClassDefFoundError is thrown. i double-checked that the class is in 
the classpath. the strange thing is when i emulate the java task by an exec 
task (running java.exe "by hand"), everything works fine.
this problem has been present at least since ant 1.3 final.
Comment 1 Conor MacNeill 2001-08-18 23:26:49 UTC
This sort of behaviour can usually be explained or investigated but we will 
need more information. We need to know your system classpath, the classpath you 
are using with your Java task and even the ant-debug output which will show the 
activity of the Ant classloader.
Comment 2 Andreas Schildbach 2001-08-21 07:33:24 UTC
Created attachment 434 [details]
demonstration of the (maybe) bug
Comment 3 Conor MacNeill 2001-08-27 07:06:58 UTC
I have improved the error reporting in the classloader for this but ultimately 
this bug comes from the interaction of the classloader and the fact that the VM 
now includes many classes from outside the java/javax namespaces. The error now 
reported is this

java.lang.NoClassDefFoundError: org/xml/sax/helpers/DefaultHandler
        at java.lang.ClassLoader.defineClass0(Native Method)

Ant's classloader for <java> tasks tries to minimize the chance of Linkage 
errors by only allowing java.* classes to be loaded from the parent 
classloader. Thus when your class tries to load 
org.xml.sax.helpers.DefaultHandler, Ant's loader says no and tries to resolve 
the class in the classpath it has been given. 

That hueristic is OK under JDK 1.3 for most cases (CORBA maybe an exception), 
but is going to breakdown under JDK 1.4 for a larger number of situations (XML 
parsing).

This will require more thought since it affects the whole classloading strategy 
which needs to be redesigned to more cleanly separate the classes available to 
the Ant core, the tasks, and tasks like <java>, while avoiding linkage errors. 
Comment 4 Conor MacNeill 2001-08-27 07:07:39 UTC
Didn't mean to close this one
Comment 5 Jason Gilman 2001-10-03 07:16:21 UTC
Created attachment 629 [details]
The targer "run_fail" demonstrates failure to load a resource. The target "run_ok" forks a new VM and successfully finds the resource.
Comment 6 Steve Loughran 2002-02-16 18:17:47 UTC
-Changed the title to emphasise java1.4 nature. I'd have made it a keyword but 
I cant. Now that 1.4 is out we should address this somehow. 
Comment 7 Diane Holt 2002-04-01 02:58:01 UTC
Conor, Steve -- do you know if this is still a problem? (I don't have Java1.4)
Comment 8 Steve Loughran 2002-05-05 05:46:19 UTC
The problem conor refers to (things like org.w3c) in the base classloader 
still exist and need fixing. 

But, I had a look at the attachment from Jason; his problem is that
ClassLoader.getSystemClassLoader().getResource( "Test2.class" ) fails

...probably because he is using the wrong classloader, right? The system 
classloader when fork=false cant see the test2.class; he should be using 
this.getClass().getClassloader() or something similar.
Comment 9 Steve Loughran 2002-07-12 17:28:18 UTC
*** Bug 10682 has been marked as a duplicate of this bug. ***
Comment 10 Christopher Kohlhaas 2002-08-18 01:18:01 UTC
I got an NoClassDefFoundError when using reflecation in combination with the
java task. I get a NoClassDefFoundError when I instanciate the same class more
than 5 times via reflection-api.

I've attached a small reproduction.
Comment 11 Christopher Kohlhaas 2002-08-18 01:20:58 UTC
Created attachment 2751 [details]
Bug report
Comment 12 Steve Schlaifer 2002-11-22 19:10:54 UTC
Created attachment 3924 [details]
Java test that fails when not forked
Comment 13 Steve Schlaifer 2002-11-22 19:13:45 UTC
Created attachment 3925 [details]
build.xml file for myTest.java
Comment 14 Steve Schlaifer 2002-11-22 19:17:50 UTC
I have provided two attachments for this bug in the hopes that they 
will help to find and fix it.  myTest.java and myBuild.xml.  If you 
comment out any one of the six tests in myTest.java, it will run 
either forked or non-forked.  If you leave all six in place, it will 
fail with a NoClassDefFound error when not forked but will run when 
forked.
Comment 15 Jesse Glick 2002-12-02 16:47:04 UTC
On at least some VMs, may work to use ClassLoader.systemClassLoader.parent; on
my Sun 1.4.1 VM, this is the extension loader (with parent null == bootstrap
loader). That will load from rt.jar (incl. org.xml.sax.** etc.) as well as
registered extensions (jre/lib/ext/). But I'm not at all sure this is guaranteed
to work, especially on JDK 1.1.
Comment 16 Conor MacNeill 2003-01-25 11:10:12 UTC
Summary
========
Andreas - your example works on Ant 1.6 alpha

Jason - your example fails and will always fail. By asking for the System
classloader, you are getting Ant's system loader. The <java> task with fork="no"
provides an imperfect approximation of running your class in its own VM. Things
like fiddling with System.out and using System resources such as the System
Loader will generally cause problems. You need to either change your loading
approach to something like

URL url = Test2.class.getClassLoader().getResource( "Test2.class" );

which will work when not forked or accept the fact that some things need to be
forked.

Christopher - your bug is fascinating - the first four iterations work - the 5th
fails. Anyway, under Ant 1.6Alpha, this works correctly.

Steve - your example also displays the weird behaviour of Christoper's example
and it too works under Ant 1.6alpha

or, in other works we have FIXED, WONTFIX, FIXED, FIXED. 

I'm going to close as FIXED.