Bug 50958 - again: SerialVersionUID conflict between eclipse and ANT based compilations
Summary: again: SerialVersionUID conflict between eclipse and ANT based compilations
Status: RESOLVED DUPLICATE of bug 10104
Alias: None
Product: JDT
Classification: Eclipse Project
Component: Core (show other bugs)
Version: 2.1.2   Edit
Hardware: PC Windows 2000
: P3 normal (vote)
Target Milestone: 3.0 M7   Edit
Assignee: JDT-Core-Inbox CLA
QA Contact:
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2004-01-30 08:01 EST by Michael Brinkmann CLA
Modified: 2005-11-04 12:57 EST (History)
0 users

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Michael Brinkmann CLA 2004-01-30 08:01:17 EST
given the java-code shown below, the fix for the bug 

https://bugs.eclipse.org/bugs/show_bug.cgi?id=37940

does not work. I tried different JDKs (1.2, 1.3.1, 1.4.1, 1.4.2, using 1.1-
target-JVM-compliance)
and different java-compiler compliance-settings 
(Window/preferences/Java/Compiler/Compliance): the JDK's javac generates
a serialVersionUID of 8523314760647912606L, the Eclipse java-compiler generates
the id 6667971213220860296L.

This makes it difficult to use Eclipse for application-server-debugging (J2EE-
JMS IOException and javax.jms.MessageFormatException ("local class 
incompatible")

----snip------------------------------------------

package com.materna.buc.macs.basics.model.connectivity;

import java.io.Serializable;

/**
 * The type of a MACS-connection to the outer world
 * 
 * @author mbrinkma
 * @version 1.0
 */
public final class ConnectionChannelType implements Serializable {

  public static final ConnectionChannelType AIC_CORBA = new 
ConnectionChannelType(1, "aic/corba");
  public static final ConnectionChannelType UCP = new ConnectionChannelType
(2, "ucp");
  public static final ConnectionChannelType MM7 = new ConnectionChannelType
(3, "mm7");
  public static final ConnectionChannelType HTTP = new ConnectionChannelType
(4, "http");

  private static final ConnectionChannelType[] ALL =
    new ConnectionChannelType[] { AIC_CORBA, UCP, MM7, HTTP };

  private final int mType;
  private final String mName;

  /**
   * Private constructor.
   */
  private ConnectionChannelType(int type, String name) {
    mType = type;
    mName = name;
  }

  /**
   * Returns a copy of the array with all instances of this class.
   * <p>
   * Modifying the returned array will not affect this class.
   * 
   * @return an array with all instances of this class
   */
  public static ConnectionChannelType[] all() {

    ConnectionChannelType[] result = new ConnectionChannelType[ALL.length];
    System.arraycopy(ALL, 0, result, 0, ALL.length);
    return result;
  }
  
  public static String allToString(){
    StringBuffer rc = new StringBuffer();
    for(int ii=0; ii<ALL.length; ++ii){
      if(ii!=0)
        rc.append(", ");
      rc.append(ALL[ii].getName());
    }
    return rc.toString();
  }

  /**
   * Returns the <code>PhysicalConnectionType</code> for the specified key field
(s),
   * or throws an IllegalArgumentException
   * if no <code>PhysicalConnectionType</code> exists for the specified key 
field(s).
   * 
   * @param type the type of the <code>PhysicalConnectionType</code> to find
   * @return the <code>PhysicalConnectionType</code> for the specified key field
(s)
   */
  public static ConnectionChannelType lookup(int type) {
    for (int i = 0; i < ALL.length; i++) {
      if (ALL[i].getType() != type) {
        continue;
      }
      return ALL[i];
    }
    StringBuffer msg = new StringBuffer();
    msg.append("type=").append(type);
    throw new IllegalArgumentException("No PhysicalConnectionType found for " + 
msg);
  }
  /**
   * lookup by name
   * 
   * @param name
   * @return the <code>PhysicalConnectionType</code> for the specified name
   */
  public static ConnectionChannelType lookup(String name) {
    for (int i = 0; i < ALL.length; i++) {
      if (!ALL[i].getName().equalsIgnoreCase(name)) {
        continue;
      }
      return ALL[i];
    }
    StringBuffer msg = new StringBuffer();
    msg.append("name=").append(name);
    throw new IllegalArgumentException("No PhysicalConnectionType found for " + 
msg);
  }

  /**
   * Returns whether this instance is the {@link 
PhysicalConnectionType#AIC_CORBA} instance.
   * 
   * @return whether this instance is the {@link 
PhysicalConnectionType#AIC_CORBA} instance
   */
  public boolean isAicCorba() {
    return this == ConnectionChannelType.AIC_CORBA;
  }
  /**
   * Returns whether this instance is the {@link PhysicalConnectionType#UCP} 
instance.
   * 
   * @return whether this instance is the {@link PhysicalConnectionType#UCP} 
instance
   */
  public boolean isUcp() {
    return this == ConnectionChannelType.UCP;
  }
  /**
   * Returns whether this instance is the {@link PhysicalConnectionType#MM7} 
instance.
   * 
   * @return whether this instance is the {@link PhysicalConnectionType#MM7} 
instance
   */
  public boolean isMm7() {
    return this == ConnectionChannelType.MM7;
  }
  /**
   * Returns whether this instance is the {@link PhysicalConnectionType#HTTP} 
instance.
   * 
   * @return whether this instance is the {@link PhysicalConnectionType#HTTP} 
instance
   */
  public boolean isHttp() {
    return this == ConnectionChannelType.HTTP;
  }

  /**
   * Returns the type.
   *
   * @return the type. 
   */
  public int getType() {
    return mType;
  }

  /**
   * Returns the name.
   *
   * @return the name. 
   */
  public String getName() {
    return mName;
  }

  /**
   * Returns a String description of this <code>PhysicalConnectionType</code>.
   *
   * @return a String description of this object.
   */
  public String toString() {

    StringBuffer result = new StringBuffer();
    result.append(ConnectionChannelType.class.getName()+"[");
    result.append("type=").append(getType());
    result.append(", ");
    result.append("name=").append(getName());
    result.append("]");
    return result.toString();
  }

  /*
   * Non-javadoc.
   * @see java.lang.Object#equals(Object)
   */
  // Algorithm from "Effective Java" by Joshua Bloch.
  public boolean equals(Object o) {
    if (o == this) {
      return true;
    }
    if (!(o instanceof ConnectionChannelType)) {
      return false;
    }
    ConnectionChannelType other = (ConnectionChannelType) o;
    return true && getType() == other.getType();
  }

  /*
   * Non-javadoc.
   * @see java.lang.Object#hashCode()
   */
  // Algorithm from "Effective Java" by Joshua Bloch.
  public int hashCode() {
    int result = 17 * getClass().getName().hashCode();
    result = 37 * result + getType();
    return result;
  }

  /**
   * If this class implements <code>java.io.Serializable</code>,
   * the Java serialization mechanism provides a "hidden constructor".
   * To ensure that no other instances are created than the
   * ones declared above, we implement <code>readResolve</code>.
   * (This is not necessary if this class does not
   * implement <code>java.io.Serializable</code>).
   */
  // Algorithm from "Effective Java" by Joshua Bloch.
  private Object readResolve() throws java.io.ObjectStreamException {

    // look at the key attribute values of the instance 
    // that was just deserialized,
    // and replace the deserialized instance 
    // with one of the static objects
    return lookup(mType);
  }
}
----snip------------------------------------------
Comment 1 Philipe Mulet CLA 2004-01-30 10:17:58 EST
This is indeed not the same issue. Your problem is that you are using 2 
different compiler implementations which are not exactly behaving the same on 
unspecified aspects of the language (i.e. internal structures generated by 
compiler to emulate access to enclosing types, etc...). 

As these are not spec'ed, neither compiler is right or wrong. You simply must 
use the same compiler on both the client and server side if you want to be able 
to serialize/deserialize correctly, or tag your classes with a SerialVersionUID 
slot.

Note that different versions of the same compiler brand are likely to expose 
the same issue again. This is imposed by the language specs which aren't 
accurate enough in this area so as to dictate a common behavior. 

Comment 2 Philipe Mulet CLA 2004-01-30 10:19:08 EST

*** This bug has been marked as a duplicate of 10104 ***
Comment 3 Michael Brinkmann CLA 2004-02-03 09:43:43 EST
OK, just one thing:

- I cannot use the SUN-javac in Eclipse, right?
- creating .ear, .jar, .war, .sar-files out of Eclipse can best be
  automatized with "ant"
- so, if I want to use Eclipse for launching apps talking with remote 
  J2EE-servers, my only chance to cope with the serialVersionUID-problem
  is to use the Eclipse-javac in "ant" to generate the J2EE-Application

How can I do that?
Comment 4 Olivier Thomann CLA 2004-02-03 11:10:01 EST
You can use the Eclipse compiler inside an ant javac task by setting the
build.compiler property.
With something like this:
<target name="properties" if="eclipse.running">
<property name="build.compiler" value="org.eclipse.jdt.core.JDTCompilerAdapter"/>
</target>

If your ant environment is properly set in Eclipse, this should work. Otherwise
please report the problem to the Platform/Ant component.

Using the same compiler, you will get the same version id. The best solution is
to provide a serialVersionUID field for each of the class you want to serialize.
This would prevent future problems if you want to deserialize old instances of
your classes.

Closing as duplicate of bug 10104.

*** This bug has been marked as a duplicate of 10104 ***
Comment 5 raji CLA 2005-11-04 12:57:22 EST
(In reply to comment #0)
> given the java-code shown below, the fix for the bug 
> https://bugs.eclipse.org/bugs/show_bug.cgi?id=37940
> does not work. I tried different JDKs (1.2, 1.3.1, 1.4.1, 1.4.2, using 1.1-
> target-JVM-compliance)
> and different java-compiler compliance-settings 
> (Window/preferences/Java/Compiler/Compliance): the JDK's javac generates
> a serialVersionUID of 8523314760647912606L, the Eclipse java-compiler 
generates
> the id 6667971213220860296L.
> This makes it difficult to use Eclipse for application-server-debugging 
(J2EE-
> JMS IOException and javax.jms.MessageFormatException ("local class 
> incompatible")
> ----snip------------------------------------------
> package com.materna.buc.macs.basics.model.connectivity;
> import java.io.Serializable;
> /**
>  * The type of a MACS-connection to the outer world
>  * 
>  * @author mbrinkma
>  * @version 1.0
>  */
> public final class ConnectionChannelType implements Serializable {
>   public static final ConnectionChannelType AIC_CORBA = new 
> ConnectionChannelType(1, "aic/corba");
>   public static final ConnectionChannelType UCP = new ConnectionChannelType
> (2, "ucp");
>   public static final ConnectionChannelType MM7 = new ConnectionChannelType
> (3, "mm7");
>   public static final ConnectionChannelType HTTP = new ConnectionChannelType
> (4, "http");
>   private static final ConnectionChannelType[] ALL =
>     new ConnectionChannelType[] { AIC_CORBA, UCP, MM7, HTTP };
>   private final int mType;
>   private final String mName;
>   /**
>    * Private constructor.
>    */
>   private ConnectionChannelType(int type, String name) {
>     mType = type;
>     mName = name;
>   }
>   /**
>    * Returns a copy of the array with all instances of this class.
>    * <p>
>    * Modifying the returned array will not affect this class.
>    * 
>    * @return an array with all instances of this class
>    */
>   public static ConnectionChannelType[] all() {
>     ConnectionChannelType[] result = new ConnectionChannelType[ALL.length];
>     System.arraycopy(ALL, 0, result, 0, ALL.length);
>     return result;
>   }
>   
>   public static String allToString(){
>     StringBuffer rc = new StringBuffer();
>     for(int ii=0; ii<ALL.length; ++ii){
>       if(ii!=0)
>         rc.append(", ");
>       rc.append(ALL[ii].getName());
>     }
>     return rc.toString();
>   }
>   /**
>    * Returns the <code>PhysicalConnectionType</code> for the specified key 
field
> (s),
>    * or throws an IllegalArgumentException
>    * if no <code>PhysicalConnectionType</code> exists for the specified key 
> field(s).
>    * 
>    * @param type the type of the <code>PhysicalConnectionType</code> to find
>    * @return the <code>PhysicalConnectionType</code> for the specified key 
field
> (s)
>    */
>   public static ConnectionChannelType lookup(int type) {
>     for (int i = 0; i < ALL.length; i++) {
>       if (ALL[i].getType() != type) {
>         continue;
>       }
>       return ALL[i];
>     }
>     StringBuffer msg = new StringBuffer();
>     msg.append("type=").append(type);
>     throw new IllegalArgumentException("No PhysicalConnectionType found 
for " + 
> msg);
>   }
>   /**
>    * lookup by name
>    * 
>    * @param name
>    * @return the <code>PhysicalConnectionType</code> for the specified name
>    */
>   public static ConnectionChannelType lookup(String name) {
>     for (int i = 0; i < ALL.length; i++) {
>       if (!ALL[i].getName().equalsIgnoreCase(name)) {
>         continue;
>       }
>       return ALL[i];
>     }
>     StringBuffer msg = new StringBuffer();
>     msg.append("name=").append(name);
>     throw new IllegalArgumentException("No PhysicalConnectionType found 
for " + 
> msg);
>   }
>   /**
>    * Returns whether this instance is the {@link 
> PhysicalConnectionType#AIC_CORBA} instance.
>    * 
>    * @return whether this instance is the {@link 
> PhysicalConnectionType#AIC_CORBA} instance
>    */
>   public boolean isAicCorba() {
>     return this == ConnectionChannelType.AIC_CORBA;
>   }
>   /**
>    * Returns whether this instance is the {@link PhysicalConnectionType#UCP} 
> instance.
>    * 
>    * @return whether this instance is the {@link PhysicalConnectionType#UCP} 
> instance
>    */
>   public boolean isUcp() {
>     return this == ConnectionChannelType.UCP;
>   }
>   /**
>    * Returns whether this instance is the {@link PhysicalConnectionType#MM7} 
> instance.
>    * 
>    * @return whether this instance is the {@link PhysicalConnectionType#MM7} 
> instance
>    */
>   public boolean isMm7() {
>     return this == ConnectionChannelType.MM7;
>   }
>   /**
>    * Returns whether this instance is the {@link 
PhysicalConnectionType#HTTP} 
> instance.
>    * 
>    * @return whether this instance is the {@link 
PhysicalConnectionType#HTTP} 
> instance
>    */
>   public boolean isHttp() {
>     return this == ConnectionChannelType.HTTP;
>   }
>   /**
>    * Returns the type.
>    *
>    * @return the type. 
>    */
>   public int getType() {
>     return mType;
>   }
>   /**
>    * Returns the name.
>    *
>    * @return the name. 
>    */
>   public String getName() {
>     return mName;
>   }
>   /**
>    * Returns a String description of this 
<code>PhysicalConnectionType</code>.
>    *
>    * @return a String description of this object.
>    */
>   public String toString() {
>     StringBuffer result = new StringBuffer();
>     result.append(ConnectionChannelType.class.getName()+"[");
>     result.append("type=").append(getType());
>     result.append(", ");
>     result.append("name=").append(getName());
>     result.append("]");
>     return result.toString();
>   }
>   /*
>    * Non-javadoc.
>    * @see java.lang.Object#equals(Object)
>    */
>   // Algorithm from "Effective Java" by Joshua Bloch.
>   public boolean equals(Object o) {
>     if (o == this) {
>       return true;
>     }
>     if (!(o instanceof ConnectionChannelType)) {
>       return false;
>     }
>     ConnectionChannelType other = (ConnectionChannelType) o;
>     return true && getType() == other.getType();
>   }
>   /*
>    * Non-javadoc.
>    * @see java.lang.Object#hashCode()
>    */
>   // Algorithm from "Effective Java" by Joshua Bloch.
>   public int hashCode() {
>     int result = 17 * getClass().getName().hashCode();
>     result = 37 * result + getType();
>     return result;
>   }
>   /**
>    * If this class implements <code>java.io.Serializable</code>,
>    * the Java serialization mechanism provides a "hidden constructor".
>    * To ensure that no other instances are created than the
>    * ones declared above, we implement <code>readResolve</code>.
>    * (This is not necessary if this class does not
>    * implement <code>java.io.Serializable</code>).
>    */
>   // Algorithm from "Effective Java" by Joshua Bloch.
>   private Object readResolve() throws java.io.ObjectStreamException {
>     // look at the key attribute values of the instance 
>     // that was just deserialized,
>     // and replace the deserialized instance 
>     // with one of the static objects
>     return lookup(mType);
>   }
> }
> ----snip------------------------------------------