Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-4651879

REGRESSION: JDK1.4 SerialVersionUID is different when compiled with -g

    XMLWordPrintable

Details

    • Bug
    • Resolution: Duplicate
    • P3
    • None
    • 1.4.0
    • core-libs

    Description

            return str.trim();
          }

          /**
           * Get the instance name of the execution status.
           *
           * @return String containing the instance name.
           */
          public String getInstanceName() {
              String str = "";
              if (instanceName != null) {
                  str = new String(instanceName);
              }
              return str.trim();
          }


          /**
           * Get the process specific message.
           *
           * @return String containing the process specific message.
           */
          public String getProcessMsg() {
              String str = "";
              if (processMsg != null) {
                  str = new String(processMsg);
              }
              return str.trim();
          }

          /**
           * Set the corresponding execption object for this message.
           *
           * @param ex Exception object as a result of a Java exception.
           */

          public void setException(Exception ex) {
              this.ex = ex;
          }

          /**
           * Get the Exception object for this status.
           *
           * @return Exception object for this status.
           */
          public Exception getException() {
              return this.ex;
          }

          /**
           * Return a string version of the execution status. Combines the following
      members: major, minor, msg, desc,
           * instance name, operation, and process specific message.
           *
           * @return String containing the execution status.
           */



          public String toString() {
              String retVal;
              retVal = "\nStatus code " + statusMajor + "." + statusMinor + "\n";
              retVal += "Message: " + this.getStatusMsg() + "\n";
              retVal += "Description: " + this.getStatusDesc() + "\n";
              retVal += "Instance: " + this.getInstanceName() + "\n";
              retVal += "Operation: " + this.getOperation() + "\n";
              retVal += "Server Msg: " + this.getProcessMsg() + "\n";
              return retVal;
          }

      }




      /**
       * The following execution status categories are represented:
       * <OL>
       * <LI>General</LI>
       * <LI>AIRE</LI>
       * <LI>PERCY</LI>
       * <LI>COORD</LI>
       * </OL>
       * Each category contains any number of status codes and corresponding messages.
       * The message strings are stored in the <B>execstatus.properties</B> file in
      the following format:
       * <PRE>
       * nnnnn.nnnnn.msg = status message here
       * nnnnn.nnnnn.desc = status description here
       * nnnnn.nnnnn.inst = status instance (optional)
       * nnnnn.nnnnn.op = status operation (optional)
       * </PRE>
       * The first two entries (msg and desc) are required. The second two are
      optional and can be specified at runtime.
       * (If known they should be included here, the values can be overridded at
      runtime).
       * The first 'nnnnn' sequence represents the major status code. The
      second 'nnnnn' sequence represents
       * minor status code.
       * <UL>
       * <LI>msg - the status message, short form.</LI>
       * <LI>desc - the full description of the the status.</LI>
       * <LI>inst - the class instance name that created the status.</LI>
       * <LI>op - the operation of the instance that generated the status.</LI>
       * </UL>
       * There are a maximum of 65536 major and 65536 minor error status codes. Do
      not code to the numeric value
       * of the status code, these are subject to change.
       * <BR>
       * <h3>CVS Info</h3>
       * <div align="left">
       *
       * <table border="1" width="366">
       * <tr>
       *
      $Header: /ssc/cvs/root/uplink/java/src/edu/caltech/ipac/sirtf/util/ExecStatusCon
      st.java,v 1.7 2001/12/20 17:56:23 jchavez Exp $
       * </tr>
       * </table>
       * <BR>
       * <BR>
       *
       * @author <a href="mailto:###@###.###?subject=Java Docs">Joe
      Chavez</a>
       * @version 0.2
       * @see ExecStatus
       */
      public final class ExecStatusConst
      {

          /**
           * Status of the operation is not an error.
           */
          public static final int STATUS_OK = 0;

          /**
           * General server error.
           */
      public static final int SERVER_ERROR_GENERAL = 100;

      /**
      * The server attempted to deserialize an object, but the class is not
      known by the server.
      */
      public static final int GENERAL_UNKNOWN_OBJECT_TYPE = 1;

          /**
           * General EJB processing error.
           */
          public static final int GENERAL_EJB = 2;

      /**
      * General exception. The ExecStatus instance will contain the
      Exception object.
      */
      public static final int GENERAL_EXCEPTION = 3;


          /**
           * The API did not receive the expected object type.
           */
          public static final int GENERAL_INCORRECT_OBJECT_TYPE = 4;

          /**
           * PERCY server error.
           */
          public static final int SERVER_ERROR_PERCY = 200;

          /**
           * PERCY server returned an error.
           */
          public static final int PERCY_SERVER_PROCESSING_ERROR = 1;

          /**
           * Timeout waiting for PERCY server to process a request.
           */
          public static final int PERCY_TIMEOUT_WAITING_FOR_SERVER = 2;

          /**
           * PERCY server is not available to process requests.
           */
          public static final int PERCY_SERVER_NOT_AVAILALABLE = 3;

          /**
           * PERCY server refused a connection.
           */
          public static final int PERCY_SERVER_CONNECTION_REFUSED = 4;

          /**
           * AIRE server error.
           */
          public static final int SERVER_ERROR_AIRE = 300;

          /**
           * AIRE Server processing error
           */
          public static final int AIRE_SERVER_PROCESSING_ERROR = 1;

          /**
           * AIRE Services not available. The aire component of the SutAPI has not
      been loaded
           * or is disabled for maintenance.
           */
          public static final int AIRE_SERVER_NOT_AVAILABLE = 2;

          /**
           * COORD server error.
           */
          public static final int SERVER_ERROR_COORD = 400;

          /**
           * COORD Server processing error
           */
          public static final int COORD_SERVER_PROCESSING_ERROR = 1;

          /**
           * COORD Services not available. The coord component of the SutAPI has not
      been loaded
           * or is disabled for maintenance.
           */
          public static final int COORD_SERVER_NOT_AVAILABLE = 2;

          /**
           * AOR Parse error
           */
          public static final int AOR_PARSE_ERROR = 500;

          /**
           * AOR: General error parsing the AOR file
           */
          public static final int AOR_PARSE_ERROR_GENERAL = 1;

          /**
           * AOR: error parsing the AOR file
           */
          public static final int AOR_PARSE_ERROR_PARSING = 2;

          /**
           * AOR: Invalid version in AOR file
           */
          public static final int AOR_PARSE_ERROR_INVALID_VERSION = 3;

          /**
           * DBMS Store error
           */
          public static final int DMBS_STORE_ERROR = 600;

          /**
           * General exception store data in DBMS
           */
          public static final int DBMS_GENERAL_EXCEPTION = 1;


          /**
           * VIS server error.
           */
          public static final int SERVER_ERROR_VIS = 700;

          /**
           * VIS server returned an error.
           */
          public static final int VIS_SERVER_PROCESSING_ERROR = 1;

          /**
           * Timeout waiting for VIS server to process a request.
           */
          public static final int VIS_TIMEOUT_WAITING_FOR_SERVER = 2;

          /**
           * VIS server is not available to process requests.
           */
          public static final int VIS_SERVER_NOT_AVAILALABLE = 3;

          /**
           * VIS server refused a connection.
           */
          public static final int VIS_SERVER_CONNECTION_REFUSED = 4;

          /**
           * Security Server Errors
           */
          public static final int SERVER_ERROR_SECURITY = 800;

          /**
           * Security error for user login
           */
          public static final int SECURITY_USER_AUTHENTICATION = 1;

          /**
           * Security for user authorization
           */
          public static final int SECURITY_USER_AUTHORIZATION = 2;

          /**
           * Error processing security request
           */
          public static final int SECURITY_PROCESSING_ERROR = 2;

          /**
           * Persistence Server Errors
           */
          public static final int SERVER_ERROR_PERSISTENCE = 900;

          /**
           * General exception store data in DBMS
           */
          public static final int PERSISTENCE_GENERAL_EXCEPTION = 1;

          /**
           * Returned when trying to get a Program from the sodb
           * and the program name is not found in the database
           */
          public static final int PERSISTENCE_PROGRAM_DOES_NOT_EXIST = 2;

          /**
           * Returned with trying to get a Program from the sodb
           * and the password is not correct
           */
          public static final int PERSISTENCE_INCORRECT_PASSWORD_FOR_PROGRAM = 3;
      // JC: CR1275
          /**
           * Software Update Server Errors
           */
      public static final int SERVER_ERROR_SOFTWARE_UPDATE = 1000;


          /**
           * Client version is not supported by automatic software update
           */
          public static final int SOFTWARE_UPDATE_VERSION_NOT_SUPPORTED = 1;
      }





      ---------- END SOURCE ----------

      CUSTOMER WORKAROUND :
      Turn off debug compilation "-g" for all or turn on for all
      serialized classes.

      Release Regression From : 1.3.1_02
      The above release value was the last known release where this
      bug was known to work. Since then there has been a regression.

      (Review ID: 138817)
      ======================================================================


      Name: gm110360 Date: 03/12/2002


      FULL PRODUCT VERSION :
      java version "1.4.0-rc"
      Java(TM) 2 Runtime Environment, Standard Edition (build 1.4.0-rc-b91)
      Java HotSpot(TM) Client VM (build 1.4.0-rc-b91, mixed mode)

      FULL OPERATING SYSTEM VERSION :
      Microsoft Windows 2000 [Version 5.00.2195]



      A DESCRIPTION OF THE PROBLEM :
      BACKGROUND

      As you know, for a class to be passed between server and
      client it must
      implement Serializable, which causes the compiler to embedd
      a
      SerialVersionUID inside the .class file. The
      SerialVersionUID is
      some sort of hash code or checksum intended to be unique
      for the
      current code in the class. It changes whenever the class
      is changed in
      a significant way, like changing fields or method
      signatures. This
      SerialVersionUID is sent across the connection with the
      class, and the
      receiver checks that it matches the SerialVersionUID in the
      local
      class. If it doesn't match, Java throws an exception,
      since it has no
      way to unpack the bytes into an object which is different
      from the
      object on the other end of the connection.


      THE PROBLEM

      When I&T compiled our servers with Java 1.4, development
      started
      getting the SerialVersionUID exceptions. Since the Java
      documentation
      warns that SerialVersionUID may change with compiler
      releases, we
      assumed that either SPOT or the server was compiled with
      the wrong
      Java version. Our (incorrect) notion was reinforced when
      we recompiled
      SPOT under Java 1.3 and the SerialVersionUID matched the
      server. But
      when we looked at I&T build logs, it was clear that he had
      indeed
      built with Java 1.4.


      THE SOLUTION

      After man-hours of experimentation we found the problem.
      In Java 1.3
      the SerialVersionUID did not the include debugging
      information in the
      class. That is, if one compiles with the "g" option, e.g.
          javac -g Class.java
      which includes debugging information in the class file, the
      SerialVersionUID was the same as when the class was
      compiled without
      the "g" option.

        Development
      always compile using the "g" option for debugging, and I&T
      never uses
      the "g" option, since the servers are production code.
      Hence the
      SerialVersionUID mismatch.



      REGRESSION. Last worked in version 1.3.1

      STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
      1. Create a class that implementes java.io.Serilizeable
      2. Compile the class under 1.4 with debug (-g) and without
      debug
      3. Compare the SerialVersionUID of serialver for the debug
      and non-debug version.

      EXPECTED VERSUS ACTUAL BEHAVIOR :
      Expected: The SerialVersionUID should be the same for.
      Acutal: The SerialVersionUID is different.



      This bug can be reproduced always.

      ---------- BEGIN SOURCE ----------
      ============= SCRIPT TO RUN TEST CASE =============

      #!/bin/csh

      #set to java 1.3.1
      echo "Setting up for Java 1.3.1"
      # Configure JAVA_HOME for your evironment Java 1.3.1
      setenv JAVA_HOME /ssc/sos/ext/jdk/j2sdk1_3_1
      set path = (${JAVA_HOME}/bin $path)

      echo "Performing Java 1.3.1 with debug"
      rm -f ExecStatus.class
      javac -g -classpath . ExecStatus.java
      serialver -classpath . ExecStatus

      mv ExecStatus.class ExecStatus.class.131Debug

      echo "Performing Java 1.3.1 without debug"
      javac -classpath . ExecStatus.java
      serialver -classpath . ExecStatus

      mv ExecStatus.class ExecStatus.class.131NoDebug

      echo "Setting up for Java 1.4"
      # Configure JAVA_HOME for your evironment Java 1.4
      # This problem also occurs with 1.4 RC
      setenv JAVA_HOME /ssc/sos/ext/jdk/j2sdk1.4.0b3
      set path = (${JAVA_HOME}/bin $path)

      echo "Performing Java 1.4 with debug"
      javac -g -classpath . ExecStatus.java
      serialver -classpath . ExecStatus

      mv ExecStatus.class ExecStatus.class.14Debug

      echo "Performing Java 1.4 without debug"
      javac -classpath . ExecStatus.java
      serialver -classpath . ExecStatus

      mv ExecStatus.class ExecStatus.class.14NoDebug


      ============= SOURCE CODE =============


      import java.io.File;
      import java.io.FileInputStream;
      import java.io.FileNotFoundException;
      import java.io.IOException;
      import java.io.Serializable;
      import java.util.Properties;

      /**
       * ExecStatus represents the status of the execution of a operation on a class.
       * It contains an error major and minor number and the corresponding message,
       * description information.
       * When appropriate information pertaining to the object and method that
      generated
       * the error is also specified.
       * There are not set methods for this class, the proper method of construction
      is to use the
       * <PRE> ExecStatus(int statusMajor, int statusMinor, String instanceName,
      String operation) </PRE>
       * constructor to create and instance.
       * <PRE>ExecStatus(int statusMajor, int statusMinor, String statusMsg, String
      statusDesc,
       * String instanceName, String operation)</PRE>
       * should only be used when no existing status major/minor codes exist or the
      instance does not represent an
       * error.
       * The <PRE> ExecStatus()</PRE> constructor should be used to create an
      ExecStatus instance that does not represent an error
       * and no additional information is to be provided about the status of the
      operation.
       * <BR>
       * This API relies on the execstatus.properties file for configuration
      information. This file
       * should be located in the <B>SOS_ROOT/config</B> directory.
       * <BR>
       * <h3>CVS Info</h3>
       * <div align="left">
       *
       * <table border="1" width="366">
       * <tr>
       *
      $Header: /ssc/cvs/root/uplink/java/src/edu/caltech/ipac/sirtf/util/ExecStatus.ja
      va,v 1.6
       * 2001/05/10 01:12:09 booth Exp $
       * </tr>
       * </table>
       * <BR>
       * <BR>
       *
       * @author <a href="mailto:###@###.###?subject=Java Docs">Joe
      Chavez</a>
       * @version 0.2
       * @see ExecStatusConst
       */
      public class ExecStatus implements Serializable {

          /**
           * Name of the file containg the execution status messages.
           */
          private static final String fileName = "execstatus.properties";

          /**
           * Maximum length of the execution status message.
           */
          public static final short STATUS_MSG_LEN = 50;

          /**
           * Maximum length of the execution status description.
           */
          public static final short STATUS_DESC_LEN = 255;

          /**
           * Maximum length of the process specific message.
           */
          public static final short PROCESS_ERROR_LEN = 512;


          /**
           * Maximum length of the instance name.
           */
          public static final short INSTANCE_NAME_LEN = 255;

          /**
           * Maximum length of the operation name.
           */
          public static final short OPERATION_LEN = 80;

          /**
           * Major status.
           */
          private int statusMajor;

          /**
           * Minor status.
           */
          private int statusMinor;

          /**
           * Status message, short form.
           */
          private char statusMsg[];

          /**
           * Status description, long form.
           */
          private char statusDesc[];

          /**
           * Process specific message.
           */
          private char processMsg[];


          /**
           * Instance name.
           */
          private char instanceName[];

          /**
           * Operation name.
           */
          private char operation[];

          /**
           * Holds the execption related to this status.
           */
          private Exception ex = null;

          /**
           * Default Constructor
           * sets status to no error.
           */
          public ExecStatus() {
              this.statusMajor = ExecStatusConst.STATUS_OK;
              this.statusMinor = ExecStatusConst.STATUS_OK;
          }

          /**
           * Used to contruct an ExecStatus object with a known Major and Minor
      status number. The status numbers
           * are contained in the ExecStatusConst class.
           *
           * @param statusMajor Major number of the execution status.
           * @param statusMinor Minor number of the execution status.
           * @param instanceName Optional object/instance name. Must not be null.
           * @param operation Optional operation name for object/instance. Must not
      be null.
           * @param processMsg Optional process specific message. Must not be null.
           * @see ExecStatusConst
           */
          public ExecStatus(int statusMajor, int statusMinor,
          String instanceName, String operation, String processMsg) {
              this.statusMajor = statusMajor;
              this.statusMinor = statusMinor;
              lookupMessages();

              if (this.instanceName != null) {
                  instanceName.getChars(0, (this.INSTANCE_NAME_LEN <
      instanceName.length()) ? this.INSTANCE_NAME_LEN : instanceName.length(),
                  this.instanceName, 0);
              }

              if (this.operation != null) {
                  operation.getChars(0, (this.OPERATION_LEN < operation.length()) ?
      this.OPERATION_LEN : operation.length(),
                  this.operation, 0);
              }

              processMsg.getChars(0, (this.PROCESS_ERROR_LEN < processMsg.length()) ?
      this.PROCESS_ERROR_LEN : processMsg.length(),
              this.processMsg, 0);

          }

          /**
           * Used to contruct an ExecStatus object with a known Major and Minor
      status number. The status numbers
           * are contained in the ExecStatusConst class.
           *
           * @param statusMajor Major number of the execution status.
           * @param statusMinor Minor number of the execution status.
           * @param instanceName Optional object/instance name. Must not be null.
           * @param operation Optional operation name for object/instance. Must not
      be null.
           * @see ExecStatusConst
           */
          public ExecStatus(int statusMajor, int statusMinor,
          String instanceName, String operation) {
              this.statusMajor = statusMajor;
              this.statusMinor = statusMinor;
              lookupMessages();

              if (this.instanceName != null) {
                  instanceName.getChars(0, (this.INSTANCE_NAME_LEN <
      instanceName.length()) ? this.INSTANCE_NAME_LEN : instanceName.length(),
                  this.instanceName, 0);
              }

              if (this.operation != null) {
                  operation.getChars(0, (this.OPERATION_LEN < operation.length()) ?
      this.OPERATION_LEN : operation.length(),
                  this.operation, 0);
              }


          }


          /**
           * Checks if the execution status is an error.
           *
           * @return true if ExecStatus does not contain an error;
           * false if ExecStatus contains an error
           */
          public boolean isOK() {
              if (this.statusMajor == ExecStatusConst.STATUS_OK) {
                  return true;
              }
              else {
                  return false;
              }
          }

          /**
           * Construct an ExecStatus object specifying all characteristics.
           * A message will be stored in the application log when this constructor
           * is used to create an ExecStatus instance. This message will specify
           * the contents of the ExecStatus object and record the fact that
           * a non-standard status was reported.
           *
           * @param statusMajor Major number of the execution status.
           * @param statusMinor Minor number of the execution status.
           * @param statusMsg Exectuion status message.
           * @param statusDesc Execution status description.
           * @param instanceName Optional object/instance name. Must not be null.
           * @param operation Optional operation name for object/instance. Must not
      be null.
           * @see ExecStatusConst
           */
          public ExecStatus(int statusMajor, int statusMinor,
          String statusMsg, String statusDesc,
          String instanceName, String operation) {
              initMsgs();
              this.statusMajor = statusMajor;
              this.statusMinor = statusMinor;
              statusMsg.getChars(0, (this.STATUS_MSG_LEN < statusMsg.length()) ?
      this.STATUS_MSG_LEN : statusMsg.length(),
              this.statusMsg, 0);
              statusDesc.getChars(0, (this.STATUS_DESC_LEN < statusDesc.length()) ?
      this.STATUS_DESC_LEN : statusDesc.length(),
              this.statusDesc, 0);
              instanceName.getChars(0, (this.INSTANCE_NAME_LEN < instanceName.length
      ()) ? this.INSTANCE_NAME_LEN : instanceName.length(),
              this.instanceName, 0);
              operation.getChars(0, (this.OPERATION_LEN < operation.length()) ?
      this.OPERATION_LEN : operation.length(),
              this.operation, 0);

          }

          private void initMsgs() {
              statusMsg = new char[this.STATUS_MSG_LEN];
              statusDesc = new char[this.STATUS_DESC_LEN];
              processMsg = new char[this.PROCESS_ERROR_LEN];
              instanceName = new char[this.INSTANCE_NAME_LEN];
              operation = new char[this.OPERATION_LEN];
          }

          /**
           * Lookup the messages corresponding to the Major and Minor error status
      codes.
           */
          protected void lookupMessages() {
              try {
                  Properties msgs = new Properties();

                  FileInputStream msgFile =
                  new FileInputStream(System.getProperty("SOS_ROOT", "") +
      File.separator + "config" +
                   File.separator + this.fileName);

                  msgs.load(msgFile);

                  initMsgs();

                  String msgBase = this.statusMajor + "." + this.statusMinor + ".";

                  String statusMsg = msgs.getProperty(msgBase + "msg", "");
                  String statusDesc = msgs.getProperty(msgBase + "desc", "");
                  String instanceName = msgs.getProperty(msgBase + "inst", "");
                  String operation = msgs.getProperty(msgBase + "op", "");


                  statusMsg.getChars(0, (this.STATUS_MSG_LEN < statusMsg.length()) ?
      this.STATUS_MSG_LEN : statusMsg.length(),
                  this.statusMsg, 0);
                  statusDesc.getChars(0, (this.STATUS_DESC_LEN < statusDesc.length
      ()) ? this.STATUS_DESC_LEN : statusDesc.length(),
                  this.statusDesc, 0);
                  instanceName.getChars(0, (this.INSTANCE_NAME_LEN <
      instanceName.length()) ? this.INSTANCE_NAME_LEN : instanceName.length(),
                  this.instanceName, 0);
                  operation.getChars(0, (this.OPERATION_LEN < operation.length()) ?
      this.OPERATION_LEN : operation.length(),
                  this.operation, 0);


              }
              catch (FileNotFoundException e) {
                  e.printStackTrace();
              }
              catch (IOException e) {
                  e.printStackTrace();
              }


          }

          /**
           * Get the execution status message.
           * This is the short form of the message.
           *
           * @return String containing the status message.
           */
          public String getStatusMsg() {
              String str = "";
              if (statusMsg != null) {
                  str = new String(statusMsg);
              }
              return str.trim();
          }

          /**
           * Get the minor status value of execution status.
           *
           * @return int containing the minor status.
           */
          public int getStatusMinor() {
              return statusMinor;
          }

          /**
           * Get the major status value of the execution status.
           *
           * @return int containing the major status.
           */
          public int getStatusMajor() {
              return statusMajor;
          }

          /**
           * Get the full description of the execution status.
           *
           * @return String containing the description.
           */
          public String getStatusDesc() {
              String str = "";
              if (statusDesc != null) {
                  str = new String(statusDesc);
              }
              return str.trim();
          }

          /**
           * Get the operation name of the execution status.
           *
           * @return String containing the operation name.
           */
          public String getOperation() {
              String str = "";
              if (operation != null) {
                  str = new String(operation);
              }
        

      Attachments

        Issue Links

          Activity

            People

              mwarressunw Michael Warres (Inactive)
              gmanwanisunw Girish Manwani (Inactive)
              Votes:
              0 Vote for this issue
              Watchers:
              0 Start watching this issue

              Dates

                Created:
                Updated:
                Resolved:
                Imported:
                Indexed: