killbill-memoizeit

Details

diff --git a/beatrix/src/test/java/com/ning/billing/beatrix/integration/TestIntegrationBase.java b/beatrix/src/test/java/com/ning/billing/beatrix/integration/TestIntegrationBase.java
index 7c1fb1d..8ca8e55 100644
--- a/beatrix/src/test/java/com/ning/billing/beatrix/integration/TestIntegrationBase.java
+++ b/beatrix/src/test/java/com/ning/billing/beatrix/integration/TestIntegrationBase.java
@@ -240,7 +240,8 @@ public class TestIntegrationBase extends BeatrixTestSuiteWithEmbeddedDB implemen
 
         super.beforeMethod();
 
-        Thread.currentThread().setContextClassLoader(null);
+        log.info("beforeMethod context classLoader = " + (Thread.currentThread().getContextClassLoader() != null ? Thread.currentThread().getContextClassLoader().toString() : "null"));
+        //Thread.currentThread().setContextClassLoader(null);
 
         log.warn("\n");
         log.warn("RESET TEST FRAMEWORK\n\n");
@@ -263,6 +264,8 @@ public class TestIntegrationBase extends BeatrixTestSuiteWithEmbeddedDB implemen
         busService.getBus().unregister(busHandler);
         lifecycle.fireShutdownSequencePostEventUnRegistration();
 
+        log.info("afterMethod context classLoader = " + (Thread.currentThread().getContextClassLoader() != null ? Thread.currentThread().getContextClassLoader().toString() : "null"));
+
         log.warn("DONE WITH TEST\n");
     }
 
diff --git a/osgi/src/main/java/com/ning/billing/osgi/FileInstall.java b/osgi/src/main/java/com/ning/billing/osgi/FileInstall.java
index 1ffaec9..6fb5bd9 100644
--- a/osgi/src/main/java/com/ning/billing/osgi/FileInstall.java
+++ b/osgi/src/main/java/com/ning/billing/osgi/FileInstall.java
@@ -135,6 +135,7 @@ public class FileInstall {
             logger.info("Skipping fragment bundle {}", bundle.getLocation());
         } else {
             logger.info("Starting bundle {}", bundle.getLocation());
+            final ClassLoader previousClassLoader = Thread.currentThread().getContextClassLoader();
             try {
                 bundle.start();
                 return true;
diff --git a/osgi-bundles/bundles/jruby/src/main/java/com/ning/billing/osgi/bundles/jruby/JRubyActivator.java b/osgi-bundles/bundles/jruby/src/main/java/com/ning/billing/osgi/bundles/jruby/JRubyActivator.java
index b28fc18..d70c7dc 100644
--- a/osgi-bundles/bundles/jruby/src/main/java/com/ning/billing/osgi/bundles/jruby/JRubyActivator.java
+++ b/osgi-bundles/bundles/jruby/src/main/java/com/ning/billing/osgi/bundles/jruby/JRubyActivator.java
@@ -37,32 +37,37 @@ public class JRubyActivator extends KillbillActivatorBase {
     public void start(final BundleContext context) throws Exception {
 
         super.start(context);
-        logService.log(LogService.LOG_INFO, "JRuby bundle activated");
 
-        doMagicToMakeJRubyAndFelixHappy();
+        withContextClassLoader(new PluginCall() {
+            @Override
+            public void doCall() {
 
-        // Retrieve the plugin config
-        final PluginRubyConfig rubyConfig = retrievePluginRubyConfig(context);
+                logService.log(LogService.LOG_INFO, "JRuby bundle activated");
 
-        // Setup JRuby
-        final ScriptingContainer scriptingContainer = setupScriptingContainer(rubyConfig);
-        if (PluginType.NOTIFICATION.equals(rubyConfig.getPluginType())) {
-            plugin = new JRubyNotificationPlugin(rubyConfig, scriptingContainer, context, logService);
-            dispatcher.registerEventHandler((OSGIKillbillEventHandler) plugin);
-        } else if (PluginType.PAYMENT.equals(rubyConfig.getPluginType())) {
-            plugin = new JRubyPaymentPlugin(rubyConfig, scriptingContainer, context, logService);
-        }
+                // Retrieve the plugin config
+                final PluginRubyConfig rubyConfig = retrievePluginRubyConfig(context);
+
+                // Setup JRuby
+                final ScriptingContainer scriptingContainer = setupScriptingContainer(rubyConfig);
+                if (PluginType.NOTIFICATION.equals(rubyConfig.getPluginType())) {
+                    plugin = new JRubyNotificationPlugin(rubyConfig, scriptingContainer, context, logService);
+                    dispatcher.registerEventHandler((OSGIKillbillEventHandler) plugin);
+                } else if (PluginType.PAYMENT.equals(rubyConfig.getPluginType())) {
+                    plugin = new JRubyPaymentPlugin(rubyConfig, scriptingContainer, context, logService);
+                }
 
-        // Validate and instantiate the plugin
+                // Validate and instantiate the plugin
 
-        final Map<String, Object> killbillServices = retrieveKillbillApis(context);
-        killbillServices.put("root", rubyConfig.getPluginVersionRoot().getAbsolutePath());
-        killbillServices.put("logger", logService);
-        plugin.instantiatePlugin(killbillServices);
+                final Map<String, Object> killbillServices = retrieveKillbillApis(context);
+                killbillServices.put("root", rubyConfig.getPluginVersionRoot().getAbsolutePath());
+                killbillServices.put("logger", logService);
+                plugin.instantiatePlugin(killbillServices);
 
-        logService.log(LogService.LOG_INFO, "Starting JRuby plugin " + plugin.getPluginMainClass());
-        plugin.startPlugin(context);
+                logService.log(LogService.LOG_INFO, "Starting JRuby plugin " + plugin.getPluginMainClass());
+                plugin.startPlugin(context);
 
+            }
+        }, this.getClass().getClassLoader());
     }
 
     private PluginRubyConfig retrievePluginRubyConfig(final BundleContext context) {
@@ -70,13 +75,6 @@ public class JRubyActivator extends KillbillActivatorBase {
         return pluginConfigServiceApi.getPluginRubyConfig(context.getBundle().getBundleId());
     }
 
-    // JRuby/Felix specifics, it works out of the box on Equinox.
-    // Other OSGI frameworks are untested.
-    private void doMagicToMakeJRubyAndFelixHappy() {
-        // Tell JRuby to use the correct class loader
-        Thread.currentThread().setContextClassLoader(this.getClass().getClassLoader());
-    }
-
     private ScriptingContainer setupScriptingContainer(final PluginRubyConfig rubyConfig) {
         final ScriptingContainer scriptingContainer = new ScriptingContainer();
 
@@ -87,9 +85,15 @@ public class JRubyActivator extends KillbillActivatorBase {
     }
 
     public void stop(final BundleContext context) throws Exception {
-        plugin.stopPlugin(context);
-        killbillAPI.close();
-        logService.close();
+
+        withContextClassLoader(new PluginCall() {
+            @Override
+            public void doCall() {
+                plugin.stopPlugin(context);
+                killbillAPI.close();
+                logService.close();
+            }
+        }, this.getClass().getClassLoader());
     }
 
     // We make the explicit registration in the start method by hand as this would be called too early
@@ -124,4 +128,22 @@ public class JRubyActivator extends KillbillActivatorBase {
         killbillUserApis.put("tag_user_api", killbillAPI.getTagUserApi());
         return killbillUserApis;
     }
+
+
+    private static interface PluginCall {
+        public void doCall();
+    }
+
+    // JRuby/Felix specifics, it works out of the box on Equinox.
+    // Other OSGI frameworks are untested.
+    private void withContextClassLoader(final PluginCall call, final ClassLoader pluginClassLoader) {
+        final ClassLoader enteringContextClassLoader = Thread.currentThread().getContextClassLoader();
+        try {
+            Thread.currentThread().setContextClassLoader(pluginClassLoader);
+            call.doCall();
+        } finally {
+            // We want to make sure that calling thread gets back its original context class loader when it returns
+            Thread.currentThread().setContextClassLoader(enteringContextClassLoader);
+        }
+    }
 }