You are viewing a plain text version of this content. The canonical link for it is here.
Posted to oak-commits@jackrabbit.apache.org by ch...@apache.org on 2015/10/14 08:18:52 UTC

svn commit: r1708549 - in /jackrabbit/oak/branches/1.2: ./ oak-pojosr/src/main/java/org/apache/jackrabbit/oak/run/osgi/ oak-pojosr/src/test/groovy/org/apache/jackrabbit/oak/run/osgi/ oak-pojosr/src/test/java/org/apache/jackrabbit/oak/run/osgi/

Author: chetanm
Date: Wed Oct 14 06:18:51 2015
New Revision: 1708549

URL: http://svn.apache.org/viewvc?rev=1708549&view=rev
Log:
OAK-2936 - PojoSR should use Felix Connect API instead of pojosr
OAK-3192 - Provide a way to allow embedding application to be notified about OSGi startup
OAK-3195 - Allow finer control for timeout handling in case of repository startup
OAK-3200 - Build Failure due to LuceneSupportTest and OakOSGiRepositoryFactoryTest
OAK-3214 - Enable registration of MBean via Aries JMX Whiteboard support
OAK-3203 - Make shutdown in PojoSR wait for framework shutdown
OAK-3248 - Felix Connect throws exception when launching Oak in Spring Boot env

Merging various fixes that went into oak-pojosr module. These are required to simplify merge to 1.2 branches

1686162,1694651,1694653,1694654,1695032,1695420,1696190,1696375

Added:
    jackrabbit/oak/branches/1.2/oak-pojosr/src/main/java/org/apache/jackrabbit/oak/run/osgi/SpringBootSupport.java
      - copied unchanged from r1696375, jackrabbit/oak/trunk/oak-pojosr/src/main/java/org/apache/jackrabbit/oak/run/osgi/SpringBootSupport.java
    jackrabbit/oak/branches/1.2/oak-pojosr/src/test/groovy/org/apache/jackrabbit/oak/run/osgi/MBeanIntegrationTest.groovy
      - copied unchanged from r1695420, jackrabbit/oak/trunk/oak-pojosr/src/test/groovy/org/apache/jackrabbit/oak/run/osgi/MBeanIntegrationTest.groovy
Modified:
    jackrabbit/oak/branches/1.2/   (props changed)
    jackrabbit/oak/branches/1.2/oak-pojosr/src/main/java/org/apache/jackrabbit/oak/run/osgi/OakOSGiRepositoryFactory.java
    jackrabbit/oak/branches/1.2/oak-pojosr/src/test/groovy/org/apache/jackrabbit/oak/run/osgi/AbstractRepositoryFactoryTest.groovy
    jackrabbit/oak/branches/1.2/oak-pojosr/src/test/java/org/apache/jackrabbit/oak/run/osgi/OakOSGiRepositoryFactoryTest.java

Propchange: jackrabbit/oak/branches/1.2/
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Wed Oct 14 06:18:51 2015
@@ -1,3 +1,3 @@
 /jackrabbit/oak/branches/1.0:1665962
-/jackrabbit/oak/trunk:1672350,1672468,1672537,1672603,1672642,1672644,1672834-1672835,1673351,1673410,1673414-1673415,1673436,1673644,1673662-1673664,1673669,1673695,1673713,1673738,1673787,1673791,1674046,1674065,1674075,1674107,1674228,1674780,1674880,1675054-1675055,1675319,1675332,1675354,1675357,1675382,1675555,1675566,1675593,1676198,1676237,1676407,1676458,1676539,1676670,1676693,1676703,1676725,1677579,1677581,1677609,1677611,1677774,1677788,1677797,1677804,1677806,1677939,1677991,1678023,1678095-1678096,1678124,1678171,1678173,1678211,1678323,1678758,1678938,1678954,1679144,1679165,1679191,1679232,1679235,1679503,1679958,1679961,1680170,1680172,1680182,1680222,1680232,1680236,1680461,1680633,1680643,1680747,1680805-1680806,1680903,1681282,1681767,1681918,1681955,1682042,1682218,1682235,1682437,1682494,1682555,1682855,1682904,1683059,1683089,1683213,1683249,1683259,1683278,1683323,1683687,1683700,1684174-1684175,1684186,1684376,1684442,1684561,1684570,1684601,1684618,1684820
 ,1684868,1685023,1685075,1685370,1685552,1685589-1685590,1685840,1685964,1685977,1685989,1685999,1686023,1686032,1686097,1686162,1686229,1686234,1686253,1686414,1686780,1686854,1686857,1686971,1687053-1687055,1687175,1687196,1687198,1687220,1687239-1687240,1687301,1687441,1687553,1688089-1688090,1688172,1688179,1688349,1688421,1688436,1688453,1688616,1688622,1688634,1688636,1688817,1689003-1689004,1689008,1689577,1689581,1689623,1689810,1689828,1689831,1689833,1689903,1690017,1690043,1690047,1690057,1690247,1690249,1690634-1690637,1690650,1690669,1690674,1690885,1690941,1691139,1691151,1691159,1691167,1691183,1691188,1691210,1691280,1691307,1691331-1691333,1691345,1691384-1691385,1691401,1691509,1692133-1692134,1692156,1692250,1692274,1692363,1692382,1692478,1692955,1693002,1693030,1693209,1693421,1693525-1693526,1694007,1694393-1694394,1695050,1695122,1695280,1695299,1695457,1695482,1695507,1695521,1695540,1696194,1696242,1696285,1696578,1696759,1696916,1697363,1697373,1697410,1697
 582,1697589,1697616,1697672,1700191,1700231,1700397,1700403,1700506,1700571,1700727,1700749,1700769,1700775,1701065,1701619,1701733,1701743,1701750,1701768,1701806,1701810,1701814,1701948,1701955,1701959,1701965,1701986,1702014,1702022,1702241,1702272,1702387,1702405,1702423,1702860,1702942,1702960,1703212,1703382,1703395,1703411,1703428,1703430,1703568,1703592,1703758,1703858,1703878,1704256,1704282,1704285,1704457,1704479,1704490,1704614,1704629,1704636,1704655,1704670,1704886,1705005,1705027,1705043,1705055,1705250,1705268,1705273,1705323,1705677,1705701,1705871,1705992,1706212,1706764,1706772,1707049,1707191,1707435,1708105
+/jackrabbit/oak/trunk:1672350,1672468,1672537,1672603,1672642,1672644,1672834-1672835,1673351,1673410,1673414-1673415,1673436,1673644,1673662-1673664,1673669,1673695,1673713,1673738,1673787,1673791,1674046,1674065,1674075,1674107,1674228,1674780,1674880,1675054-1675055,1675319,1675332,1675354,1675357,1675382,1675555,1675566,1675593,1676198,1676237,1676407,1676458,1676539,1676670,1676693,1676703,1676725,1677579,1677581,1677609,1677611,1677774,1677788,1677797,1677804,1677806,1677939,1677991,1678023,1678095-1678096,1678124,1678171,1678173,1678211,1678323,1678758,1678938,1678954,1679144,1679165,1679191,1679232,1679235,1679503,1679958,1679961,1680170,1680172,1680182,1680222,1680232,1680236,1680461,1680633,1680643,1680747,1680805-1680806,1680903,1681282,1681767,1681918,1681955,1682042,1682218,1682235,1682437,1682494,1682555,1682855,1682904,1683059,1683089,1683213,1683249,1683259,1683278,1683323,1683687,1683700,1684174-1684175,1684186,1684376,1684442,1684561,1684570,1684601,1684618,1684820
 ,1684868,1685023,1685075,1685370,1685552,1685589-1685590,1685840,1685964,1685977,1685989,1685999,1686023,1686032,1686097,1686162,1686229,1686234,1686253,1686414,1686780,1686854,1686857,1686971,1687053-1687055,1687175,1687196,1687198,1687220,1687239-1687240,1687301,1687441,1687553,1688089-1688090,1688172,1688179,1688349,1688421,1688436,1688453,1688616,1688622,1688634,1688636,1688817,1689003-1689004,1689008,1689577,1689581,1689623,1689810,1689828,1689831,1689833,1689903,1690017,1690043,1690047,1690057,1690247,1690249,1690634-1690637,1690650,1690669,1690674,1690885,1690941,1691139,1691151,1691159,1691167,1691183,1691188,1691210,1691280,1691307,1691331-1691333,1691345,1691384-1691385,1691401,1691509,1692133-1692134,1692156,1692250,1692274,1692363,1692382,1692478,1692955,1693002,1693030,1693209,1693421,1693525-1693526,1694007,1694393-1694394,1694651,1694653-1694654,1695032,1695050,1695122,1695280,1695299,1695420,1695457,1695482,1695507,1695521,1695540,1696190,1696194,1696242,1696285,1696
 375,1696578,1696759,1696916,1697363,1697373,1697410,1697582,1697589,1697616,1697672,1700191,1700231,1700397,1700403,1700506,1700571,1700727,1700749,1700769,1700775,1701065,1701619,1701733,1701743,1701750,1701768,1701806,1701810,1701814,1701948,1701955,1701959,1701965,1701986,1702014,1702022,1702241,1702272,1702387,1702405,1702423,1702860,1702942,1702960,1703212,1703382,1703395,1703411,1703428,1703430,1703568,1703592,1703758,1703858,1703878,1704256,1704282,1704285,1704457,1704479,1704490,1704614,1704629,1704636,1704655,1704670,1704886,1705005,1705027,1705043,1705055,1705250,1705268,1705273,1705323,1705677,1705701,1705871,1705992,1706212,1706764,1706772,1707049,1707191,1707435,1708105
 /jackrabbit/trunk:1345480

Modified: jackrabbit/oak/branches/1.2/oak-pojosr/src/main/java/org/apache/jackrabbit/oak/run/osgi/OakOSGiRepositoryFactory.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/branches/1.2/oak-pojosr/src/main/java/org/apache/jackrabbit/oak/run/osgi/OakOSGiRepositoryFactory.java?rev=1708549&r1=1708548&r2=1708549&view=diff
==============================================================================
--- jackrabbit/oak/branches/1.2/oak-pojosr/src/main/java/org/apache/jackrabbit/oak/run/osgi/OakOSGiRepositoryFactory.java (original)
+++ jackrabbit/oak/branches/1.2/oak-pojosr/src/main/java/org/apache/jackrabbit/oak/run/osgi/OakOSGiRepositoryFactory.java Wed Oct 14 06:18:51 2015
@@ -19,15 +19,17 @@
 
 package org.apache.jackrabbit.oak.run.osgi;
 
+import java.lang.management.ManagementFactory;
 import java.lang.reflect.InvocationHandler;
 import java.lang.reflect.Method;
 import java.lang.reflect.Proxy;
 import java.util.Collections;
 import java.util.HashMap;
-import java.util.Iterator;
+import java.util.Hashtable;
 import java.util.List;
 import java.util.Map;
 import java.util.ServiceLoader;
+import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.ExecutionException;
 import java.util.concurrent.TimeUnit;
 import java.util.concurrent.TimeoutException;
@@ -35,24 +37,64 @@ import java.util.concurrent.TimeoutExcep
 import javax.jcr.Repository;
 import javax.jcr.RepositoryException;
 import javax.jcr.RepositoryFactory;
+import javax.management.Attribute;
+import javax.management.AttributeList;
+import javax.management.MBeanServer;
+import javax.management.ObjectName;
 
 import com.google.common.collect.Lists;
 import com.google.common.util.concurrent.SettableFuture;
+import org.apache.commons.io.FilenameUtils;
 import org.apache.felix.connect.launch.BundleDescriptor;
 import org.apache.felix.connect.launch.ClasspathScanner;
 import org.apache.felix.connect.launch.PojoServiceRegistry;
 import org.apache.felix.connect.launch.PojoServiceRegistryFactory;
-import org.apache.commons.io.FilenameUtils;
 import org.apache.jackrabbit.api.JackrabbitRepository;
+import org.apache.jackrabbit.oak.commons.PropertiesUtil;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleActivator;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.BundleEvent;
 import org.osgi.framework.BundleException;
 import org.osgi.framework.Constants;
 import org.osgi.framework.ServiceReference;
+import org.osgi.framework.SynchronousBundleListener;
 import org.osgi.util.tracker.ServiceTracker;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 import static com.google.common.base.Preconditions.checkNotNull;
 
+/**
+ * RepositoryFactory which constructs an instance of Oak repository. Thi factory supports following
+ * parameters
+ *
+ *  <dl>
+ *      <dt>org.osgi.framework.BundleActivator</dt>
+ *      <dd>(Optional) BundleActivator instance which would be notified about the startup and shutdown</dd>
+ *
+ *      <dt>org.apache.jackrabbit.oak.repository.config</dt>
+ *      <dd>(Optional) Config key which refers to the map of config where key in that map refers to OSGi config</dd>
+ *
+ *      <dt>org.apache.jackrabbit.oak.repository.configFile</dt>
+ *      <dd>
+ *          Comma separated list of file names which referred to config stored in form of JSON. The
+ *          JSON content consist of pid as the key and config map as the value
+ *      </dd>
+ *
+ *      <dt>org.apache.jackrabbit.repository.home</dt>
+ *      <dd>Used to specify the absolute path of the repository home directory</dd>
+ *
+ *      <dt>org.apache.jackrabbit.oak.repository.bundleFilter</dt>
+ *      <dd>Used to specify the bundle filter string which is passed to ClasspathScanner</dd>
+ *
+ *      <dt>org.apache.jackrabbit.oak.repository.timeoutInSecs</dt>
+ *      <dd>Timeout in seconds for the repository startup/shutdown should wait. Defaults to 10 minutes</dd>
+ *
+ *      <dt>org.apache.jackrabbit.oak.repository.shutDownOnTimeout</dt>
+ *      <dd>Boolean flag to determine if the OSGi container should be shutdown upon timeout. Defaults to false</dd>
+ *  </dl>
+ */
 public class OakOSGiRepositoryFactory implements RepositoryFactory {
 
     private static Logger log = LoggerFactory.getLogger(OakOSGiRepositoryFactory.class);
@@ -66,8 +108,8 @@ public class OakOSGiRepositoryFactory im
     /**
      * Timeout in seconds for the repository startup should wait
      */
-    public static final String REPOSITORY_STARTUP_TIMEOUT
-            = "org.apache.jackrabbit.oak.repository.startupTimeOut";
+    public static final String REPOSITORY_TIMEOUT_IN_SECS
+            = "org.apache.jackrabbit.oak.repository.timeoutInSecs";
 
     /**
      * Config key which refers to the map of config where key in that map refers to OSGi
@@ -81,11 +123,31 @@ public class OakOSGiRepositoryFactory im
      */
     public static final String REPOSITORY_CONFIG_FILE = "org.apache.jackrabbit.oak.repository.configFile";
 
+    public static final String REPOSITORY_BUNDLE_FILTER
+            = "org.apache.jackrabbit.oak.repository.bundleFilter";
+
+    public static final String REPOSITORY_SHUTDOWN_ON_TIMEOUT =
+            "org.apache.jackrabbit.oak.repository.shutDownOnTimeout";
+
+    public static final String REPOSITORY_ENV_SPRING_BOOT =
+            "org.apache.jackrabbit.oak.repository.springBootMode";
+
     /**
      * Default timeout for repository creation
      */
     private static final int DEFAULT_TIMEOUT = (int) TimeUnit.MINUTES.toSeconds(10);
 
+    private static final BundleActivator NOOP = new BundleActivator() {
+        @Override
+        public void start(BundleContext bundleContext) throws Exception {
+
+        }
+        @Override
+        public void stop(BundleContext bundleContext) throws Exception {
+
+        }
+    };
+
     @SuppressWarnings("unchecked")
     public Repository getRepository(Map parameters) throws RepositoryException {
         if(parameters == null || !parameters.containsKey(REPOSITORY_HOME)){
@@ -97,6 +159,13 @@ public class OakOSGiRepositoryFactory im
         config.putAll(parameters);
 
         PojoServiceRegistry registry = initializeServiceRegistry(config);
+        BundleActivator activator = getApplicationActivator(config);
+
+        try {
+            activator.start(registry.getBundleContext());
+        } catch (Exception e) {
+            log.warn("Error occurred while starting activator {}", activator.getClass(), e);
+        }
 
         //Future which would be used to notify when repository is ready
         // to be used
@@ -104,16 +173,17 @@ public class OakOSGiRepositoryFactory im
 
         new RunnableJobTracker(registry.getBundleContext());
 
+        int timeoutInSecs = PropertiesUtil.toInteger(config.get(REPOSITORY_TIMEOUT_IN_SECS), DEFAULT_TIMEOUT);
+
         //Start the tracker for repository creation
-        new RepositoryTracker(registry, repoFuture);
+        new RepositoryTracker(registry, activator, repoFuture, timeoutInSecs);
 
 
         //Now wait for repository to be created with given timeout
         //if repository creation takes more time. This is required to handle case
         // where OSGi runtime fails to start due to bugs (like cycles)
-        int timeout = getTimeoutInSeconds(config);
         try {
-            return repoFuture.get(timeout, TimeUnit.SECONDS);
+            return repoFuture.get(timeoutInSecs, TimeUnit.SECONDS);
         } catch (InterruptedException e) {
             Thread.currentThread().interrupt();
             throw new RepositoryException("Repository initialization was interrupted");
@@ -121,13 +191,18 @@ public class OakOSGiRepositoryFactory im
             throw new RepositoryException(e);
         } catch (TimeoutException e) {
             try {
-                shutdown(registry);
+                if (PropertiesUtil.toBoolean(config.get(REPOSITORY_SHUTDOWN_ON_TIMEOUT), true)) {
+                    shutdown(registry, timeoutInSecs);
+                    log.info("OSGi container shutdown after waiting for repository initialization for {} sec",timeoutInSecs);
+                }else {
+                    log.warn("[{}] found to be false. Container is not stopped", REPOSITORY_SHUTDOWN_ON_TIMEOUT);
+                }
             } catch (BundleException be) {
                 log.warn("Error occurred while shutting down the service registry (due to " +
                         "startup timeout) backing the Repository ", be);
             }
             throw new RepositoryException("Repository could not be started in " +
-                    timeout + " seconds", e);
+                    timeoutInSecs + " seconds", e);
         }
     }
 
@@ -136,9 +211,10 @@ public class OakOSGiRepositoryFactory im
         processConfig(config);
 
         PojoServiceRegistry registry = createServiceRegistry(config);
+        registerMBeanServer(registry);
         startConfigTracker(registry, config);
         preProcessRegistry(registry);
-        startBundles(registry);
+        startBundles(registry, (String)config.get(REPOSITORY_BUNDLE_FILTER), config);
         postProcessRegistry(registry);
 
         return registry;
@@ -169,9 +245,32 @@ public class OakOSGiRepositoryFactory im
         return descriptors;
     }
 
-    static void shutdown(PojoServiceRegistry registry) throws BundleException {
-        if (registry != null) {
-            registry.getBundleContext().getBundle().stop();
+    private static void shutdown(PojoServiceRegistry registry, int timeoutInSecs) throws BundleException {
+        if (registry == null){
+            return;
+        }
+        final Bundle systemBundle = registry.getBundleContext().getBundle();
+        final CountDownLatch shutdownLatch = new CountDownLatch(1);
+
+        //Logic here is similar to org.apache.felix.connect.PojoServiceRegistryFactoryImpl.FrameworkImpl.waitForStop()
+        systemBundle.getBundleContext().addBundleListener(new SynchronousBundleListener() {
+            public void bundleChanged(BundleEvent event) {
+                if (event.getBundle() == systemBundle && event.getType() == BundleEvent.STOPPED) {
+                    shutdownLatch.countDown();
+                }
+            }
+        });
+
+        //Initiate shutdown
+        systemBundle.stop();
+
+        //Wait for framework shutdown to complete
+        try {
+            shutdownLatch.await(timeoutInSecs, TimeUnit.SECONDS);
+        } catch (InterruptedException e) {
+            Thread.currentThread().interrupt();
+            throw new BundleException("Timed out while waiting for repository " +
+                    "shutdown for "+ timeoutInSecs + " secs", e);
         }
     }
 
@@ -179,12 +278,17 @@ public class OakOSGiRepositoryFactory im
         new ConfigTracker(config, registry.getBundleContext());
     }
 
-    private static int getTimeoutInSeconds(Map config) {
-        Integer timeout = (Integer) config.get(REPOSITORY_STARTUP_TIMEOUT);
-        if (timeout == null) {
-            timeout = DEFAULT_TIMEOUT;
+    /**
+     * Return the BundleActivator provided by the embedding application
+     * @param config config passed to factory for initialization
+     * @return BundleActivator instance
+     */
+    private static BundleActivator getApplicationActivator(Map config) {
+        BundleActivator activator = (BundleActivator) config.get(BundleActivator.class.getName());
+        if (activator == null){
+            activator = NOOP;
         }
-        return timeout;
+        return activator;
     }
 
     @SuppressWarnings("unchecked")
@@ -224,10 +328,13 @@ public class OakOSGiRepositoryFactory im
     }
 
 
-    private void startBundles(PojoServiceRegistry registry) {
+    private void startBundles(PojoServiceRegistry registry, String bundleFilter, Map config) {
         try {
-            List<BundleDescriptor> descriptors = new ClasspathScanner().scanForBundles();
+            List<BundleDescriptor> descriptors = new ClasspathScanner().scanForBundles(bundleFilter);
             descriptors = Lists.newArrayList(descriptors);
+            if (PropertiesUtil.toBoolean(config.get(REPOSITORY_ENV_SPRING_BOOT), false)){
+                descriptors = SpringBootSupport.processDescriptors(descriptors);
+            }
             descriptors = processDescriptors(descriptors);
             registry.startBundles(descriptors);
         } catch (Exception e) {
@@ -235,15 +342,49 @@ public class OakOSGiRepositoryFactory im
         }
     }
 
+    /**
+     * Registers the Platform MBeanServer as OSGi service. This would enable
+     * Aries JMX Whitboard support to then register the JMX MBean which are registered as OSGi service
+     * to be registered against the MBean server
+     */
+    private static void registerMBeanServer(PojoServiceRegistry registry) {
+        MBeanServer platformMBeanServer = ManagementFactory.getPlatformMBeanServer();
+        Hashtable<String, Object> mbeanProps = new Hashtable<String, Object>();
+        try {
+            ObjectName beanName = ObjectName.getInstance("JMImplementation:type=MBeanServerDelegate");
+            AttributeList attrs = platformMBeanServer.getAttributes(beanName,
+                    new String[]{"MBeanServerId", "SpecificationName",
+                            "SpecificationVersion", "SpecificationVendor",
+                            "ImplementationName", "ImplementationVersion",
+                            "ImplementationVendor"});
+            for (Object object : attrs) {
+                Attribute attr = (Attribute) object;
+                if (attr.getValue() != null) {
+                    mbeanProps.put(attr.getName(), attr.getValue().toString());
+                }
+            }
+        } catch (Exception je) {
+            log.info("Cannot set service properties of Platform MBeanServer service, registering without",
+                    je);
+        }
+        registry.registerService(MBeanServer.class.getName(),
+                platformMBeanServer, mbeanProps);
+    }
+
     private static class RepositoryTracker extends ServiceTracker<Repository, Repository> {
         private final SettableFuture<Repository> repoFuture;
         private final PojoServiceRegistry registry;
+        private final BundleActivator activator;
         private RepositoryProxy proxy;
+        private final int timeoutInSecs;
 
-        public RepositoryTracker(PojoServiceRegistry registry, SettableFuture<Repository> repoFuture) {
+        public RepositoryTracker(PojoServiceRegistry registry, BundleActivator activator,
+                                 SettableFuture<Repository> repoFuture, int timeoutInSecs) {
             super(registry.getBundleContext(), Repository.class.getName(), null);
             this.repoFuture = repoFuture;
             this.registry = registry;
+            this.activator = activator;
+            this.timeoutInSecs = timeoutInSecs;
             this.open();
         }
 
@@ -275,6 +416,15 @@ public class OakOSGiRepositoryFactory im
             return (Repository) Proxy.newProxyInstance(getClass().getClassLoader(),
                     new Class[]{Repository.class, JackrabbitRepository.class, ServiceRegistryProvider.class}, proxy);
         }
+
+        public void shutdownRepository() throws BundleException {
+            try {
+                activator.stop(getRegistry().getBundleContext());
+            } catch (Exception e) {
+                log.warn("Error occurred while shutting down activator {}", activator.getClass(), e);
+            }
+            shutdown(getRegistry(), timeoutInSecs);
+        }
     }
 
     /**
@@ -301,13 +451,17 @@ public class OakOSGiRepositoryFactory im
             checkNotNull(obj, "Repository service is not available");
 
             final String name = method.getName();
-            if ("shutdown".equals(name)) {
-                shutdown(tracker.getRegistry());
-            } else if ("getServiceRegistry".equals(name)){
+            if ("getServiceRegistry".equals(name)){
                 return tracker.getRegistry();
             }
 
-            return method.invoke(obj, args);
+            Object result = method.invoke(obj, args);
+
+            //If shutdown then close the framework *after* repository shutdown
+            if ("shutdown".equals(name)) {
+                tracker.shutdownRepository();
+            }
+            return result;
         }
 
         public void clearInitialReference() {

Modified: jackrabbit/oak/branches/1.2/oak-pojosr/src/test/groovy/org/apache/jackrabbit/oak/run/osgi/AbstractRepositoryFactoryTest.groovy
URL: http://svn.apache.org/viewvc/jackrabbit/oak/branches/1.2/oak-pojosr/src/test/groovy/org/apache/jackrabbit/oak/run/osgi/AbstractRepositoryFactoryTest.groovy?rev=1708549&r1=1708548&r2=1708549&view=diff
==============================================================================
--- jackrabbit/oak/branches/1.2/oak-pojosr/src/test/groovy/org/apache/jackrabbit/oak/run/osgi/AbstractRepositoryFactoryTest.groovy (original)
+++ jackrabbit/oak/branches/1.2/oak-pojosr/src/test/groovy/org/apache/jackrabbit/oak/run/osgi/AbstractRepositoryFactoryTest.groovy Wed Oct 14 06:18:51 2015
@@ -20,36 +20,46 @@
 package org.apache.jackrabbit.oak.run.osgi
 
 import org.apache.felix.connect.launch.PojoServiceRegistry
-import org.apache.commons.io.FileUtils
 import org.apache.commons.io.FilenameUtils
 import org.apache.jackrabbit.api.JackrabbitRepository
 import org.junit.After
 import org.junit.Before
+import org.junit.Rule
+import org.junit.rules.TemporaryFolder
 import org.osgi.framework.ServiceReference
 import org.osgi.service.cm.ConfigurationAdmin
 import org.osgi.util.tracker.ServiceTracker
 
 import javax.jcr.*
 import java.util.concurrent.TimeUnit
-import java.util.concurrent.atomic.AtomicInteger
 
 import static org.apache.jackrabbit.oak.run.osgi.OakOSGiRepositoryFactory.REPOSITORY_HOME
-import static org.apache.jackrabbit.oak.run.osgi.OakOSGiRepositoryFactory.REPOSITORY_STARTUP_TIMEOUT
+import static org.apache.jackrabbit.oak.run.osgi.OakOSGiRepositoryFactory.REPOSITORY_TIMEOUT_IN_SECS
+import static org.apache.jackrabbit.oak.run.osgi.OakOSGiRepositoryFactory.REPOSITORY_BUNDLE_FILTER
 
 abstract class AbstractRepositoryFactoryTest{
     static final int SVC_WAIT_TIME = Integer.getInteger("pojosr.waitTime", 10)
-    static final AtomicInteger counter = new AtomicInteger()
     Map config
     File workDir
     Repository repository
     RepositoryFactory repositoryFactory = new OakOSGiRepositoryFactory();
 
+    @Rule
+    public final TemporaryFolder tmpFolder = new TemporaryFolder()
+
     @Before
     void setUp() {
-        workDir = new File("target", "repotest-${counter.incrementAndGet()}-${System.currentTimeMillis()}");
+        workDir = tmpFolder.getRoot();
         config = [
                 (REPOSITORY_HOME): workDir.absolutePath,
-                (REPOSITORY_STARTUP_TIMEOUT) : 2
+                (REPOSITORY_TIMEOUT_IN_SECS) : 60,
+                (REPOSITORY_BUNDLE_FILTER) : '''
+                            (|
+                            (Bundle-SymbolicName=org.apache.jackrabbit*)
+                            (Bundle-SymbolicName=org.apache.sling*)
+                            (Bundle-SymbolicName=org.apache.felix*)
+                            (Bundle-SymbolicName=org.apache.aries*)
+                            )''',
         ]
     }
 
@@ -58,10 +68,6 @@ abstract class AbstractRepositoryFactory
         if (repository instanceof JackrabbitRepository) {
             ((JackrabbitRepository) repository).shutdown();
         }
-
-        if (workDir.exists()) {
-            FileUtils.deleteQuietly(workDir);
-        }
     }
 
     protected PojoServiceRegistry getRegistry() {

Modified: jackrabbit/oak/branches/1.2/oak-pojosr/src/test/java/org/apache/jackrabbit/oak/run/osgi/OakOSGiRepositoryFactoryTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/branches/1.2/oak-pojosr/src/test/java/org/apache/jackrabbit/oak/run/osgi/OakOSGiRepositoryFactoryTest.java?rev=1708549&r1=1708548&r2=1708549&view=diff
==============================================================================
--- jackrabbit/oak/branches/1.2/oak-pojosr/src/test/java/org/apache/jackrabbit/oak/run/osgi/OakOSGiRepositoryFactoryTest.java (original)
+++ jackrabbit/oak/branches/1.2/oak-pojosr/src/test/java/org/apache/jackrabbit/oak/run/osgi/OakOSGiRepositoryFactoryTest.java Wed Oct 14 06:18:51 2015
@@ -51,10 +51,13 @@ import org.apache.jackrabbit.oak.spi.sec
 import org.junit.Before;
 import org.junit.Ignore;
 import org.junit.Test;
+import org.osgi.framework.BundleActivator;
+import org.osgi.framework.BundleContext;
 
 import static org.apache.commons.io.FilenameUtils.concat;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
 
 @Ignore("OAK-1522")
 public class OakOSGiRepositoryFactoryTest {
@@ -63,6 +66,8 @@ public class OakOSGiRepositoryFactoryTes
     private RepositoryFactory repositoryFactory = new CustomOakFactory();
     private Map config = new HashMap();
     private String newPassword;
+    private boolean calledOnStart;
+    private boolean calledOnStop;
 
     @Before
     public void setUp() throws IOException {
@@ -79,9 +84,10 @@ public class OakOSGiRepositoryFactoryTes
     @Test
     public void testRepositoryTar() throws Exception {
         copyConfig("tar");
-
+        config.put(BundleActivator.class.getName(), new TestActivator());
         Repository repository = repositoryFactory.getRepository(config);
 
+        assertTrue("test activator should have been called on startup", calledOnStart);
         //Give time for system to stablize :(
         TimeUnit.SECONDS.sleep(1);
 
@@ -95,6 +101,7 @@ public class OakOSGiRepositoryFactoryTes
         testCallback(repository);
 
         shutdown(repository);
+        assertTrue("test activator should have been called on stop", calledOnStop);
     }
 
     private void testCallback(Repository repository) throws RepositoryException {
@@ -156,6 +163,19 @@ public class OakOSGiRepositoryFactoryTes
         }
     }
 
+    private class TestActivator implements BundleActivator {
+
+        @Override
+        public void start(BundleContext bundleContext) throws Exception {
+            calledOnStart = true;
+        }
+
+        @Override
+        public void stop(BundleContext bundleContext) throws Exception {
+            calledOnStop = true;
+        }
+    }
+
     private class TestAction extends AbstractAuthorizableAction {
 
         @Override