This Bugzilla instance is a read-only archive of historic NetBeans bug reports. To report a bug in NetBeans please follow the project's instructions for reporting issues.

Bug 130352 - [65cat] Tests don't compile on default java platform
Summary: [65cat] Tests don't compile on default java platform
Status: RESOLVED WORKSFORME
Alias: None
Product: java
Classification: Unclassified
Component: Classpath (show other bugs)
Version: 6.x
Hardware: PC Windows XP
: P3 blocker with 1 vote (vote)
Assignee: ulfzibis
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2008-03-18 00:32 UTC by ulfzibis
Modified: 2009-11-20 01:20 UTC (History)
2 users (show)

See Also:
Issue Type: DEFECT
Exception Reporter:


Attachments
Project tree (18.33 KB, application/x-compressed)
2008-03-18 00:36 UTC, ulfzibis
Details
Alternative platform (5.11 KB, text/xml)
2008-03-18 00:37 UTC, ulfzibis
Details
Test clas moved to "Source Packages" (5.12 KB, image/jpeg)
2008-03-28 22:00 UTC, ulfzibis
Details
regenerated build-impl.xml (45.13 KB, text/xml)
2009-11-19 08:20 UTC, ulfzibis
Details

Note You need to log in before you can comment on or make changes to this bug.
Description ulfzibis 2008-03-18 00:32:10 UTC
For test purposes I have modified java.lang.Boolean. See attachment

When I compile with the default platform (here: JDK 1.6.0_04-b12) I get errors:
init:
deps-jar:
compile:
Compiling 1 source file to C:\Projects\netBeans\Bug-Compile_BooleanTest\build\test\classes
C:\Projects\netBeans\Bug-Compile_BooleanTest\test\java\lang\BooleanTest.java:24: cannot find symbol
symbol  : method valueOf(int)
location: class java.lang.Boolean
        assertTrue(Boolean.valueOf(1));
C:\Projects\netBeans\Bug-Compile_BooleanTest\test\java\lang\BooleanTest.java:25: cannot find symbol
symbol  : method valueOf(int)
location: class java.lang.Boolean
        assertFalse(Boolean.valueOf(0));
2 errors
BUILD FAILED (total time: 0 seconds)

When I compile with an alternative platform (here: JDK 1.6.0-b105, see attachment) I have no problems.

When I compile from command line (see ../bin in project dir), both work:
- C:\Programme\Java\jdk1.6.0_04\bin\javac -cp "C:\Programme\Java\NetBeans 6.0.1\java1\modules\ext\junit-3.8.2.jar"
-Xbootclasspath/p:..\build\classes -d ..\build\test\classes ..\test\java\lang\BooleanTest.java
- C:\Programme\Java\jdk1.6.0\bin\javac -cp "C:\Programme\Java\NetBeans 6.0.1\java1\modules\ext\junit-3.8.2.jar"
-Xbootclasspath/p:..\build\classes -d ..\build\test\classes ..\test\java\lang\BooleanTest.java

You have to run first:
- C:\Programme\Java\jdk1.6.0\bin\javac -d ..\build\classes ..\src\java\lang\Boolean.java
Comment 1 ulfzibis 2008-03-18 00:36:29 UTC
Created attachment 58531 [details]
Project tree
Comment 2 ulfzibis 2008-03-18 00:37:41 UTC
Created attachment 58532 [details]
Alternative platform
Comment 3 ulfzibis 2008-03-20 12:18:09 UTC
I'm not shure, if core is the right component for this issue. I tried there, as it "provides compilation".

Long time I thought, that this is a JDK bug, see:
http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6575083
Comment 4 Tomas Zezula 2008-03-27 13:24:03 UTC
It's an Ant behavior (performance).
By default Ant doesn't fork VM for javac target. Forcing the fork will slowdown the compilation by default platform for everyone.
You can either use the non default platform as you found or you can override the -init-macrodef-javac target and add fork="true"
attribute to it.

Comment 5 Tomas Zezula 2008-03-27 13:25:11 UTC
I've added doc team to the cc list, it probably should be documented.
Comment 6 Patrick Keegan 2008-03-27 14:41:11 UTC
Let me attempt to understand the issue:

You are patching the JDK and trying to run an app against the JDK? It works when you run the IDE from a different IDE
than the one you are patching?
Comment 7 ulfzibis 2008-03-28 20:36:52 UTC
> You are patching the JDK and trying to run an app against the JDK? It works when you run the IDE from a different IDE
> than the one you are patching?

A little bit different:
I am patching the JDK and trying to run a test class against the patched JDK?
Patching the Boolean class is only for finding out the source of my compile errors. The patch I'm working on is:
https://jdbc-odbc-enhanced.dev.java.net/
As I'm not patching the IDE, I see no cause, why to start it from a different IDE.
Comment 8 ulfzibis 2008-03-28 21:06:00 UTC
Correction:
I am patching the JDK and trying to _compile_ a test class against the patched JDK?
Comment 9 ulfzibis 2008-03-28 21:55:41 UTC
Something I don't understand:
If I move my test class from "Test Packages" to "Source Packages", I can compile the test class without setting
fork="true". Why?

For me it seems, that there must be a significant difference in the settings involved by ant target -do-compile-single
vs. -do-compile-test-single.
Can this brought more in line?
Comment 10 ulfzibis 2008-03-28 22:00:55 UTC
Created attachment 59323 [details]
Test clas moved to "Source Packages"
Comment 11 ulfzibis 2008-03-28 22:10:08 UTC
Perhaps issue 122677 gives some idea.
Comment 12 ulfzibis 2008-03-28 23:53:57 UTC
I've tried the fork stuff ...

build.xml:
<project name="Bug-Compile_BooleanTest" default="default" basedir=".">
    <description>Builds, tests, and runs the project Bug-Compile_BooleanTest.</description>
    <import file="nbproject/build-impl.xml"/>
    <target name="-init-macrodef-javac">
        <macrodef name="javac" uri="http://www.netbeans.org/ns/j2se-project/3">
            <attribute fork="true"/>
            <attribute default="${src.dir}" name="srcdir"/>
            <attribute default="${build.classes.dir}" name="destdir"/>
            <attribute default="${javac.classpath}" name="classpath"/>
...

... and got an error on compiling BooleanTest.java :

C:\Projects\netBeans\Bug-Compile_BooleanTest\build.xml:9: attribute doesn't support the "fork" attribute
BUILD FAILED (total time: 0 seconds)
Comment 13 Jiri Prox 2008-04-11 00:54:09 UTC
moving opened issues from TM <= 6.1 to TM=Dev
Comment 14 ulfzibis 2008-07-29 11:18:07 UTC
Just wanted to draw some attention to this issue for 6.5.

Thanks, Ulf
Comment 15 Max Sauer 2009-02-17 10:28:11 UTC
Have you tried fork="true" as a javac attribute (http://ant.apache.org/manual/CoreTasks/javac.html)?:

    <target name="-init-macrodef-javac">
        <macrodef name="javac" uri="http://www.netbeans.org/ns/j2se-project/3">
            <attribute default="${src.dir}" name="srcdir"/>
...
            <element name="customize" optional="true"/>
            <sequential>
                <javac fork="true" debug="@{debug}" deprecation="${javac.deprecation}" destdir="@{destdir}" encoding="${source.encoding}" 
excludes="@{excludes}" includeantruntime="false" includes="@{includes}" source="${javac.source}" sourcepath="@{sourcepath}" srcdir="@{srcdir}" 
target="${javac.target}">

Comment 16 ulfzibis 2009-02-19 12:46:40 UTC
Hi Max,

thanks for indirectly answering my question from Fri Mar 28 22:53:57 +0000 2008.

I've waited so long for it.

So you guess right, I didn't try that.

Do I understand right, that the options, given by <sequential> <javac ......> are not really javac options, but ant
options, which partly were forwarded to javac options?
Comment 17 ulfzibis 2009-02-19 13:21:09 UTC
I have read, what is written about fork="true" as a javac attribute (http://ant.apache.org/manual/CoreTasks/javac.html).

Hm, not easy to understand. :-(
E.g. I don't understand the difference between fork="true" and fork="yes". (Maybe error in doku?)
Comment 18 Tomas Zezula 2009-11-12 06:15:01 UTC
As I have described in #4. The default platform uses the fork='false' because of performance reasons.
If you need an patched boot cp (not very common) use the non default platform.
Comment 19 ulfzibis 2009-11-12 06:30:30 UTC
Is it possible to fork javac by custom setting in build.xml ?
Comment 20 Tomas Zezula 2009-11-12 06:51:25 UTC
You can override the -init-macrodef-javac javac as Max described above.
In addition to this I can add the property into the project.properties (java.fork.force) which will force the fork=true. If you want this option let me know.
Comment 21 ulfzibis 2009-11-12 10:24:47 UTC
Yes, that would be very cool.

If I understand you right, this would implicit Max's macro in standard build-impl.xml, so I should only need to toggle the property in project.properties.
Comment 22 ulfzibis 2009-11-12 10:35:24 UTC
> As I have described in #4. The default platform uses the fork='false' because
> of performance reasons.

I don't understand, why compiling those sources is successful even with fork='false' if they are located in src dir tree rather than in test dir tree.

Please clarify.
Comment 23 Tomas Zezula 2009-11-13 01:14:58 UTC
>Yes, that would be very cool.
OK, I will add it.

>If I understand you right, this would implicit Max's macro in standard
>build-impl.xml, so I should only need to toggle the property in
>project.properties.
Right, the Max's change just changed fork='false' to fork='true'

>I don't understand, why compiling those sources is successful even with
>fork='false' if they are located in src dir tree rather than in test dir tree.
It's because of the javac ClassReader.fillIn which lists the java.lang package in both the src folder and rt.jar and than it prefers the file with the higher modification time.
For tests the modified Boolean is not on source path but on boot classpath and compile classpath. The boot classpath has higher precedence to compile classpath. The modified Boolean is not used.
The difference among these two cases is where the second Boolean is src classpath vs. compile classpath.
Comment 24 Tomas Zezula 2009-11-13 02:57:42 UTC
I've added the javac.fork property, used when compile on save is off and the default platform is used.
By default the build-impl.xml defines it to 'false' if you sets it to true in the project.properties or private.properties the javac will run in separated jvm.
Inegrated into jet-main: 713cfd6c310d
Comment 25 Quality Engineering 2009-11-16 03:20:24 UTC
Integrated into 'main-golden', will be available in build *200911160201* on http://bits.netbeans.org/dev/nightly/ (upload may still be in progress)
Changeset: http://hg.netbeans.org/main/rev/713cfd6c310d
User: Tomas Zezula <tzezula@netbeans.org>
Log: #130352:Tests don't compile on default java platform
Comment 26 ulfzibis 2009-11-17 07:48:09 UTC
> Integrated into 'main-golden', will be available in build *200911160201*

Can't find any change regarding javac.fork property in build-impl.xml of my project after opening from this build. :-(
Comment 27 ulfzibis 2009-11-17 08:16:59 UTC
> The difference among these two cases is where the second Boolean is src
> classpath vs. compile classpath.

Do I understand right:
In case of "Build" customized Boolean is compiled, because it instantiates separate JVM instance, so younger Boolean.java in src folder is preceded over older Boolean.class from rt.jar. This would explain, why I sometimes have problems after updating to new JDK.
Order:
- src folder files (if younger or not existent in rt.jar)
- additional source paths defined by project properties

In case of "Run Test", JVM instance, which was instantiated to run netbeans, is used to compile test/src sources if not just present in JVM/build folder paths.
Order:
- rt.jar classes
- build folder classes
- src folder source files (if not existent in rt.jar or build folder classes)
- test folder source files
Comment 28 Tomas Zezula 2009-11-18 01:56:50 UTC
If you have build with the fix the javac task for default platform should look like:

<javac debug="@{debug}" deprecation="${javac.deprecation}" destdir="@{destdir}" encoding="${source.encoding}" excludes="@{excludes}" fork="${javac.fork}" includeantruntime="false" includes="@{includes}" source="${javac.source}" sourcepath="@{sourcepath}" srcdir="@{srcdir}" target="${javac.target}" tempdir="${java.io.tmpdir}">
......
</javac>

For existing projects, the project infrastructure should regenerate the build-impl.xml iff the project is up to date (no older version of project.xml) and there were no changes in the build-impl.xml file. You can force the regeneration by deleting (renaming) the build-impl.xml, closing and reopening the project.
Comment 29 Tomas Zezula 2009-11-18 02:15:26 UTC
>In case of "Build" customized Boolean is compiled.....
In reality there are 4 cases:
1) Compile of sources with forked JDK
2) Compile of tests with forked JDK
3) Compile of sources with non forked JDK (the JDK IDE runs on)
4) Compile of tests with forked JDK (the JDK IDE runs on)

The case 1 and 2 will work fine when your modified boolean is a part of your platform (JDK).
In the case 3 java will load the boolean both from rt.jar (of the platform IDE is running on) and src folder
and the file with higher time stamp will be used. (As I described above).
The case 4 Boolean is load from rt.jar only as it is preferred to classpath.
Comment 30 ulfzibis 2009-11-19 06:50:36 UTC
> By default Ant doesn't fork VM for javac target. [2008-03-27 13:24:03]

I guess you meant "doesn't fork _JDK_". This would help to clarify my long lasting confusion.

What is right? :
- Ant ignores the javac -Xbootclasspath option, if fork=false AND platform=default
Or:
- Ant always ignores javac -Xbootclasspath option, but compiles if customized Boolean is newer than from JDK's rt.jar, AND is in src folder (not other sourcepath)
- If rt.jar is updated to newer version, former successive project doesn't compile any more, until Boolean.java is touched

In case of compile a file in "Test Packages":
- the src folder is no more in javac -sourcepath
  - javac prefers Boolean from rt.jar vs. -classpath i.e. build folder
- if Foo is in src folder, but not compiled to build folder, compiling FooTest (referring to Foo) fails
Comment 31 ulfzibis 2009-11-19 07:40:10 UTC
Can you additionally clarify the difference between fork="true" and fork="yes"?
(found in built-impl.xml)
BTW, I can't find any fork="false", so where is defined, that JDK is not forked, if platform is default?
In my former -init-macrodef-javac target I surprisingly see fork="yes"
Comment 32 ulfzibis 2009-11-19 08:20:16 UTC
Created attachment 91355 [details]
regenerated build-impl.xml

At least I tried your rename trick on Build 200911160201:
- close project
- rename build-impl.xml
- open project
I still can't find javac.fork in regenerated build-impl.xml, but a mixture of fork="true" and fork="yes".
Comment 33 Tomas Zezula 2009-11-20 01:07:45 UTC
>I guess you meant "doesn't fork _JDK_". This would help to clarify my longlasting confusion.
Yes. When fork='fasle' the Ant do not create a new JVM instance and runs the compiler in the same instance of JVM as it is running by creating a new ClassLoader, loading the javac main class.

>What is right? :
>- Ant ignores the javac -Xbootclasspath option, if fork=false AND platform=default
>Or:
>- Ant always ignores javac -Xbootclasspath option, but compiles if customized Boolean is newer than >from JDK's rt.jar, AND is in src folder (not other sourcepath)
In general Ant do not ignore -Xbootclasspath if it's given. But NetBeans Ant script do not pass the platform path explicitly (we do not modify boot cp). In general the javac ant task can take the boot class path, either using the bootclasspath attribute or on by compilerarg, e.g.

<javac srcdir="src" destdir="classes">
    <compilerarg arg="-Xbootstrap/p:${toString:prepend.path.ref}"/>
</javac>

 
>- If rt.jar is updated to newer version, former successive project doesn't
>compile any more, until Boolean.java is touched
Right. If the lastModified(rt.jar/j/l/Boolean.class) > lastModified(src/j/l/Boolean.java) the Boolean.java is not used.

>In case of compile a file in "Test Packages":
>- the src folder is no more in javac -sourcepath
Right
>- javac prefers Boolean from rt.jar vs. -classpath i.e. build folder
Right
>- if Foo is in src folder, but not compiled to build folder, compiling FooTest (referring to Foo) fails
Yes. The test source path contains only the test roots not the source roots. The compile path of the test contains by default junit, build folder of sources and libs.
Comment 34 Tomas Zezula 2009-11-20 01:10:46 UTC
>Can you additionally clarify the difference between fork="true" and fork="yes"?
There is not difference. Ant takes 'true', 'yes', 'on' and 1 as positives and 'false','no','off',0 as negatives.
Comment 35 Tomas Zezula 2009-11-20 01:20:06 UTC
From the attached build-impl.xml it seems that the script is generated for explicit (non default) platform.
The javac task always has fork='true' in this case.

<java classname="@{classname}" dir="${work.dir}" fork="true" jvm="${platform.java}"> <---- explicit platform, the java task takes explicitly the jvm to start.