Paulo,
How would you like to become a committer?
You've been around long enough contributing good patches/feedback. I
think giving you direct access to the cvs would be a real win for the
community.
What do you say?
-David
On Mon, Sep 27, 2004 at 11:07:20AM +0100, Paulo Lopes wrote:
> Hi,
>
> I found that there were some errors when i tryed to run my OpenEJB 0.9.2
> Beans on OpenEJB 1.0 and they were related with the passivation code.
> These are my changes that made it possible to run the old code.
>
> I also made a small change in the JDBC connection component because
> sometimes under heavy stress there seem to be some concurrency problems,
> so i locked the jdbcConnection "Collection" whenever a method needs to
> add or remove a connection to or from the collection. It seems that this
> solutions works (at least for "my" code).
>
> Best regards,
> Paulo
> Index: modules/core/src/java/org/openejb/core/stateful/RAFPassivater.java
> ===================================================================
> RCS file:
> /scm/openejb/openejb1/modules/core/src/java/org/openejb/core/stateful/RAFPassivater.java,v
> retrieving revision 1.1.1.1
> diff -u -r1.1.1.1 RAFPassivater.java
> --- modules/core/src/java/org/openejb/core/stateful/RAFPassivater.java 26 Mar
> 2004 21:42:33 -0000 1.1.1.1
> +++ modules/core/src/java/org/openejb/core/stateful/RAFPassivater.java 23 Sep
> 2004 09:47:35 -0000
> @@ -48,6 +48,7 @@
>
>
> import java.io.RandomAccessFile;
> +import java.io.File;
> import java.util.Enumeration;
> import java.util.Hashtable;
> import java.util.Properties;
> @@ -56,11 +57,11 @@
>
>
> // optimization: replace HashTable with HashMap (vc no debug hashmap)
> -public class RAFPassivater implements PassivationStrategy{
> -
> +public class RAFPassivater implements PassivationStrategy{
> +
> int fileID = 0;
> Hashtable masterTable = new Hashtable();
> -
> +
> static class Pointer {
> int fileid;
> long filepointer;
> @@ -71,16 +72,16 @@
> bytesize = bytecount;
> }
> }
> -
> +
> public void init(Properties props) throws org.openejb.SystemException {}
> -
> -
> +
> +
> public synchronized void passivate(Hashtable stateTable)
> throws org.openejb.SystemException{
> try{
> fileID++;
> -
> - RandomAccessFile ras = new
> RandomAccessFile("passivation"+fileID+".ser","rw");
> +
> + RandomAccessFile ras = new
> RandomAccessFile(System.getProperty("java.io.tmpdir", File.separator + "tmp") +
> File.separator + "passivation"+fileID+".ser","rw");
> Enumeration enum = stateTable.keys();
> Pointer lastPointer = null;
> while(enum.hasMoreElements()){
> @@ -88,10 +89,10 @@
> Object obj = stateTable.get(id);
> byte [] bytes = Serializer.serialize(obj);
> long filepointer = ras.getFilePointer();
> -
> +
> if( lastPointer == null ) lastPointer = new Pointer(fileID,
> filepointer, (int)(filepointer));
> else lastPointer = new Pointer(fileID, filepointer,
> (int)(filepointer-lastPointer.filepointer));
> -
> +
> masterTable.put(id,lastPointer);
> ras.write(bytes);
> }
> @@ -100,16 +101,16 @@
> throw new org.openejb.SystemException(e);
> }
> }
> -
> +
> public synchronized Object activate(Object primaryKey)
> throws org.openejb.SystemException{
> -
> +
> Pointer pointer = (Pointer)masterTable.get(primaryKey);
> if(pointer == null)
> return null;
> -
> +
> try{
> - RandomAccessFile ras = new
> RandomAccessFile("passivation"+pointer.fileid+".ser","r");
> + RandomAccessFile ras = new
> RandomAccessFile(System.getProperty("java.io.tmpdir", File.separator + "tmp") +
> File.separator + "passivation"+pointer.fileid+".ser","r");
> byte [] bytes = new byte[(int)pointer.bytesize];
> ras.seek(pointer.filepointer);
> ras.readFully(bytes);
> @@ -118,7 +119,7 @@
> }catch(Exception e){
> throw new org.openejb.SystemException(e);
> }
> -
> +
> }
> -
> -}
> +
> +}
> \ No newline at end of file
> Index: modules/core/src/java/org/openejb/core/stateful/SimplePassivater.java
> ===================================================================
> RCS file:
> /scm/openejb/openejb1/modules/core/src/java/org/openejb/core/stateful/SimplePassivater.java,v
> retrieving revision 1.1.1.1
> diff -u -r1.1.1.1 SimplePassivater.java
> --- modules/core/src/java/org/openejb/core/stateful/SimplePassivater.java 26 Mar
> 2004 21:42:34 -0000 1.1.1.1
> +++ modules/core/src/java/org/openejb/core/stateful/SimplePassivater.java 23 Sep
> 2004 09:30:32 -0000
> @@ -56,7 +56,7 @@
> import org.openejb.core.EnvProps;
> import org.openejb.util.FileUtils;
> /**
> - *
> + *
> * @author <a href="mailto:[EMAIL PROTECTED]">Richard Monson-Haefel</a>
> * @author <a href="mailto:[EMAIL PROTECTED]">David Blevins</a>
> * @version $Revision: 1.1.1.1 $ $Date: 2004/03/26 21:42:34 $
> @@ -71,20 +71,20 @@
> }
>
> String dir = props.getProperty(EnvProps.IM_PASSIVATOR_PATH_PREFIX);
> -
> +
> try{
> -
> +
> if(dir!=null) {
> sessionDirectory = FileUtils.getBase().getDirectory(dir);
> }else {
> - sessionDirectory = new File("java.io.tmpdir");
> + sessionDirectory = new File(System.getProperty("java.io.tmpdir",
> File.separator + "tmp"));
> }
> logger.info("Using directory "+sessionDirectory+" for stateful session
> passivation");
> }catch(java.io.IOException e) {
> throw new org.openejb.SystemException(getClass().getName()+".init():
> can't use directory prefix "+dir+":"+e);
> }
> }
> -
> +
> public void passivate(Object primaryKey, Object state)
> throws org.openejb.SystemException{
> try{
> @@ -95,21 +95,21 @@
>
> logger.info("Passivating to file "+sessionFile);
> ObjectOutputStream oos = new ObjectOutputStream(new
> FileOutputStream(sessionFile));
> -
> +
> oos.writeObject(state);// passivate just the bean instance
> oos.close();
> sessionFile.deleteOnExit();
> }
> catch(java.io.NotSerializableException nse ) {
> logger.info("Passivation failed ", nse);
> - throw new org.openejb.SystemException("The type " + nse.getMessage() +
> " in the bean class " + ((BeanEntry)state).bean.getClass().getName() + " is not
> serializable as mandated by the EJB specification.");
> + throw new org.openejb.SystemException("The type " + nse.getMessage() +
> " in the bean class " + ((BeanEntry)state).bean.getClass().getName() + " is not
> serializable as mandated by the EJB specification.");
> }
> catch(Exception t){
> logger.info("Passivation failed ", t);
> // FIXME: More intelligent exception handling needed
> throw new org.openejb.SystemException(t);
> }
> -
> +
> }
> public void passivate(Hashtable hash)throws org.openejb.SystemException{
> Enumeration enum = hash.keys();
> @@ -118,41 +118,41 @@
> passivate(id, hash.get(id));
> }
> }
> -
> +
> /**
> - *
> + *
> * @param primaryKey
> - * @return
> + * @return
> * @exception org.openejb.SystemException
> * If there is an problem retreiving the instance from the
> .ser file.
> */
> public Object activate(Object primaryKey) throws org.openejb.SystemException{
> -
> +
> try{
> // The replace(':','=') ensures the filename is correct under Microsoft
> Windows OS
> String filename = primaryKey.toString().replace(':', '=' );
> -
> +
> File sessionFile = new File( sessionDirectory, filename);
>
> - if(sessionFile.exists()){
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
> + if(sessionFile.exists()){
> logger.info("Activating from file "+sessionFile);
>
> ObjectInputStream ois = new ObjectInputStream(new
> FileInputStream(sessionFile));
> Object state = ois.readObject();
> ois.close();
> sessionFile.delete();
> - return state;
> + return state;
> }else{
> logger.info("Activation failed: file not found "+sessionFile);
> return null;
> }
> -
> +
> }catch(Exception t){
> logger.info("Activation failed ", t);
> // FIXME: More intelligent exception handling needed
> throw new org.openejb.SystemException(t);
> }
> -
> +
> }
> -
> -}
> +
> +}
> \ No newline at end of file
> Index: modules/core/src/java/org/openejb/resource/jdbc/JdbcConnection.java
> ===================================================================
> RCS file:
> /scm/openejb/openejb1/modules/core/src/java/org/openejb/resource/jdbc/JdbcConnection.java,v
> retrieving revision 1.1.1.1
> diff -u -r1.1.1.1 JdbcConnection.java
> --- modules/core/src/java/org/openejb/resource/jdbc/JdbcConnection.java 26 Mar
> 2004 21:42:47 -0000 1.1.1.1
> +++ modules/core/src/java/org/openejb/resource/jdbc/JdbcConnection.java 23 Sep
> 2004 15:12:59 -0000
> @@ -55,7 +55,7 @@
> private java.sql.Connection physicalConn;
> private JdbcManagedConnection managedConn;
> protected boolean isClosed = false;
> -
> +
> protected JdbcConnection(JdbcManagedConnection managedConn, java.sql.Connection
> physicalConn){
> this.physicalConn = physicalConn;
> this.managedConn = managedConn;
> @@ -67,9 +67,9 @@
> return managedConn;
> }
> /**
> - * Renders this conneciton invalid; unusable. Its called by the
> - * JdbcManagedConnection when its connectionClose() or cleanup()
> - * methods are invoked.
> + * Renders this conneciton invalid; unusable. Its called by the
> + * JdbcManagedConnection when its connectionClose() or cleanup()
> + * methods are invoked.
> */
> protected void invalidate(){
> isClosed = true;
> @@ -139,12 +139,12 @@
> throw new java.sql.SQLException("Method not supported. Rollback is managed
> automatically by container provider");
> }
> public void close() throws SQLException{
> - if(isClosed)
> + if(isClosed)
> return;
> else{
> - // managed conneciton will call this object's invalidate() method which
> + // managed conneciton will call this object's invalidate() method which
> // will set isClosed = true, and nullify references to the
> sqlConnection and managed connection.
> - managedConn.connectionClose(this);
> + managedConn.connectionClose(this);
> }
> }
> public boolean isClosed() throws SQLException{
> @@ -249,7 +249,7 @@
> throw sqlE;
> }
> }
> - public Statement createStatement(int resultSetType, int resultSetConcurrency)
> + public Statement createStatement(int resultSetType, int resultSetConcurrency)
> throws SQLException{
> if(isClosed) throw new SQLException("Connection is closed");
> try{
> @@ -347,9 +347,6 @@
> throw new SQLException("method not implemented");
> }
> }
> -
> -
> -
>
>
>
> Index: modules/core/src/java/org/openejb/resource/jdbc/JdbcManagedConnection.java
> ===================================================================
> RCS file:
> /scm/openejb/openejb1/modules/core/src/java/org/openejb/resource/jdbc/JdbcManagedConnection.java,v
> retrieving revision 1.1.1.1
> diff -u -r1.1.1.1 JdbcManagedConnection.java
> --- modules/core/src/java/org/openejb/resource/jdbc/JdbcManagedConnection.java
> 26 Mar 2004 21:42:48 -0000 1.1.1.1
> +++ modules/core/src/java/org/openejb/resource/jdbc/JdbcManagedConnection.java
> 23 Sep 2004 15:33:22 -0000
> @@ -54,18 +54,18 @@
> import javax.resource.spi.ManagedConnectionMetaData;
>
> public class JdbcManagedConnection implements ManagedConnection {
> -
> +
> private JdbcManagedConnectionFactory managedFactory;
> private java.sql.Connection sqlConn;
> private JdbcConnectionRequestInfo requestInfo;
> private JdbcManagedConnectionMetaData metaData;
> -
> +
> // there may be many conneciton handles active at any one time
> private java.util.Vector jdbcConnections = new java.util.Vector();
> private Set listeners;
> private java.io.PrintWriter logWriter;
> - private JdbcLocalTransaction localTransaction;
> -
> + private JdbcLocalTransaction localTransaction;
> +
> public JdbcManagedConnection(JdbcManagedConnectionFactory managedFactory,
> java.sql.Connection sqlConn, JdbcConnectionRequestInfo rxInfo)
> throws javax.resource.spi.ResourceAdapterInternalException {
> listeners = java.util.Collections.synchronizedSet(new HashSet());
> @@ -73,26 +73,26 @@
> this.requestInfo = rxInfo;
> this.sqlConn = sqlConn;
> logWriter = managedFactory.getLogWriter();
> - try{
> + try{
> metaData = new JdbcManagedConnectionMetaData(sqlConn.getMetaData());
> }catch(java.sql.SQLException sqlE){
> - throw new javax.resource.spi.ResourceAdapterInternalException("Problem
> while attempting to access meta data from physical connection",
> ErrorCode.JDBC_0004);
> + throw new javax.resource.spi.ResourceAdapterInternalException("Problem
> while attempting to access meta data from physical connection", ErrorCode.JDBC_0004);
> }
> localTransaction = new JdbcLocalTransaction(this);
> }
> -
> +
> protected java.sql.Connection getSQLConnection(){
> return sqlConn;
> }
> -
> +
> protected JdbcConnectionRequestInfo getRequestInfo(){
> return requestInfo;
> }
> -
> +
> public void addConnectionEventListener(ConnectionEventListener listener) {
> listeners.add(listener);
> }
> -
> +
> public void associateConnection(java.lang.Object connection) throws
> javax.resource.ResourceException {
> if(connection instanceof JdbcConnection){
> JdbcConnection jdbcConn = (JdbcConnection)connection;
> @@ -101,20 +101,23 @@
> throw new javax.resource.ResourceException("Connection object is the
> wrong type. It must be an instance of JdbcConnection");
> }
> }
> -
> +
> /**
> * This method will invalidate any JdbcConnection handles that have not already
> been invalidated (they self invalidate when they are explicitly closed).
> */
> public void cleanup() throws javax.resource.ResourceException {
> - Object [] connectionHandles = jdbcConnections.toArray();
> - for(int i = 0; i < connectionHandles.length; i++){
> - JdbcConnection handle = (JdbcConnection)connectionHandles[i];
> - handle.invalidate();
> - }
> - jdbcConnections.clear();
> - localTransaction.cleanup();
> + synchronized(jdbcConnections)
> + {
> + Object [] connectionHandles = jdbcConnections.toArray();
> + for(int i = 0; i < connectionHandles.length; i++){
> + JdbcConnection handle = (JdbcConnection)connectionHandles[i];
> + handle.invalidate();
> + }
> + jdbcConnections.clear();
> + localTransaction.cleanup();
> + }
> }
> -
> +
> public void destroy() throws javax.resource.ResourceException {
> cleanup();
> try{
> @@ -125,43 +128,46 @@
> managedFactory = null;
> sqlConn = null;
> listeners.clear();
> - }
> -
> + }
> +
> /*
> * Returns an application level connection handle in the form of a
> JdbcConnection object
> * which implements the java.sql.Connection interface and wrappers the physical
> JDBC connection.
> *
> */
> public java.lang.Object getConnection(javax.security.auth.Subject
> subject,ConnectionRequestInfo cxRequestInfo) throws
> javax.resource.ResourceException {
> - JdbcConnection jdbcCon = new JdbcConnection(this,sqlConn);
> - jdbcConnections.add(jdbcCon);
> - return jdbcCon;
> + synchronized(jdbcConnections)
> + {
> + JdbcConnection jdbcCon = new JdbcConnection(this,sqlConn);
> + jdbcConnections.add(jdbcCon);
> + return jdbcCon;
> + }
> }
> -
> +
> public javax.resource.spi.LocalTransaction getLocalTransaction() throws
> javax.resource.ResourceException {
> return localTransaction;
> }
> -
> +
> public java.io.PrintWriter getLogWriter() throws
> javax.resource.ResourceException {
> return logWriter;
> }
> -
> +
> public ManagedConnectionMetaData getMetaData() throws
> javax.resource.ResourceException {
> return metaData;
> }
> -
> +
> public javax.transaction.xa.XAResource getXAResource() throws
> javax.resource.ResourceException {
> throw new javax.resource.NotSupportedException("Method not implemented");
> }
> -
> +
> public void removeConnectionEventListener(ConnectionEventListener listener) {
> listeners.remove(listener);
> }
> -
> +
> public void setLogWriter(java.io.PrintWriter out) throws
> javax.resource.ResourceException {
> logWriter = out;
> }
> -
> +
> protected void localTransactionCommitted(){
> ConnectionEvent event = new ConnectionEvent(this,
> ConnectionEvent.LOCAL_TRANSACTION_COMMITTED);
> Object [] elements = listeners.toArray();
> @@ -170,7 +176,7 @@
> eventListener.localTransactionCommitted(event);
> }
> }
> -
> +
> protected void localTransactionRolledback(){
> ConnectionEvent event = new ConnectionEvent(this,
> ConnectionEvent.LOCAL_TRANSACTION_ROLLEDBACK);
> Object [] elements = listeners.toArray();
> @@ -179,7 +185,7 @@
> eventListener.localTransactionRolledback(event);
> }
> }
> -
> +
> protected void localTransactionStarted(){
> ConnectionEvent event = new ConnectionEvent(this,
> ConnectionEvent.LOCAL_TRANSACTION_STARTED);
> Object [] elements = listeners.toArray();
> @@ -188,9 +194,9 @@
> eventListener.localTransactionStarted(event);
> }
> }
> -
> +
> protected void connectionErrorOccurred(JdbcConnection jdbcConn,
> java.sql.SQLException sqlE){
> -
> +
> if(logWriter !=null){
> logWriter.print("\nJdbcConnection Error: On java.sql.Connection (");
> logWriter.print(jdbcConn);
> @@ -202,7 +208,7 @@
> temp.printStackTrace(logWriter);
> }
> }
> -
> +
> ConnectionEvent event = new ConnectionEvent(this,
> ConnectionEvent.CONNECTION_ERROR_OCCURRED , sqlE);
> Object [] elements = listeners.toArray();
> for(int i = 0; i < elements.length; i++){
> @@ -210,24 +216,27 @@
> eventListener.connectionErrorOccurred(event);
> }
> }
> -
> +
> /**
> * Invoked by the JdbcConneciton when its close() method is called.
> * This method invalidates the JdbcConnection handle, removes it from
> * the list of active handles and notifies all the ConnectionEventListeners.
> */
> protected void connectionClose(JdbcConnection jdbcConn){
> - jdbcConn.invalidate();
> - jdbcConnections.remove(jdbcConn);
> - ConnectionEvent event = new ConnectionEvent(this,
> ConnectionEvent.CONNECTION_CLOSED);
> - Object [] elements = listeners.toArray();
> - for(int i = 0; i < elements.length; i++){
> - ConnectionEventListener eventListener =
> (ConnectionEventListener)elements[i];
> - eventListener.connectionClosed(event);
> - }
> + synchronized(jdbcConnections)
> + {
> + jdbcConn.invalidate();
> + jdbcConnections.remove(jdbcConn);
> + ConnectionEvent event = new ConnectionEvent(this,
> ConnectionEvent.CONNECTION_CLOSED);
> + Object [] elements = listeners.toArray();
> + for(int i = 0; i < elements.length; i++){
> + ConnectionEventListener eventListener =
> (ConnectionEventListener)elements[i];
> + eventListener.connectionClosed(event);
> + }
> + }
> }
> -
> +
> public String toString( ){
> return "JdbcManagedConnection ("+sqlConn.toString()+")";
> }
> -}
> +}
> \ No newline at end of file