Bug 37940 - SerialVersionUID conflict between eclipse and ANT based compilations
Summary: SerialVersionUID conflict between eclipse and ANT based compilations
Status: RESOLVED WORKSFORME
Alias: None
Product: JDT
Classification: Eclipse Project
Component: Core (show other bugs)
Version: 2.1   Edit
Hardware: PC Windows 2000
: P3 normal (vote)
Target Milestone: 3.0 M1   Edit
Assignee: JDT-Core-Inbox CLA
QA Contact:
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2003-05-21 15:37 EDT by Andreas Zimmer CLA
Modified: 2003-09-05 07:57 EDT (History)
2 users (show)

See Also:


Attachments
Sample to reproduce the bug (14.09 KB, application/x-zip-compressed)
2003-05-21 16:06 EDT, Andreas Zimmer CLA
no flags Details
Screenshot to set the target level (21.17 KB, image/png)
2003-05-22 12:01 EDT, Olivier Thomann CLA
no flags Details

Note You need to log in before you can comment on or make changes to this bug.
Description Andreas Zimmer CLA 2003-05-21 15:37:04 EDT
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
Comment 1 Andreas Zimmer CLA 2003-05-21 16:06:13 EDT
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
Comment 2 David Wegener CLA 2003-05-22 00:01:13 EDT
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.
Comment 3 Olivier Thomann CLA 2003-05-22 10:27:25 EDT
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.
Comment 4 Olivier Thomann CLA 2003-05-22 11:24:40 EDT
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
Comment 5 Andreas Zimmer CLA 2003-05-22 11:53:28 EDT
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



 
Comment 6 Olivier Thomann CLA 2003-05-22 12:00:42 EDT
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.
Comment 7 Olivier Thomann CLA 2003-05-22 12:01:39 EDT
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.
Comment 8 Darin Swanson CLA 2003-05-22 12:06:41 EDT
Moving to JDT Core.
Comment 9 Olivier Thomann CLA 2003-05-22 12:09:54 EDT
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.
Comment 10 Philipe Mulet CLA 2003-05-22 12:37:55 EDT
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).
Comment 11 Andreas Zimmer CLA 2003-05-22 16:45:58 EDT
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

Comment 12 Olivier Thomann CLA 2003-05-23 10:25:18 EDT
Close.
Comment 13 Philipe Mulet CLA 2003-09-05 07:55:40 EDT
Should have been tagged as duplicate
Comment 14 Philipe Mulet CLA 2003-09-05 07:55:55 EDT

*** This bug has been marked as a duplicate of 10104 ***
Comment 15 Philipe Mulet CLA 2003-09-05 07:57:18 EDT
Oops, this one isn't actually a duplicate
Comment 16 Philipe Mulet CLA 2003-09-05 07:57:59 EDT
Closing