Community
Participate
Working Groups
I just recognized a problem with the JDK classpath used during ANT based compilations. I'm running eclipse itself with jdk 1.4.1 (the IDE startup) but have jdk 1.3.1 based application projects (using the preferences from Java/Installed JREs). Despite having set ANTs runtime classpath explicitly to the jdk1.3.1 jars, compilation runs seem to mix with classes from the jdk 1.4.1 (the JRE under which the eclipse IDE itself is running). Application classes with direct reference to jdk classes/interfaces (i.e. implementing java.io.Serializable) get a different serial version UID when compiled from within eclipse (where the preferences configured JRE with jdk 1.3.1 is used) compared to the class files which are created when I compile through ANT scripts (invoked with the eclipse ANT runner, of course with the JDTCompilerAdapter correctly set). When I start the Eclipse IDE with a 1.3.1 JRE as well, the "normal" eclipse compile and the compile with ANT scripts through the eclipse ANT runner produce identical class results with identical serial version UID (which is what we need). This currently prevents using the eclipse ANT runner when the eclipse IDE and the application projects have to be based on different jdk's. The problem is new since eclipse 2.1. - we did the same things (mixing IDE used jdk 1.4.1 and "Installed JREs "settings jdk 1.3.1) with eclipse 2.0 and the related ANT runner without any problem (always had identical classes from compilations with both compilation methods). I have isolated the problem in a reproducable sample (just one little class implementing Serializable) and could provide this sample with the ANT xml script if you let me know where to email it. Regards Andreas
Created attachment 4927 [details] Sample to reproduce the bug The attached zip archive contains the following four other zip archives to reproduce the problem as well as the sample results from my system: 1. testcompile.zip (AbstractPeriod.java sample class and a little jar which is a classpath prerequisite for compiling the class) 2. AntScript.zip (the xml script used for compilation with a related properties file. The properties file needs to be adapted to the directory path to which the testcompile.zip has been extracted. 3. EclipseClass.zip - the class file as compiled with the native eclipse IDE compile run - SerialVersionUID=-316726712380011160L 4. ANT_temp.zip - the ant compilation result, class file with SerialVersionUID=-892296186103072337L
I have recreated the problem. Performing a javap on the classes produced produces the following results. Class files created inside Eclipse when starting with either the JDK 1.3.1_02 or J2SDK1.4.1_02 produce the same results: Compiled from AbstractPeriod.java public abstract class com.jcoffee.abstractions.calendar.interfaces.AbstractPeriod extends java.lang.Object implements com.jcoffee.abstractions.calendar.interfaces.Period, java.io.Serializable, com.jcoffee.base.global.literals.LiteralObject { public com.jcoffee.abstractions.calendar.interfaces.AbstractPeriod(); public boolean contains (com.jcoffee.abstractions.calendar.interfaces.Period); public boolean intersects (com.jcoffee.abstractions.calendar.interfaces.Period); public boolean isDay(); public java.lang.String toString(); public abstract java.lang.String getName(); public abstract java.lang.String getKey(); public abstract com.jcoffee.abstractions.calendar.Day getStartingDay(); public abstract com.jcoffee.abstractions.calendar.Day getEndingDay(); public abstract java.lang.String getType(); } This matches the ant built class file when Eclipse is started with JDK1.3.1_02 using the JDTCompilerAdapter: No sourcepublic abstract class com.jcoffee.abstractions.calendar.interfaces.AbstractPeriod extends java.lang.Object implements com.jcoffee.abstractions.calendar.interfaces.Period, java.io.Serializable, com.jcoffee.base.global.literals.LiteralObject { public com.jcoffee.abstractions.calendar.interfaces.AbstractPeriod(); public boolean contains (com.jcoffee.abstractions.calendar.interfaces.Period); public boolean intersects (com.jcoffee.abstractions.calendar.interfaces.Period); public boolean isDay(); public java.lang.String toString(); public abstract java.lang.String getName(); public abstract java.lang.String getKey(); public abstract com.jcoffee.abstractions.calendar.Day getStartingDay(); public abstract com.jcoffee.abstractions.calendar.Day getEndingDay(); public abstract java.lang.String getType(); } Note the abstract methods at the end. Here is the javap output for the same class file built with ant when Eclipse is started with J2SDK1.4.1_02. The JDTCompilerAdapter was defined to use the internal Eclipse compiler: No sourcepublic abstract class com.jcoffee.abstractions.calendar.interfaces.AbstractPeriod extends java.lang.Object implements com.jcoffee.abstractions.calendar.interfaces.Period, java.io.Serializable, com.jcoffee.base.global.literals.LiteralObject { public com.jcoffee.abstractions.calendar.interfaces.AbstractPeriod(); public boolean contains (com.jcoffee.abstractions.calendar.interfaces.Period); public boolean intersects (com.jcoffee.abstractions.calendar.interfaces.Period); public boolean isDay(); public java.lang.String toString(); } Note that the abstract methods are not included in this version.
The default abstract methods are not generated if the compliance mode is 1.4. Your problem is the following. The ant adapter sets the compliance level according to the VM on which it is running. Inside Eclipse you set the compliance level to be 1.3, but because you run Eclipse on a 1.4 VM, when you recompile using ant it will set the compliance level to 1.4. So I can see three solutions: 1) You set the compliance level to 1.4 inside Eclipse and you change the default compliance settings to keep the generated .class file compatibility with 1.1 and the source level with 1.3. Basically this will only change the compliance level. 2) You run your ant script on a new VM using a 1.3.1 VM and then the compliance level will be set to 1.3. 3) You set yourself the serialVersionID in your classes. This will prevent the VM from setting it at runtime. Let me know if this works for you.
I said something wrong. It is not related to the compliance level. In this case the problem is the target value. This is set by the VM on which the ant build is running. Inside Eclipse you can change the target value. By default it is 1.1. When running on a 1.4 VM, I think the default is 1.2. Abstract methods are no longer required when the target level is greater than or equal to 1.2. So in this case a solution for you could be to set the target level in your ant script to 1.1. This is written in bold in the ant javac task documentation. See: http://ant.apache.org/manual/CoreTasks/javac.html
I already recognized it, just had tried your proposal 1) with the same result of different class size and SerialVersionUID as originally described. Was just reporting back when your last response hit me. I'll try out setting the target level. You state "Inside Eclipse you can change the target value" - but I'm not clear which preferences parameter this is. Obviously it seems not to be one of the "JDK Compliance" parameters? I was doing my latest test with your proposal 1) from previous post with the following "JDK Compliance" settings: Compiler compliance level: 1.4 Generated .class file compatibility: 1.1 Source compatibility: 1.3 This has not helped. Thanks for your support. Regards Andreas
According to my last answer, you can either set the target value to 1.2 inside Eclipse (see my screenshot) or set the target value to 1.1 in your ant javac task. Let me know if it works.
Created attachment 4936 [details] Screenshot to set the target level You need to uncheck the default compliance settings and change the target level to 1.2.
Moving to JDT Core.
The best solution remains to set the serialVersionID for your classes. As long as you don't do that, you are VM dependant in the sense that the VM will compute this value at runtime.
Given it is the same compiler on both ends (ours) and the same VM, it should just work once the configuration is the same (compliance and target).
Thanks! I checked both variations, setting eclipse target to 1.2 and leave my ANT scripts as they are as well as adding the target="1.1" parameter to my ANT scripts and leaving eclipse on target 1.1. (which is what fits best with the desired environment for the application, so we'll do that). BOTH WORK WELL - Identical class files and SerialVersionUID from compile within eclipse as well as from the ANT runner compilation. So, for me the problem is fixed. Probably you'll be able to align the ANT runtime environment which is used by the eclipse ANT runner with the eclipse JRE preferences settings at some time in the future? Would be more intuitive. Thanks again to all who helped! Regards Andreas
Close.
Should have been tagged as duplicate
*** This bug has been marked as a duplicate of 10104 ***
Oops, this one isn't actually a duplicate
Closing