Whew, I've got it!

Matt, thanks for your sample JUnit testcase. I should have guessed the 
real reason sooner. This is not an issue with <junit> per se but rather 
with ANT itself [specifically with the way Execute class forks a VM {which 
is different from how forkable tasks like <java> work} combined with how 
ANT is packaged].

Basically, ANT ships with several jars that contain manifest Class-Path 
attributes pointing to each other, e.g.

        Manifest-Version: 1.0
        Main-Class: org.apache.tools.ant.Main
        Created-By: Ant 1.4
        Class-Path: jaxp.jar parser.jar crimson.jar optional.jar xalan.jar

There are at least two jars like that: ant.jar and the optional tasks jar. 
Both of these jars percolate to the -classpath of the JVM forked by 
Execute. The Class-Path attributes in their manifests effectively place 
the entire set {jaxp.jar, parser.jar, crimson.jar, optional.jar, 
xalan.jar} into the application classpath. The thing that threw me off was 
that such classpath entries will not show up either in java.class.path 
system property or java.net.URLClassLoader.getURLs () -- a pretty good 
reason never to use manifest files with Class-Path, if you ask me.

Anyway, that's how crimson.jar found its way into the forked VM in a 
completely silent fashion... I leave the proper resolution up to the dev 
team, but for you the workaround would be to edit or delete the 
manifest.mf files in the two jars I mentioned above. Not ideal, but better 
than patching ANT code yourself.

Vlad.



To:     <[EMAIL PROTECTED]>
cc: 

Subject:        RE: forked JVM's classpath not clean when using JUnit task


Vlad,

You are quite a detective!  Here's the output (below).  As I suspected,
crimson.jar is sneaking in there.  I guess the question now is, "how?"  As
you requested, I've directed this message to you only.  I'm glad that 
you're
interested in my problem, as you have a good grasp on classloading in
general.

At this point, it seems to me that a close reading of the JunitTask source
code is necessary to fix the problem, and I'm not sure that I'm up to 
doing
that.  I have a custom test runner of my own that I can wire in to ant for 
a
quick fix that will work for my current needs.  I do plan on attacking 
this
problem later on, however, so if you have any more ideas on this issue
(which I am now certain *is* a defect), I'd be glad to hear them.

[junit] resource for crimson ==
jar:file:/D:/programs/jakarta-ant-1.4.1/lib/crimson.jar!/org/apache/crimson/
parser/X
MLReaderImpl.class
[junit] Tests run: 1, Failures: 0, Errors: 0, Time elapsed: 0.221 sec

- Matt

-----Original Message-----
From: [EMAIL PROTECTED] [mailto:[EMAIL PROTECTED]]
Sent: Thursday, January 24, 2002 9:59 AM
To: Ant Users List
Subject: RE: forked JVM's classpath not clean when using JUnit task


The "current loader" shown below is the usual Java 2 application
classloader, not a custom JUnit one.... Bummer, that blows my first clue
away. If you absolutely sure none of the other jars contains crimson
classes (what are those parser.jar and xml.jar?) then hmmm....

Ok, I feel challenged now. I've thought of another trick that is even
better than my previous one. Luckily, Sun JVMs allow retrieving classes as
resource URLs and those, when converted to a String, give away the actual
disk location of a class. So, add another line to your testcase that does
this:

System.out.println (getClass().getClassLoader().getResource
("org/apache/crimson/parser/XMLReaderImpl.class"));

and let us know. Or you can just email me only, 'cause I am beginning to
suspect that we are starting to annoy the rest of the list...

Vlad.



Please respond to "Ant Users List" <[EMAIL PROTECTED]>
To:     "Ant Users List" <[EMAIL PROTECTED]>
cc:

Subject:        RE: forked JVM's classpath not clean when using JUnit task


Vlad & list,

Thanks again for all your insightful suggestions.

I created the test you suggested, and have included my output below.
Unfortunately, crimson.jar is not listed there.  Perhaps the classpath the
loader is using and the java.class.path variable are different?  Is this
possible?

Could someone out there who has experience with the junit task please
respond to this thread?  If the classpath isn't being set properly, there
is
likely a serious defect in the task that would prevent many developers
from
using it.  If at all possible, this defect should be tracked down and
removed, or at least a workaround should be found.

[junit] app classpath =
D:\programs\jakarta-ant-1.4.1\lib\junit.jar;D:\programs\jakarta-ant-1.4.1\li
b\ant.jar;D:\pro
grams\jakarta-ant-1.4.1\lib\jakarta-ant-1.4.1-optional.jar;D:\Matt\apelon\vs
s\dev200104\build\tests\ApelonCommon\jars\Te
stApelonCommon.jar;D:\Matt\apelon\vss\dev200104\build\dist\lib\ApelonCommon.
jar;D:\Matt\apelon\vss\dev200104\jars\log4j.
jar;D:\Matt\apelon\vss\dev200104\jars\parser.jar;D:\Matt\apelon\vss\dev20010
4\jars\xml.jar
[junit] current loader = sun.misc.Launcher$AppClassLoader@71732b
[junit] user.home == C:\Documents and Settings\mmunz

- Matt

-----Original Message-----
From: [EMAIL PROTECTED] [mailto:[EMAIL PROTECTED]]
Sent: Wednesday, January 23, 2002 3:42 PM
To: Ant Users List
Subject: RE: forked JVM's classpath not clean when using JUnit task


Ok, sorry about not being able to help you more right now but I can't take
any more time away from work at this point. I've looked into junit task
code [I only have ANT 1.4] and that seems to eventually fork a JVM
correctly. Unless someone else sorts this out in the meantime, I leave you
with these clues for now:

- during the fork the JUnitTest class exports all ANT project properties
into a temp props file that is
later picked up by the JUnitTestRunner class in a forked JVM. The idea is
to
resurrect the Java runtime as
closely as possible. Well, one of the properties exported is of course
"java.class.path" and it will look something like this from ANT source JVM
[note crimson.jar]:

java.class.path:
D:\J\JDK1.3\lib\tools.jar;D:\ANT\lib\jaxp.jar;D:\ANT\lib\jakarta-ant-1.4-opt
ional.jar;D:\ANT\lib\crimson.jar;D:\ANT\lib\ant.jar;

JUnitTestRunner will later absorb these into the forked JVM. Next,
normally
just setting
java.class.path post-bootstrap [like in main() or later] will not have an
effect on the normal app classloader, but [!] I happened to know that
JUnit made use of its own custom classloader. I happened to have v3.7
sources in the office and I looked at the classloader impl: lo and behold,
the first thing it does is set its classpath from "java.class.path"
property.

Anyway, I am not convinced that when JUnit is executed from <junit> task
the same init sequence takes place as when running JUnit standalone but
this is my strongest clue so far. If this proves to be correct, try
disabling JUnit classloader [I remember it has a property for that].

- if the above is a wrong clue, you could get some more data by adding a
quick pseudo-TestCase to you suite and have it output the following:

System.out.println ("app classpath = " + System.getProperty
("java.class.path"));
System.out.println ("current loader = " + getClass().getClassLoader());

Hope this helps,
Vlad.



Please respond to "Ant Users List" <[EMAIL PROTECTED]>
To:     "Ant Users List" <[EMAIL PROTECTED]>
cc:

Subject:        RE: forked JVM's classpath not clean when using JUnit task


Vlad and list,

> Is the JVM really forked as you made me think? Otherwise all ANT classes
> have access to crimson classes because it is seen by AntClassLoader....

I have indicated that I want it to be forked, and the build output seems
to
indicate this.  I can't know however, wether or not it actually does run
on
a forked JVM.  I've included the relevant build file snippet (below) in
case
it helps in your diagnosis.

In browsing the bug-tracking system for junit-related cases, I've noticed
that the junit task has produced buggy behavior in the past, so it's
possible that the junit task is responsible for this error (rather than
the
more commonly used ant code).  Are there any people on this list who are
familiar with the junit task specifically?  If so, I'd love to hear from
them about this.

Thanks again for your help with this issue.

<junit fork="true" printsummary="yes" haltonfailure="no"
failureProperty="test-failed">
<classpath>
<pathelement path="${test-proj-path}/jars/Test${jar-name}.jar" />
<pathelement path="${LIB.DIR}/${jar-name}.jar" />
<pathelement path="${classpath-ext}" />
</classpath>
<formatter type="xml" />
<batchtest fork="true" todir="${reports-dir}">
<fileset dir="${tests-src-dir}">
<include name="**/${pkg-path}/**/Test*.java" />
</fileset>
</batchtest>
</junit>

- Matt

-----Original Message-----
From: [EMAIL PROTECTED] [mailto:[EMAIL PROTECTED]]
Sent: Wednesday, January 23, 2002 2:39 PM
To: Ant Users List
Subject: RE: forked JVM's classpath not clean when using JUnit task


Is the JVM really forked as you made me think? Otherwise all ANT classes
have access to crimson classes because it is seen by AntClassLoader....




Please respond to "Ant Users List" <[EMAIL PROTECTED]>
To:     "Ant Users List" <[EMAIL PROTECTED]>
cc:

Subject:        RE: forked JVM's classpath not clean when using JUnit task


Vlad,

Thanks for your reply.

> - if crimson is in your JRE ext directory, removing it from the task's
> classpath won't make a difference.

not the case here

> - are you sure you are not including the crimson classes through one of
> the other jars? How about the CLASSPATH env var?

all of these things do not contain the crimson class files.

Any other ideas?

- Matt

-----Original Message-----
From: [EMAIL PROTECTED] [mailto:[EMAIL PROTECTED]]
Sent: Wednesday, January 23, 2002 12:27 PM
To: Ant Users List
Subject: Re: forked JVM's classpath not clean when using JUnit task


I am not familiar with junit task but I can make these comments:

- if crimson is in your JRE ext directory, removing it from the task's
classpath won't make a difference.
- are you sure you are not including the crimson classes through one of
the other jars? How about the CLASSPATH env var?

Vlad.


Please respond to "Ant Users List" <[EMAIL PROTECTED]>
To:     <[EMAIL PROTECTED]>
cc:

Subject:        forked JVM's classpath not clean when using JUnit task


Hi.

I am aware that the answer to this may already be in the archives.  They
are not available at the moment, however, so I thought I'd ask all of you
for your help.  If there is a mirror to the mail archive, or another
resource that covers this issue, I'd be happy to read it.

Problem (w2k., ant 1.4.1):

When building a project that includes a junit task, it is apparent that
crimson.jar is accessible from the JUnitTestRunner.  This is undesireable,
as my test should have no knowledge / access to crimson.jar.  I see this
behavior even when the fork attribute to my junit task is set to true.

As the output (below) shows, the execution of java.exe has the classpath
arg set to a path that does not include crimson.jar.  According to the
docs
for java.exe, this path should override any classpath set in the System's
environment variables.  Nonetheless, the output from my test clearly
indicates that crimson.jar is available to the test runner (and test).

Is there a way to fix this so that I can cleanly (w/o crimson.jar on the
classpath) run my tests?

Output (verbose):

run-test-package:
[junit] Running com.apelonTests.common.dom.TestApelDOMParser
[junit] Executing:
d:\programs\jdk1.3.1_01\jre\..\bin\java.exe -classpath
D:\programs\jakarta-ant-1.4.1\lib\junit.ja
r;D:\programs\jakarta-ant-1.4.1\lib\ant.jar;D:\programs\jakarta-ant-1.4.1\li
b\jakarta-ant-1.4.1-optional.jar;D:\Matt\ape
lon\vss\dev200104\build\tests\ApelonCommon\jars\TestApelonCommon.jar;D:\Matt
\apelon\vss\dev200104\build\dist\lib\ApelonC
ommon.jar;D:\Matt\apelon\vss\dev200104\jars\log4j.jar;D:\Matt\apelon\vss\dev
200104\jars\parser.jar;D:\Matt\apelon\vss\de
v200104\jars\xml.jar
org.apache.tools.ant.taskdefs.optional.junit.JUnitTestRunner
com.apelonTests.common.dom.TestApelDOM
Parser haltOnError=false haltOnFailure=false
formatter=org.apache.tools.ant.taskdefs.optional.junit.SummaryJUnitResultFo
rmatter
formatter=org.apache.tools.ant.taskdefs.optional.junit.XMLJUnitResultFormatt
er,D:\Matt\apelon\vss\dev200104\buil
d\tests\ApelonCommon\reports\TEST-com.apelonTests.common.dom.TestApelDOMPars
er.xml propsfile=D:\Matt\apelon\vss\Dev20010
4\build\tests\junit4486939605375226940.properties
[junit] org.xml.sax.SAXParseException: Element type "s" is not declared.
[junit]     at
org.apache.crimson.parser.Parser2.error(Parser2.java:3086)
[junit]     at
org.apache.crimson.parser.Parser2.maybeElement(Parser2.java:1316)
[junit]     at
org.apache.crimson.parser.Parser2.parseInternal(Parser2.java:500)
[junit]     at org.apache.crimson.parser.Parser2.parse(Parser2.java:305)
[junit]     at
org.apache.crimson.parser.XMLReaderImpl.parse(XMLReaderImpl.java:433)
[junit]     at
org.xml.sax.helpers.XMLReaderAdapter.parse(XMLReaderAdapter.java:223)
[junit]     at com.apelon.common.dom.ApelDOMParser.parse(Unknown Source)
[junit]     at
com.apelonTests.common.dom.TestApelDOMParser.testParse(Unknown Source)
[junit]     at java.lang.reflect.Method.invoke(Native Method)
[junit]     at junit.framework.TestCase.runTest(TestCase.java:166)
[junit]     at junit.framework.TestCase.runBare(TestCase.java:140)
[junit]     at junit.framework.TestResult$1.protect(TestResult.java:106)
[junit]     at
junit.framework.TestResult.runProtected(TestResult.java:124)
[junit]     at junit.framework.TestResult.run(TestResult.java:109)
[junit]     at junit.framework.TestCase.run(TestCase.java:131)
[junit]     at junit.framework.TestSuite.runTest(TestSuite.java:173)
[junit]     at junit.framework.TestSuite.run(TestSuite.java:168)
[junit]     at
org.apache.tools.ant.taskdefs.optional.junit.JUnitTestRunner.run(JUnitTestRu
nner.java:231)
[junit]     at
org.apache.tools.ant.taskdefs.optional.junit.JUnitTestRunner.main(JUnitTestR
unner.java:409)

Thanks in advance for any help you can offer.

- Matt Munz ([EMAIL PROTECTED])




--
To unsubscribe, e-mail:   <mailto:[EMAIL PROTECTED]>
For additional commands, e-mail: <mailto:[EMAIL PROTECTED]>

Reply via email to