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.
Summary: | [65cat] Tests don't compile on default java platform | ||
---|---|---|---|
Product: | java | Reporter: | ulfzibis <ulfzibis> |
Component: | Classpath | Assignee: | ulfzibis <ulfzibis> |
Status: | RESOLVED WORKSFORME | ||
Severity: | blocker | CC: | msauer, pkeegan |
Priority: | P3 | ||
Version: | 6.x | ||
Hardware: | PC | ||
OS: | Windows XP | ||
Issue Type: | DEFECT | Exception Reporter: | |
Attachments: |
Project tree
Alternative platform Test clas moved to "Source Packages" regenerated build-impl.xml |
Description
ulfzibis
2008-03-18 00:32:10 UTC
Created attachment 58531 [details]
Project tree
Created attachment 58532 [details]
Alternative platform
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 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. I've added doc team to the cc list, it probably should be documented. 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? > 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. Correction: I am patching the JDK and trying to _compile_ a test class against the patched JDK? 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? Created attachment 59323 [details]
Test clas moved to "Source Packages"
Perhaps issue 122677 gives some idea. 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) moving opened issues from TM <= 6.1 to TM=Dev Just wanted to draw some attention to this issue for 6.5. Thanks, Ulf 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}"> 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? 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?) 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. Is it possible to fork javac by custom setting in build.xml ? 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. 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. > 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.
>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. 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 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 > 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. :-(
> 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
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. >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.
> 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
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" 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".
>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. >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.
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. |