Improve memory usage for headless generation of many projects, by using a shared Tigerstripe runtime instance per-thread.
Change-Id: I2e7fc06cbf167d3ea66a88a2b4079dacc42140b2
diff --git a/core/org.eclipse.tigerstripe.api/pom.xml b/core/org.eclipse.tigerstripe.api/pom.xml
index 9567968..e7a398a 100644
--- a/core/org.eclipse.tigerstripe.api/pom.xml
+++ b/core/org.eclipse.tigerstripe.api/pom.xml
@@ -42,6 +42,11 @@
<artifactId>velocity</artifactId>
<version>1.5</version>
</dependency>
+ <dependency>
+ <groupId>commons-io</groupId>
+ <artifactId>commons-io</artifactId>
+ <version>2.8.0</version>
+ </dependency>
</dependencies>
<build>
diff --git a/core/org.eclipse.tigerstripe.api/src/main/java/org/eclipse/tigerstripe/workbench/internal/core/plugin/pluggable/TigerstripeJarUtils.java b/core/org.eclipse.tigerstripe.api/src/main/java/org/eclipse/tigerstripe/workbench/internal/core/plugin/pluggable/TigerstripeJarUtils.java
index 2a2d480..1e262ab 100644
--- a/core/org.eclipse.tigerstripe.api/src/main/java/org/eclipse/tigerstripe/workbench/internal/core/plugin/pluggable/TigerstripeJarUtils.java
+++ b/core/org.eclipse.tigerstripe.api/src/main/java/org/eclipse/tigerstripe/workbench/internal/core/plugin/pluggable/TigerstripeJarUtils.java
@@ -8,6 +8,7 @@
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
+import org.apache.commons.io.IOUtils;
import org.eclipse.tigerstripe.workbench.TigerstripeException;
public class TigerstripeJarUtils {
@@ -25,15 +26,9 @@
File file = File.createTempFile(name.substring(0, name.length() - extension.length()) + ".",
extension);
file.deleteOnExit();
- try (
- InputStream input = jarFile.getInputStream(jarEntry);
- OutputStream output = new FileOutputStream(file);) {
-
- int readCount;
- byte[] buffer = new byte[4096];
- while ((readCount = input.read(buffer)) != -1) {
- output.write(buffer, 0, readCount);
- }
+ try (InputStream input = jarFile.getInputStream(jarEntry);
+ OutputStream output = new FileOutputStream(file)) {
+ IOUtils.copy(input, output);
}
return file;
} catch (IOException e) {
diff --git a/core/org.eclipse.tigerstripe.core/src/main/java/org/eclipse/tigerstripe/runner/GenerationData.java b/core/org.eclipse.tigerstripe.core/src/main/java/org/eclipse/tigerstripe/runner/GenerationData.java
new file mode 100644
index 0000000..248e629
--- /dev/null
+++ b/core/org.eclipse.tigerstripe.core/src/main/java/org/eclipse/tigerstripe/runner/GenerationData.java
@@ -0,0 +1,40 @@
+/********************************************************************************
+ * Copyright (c) 2018 by Cisco Systems, Inc. All rights reserved.
+ *
+ * This software contains proprietary information which shall not be reproduced or
+ * transferred to other documents and shall not be disclosed to others or used for
+ * manufacturing or any other purpose without prior permission of Cisco Systems.
+ ********************************************************************************/
+package org.eclipse.tigerstripe.runner;
+
+import java.io.File;
+
+import org.eclipse.tigerstripe.workbench.TigerstripeException;
+import org.eclipse.tigerstripe.workbench.internal.api.ITigerstripeRuntime;
+
+public class GenerationData {
+
+ private String loggingDir;
+ private String primitivesDir;
+
+ GenerationData(ITigerstripeRuntime runtime) throws TigerstripeException {
+ setLoggingDir(runtime.getLoggingDir());
+ setPrimitivesDir(new File(runtime.getPhantomProject().getBaseDir(), "classes").getAbsolutePath());
+ }
+
+ public String getLoggingDir() {
+ return loggingDir;
+ }
+
+ void setLoggingDir(String loggingDir) {
+ this.loggingDir = loggingDir;
+ }
+
+ public String getPrimitiviesDir() {
+ return primitivesDir;
+ }
+
+ void setPrimitivesDir(String primitivesDir) {
+ this.primitivesDir = primitivesDir;
+ }
+}
diff --git a/core/org.eclipse.tigerstripe.core/src/main/java/org/eclipse/tigerstripe/runner/ProjectGenerator.java b/core/org.eclipse.tigerstripe.core/src/main/java/org/eclipse/tigerstripe/runner/ProjectGenerator.java
index 2c8ac34..3b8341e 100644
--- a/core/org.eclipse.tigerstripe.core/src/main/java/org/eclipse/tigerstripe/runner/ProjectGenerator.java
+++ b/core/org.eclipse.tigerstripe.core/src/main/java/org/eclipse/tigerstripe/runner/ProjectGenerator.java
@@ -10,6 +10,7 @@
import java.io.File;
import java.net.URL;
import java.net.URLClassLoader;
+import java.util.AbstractMap;
import java.util.Collection;
import org.apache.commons.lang.StringUtils;
@@ -38,6 +39,16 @@
public class ProjectGenerator {
private static final Logger LOG = LoggerFactory.getLogger(ProjectGenerator.class);
+
+ // To improve memory consumption and class loading overhead, we create just one
+ // Tigerstripe runtime instance per thread. This does mean things like
+ // Tigerstripe Profile and Installed Generators/Plugins are cached, so we may
+ // need to consider an option to not cache the instance for projects that want
+ // to run different profiles/generators within a single JVM.
+ // NOTE: This is technically a memory leak, as we don't have any way to release
+ // the instances once they are no longer needed. That said, we do "dispose" them
+ // to clean up some data that we know will not need to be referenced again.
+ private static final ThreadLocal<NewTigerstripeRuntime> threadRuntime = new ThreadLocal<>();
/**
* Runs generation of the given Tigerstripe project(s).
@@ -45,28 +56,32 @@
* @param arguments
* - the generation arguments
*/
- public static ITigerstripeRuntime generate(GeneratorArguments arguments) throws TigerstripeException {
+ public static GenerationData generate(GeneratorArguments arguments) throws TigerstripeException {
File tigerstripeDir = arguments.getWorkingDirectory();
String modelName = arguments.getProject() != null ? arguments.getProject().getName() : arguments.getModuleId();
LOG.info("Starting Tigerstripe generation of {} at: {}", modelName, tigerstripeDir.getAbsolutePath());
- ClassLoader originalContext = setThreadContextForGeneration(arguments);
+
+ AbstractMap.SimpleEntry<ClassLoader, URLClassLoader> classloaders = prepareThreadContextForGeneration(arguments);
+ NewTigerstripeRuntime runtime = null;
try {
long start = System.currentTimeMillis();
- ITigerstripeRuntime runtime = prepareRuntime(tigerstripeDir);
+ runtime = prepareRuntime(tigerstripeDir);
performGeneration(runtime, arguments);
long duration = System.currentTimeMillis() - start;
LOG.info("Generation of {} completed in {} milliseconds.", modelName, Long.valueOf(duration));
- return runtime;
+ return new GenerationData(runtime);
} finally {
- NewTigerstripeRuntime.setThreadActiveRuntime(null);
- resetThreadContext(originalContext);
+ if (runtime != null) {
+ runtime.dispose();
+ }
+ resetThreadContext(classloaders);
}
}
@SuppressWarnings("resource")
- private static ClassLoader setThreadContextForGeneration(GeneratorArguments arguments) {
+ private static AbstractMap.SimpleEntry<ClassLoader, URLClassLoader> prepareThreadContextForGeneration(GeneratorArguments arguments) {
if (!arguments.getExtraClasspathEntries().isEmpty()) {
ClassLoader cl = Thread.currentThread().getContextClassLoader();
URLClassLoader generationCL = URLClassLoader
@@ -77,25 +92,35 @@
}
LOG.trace("Setting updated thread classloader before generation");
Thread.currentThread().setContextClassLoader(generationCL);
- return cl;
+ return new AbstractMap.SimpleEntry<>(cl, generationCL);
}
return null;
}
- private static void resetThreadContext(ClassLoader context) {
- if (context != null) {
+ private static void resetThreadContext(AbstractMap.SimpleEntry<ClassLoader, URLClassLoader> classloaders) {
+ if (classloaders != null) {
LOG.trace("Resetting thread classloader context after generation");
- Thread.currentThread().setContextClassLoader(context);
+ Thread.currentThread().setContextClassLoader(classloaders.getKey());
+ try {
+ classloaders.getValue().close();
+ } catch (Exception e) {
+ LOG.error("An error occurred closing the generation classloader", e);
+ }
}
}
- private static ITigerstripeRuntime prepareRuntime(File tigerstripeDir) throws TigerstripeException {
- // TODO - runtime/directory/init/thread-local should all be handled by constructor
- NewTigerstripeRuntime runtime = new NewTigerstripeRuntime();
- runtime.setRuntype(NewTigerstripeRuntime.STANDALONE_RUN);
+ private static NewTigerstripeRuntime prepareRuntime(File tigerstripeDir) throws TigerstripeException {
+ // Only instantiate a new runtime if we don't already have one cached in the thread.
+ NewTigerstripeRuntime runtime = threadRuntime.get();
+ if (threadRuntime.get() == null) {
+ runtime = new NewTigerstripeRuntime();
+ runtime.setRuntype(NewTigerstripeRuntime.STANDALONE_RUN);
+ NewTigerstripeRuntime.setThreadActiveRuntime(runtime);
+ threadRuntime.set(runtime);
+ }
+
// Set as the new thread local instance before calling init, otherwise
// some code may acquire the old instance
- NewTigerstripeRuntime.setThreadActiveRuntime(runtime);
runtime.init(tigerstripeDir.getAbsolutePath());
IWorkbenchProfile profile = runtime.getWorkbenchProfileSession().getActiveProfile();
diff --git a/core/org.eclipse.tigerstripe.core/src/main/java/org/eclipse/tigerstripe/workbench/internal/core/NewTigerstripeRuntime.java b/core/org.eclipse.tigerstripe.core/src/main/java/org/eclipse/tigerstripe/workbench/internal/core/NewTigerstripeRuntime.java
index 718f2b1..8d4f549 100644
--- a/core/org.eclipse.tigerstripe.core/src/main/java/org/eclipse/tigerstripe/workbench/internal/core/NewTigerstripeRuntime.java
+++ b/core/org.eclipse.tigerstripe.core/src/main/java/org/eclipse/tigerstripe/workbench/internal/core/NewTigerstripeRuntime.java
@@ -6,6 +6,7 @@
import java.security.CodeSource;
import java.text.SimpleDateFormat;
import java.time.Year;
+import java.util.Enumeration;
import java.util.GregorianCalendar;
import java.util.Map;
import java.util.TimeZone;
@@ -14,6 +15,7 @@
import java.util.jar.Manifest;
import org.apache.commons.lang.StringUtils;
+import org.apache.log4j.Appender;
import org.apache.log4j.Level;
import org.apache.log4j.Logger;
import org.apache.log4j.PatternLayout;
@@ -38,9 +40,17 @@
public class NewTigerstripeRuntime implements ITigerstripeRuntime {
// Version of the currently active tigerstripe feature
- public static final String TIGERSTRIPE_FEATURE_VERSION = "tigerstripe.feature.version";
+ public static final String TIGERSTRIPE_FEATURE_VERSION = "tigerstripe.feature.version"; // $NON-NLS-1$
- public static final String CURRENT_YEAR = "tigerstripe.runtime.year";
+ public static final String CURRENT_YEAR = "tigerstripe.runtime.year"; // $NON-NLS-1$
+
+ public static final String TIGERSTRIPE_HOME_DIR = "tigerstripe"; // $NON-NLS-1$
+
+ public static final String TIGERSTRIPE_PLUGINS_DIR = "plugins"; // $NON-NLS-1$
+
+ public static final String TIGERSTRIPE_MODULES_DIR = "modules"; // $NON-NLS-1$
+
+ public static final String PRODUCT_NAME = "product.name"; // $NON-NLS-1$
/** Signaling we're running as a generic Eclipse Run */
public static final int ECLIPSE_GUI_RUN = 1;
@@ -56,7 +66,34 @@
/** Signaling we're running thru the Eclipse Headless harness */
public static final int STANDALONE_RUN = 4;
+
+ private static final String LOG4J_FQCN = NewTigerstripeRuntime.class.getName();
+
+ private static NewTigerstripeRuntime defaultInstance;
+ private static ThreadLocal<NewTigerstripeRuntime> threadLocalInstance = new ThreadLocal<>();
+
+ public static NewTigerstripeRuntime getThreadActiveRuntime() {
+ return threadLocalInstance.get() != null ? threadLocalInstance.get() : getDefaultInstance();
+ }
+
+ private static synchronized NewTigerstripeRuntime getDefaultInstance() {
+ if (defaultInstance == null) {
+ defaultInstance = new NewTigerstripeRuntime();
+ }
+ return defaultInstance;
+ }
+
+ public static void setThreadActiveRuntime(NewTigerstripeRuntime runtime) {
+ NewTigerstripeRuntime old = threadLocalInstance.get();
+ if (old != null) {
+ old.dispose();
+ }
+ threadLocalInstance.set(runtime);
+ }
+
+ private volatile boolean initialized = false;
+
/*
* the current run type. This is set once and for all Valid values are
* ECLIPSE_GUI_RUN, ECLIPSE_HEADLESS_RUN, ANT_RUN, CLI_RUN
@@ -66,27 +103,16 @@
private Logger tigerstripeLogger;
private String loggingDir = null;
-
- private RollingFileAppender appender;
+ private String loggingFile = null;
private Level defaultLoggingLevel = Level.ALL;
private int maxNumBackupLogs = 9;
- private final String LOG4J_FQCN = NewTigerstripeRuntime.class.getName();
-
private String logStartTime = "";
private String tigerstripeRuntimeRoot;
- public static final String TIGERSTRIPE_HOME_DIR = "tigerstripe";
-
- public static final String TIGERSTRIPE_PLUGINS_DIR = "plugins";
-
- public static final String TIGERSTRIPE_MODULES_DIR = "modules";
-
- public static final String PRODUCT_NAME = "product.name";
-
private TigerstripePhantomProjectHandle phantomHandle = null;
private PhantomTigerstripeProjectMgr tsProjectManager;
@@ -99,34 +125,6 @@
private String ts_home;
- private volatile boolean initialized = false;
-
- // This can be called if you dpn;t need any specific instance data -
- // eg in the ArtifactPersister, it is used to get the
- // version. Don;t use for anything that needs phantom etc.
-
- // THIS is used by the eclipse plugins, as there should only be one runtime
- // instance there!
- private static NewTigerstripeRuntime defaultInstance = new NewTigerstripeRuntime();
-
- private static ThreadLocal<NewTigerstripeRuntime> threadLocalInstance = new ThreadLocal<>();
-
- public static NewTigerstripeRuntime getThreadActiveRuntime() {
- return threadLocalInstance.get() != null ? threadLocalInstance.get() : defaultInstance;
- }
-
- public static void setThreadActiveRuntime(NewTigerstripeRuntime runtime) {
- NewTigerstripeRuntime old = threadLocalInstance.get();
- if (old != null) {
- old.dispose();
- }
- threadLocalInstance.set(runtime);
- }
-
- public NewTigerstripeRuntime() {
- tsProjectManager = new PhantomTigerstripeProjectMgr(this);
- }
-
public int getRuntype() {
return runType;
}
@@ -190,7 +188,7 @@
boolean outputFileExists = false;
if (outputFile.exists())
outputFileExists = true;
- appender = new RollingFileAppender(patternLayout, outputFile.getAbsolutePath());
+ RollingFileAppender appender = new RollingFileAppender(patternLayout, outputFile.getAbsolutePath());
appender.setMaxBackupIndex(maxNumBackupLogs);
appender.setImmediateFlush(true);
tigerstripeLogger = Logger.getLogger(tigerstripeLoggerID);
@@ -201,6 +199,7 @@
tigerstripeLogger.addAppender(appender);
tigerstripeLogger.setAdditivity(false);
tigerstripeLogger.setLevel(defaultLoggingLevel);
+ loggingFile = appender.getFile();
} catch (IOException e) {
e.printStackTrace(System.err);
}
@@ -294,7 +293,7 @@
}
public String getLogPath() {
- return appender.getFile();
+ return loggingFile;
}
protected static String findWorkbenchFeatureVersion() {
@@ -334,11 +333,16 @@
}
public IPhantomProjectManager getPhantomTigerstripeProjectMgr() {
+ synchronized (this) {
+ if (tsProjectManager == null) {
+ tsProjectManager = new PhantomTigerstripeProjectMgr(this);
+ }
+ }
return tsProjectManager;
}
public IPhantomTigerstripeProject getPhantomProject() throws TigerstripeException {
- synchronized (getPhantomTigerstripeProjectMgr()) {
+ synchronized (this) {
if (phantomHandle == null) {
phantomHandle = new TigerstripePhantomProjectHandle(this);
phantomHandle.init();
@@ -349,7 +353,7 @@
}
public void resetPhantomProject() {
- synchronized (getPhantomTigerstripeProjectMgr()) {
+ synchronized (this) {
if (phantomHandle != null) {
phantomHandle.dispose();
phantomHandle = null;
@@ -390,22 +394,40 @@
}
}
- private void dispose() {
+ public void dispose() {
+ // NOTE - We do not dispose the workbench profile or plugins, as they are very
+ // expensive to reload in case this instance is re-initialized again.
if (classpathModuleManager != null) {
classpathModuleManager.dispose();
classpathModuleManager = null;
}
- if (pluginManager != null) {
- pluginManager.dispose();
- pluginManager = null;
+ if (phantomHandle != null) {
+ phantomHandle.dispose();
+ phantomHandle = null;
}
- if (workbenchProfileSession != null) {
- workbenchProfileSession.dispose();
- workbenchProfileSession = null;
+ if (tsProjectManager != null) {
+ tsProjectManager.dispose();
+ tsProjectManager = null;
}
+ if (tigerstripeLogger != null) {
+ Enumeration<Appender> appenders = tigerstripeLogger.getAllAppenders();
+ if (appenders != null) {
+ while (appenders.hasMoreElements()) {
+ Appender appender = appenders.nextElement();
+ appender.close();
+ tigerstripeLogger.removeAppender(appender);
+ }
+ }
+ tigerstripeLogger = null;
+ }
+ loggingDir = null;
+ loggingFile = null;
+ logStartTime = null;
+ tigerstripeRuntimeRoot = null;
+ ts_home = null;
initialized = false;
}
-
+
public String getTs_home() {
return ts_home;
}
diff --git a/core/org.eclipse.tigerstripe.core/src/main/java/org/eclipse/tigerstripe/workbench/internal/core/plugin/PluginManager.java b/core/org.eclipse.tigerstripe.core/src/main/java/org/eclipse/tigerstripe/workbench/internal/core/plugin/PluginManager.java
index 3c8f628..ad4a72d 100644
--- a/core/org.eclipse.tigerstripe.core/src/main/java/org/eclipse/tigerstripe/workbench/internal/core/plugin/PluginManager.java
+++ b/core/org.eclipse.tigerstripe.core/src/main/java/org/eclipse/tigerstripe/workbench/internal/core/plugin/PluginManager.java
@@ -220,7 +220,7 @@
}
}
- PluggablePlugin pluginBody = new PluggablePlugin(runtime,unZippedFile, zippedFile);
+ PluggablePlugin pluginBody = new PluggablePlugin(runtime, unZippedFile);
if (pluginBody.isValid()) {
PluggableHousing housing = new PluggableHousing(pluginBody);
registerHousing(housing);
diff --git a/core/org.eclipse.tigerstripe.core/src/main/java/org/eclipse/tigerstripe/workbench/internal/core/plugin/pluggable/ContributedPlugin.java b/core/org.eclipse.tigerstripe.core/src/main/java/org/eclipse/tigerstripe/workbench/internal/core/plugin/pluggable/ContributedPlugin.java
index 8a0ceca..6b27b45 100644
--- a/core/org.eclipse.tigerstripe.core/src/main/java/org/eclipse/tigerstripe/workbench/internal/core/plugin/pluggable/ContributedPlugin.java
+++ b/core/org.eclipse.tigerstripe.core/src/main/java/org/eclipse/tigerstripe/workbench/internal/core/plugin/pluggable/ContributedPlugin.java
@@ -22,7 +22,7 @@
* @throws TigerstripeException
*/
public ContributedPlugin(ITigerstripeRuntime runtime, String path, Bundle bundle) throws TigerstripeException {
- super(runtime, path, null);
+ super(runtime, path);
this.bundle = bundle;
this.bundleName = bundle.getHeaders().get("Bundle-Name");
}
diff --git a/core/org.eclipse.tigerstripe.core/src/main/java/org/eclipse/tigerstripe/workbench/internal/core/plugin/pluggable/JarInJarClassLoader.java b/core/org.eclipse.tigerstripe.core/src/main/java/org/eclipse/tigerstripe/workbench/internal/core/plugin/pluggable/JarInJarClassLoader.java
index 2e310ef..31f12f1 100644
--- a/core/org.eclipse.tigerstripe.core/src/main/java/org/eclipse/tigerstripe/workbench/internal/core/plugin/pluggable/JarInJarClassLoader.java
+++ b/core/org.eclipse.tigerstripe.core/src/main/java/org/eclipse/tigerstripe/workbench/internal/core/plugin/pluggable/JarInJarClassLoader.java
@@ -5,6 +5,8 @@
import java.net.URL;
import java.net.URLClassLoader;
import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.Map;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
@@ -35,8 +37,8 @@
}
private void addJarResource(File file) throws TigerstripeException {
- try (JarFile jarFile = new JarFile(file);){
+ try (JarFile jarFile = new JarFile(file)) {
addURL(file.toURL());
Enumeration<JarEntry> jarEntries = jarFile.entries();
while (jarEntries.hasMoreElements()) {
@@ -45,36 +47,38 @@
addJarResource(TigerstripeJarUtils.jarEntryAsFile(jarFile, jarEntry));
}
}
-
} catch (IOException e) {
- runtime.logErrorMessage(
- "Error adding Jar resource to classpath",
- e);
+ runtime.logErrorMessage("Error adding Jar resource to classpath", e);
}
}
@Override
- protected synchronized Class<?> loadClass(String name, boolean resolve)
+ protected Class<?> loadClass(String name, boolean resolve)
throws ClassNotFoundException {
- try {
- Class<?> clazz = findLoadedClass(name);
- if (clazz == null) {
- clazz = findClass(name);
+
+ synchronized (getClassLoadingLock(name)) {
+ try {
+ Class<?> clazz = findLoadedClass(name);
+ if (clazz == null) {
+ clazz = findClass(name);
+ }
if (resolve) {
resolveClass(clazz);
}
+ return clazz;
+ } catch (ClassNotFoundException e) {
+ return super.loadClass(name, resolve);
}
- return clazz;
- } catch (ClassNotFoundException e) {
- return super.loadClass(name, resolve);
}
}
-
private static boolean isJar(String fileName) {
return fileName != null && (fileName.toLowerCase().endsWith(".jar"));
}
-
-
-
+
+ @Override
+ public void close() throws IOException {
+ this.runtime = null;
+ super.close();
+ }
}
diff --git a/core/org.eclipse.tigerstripe.core/src/main/java/org/eclipse/tigerstripe/workbench/internal/core/plugin/pluggable/PluggablePlugin.java b/core/org.eclipse.tigerstripe.core/src/main/java/org/eclipse/tigerstripe/workbench/internal/core/plugin/pluggable/PluggablePlugin.java
index 749b357..cd0fd25 100644
--- a/core/org.eclipse.tigerstripe.core/src/main/java/org/eclipse/tigerstripe/workbench/internal/core/plugin/pluggable/PluggablePlugin.java
+++ b/core/org.eclipse.tigerstripe.core/src/main/java/org/eclipse/tigerstripe/workbench/internal/core/plugin/pluggable/PluggablePlugin.java
@@ -11,6 +11,7 @@
package org.eclipse.tigerstripe.workbench.internal.core.plugin.pluggable;
import java.io.File;
+import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLClassLoader;
@@ -29,7 +30,6 @@
import org.eclipse.tigerstripe.workbench.internal.core.plugin.base.BasePlugin;
import org.eclipse.tigerstripe.workbench.internal.core.project.pluggable.M0ProjectDescriptor;
import org.eclipse.tigerstripe.workbench.internal.core.project.pluggable.PluggablePluginProject;
-import org.eclipse.tigerstripe.workbench.internal.core.util.FileUtils;
import org.eclipse.tigerstripe.workbench.plugins.EPluggablePluginNature;
import org.eclipse.tigerstripe.workbench.plugins.IPluginClasspathEntry;
import org.eclipse.tigerstripe.workbench.plugins.IPluginProperty;
@@ -46,8 +46,11 @@
* @since 1.2
*/
public class PluggablePlugin extends BasePlugin {
+
+ public static final String TEMPLATE_PREFIX = "org/eclipse/tigerstripe/workbench/internal/core/plugin/pluggable/resources"; // $NON-NLS-1$
- private static final String DEFAULT_LOG_DIR = "logs";
+ private static final String DEFAULT_LOG_DIR = "logs"; // $NON-NLS-1$
+ private static final String REPORTTEMPLATE = "PLUGGABLE_REPORT.vm"; // $NON-NLS-1$
private boolean canDelete = true;
@@ -58,47 +61,38 @@
*/
private String path;
- /**
- * This is only passed around so that we can delete it.
- */
- private String zippedFile;
-
protected IGeneratorDescriptor descriptor = null;
private String[] definedProperties = null;
- private final static String REPORTTEMPLATE = "PLUGGABLE_REPORT.vm";
-
- public final static String TEMPLATE_PREFIX = "org/eclipse/tigerstripe/workbench/internal/core/plugin/pluggable/resources";
-
private PluggablePluginReport report;
private ITigerstripeRuntime runtime;
- public ITigerstripeRuntime getRuntime() {
- return runtime;
+
+ public PluggablePlugin() {
+
}
-
- public void setRuntime(ITigerstripeRuntime runtime) {
- this.runtime = runtime;
- }
-
+
/**
*
* @param path
* - The path to the unzipped plugin directory
* @throws TigerstripeException
*/
- public PluggablePlugin(ITigerstripeRuntime runtime, String path, String zippedFile) throws TigerstripeException {
+ public PluggablePlugin(ITigerstripeRuntime runtime, String path) throws TigerstripeException {
this.runtime = runtime;
this.path = path;
- this.zippedFile = zippedFile;
loadProject();
}
-
- public PluggablePlugin() {
-
- }
+
+ public ITigerstripeRuntime getRuntime() {
+ return runtime;
+ }
+
+ public void setRuntime(ITigerstripeRuntime runtime) {
+ this.runtime = runtime;
+ }
public EPluggablePluginNature getPluginNature() {
return descriptor.getPluginNature();
@@ -108,8 +102,15 @@
if (descriptor != null) {
descriptor.dispose();
}
+ if (classLoader != null) {
+ try {
+ classLoader.close();
+ } catch (IOException e) {
+ runtime.logErrorMessage("Failed to close plugin classloader", e);
+ }
+ classLoader = null;
+ }
this.path = null;
- this.zippedFile = null;
this.runtime = null;
}
diff --git a/core/org.eclipse.tigerstripe.core/src/main/java/org/eclipse/tigerstripe/workbench/internal/core/profile/PhantomTigerstripeProjectMgr.java b/core/org.eclipse.tigerstripe.core/src/main/java/org/eclipse/tigerstripe/workbench/internal/core/profile/PhantomTigerstripeProjectMgr.java
index c83fdd9..e1b7cc1 100644
--- a/core/org.eclipse.tigerstripe.core/src/main/java/org/eclipse/tigerstripe/workbench/internal/core/profile/PhantomTigerstripeProjectMgr.java
+++ b/core/org.eclipse.tigerstripe.core/src/main/java/org/eclipse/tigerstripe/workbench/internal/core/profile/PhantomTigerstripeProjectMgr.java
@@ -40,6 +40,11 @@
}
}
+ public void dispose() {
+ reset();
+ runtime = null;
+ }
+
public synchronized PhantomTigerstripeProject getPhantomProject()
throws TigerstripeException {
if (phantomProject == null) {