You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tomee.apache.org by an...@apache.org on 2010/10/06 15:30:41 UTC

svn commit: r1005029 - in /openejb/trunk/openejb3: assembly/javaee-api-libs/ container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/ container/openejb-core/src/main/java/org/apache/openejb/resource/activemq/ container/openejb-core/sr...

Author: andygumbrecht
Date: Wed Oct  6 13:30:41 2010
New Revision: 1005029

URL: http://svn.apache.org/viewvc?rev=1005029&view=rev
Log:
The JMS xbean configuration, eg. BrokerXmlConfig xbean:file:conf/activemq.xml, was not creating and holding on to the broker for shutdown. If the broker was not configured with a shutdown hook (which is bad from an RA perspective) then this would lead to persistence corruption.

Modified:
    openejb/trunk/openejb3/assembly/javaee-api-libs/pom.xml
    openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/Assembler.java
    openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/resource/activemq/ActiveMQ5Factory.java
    openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/resource/activemq/ActiveMQFactory.java
    openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/resource/activemq/ActiveMQResourceAdapter.java
    openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/util/URISupport.java

Modified: openejb/trunk/openejb3/assembly/javaee-api-libs/pom.xml
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb3/assembly/javaee-api-libs/pom.xml?rev=1005029&r1=1005028&r2=1005029&view=diff
==============================================================================
--- openejb/trunk/openejb3/assembly/javaee-api-libs/pom.xml (original)
+++ openejb/trunk/openejb3/assembly/javaee-api-libs/pom.xml Wed Oct  6 13:30:41 2010
@@ -211,7 +211,7 @@
     <dependency>
       <groupId>org.apache.geronimo.specs</groupId>
       <artifactId>geronimo-activation_1.1_spec</artifactId>
-      <version>1.0</version>
+      <version>1.1</version>
     </dependency>
     <dependency>
       <groupId>org.apache.geronimo.specs</groupId>

Modified: openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/Assembler.java
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/Assembler.java?rev=1005029&r1=1005028&r2=1005029&view=diff
==============================================================================
--- openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/Assembler.java (original)
+++ openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/Assembler.java Wed Oct  6 13:30:41 2010
@@ -844,10 +844,26 @@ public class Assembler extends Assembler
                 ResourceAdapter resourceAdapter = (ResourceAdapter) object;
                 try {
                     logger.info("Stopping ResourceAdapter: " + binding.getName());
+
+                    if (logger.isDebugEnabled()) {
+                        logger.debug("Stopping ResourceAdapter: " + binding.getClassName());
+                    }
+
                     resourceAdapter.stop();
-                } catch (Exception e) {
-                    logger.fatal("ResourceAdapter Shutdown Failed: " + binding.getName(), e);
+                } catch (Throwable t) {
+                    logger.fatal("ResourceAdapter Shutdown Failed: " + binding.getName(), t);
                 }
+            } else if (object instanceof org.apache.commons.dbcp.BasicDataSource) {
+                logger.info("Closing DataSource: " + binding.getName());
+
+                try {
+                    ((org.apache.commons.dbcp.BasicDataSource) object).close();
+                } catch (Throwable t) {
+                    //Ignore
+                }
+
+            } else if (logger.isDebugEnabled()) {
+                logger.debug("Not processing resource on destroy: " + binding.getClassName());
             }
         }
 

Modified: openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/resource/activemq/ActiveMQ5Factory.java
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/resource/activemq/ActiveMQ5Factory.java?rev=1005029&r1=1005028&r2=1005029&view=diff
==============================================================================
--- openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/resource/activemq/ActiveMQ5Factory.java (original)
+++ openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/resource/activemq/ActiveMQ5Factory.java Wed Oct  6 13:30:41 2010
@@ -24,6 +24,7 @@ import org.apache.activemq.store.jdbc.JD
 import org.apache.activemq.store.memory.MemoryPersistenceAdapter;
 import org.apache.openejb.loader.SystemInstance;
 import org.apache.openejb.spi.ContainerSystem;
+import org.apache.openejb.util.LogCategory;
 
 import javax.naming.Context;
 import javax.naming.NamingException;
@@ -31,10 +32,10 @@ import javax.sql.DataSource;
 import java.net.URI;
 import java.util.Map;
 import java.util.Properties;
-import org.apache.openejb.util.LogCategory;
 
 public class ActiveMQ5Factory implements BrokerFactoryHandler {
 
+    public static final String XBEAN = "xbean";
     private static final ThreadLocal<Properties> threadProperties = new ThreadLocal<Properties>();
     private static BrokerService broker = null;
     private static Throwable throwable = null;
@@ -49,95 +50,102 @@ public class ActiveMQ5Factory implements
         final URI uri = new URI(brokerURI.getRawSchemeSpecificPart());
         broker = BrokerFactory.createBroker(uri);
 
-        Properties properties = getLowerCaseProperties();
-
-        Object value = properties.get("datasource");
-        if (value instanceof String && value.toString().length() == 0) {
-            value = null;
-        }
-
-        if (value != null) {
-            DataSource dataSource;
-            if (value instanceof DataSource) {
-                dataSource = (DataSource) value;
-            } else {
-                String resouceId = (String) value;
+        if (!uri.getScheme().toLowerCase().startsWith(XBEAN)) {
+      
+            Properties properties = getLowerCaseProperties();
+
+            Object value = properties.get("datasource");
+            if (value instanceof String && value.toString().length() == 0) {
+                value = null;
+            }
 
-                try {
-                    ContainerSystem containerSystem = SystemInstance.get().getComponent(ContainerSystem.class);
-                    Context context = containerSystem.getJNDIContext();
-                    Object obj = context.lookup("openejb/Resource/" + resouceId);
-                    if (!(obj instanceof DataSource)) {
-                        throw new IllegalArgumentException("Resource with id " + resouceId
-                                + " is not a DataSource, but is " + obj.getClass().getName());
+            if (value != null) {
+                DataSource dataSource;
+                if (value instanceof DataSource) {
+                    dataSource = (DataSource) value;
+                } else {
+                    String resouceId = (String) value;
+
+                    try {
+                        ContainerSystem containerSystem = SystemInstance.get().getComponent(ContainerSystem.class);
+                        Context context = containerSystem.getJNDIContext();
+                        Object obj = context.lookup("openejb/Resource/" + resouceId);
+                        if (!(obj instanceof DataSource)) {
+                            throw new IllegalArgumentException("Resource with id " + resouceId
+                                                               + " is not a DataSource, but is " + obj.getClass().getName());
+                        }
+                        dataSource = (DataSource) obj;
+                    } catch (NamingException e) {
+                        throw new IllegalArgumentException("Unknown datasource " + resouceId);
                     }
-                    dataSource = (DataSource) obj;
-                } catch (NamingException e) {
-                    throw new IllegalArgumentException("Unknown datasource " + resouceId);
                 }
-            }
 
-            JDBCPersistenceAdapter persistenceAdapter = new JDBCPersistenceAdapter();
+                JDBCPersistenceAdapter persistenceAdapter = new JDBCPersistenceAdapter();
 
-            if (properties.containsKey("usedatabaselock")) {
-                //This must be false for hsqldb
-                persistenceAdapter.setUseDatabaseLock(Boolean.parseBoolean(properties.getProperty("usedatabaselock", "true")));
+                if (properties.containsKey("usedatabaselock")) {
+                    //This must be false for hsqldb
+                    persistenceAdapter.setUseDatabaseLock(Boolean.parseBoolean(properties.getProperty("usedatabaselock", "true")));
+                }
+
+                persistenceAdapter.setDataSource(dataSource);
+                broker.setPersistenceAdapter(persistenceAdapter);
+            } else {
+                MemoryPersistenceAdapter persistenceAdapter = new MemoryPersistenceAdapter();
+                broker.setPersistenceAdapter(persistenceAdapter);
+            }            
+
+            try {
+                //TODO - New in 5.4.x
+                broker.setSchedulerSupport(false);
+            } catch (Throwable t) {
+                //Ignore
             }
 
-            persistenceAdapter.setDataSource(dataSource);
-            broker.setPersistenceAdapter(persistenceAdapter);
-        } else {
-            MemoryPersistenceAdapter persistenceAdapter = new MemoryPersistenceAdapter();
-            broker.setPersistenceAdapter(persistenceAdapter);
+            //Notify when an error occurs on shutdown.
+            broker.setUseLoggingForShutdownErrors(org.apache.openejb.util.Logger.getInstance(LogCategory.OPENEJB, "org.apache.openejb.util.resources").isErrorEnabled());
         }
 
         //We must close the broker
         broker.setUseShutdownHook(false);
         broker.setSystemExitOnShutdown(false);
-        
-        try {
-            broker.setSchedulerSupport(false);
-        } catch (Throwable t) {
-            //Ignore
-        }
 
-        //Notify when an error occurs on shutdown.
-        broker.setUseLoggingForShutdownErrors(org.apache.openejb.util.Logger.getInstance(LogCategory.OPENEJB, "org.apache.openejb.util.resources").isErrorEnabled());
+        if (!broker.isStarted()) {
 
-        final Thread start = new Thread("ActiveMQFactory start and checkpoint") {
+            final Thread start = new Thread("ActiveMQFactory start and checkpoint") {
 
-            @Override
-            public void run() {
-                try {
-                    //Start before returning - this is known to be safe.
-                    broker.start();
-
-                    try{
-                        //This is no longer available from AMQ5.4
-                        broker.waitUntilStarted();
-                    }catch(Throwable t){
-                        org.apache.openejb.util.Logger.getInstance(LogCategory.OPENEJB, "org.apache.openejb.util.resources").warning("ActiveMQ waitUntilStarted failed", t);
+                @Override
+                public void run() {
+                    try {
+                        //Start before returning - this is known to be safe.
+                        broker.start();
+
+                        try {
+                            //This is no longer available from AMQ5.4
+                            broker.waitUntilStarted();
+                        } catch (Throwable t) {
+                            org.apache.openejb.util.Logger.getInstance(LogCategory.OPENEJB, "org.apache.openejb.util.resources").warning("ActiveMQ waitUntilStarted failed", t);
+                        }
+
+                        //Force a checkpoint to initialize pools
+                        broker.getPersistenceAdapter().checkpoint(true);
+                    } catch (Throwable t) {
+                        throwable = t;
                     }
-
-                    //Force a checkpoint to initialize pools
-                    broker.getPersistenceAdapter().checkpoint(true);
-                } catch (Throwable t) {
-                    throwable = t;
                 }
-            }
-        };
+            };
 
-        start.setDaemon(true);
-        start.start();
+            start.setDaemon(true);
+            start.start();
 
-        try {
-            start.join(5000);
-        } catch (InterruptedException e) {
-            //Ignore
-        }
+            try {
+                start.join(5000);
+            } catch (InterruptedException e) {
+                //Ignore
+            }
 
-        if (null != throwable) {
-            org.apache.openejb.util.Logger.getInstance(LogCategory.OPENEJB, "org.apache.openejb.util.resources").error("ActiveMQ failed to start within 5 seconds - It may not be usable", throwable);
+            if (null != throwable) {
+                org.apache.openejb.util.Logger.getInstance(LogCategory.OPENEJB, "org.apache.openejb.util.resources").error("ActiveMQ failed to start within 5 seconds - It may not be usable", throwable);
+            }
         }
 
         return broker;

Modified: openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/resource/activemq/ActiveMQFactory.java
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/resource/activemq/ActiveMQFactory.java?rev=1005029&r1=1005028&r2=1005029&view=diff
==============================================================================
--- openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/resource/activemq/ActiveMQFactory.java (original)
+++ openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/resource/activemq/ActiveMQFactory.java Wed Oct  6 13:30:41 2010
@@ -29,42 +29,46 @@ public class ActiveMQFactory {
     private static final Method setThreadProperties;
     private static final Method createBroker;
     private static final Object instance;
-
-    private static Class clazz;
+    private static final Class clazz;
     private static String brokerPrefix;
+    private static BrokerService broker;
 
     static {
 
+        Class tmp = null;
+
         try {
-            clazz = Class.forName("org.apache.openejb.resource.activemq.ActiveMQ5Factory");
+            tmp = Class.forName("org.apache.openejb.resource.activemq.ActiveMQ5Factory");
             brokerPrefix = "amq5factory:";
         } catch (java.lang.Throwable t1) {
             try {
-                clazz = Class.forName("org.apache.openejb.resource.activemq.ActiveMQ4Factory");
+                tmp = Class.forName("org.apache.openejb.resource.activemq.ActiveMQ4Factory");
                 brokerPrefix = "amq4factory:";
             } catch (java.lang.Throwable t2) {
-                    throw new RuntimeException("Unable to load ActiveMQFactory: Check ActiveMQ jar files are on classpath", t1);
+                throw new RuntimeException("Unable to load ActiveMQFactory: Check ActiveMQ jar files are on classpath", t1);
             }
         }
 
+        clazz = tmp;
+
         try {
             instance = clazz.newInstance();
         } catch (InstantiationException e) {
-                throw new RuntimeException("Unable to create ActiveMQFactory instance", e);
+            throw new RuntimeException("Unable to create ActiveMQFactory instance", e);
         } catch (IllegalAccessException e) {
-                throw new RuntimeException("Unable to access ActiveMQFactory instance", e);
+            throw new RuntimeException("Unable to access ActiveMQFactory instance", e);
         }
 
         try {
             setThreadProperties = clazz.getDeclaredMethod("setThreadProperties", new Class[]{Properties.class});
         } catch (NoSuchMethodException e) {
-                throw new RuntimeException("Unable to create ActiveMQFactory setThreadProperties method", e);
+            throw new RuntimeException("Unable to create ActiveMQFactory setThreadProperties method", e);
         }
 
         try {
             createBroker = clazz.getDeclaredMethod("createBroker", new Class[]{URI.class});
         } catch (NoSuchMethodException e) {
-                throw new RuntimeException("Unable to create ActiveMQFactory setThreadProperties method", e);
+            throw new RuntimeException("Unable to create ActiveMQFactory createBroker method", e);
         }
     }
 
@@ -92,7 +96,8 @@ public class ActiveMQFactory {
 
     public BrokerService createBroker(final URI brokerURI) throws Exception {
         try {
-            return (BrokerService) createBroker.invoke(instance, brokerURI);
+            broker = (BrokerService) createBroker.invoke(instance, brokerURI);
+            return broker;
         } catch (IllegalAccessException e) {
             throw new Exception("ActiveMQFactory.createBroker.IllegalAccessException", e);
         } catch (IllegalArgumentException e) {
@@ -101,4 +106,13 @@ public class ActiveMQFactory {
             throw new Exception("ActiveMQFactory.createBroker.InvocationTargetException", e);
         }
     }
+
+    /**
+     * Returns either the configured broker, or null if it has not yet been created.
+     * This intended for access upon RA shutdown in order to wait for the broker to finish.
+     * @return BrokerService or null
+     */
+    public static BrokerService getBroker() {
+        return broker;
+    }
 }

Modified: openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/resource/activemq/ActiveMQResourceAdapter.java
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/resource/activemq/ActiveMQResourceAdapter.java?rev=1005029&r1=1005028&r2=1005029&view=diff
==============================================================================
--- openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/resource/activemq/ActiveMQResourceAdapter.java (original)
+++ openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/resource/activemq/ActiveMQResourceAdapter.java Wed Oct  6 13:30:41 2010
@@ -111,7 +111,6 @@ public class ActiveMQResourceAdapter ext
 //    public void setTopicPrefetch(Integer integer) {
 //        super.setTopicPrefetch(integer);
 //    }
-    
     @Override
     public void start(final BootstrapContext bootstrapContext) throws ResourceAdapterInternalException {
         final Properties properties = new Properties();
@@ -125,13 +124,21 @@ public class ActiveMQResourceAdapter ext
             properties.put("UseDatabaseLock", this.useDatabaseLock);
         }
 
-        // prefix server uri with openejb: so our broker factory is used
+        // prefix server uri with 'broker:' so our broker factory is used
         final String brokerXmlConfig = getBrokerXmlConfig();
-        if (brokerXmlConfig != null && brokerXmlConfig.startsWith("broker:")) {
+        if (brokerXmlConfig != null) {
+
             try {
-                final URISupport.CompositeData compositeData = URISupport.parseComposite(new URI(brokerXmlConfig));
-                compositeData.getParameters().put("persistent", "false");
-                setBrokerXmlConfig(ActiveMQFactory.getBrokerMetaFile() + compositeData.toURI());
+
+                if (brokerXmlConfig.startsWith("broker:")) {
+
+                    final URISupport.CompositeData compositeData = URISupport.parseComposite(new URI(brokerXmlConfig));
+                    compositeData.getParameters().put("persistent", "false");
+                    setBrokerXmlConfig(ActiveMQFactory.getBrokerMetaFile() + compositeData.toURI());
+                } else if (brokerXmlConfig.toLowerCase().startsWith("xbean:")) {
+                    setBrokerXmlConfig(ActiveMQFactory.getBrokerMetaFile() + brokerXmlConfig);
+                }
+
             } catch (URISyntaxException e) {
                 throw new ResourceAdapterInternalException("Invalid BrokerXmlConfig", e);
             }
@@ -154,13 +161,19 @@ public class ActiveMQResourceAdapter ext
     @Override
     public void stop() {
 
+        org.apache.openejb.util.Logger.getInstance(LogCategory.OPENEJB, "org.apache.openejb.util.resources").info("Stopping ActiveMQ");
+
         final ActiveMQResourceAdapter ra = this;
 
         final Thread stopThread = new Thread("ActiveMQResourceAdapter stop") {
 
             @Override
             public void run() {
-                ra.stopImpl();
+                try {
+                    ra.stopImpl();
+                } catch (Throwable t) {
+                    org.apache.openejb.util.Logger.getInstance(LogCategory.OPENEJB, "org.apache.openejb.util.resources").error("ActiveMQ shutdown failed", t);
+                }
             }
         };
 
@@ -177,7 +190,18 @@ public class ActiveMQResourceAdapter ext
     }
 
     private void stopImpl() {
+
         super.stop();
+        final org.apache.activemq.broker.BrokerService br = ActiveMQFactory.getBroker();
+
+        if (null != br) {
+            try {
+                br.waitUntilStopped();
+            } catch (Throwable t) {
+                //Ignore
+            }
+        }
+
         org.apache.openejb.util.Logger.getInstance(LogCategory.OPENEJB, "org.apache.openejb.util.resources").info("Stopped ActiveMQ");
     }
 }

Modified: openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/util/URISupport.java
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/util/URISupport.java?rev=1005029&r1=1005028&r2=1005029&view=diff
==============================================================================
--- openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/util/URISupport.java (original)
+++ openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/util/URISupport.java Wed Oct  6 13:30:41 2010
@@ -25,7 +25,6 @@ import java.net.URLEncoder;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collections;
-import java.util.HashMap;
 import java.util.Iterator;
 import java.util.LinkedHashMap;
 import java.util.List;
@@ -118,7 +117,7 @@ public class URISupport {
         }
 
         public URI toURI() throws URISyntaxException {
-            StringBuffer sb = new StringBuffer();
+            StringBuilder sb = new StringBuilder();
             if( scheme!=null ) {
                 sb.append(scheme);
                 sb.append(':');
@@ -294,7 +293,7 @@ public class URISupport {
     public static String createQueryString(Map options) throws URISyntaxException {
         try {
             if(options.size()>0) {
-                StringBuffer rc = new StringBuffer();
+                StringBuilder rc = new StringBuilder();
                 boolean first=true;
                 for (Iterator iter = options.keySet().iterator(); iter.hasNext();) {
                     if( first )