FULL PRODUCT VERSION : Server -------- Java version "1.5.0_07" Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0_07-b03) Java HotSpot(TM) Server VM (build 1.5.0_07-b03, mixed mode) Client -------- Java Plug-in 1.6.0_05 Using JRE version 1.6.0_05 Java HotSpot(TM) Client VM ADDITIONAL OS VERSION INFORMATION : Windows XP SP2 EXTRA RELEVANT SYSTEM CONFIGURATION : RMI server runtime is JRE 1.5.0_07 RMI Client runtime is JRE 1.6_05 (latest auto-update) A DESCRIPTION OF THE PROBLEM : We have a project that uses WebRowSetImpl class to pass data to the client using RMI. The code for both the RMI Server and RMI Client was developed in JDK 1.5.0. The RMI Server is deployed using 1.5.0_07. The Client (an applet) runs java versions from 1.5.0_11 to 1.6.0_05 (depending on the user's java plug-in). The code for both RMI Server and Client was compiled on JDK 1.5.0 The application works fine for versions lesser than 1.6.0_05 (which throws a java.rmi.UnmarshalException due to incompatible serialVersionUID). Here is the full StackTrace: ------------------------------------ java.rmi.UnmarshalException: error unmarshalling return; nested exception is: java.io.InvalidClassException: com.sun.rowset.providers.RIOptimisticProvider; local class incompatible: stream classdesc serialVersionUID = -3143367176751761936, local class serialVersionUID = -8429279896237029122 at com.company.project.client.ui.thread.projectWorker.run(projectWorker.java:66) at com.company.project.client.ui.thread.ThreadManager$WorkerThread.run(ThreadManager.java:118) Caused by: java.rmi.UnmarshalException: error unmarshalling return; nested exception is: java.io.InvalidClassException: com.sun.rowset.providers.RIOptimisticProvider; local class incompatible: stream classdesc serialVersionUID = -3143367176751761936, local class serialVersionUID = -8429279896237029122 at sun.rmi.server.UnicastRef.invoke(Unknown Source) at java.rmi.server.RemoteObjectInvocationHandler.invokeRemoteMethod(Unknown Source) at java.rmi.server.RemoteObjectInvocationHandler.invoke(Unknown Source) at $Proxy2.execute(Unknown Source) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) at java.lang.reflect.Method.invoke(Unknown Source) ... 1 more Caused by: java.io.InvalidClassException: com.sun.rowset.providers.RIOptimisticProvider; local class incompatible: stream classdesc serialVersionUID = -3143367176751761936, local class serialVersionUID = -8429279896237029122 at java.io.ObjectStreamClass.initNonProxy(Unknown Source) at java.io.ObjectInputStream.readNonProxyDesc(Unknown Source) at java.io.ObjectInputStream.readClassDesc(Unknown Source) at java.io.ObjectInputStream.readOrdinaryObject(Unknown Source) at java.io.ObjectInputStream.readObject0(Unknown Source) at java.io.ObjectInputStream.defaultReadFields(Unknown Source) at java.io.ObjectInputStream.readSerialData(Unknown Source) at java.io.ObjectInputStream.readOrdinaryObject(Unknown Source) at java.io.ObjectInputStream.readObject0(Unknown Source) at java.io.ObjectInputStream.readObject(Unknown Source) at sun.rmi.server.UnicastRef.unmarshalValue(Unknown Source) ... 13 more STEPS TO FOLLOW TO REPRODUCE THE PROBLEM : 0. Please use the code from the 'Source Code' section of this bug report. 1. Run the RMIServer class using JRE 1.50_07. 2. Run the RMIClientApplet class using JRE 1.6.0_05 (preferrably from a java IDE like Netbeans. Deploying it as a web applet requires signing the applet jar). 3. The RMIClientApplet will through a java.rmi.UnmarshalException due to the incompatible classdesc serialVersionUID. Sample StackTrace: =============== java.rmi.UnmarshalException: error unmarshalling return; nested exception is: java.io.InvalidClassException: com.sun.rowset.providers.RIOptimisticProvider; local class incompatible: stream classdesc serialVersionUID = -3143367176751761936, local class serialVersionUID = -8429279896237029122 EXPECTED VERSUS ACTUAL BEHAVIOR : EXPECTED - Expected a WebRowSet object which can be accessed as a ResultSet. ACTUAL - java.rmi.UnmarshalException: error unmarshalling return; nested exception is: java.io.InvalidClassException: com.sun.rowset.providers.RIOptimisticProvider; local class incompatible: stream classdesc serialVersionUID = -3143367176751761936, local class serialVersionUID = -8429279896237029122 ERROR MESSAGES/STACK TRACES THAT OCCUR : java.rmi.UnmarshalException: error unmarshalling return; nested exception is: java.io.InvalidClassException: com.sun.rowset.providers.RIOptimisticProvider; local class incompatible: stream classdesc serialVersionUID = -3143367176751761936, local class serialVersionUID = -8429279896237029122 at com.company.project.client.ui.thread.projectWorker.run(projectWorker.java:66) at com.company.project.client.ui.thread.ThreadManager$WorkerThread.run(ThreadManager.java:118) Caused by: java.rmi.UnmarshalException: error unmarshalling return; nested exception is: java.io.InvalidClassException: com.sun.rowset.providers.RIOptimisticProvider; local class incompatible: stream classdesc serialVersionUID = -3143367176751761936, local class serialVersionUID = -8429279896237029122 at sun.rmi.server.UnicastRef.invoke(Unknown Source) at java.rmi.server.RemoteObjectInvocationHandler.invokeRemoteMethod(Unknown Source) at java.rmi.server.RemoteObjectInvocationHandler.invoke(Unknown Source) at $Proxy2.execute(Unknown Source) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) at java.lang.reflect.Method.invoke(Unknown Source) ... 1 more Caused by: java.io.InvalidClassException: com.sun.rowset.providers.RIOptimisticProvider; local class incompatible: stream classdesc serialVersionUID = -3143367176751761936, local class serialVersionUID = -8429279896237029122 at java.io.ObjectStreamClass.initNonProxy(Unknown Source) at java.io.ObjectInputStream.readNonProxyDesc(Unknown Source) at java.io.ObjectInputStream.readClassDesc(Unknown Source) at java.io.ObjectInputStream.readOrdinaryObject(Unknown Source) at java.io.ObjectInputStream.readObject0(Unknown Source) at java.io.ObjectInputStream.defaultReadFields(Unknown Source) at java.io.ObjectInputStream.readSerialData(Unknown Source) at java.io.ObjectInputStream.readOrdinaryObject(Unknown Source) at java.io.ObjectInputStream.readObject0(Unknown Source) at java.io.ObjectInputStream.readObject(Unknown Source) at sun.rmi.server.UnicastRef.unmarshalValue(Unknown Source) ... 13 more REPRODUCIBILITY : This bug can be reproduced always. ---------- BEGIN SOURCE ---------- RMIServer (Sample) ------------------------------ import com.sun.rowset.WebRowSetImpl; import java.rmi.RemoteException; import java.rmi.registry.LocateRegistry; import java.rmi.registry.Registry; import java.rmi.server.UnicastRemoteObject; import java.sql.Connection; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; import javax.sql.rowset.WebRowSet; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; public class RMIServer { private static final Log logger = LogFactory.getLog(RMIServer.class); public static void main(String[] args) { new RMIServer(); } public RMIServer() { try { Registry r = LocateRegistry.createRegistry(7500); DBInterfaceManager dbInterfaceManager = new DBInterfaceManagerImpl(); r.rebind("dbInterfaceManager", dbInterfaceManager); logger.info("Registry created and the following Objects have been bound..."); for (String service: r.list()) { logger.info(service); } } catch (Throwable t) { t.printStackTrace(); logger.error(t.getMessage()); // Don't start RMI service System.exit(-1); } } public class DBInterfaceManagerImpl extends UnicastRemoteObject implements DBInterfaceManager { public DBInterfaceManagerImpl() throws RemoteException { } public ResultSet executeQuery(String query) throws RemoteException { Connection con = null; try { logger.debug(query); con = DBConnectionPool.getConnection(); WebRowSet wRS = new WebRowSetImpl(); Statement stmt = con.createStatement(); logger.debug("About to execute."); wRS.populate(stmt.executeQuery(query)); logger.debug("rs populated."); return wRS; } catch (SQLException sqle) { logger.error(query); logger.error(sqle.getMessage()); throw new RemoteException(sqle.getMessage()); } finally { if (con != null) DBConnectionPool.releaseConnection(con); } } } /** * PlaceHolder class */ private static class DBConnectionPool { public static void init() { //Setup the Connection pool } public static synchronized Connection getConnection() throws SQLException { //Fetches connection from the Connection pool return null; } public static synchronized void releaseConnection(Connection con) { //Releases the connection to the Connection pool } } } ======================================== RMIClient (Sample Applet) ==================== import java.rmi.Naming; import java.rmi.RMISecurityManager; import java.security.Permission; import java.sql.ResultSet; import javax.swing.JApplet; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; public class RMIClientApplet extends JApplet { private DBInterfaceManager dbM = null; private static final Log logger = LogFactory.getLog(RMIClientApplet.class); public void init() { System.setSecurityManager(new CustomRMISecurityManager()); String host = getCodeBase().getHost(); String rmiURL = "rmi://" + host + ":" + 7500 + "/"; try { dbM = (DBInterfaceManager)Naming.lookup(rmiURL + "dbInterfaceManager"); //Actual application uses a ThreadManager to run queries in background //instead of using the EventThread. The System breaks during the //Unmarshal phase of the RMI return. ResultSet rs = dbM.executeQuery("select sysdate from dual"); if ( rs.next() ) { System.out.println(rs.getString(1)); } } catch (Exception e) { logger.error(e); } } private static class CustomRMISecurityManager extends RMISecurityManager { public void checkConnect(String host, int port) {} public void checkCreateClassLoader() {} public void checkConnect(String host, int port, Object context) {} public void checkPermission(Permission perm, Object context) {} public void checkPermission(Permission perm) {} } } ---------- END SOURCE ---------- Release Regression From : 6u4 The above release value was the last known release where this bug was not reproducible. Since then there has been a regression.
|