Added application configuration which is used to determine directory containing dependency jars.
git-svn-id: http://taverna.googlecode.com/svn/taverna/engine/net.sf.taverna.t2.activities/trunk/dependency-activity@15004 bf327186-88b3-11dd-a302-d386e5130c1c Project: http://git-wip-us.apache.org/repos/asf/incubator-taverna-common-activities/repo Commit: http://git-wip-us.apache.org/repos/asf/incubator-taverna-common-activities/commit/13491a07 Tree: http://git-wip-us.apache.org/repos/asf/incubator-taverna-common-activities/tree/13491a07 Diff: http://git-wip-us.apache.org/repos/asf/incubator-taverna-common-activities/diff/13491a07 Branch: refs/heads/master Commit: 13491a07183d0af44379cb37a47b84f053e48986 Parents: bee5245 Author: [email protected] <[email protected]@bf327186-88b3-11dd-a302-d386e5130c1c> Authored: Tue Jun 12 11:28:01 2012 +0000 Committer: [email protected] <[email protected]@bf327186-88b3-11dd-a302-d386e5130c1c> Committed: Tue Jun 12 11:28:01 2012 +0000 ---------------------------------------------------------------------- pom.xml | 5 + .../AbstractAsynchronousDependencyActivity.java | 132 ++++++++++--------- 2 files changed, 76 insertions(+), 61 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-taverna-common-activities/blob/13491a07/pom.xml ---------------------------------------------------------------------- diff --git a/pom.xml b/pom.xml index 8481869..a91b407 100644 --- a/pom.xml +++ b/pom.xml @@ -16,6 +16,11 @@ <artifactId>workflowmodel-api</artifactId> <version>${t2.core.version}</version> </dependency> + <dependency> + <groupId>uk.org.taverna.configuration</groupId> + <artifactId>taverna-app-configuration-api</artifactId> + <version>${taverna.configuration.version}</version> + </dependency> </dependencies> </project> http://git-wip-us.apache.org/repos/asf/incubator-taverna-common-activities/blob/13491a07/src/main/java/net/sf/taverna/t2/activities/dependencyactivity/AbstractAsynchronousDependencyActivity.java ---------------------------------------------------------------------- diff --git a/src/main/java/net/sf/taverna/t2/activities/dependencyactivity/AbstractAsynchronousDependencyActivity.java b/src/main/java/net/sf/taverna/t2/activities/dependencyactivity/AbstractAsynchronousDependencyActivity.java index f5fe2ab..d804b0e 100644 --- a/src/main/java/net/sf/taverna/t2/activities/dependencyactivity/AbstractAsynchronousDependencyActivity.java +++ b/src/main/java/net/sf/taverna/t2/activities/dependencyactivity/AbstractAsynchronousDependencyActivity.java @@ -1,19 +1,19 @@ /******************************************************************************* - * Copyright (C) 2007 The University of Manchester - * + * Copyright (C) 2007 The University of Manchester + * * Modifications to the initial code base are copyright of their * respective authors, or their employers as appropriate. - * + * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License * as published by the Free Software Foundation; either version 2.1 of * the License, or (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 @@ -37,20 +37,22 @@ import net.sf.taverna.t2.workflowmodel.processor.activity.NestedDataflow; import org.apache.log4j.Logger; +import uk.org.taverna.configuration.app.ApplicationConfiguration; + /** * A parent abstract class for activities that require dependency management, such as - * API Consumer and Beanshell. Defines dependencies on local JAR files + * API Consumer and Beanshell. Defines dependencies on local JAR files * and Raven artifacts. - * + * * @author Alex Nenadic * @author Tom Oinn * @author Stian Soiland-Reyes - * + * * @param <ConfigType> the configuration type used for this activity * */ public abstract class AbstractAsynchronousDependencyActivity<ConfigType> extends AbstractAsynchronousActivity<ConfigType>{ - + private static final String LOCAL_JARS = "Local jars"; private static final String ARTIFACTS = "Artifacts"; @@ -59,12 +61,12 @@ public abstract class AbstractAsynchronousDependencyActivity<ConfigType> extends /** * For persisting class loaders across a whole workflow run (when classloader sharing - * is set to 'workflow'). The key in the map is the workflow run ID and we are using + * is set to 'workflow'). The key in the map is the workflow run ID and we are using * a WeakHashMap so we don't keep up references to classloaders of old workflow runs. */ private static WeakHashMap<String, ClassLoader> workflowClassLoaders = new WeakHashMap<String, ClassLoader>(); - + /** * System classloader, in case when classloader sharing is set to 'system'. */ @@ -75,56 +77,64 @@ public abstract class AbstractAsynchronousDependencyActivity<ConfigType> extends * class loader sharing policy. */ protected ClassLoader classLoader = null; - + + private ApplicationConfiguration applicationConfiguration; + /** * The location of the <code>lib</code> directory in TAVERNA_HOME, * where local JAR files the activity depends on should be located. */ // public static File libDir = new File(ApplicationRuntime.getInstance().getApplicationHomeDir(), "lib"); - public static File libDir = null; + public File libDir; /** * Different ways to share a class loader among activities: - * + * * <dl> * <dt>workflow</dt> * <dd>Same classloader for all activities using the <code>workflow</code> classloader sharing policy</dd> * <dt>system</dt> * <dd>System classloader</dd> * </dl> - * + * */ public static enum ClassLoaderSharing { workflow, system } - + + public AbstractAsynchronousDependencyActivity(ApplicationConfiguration applicationConfiguration) { + if (applicationConfiguration != null) { + libDir = new File(applicationConfiguration.getApplicationHomeDir(), "lib"); + } + } + /** * Finds or constructs the classloader. The classloader depends on the * current classloader sharing policy as defined by {@link #ClassLoaderSharing}. * <p> * If the classloader sharing is {@link ClassLoaderSharing#workflow}, a * common classloader will be used for the whole workflow for all activities - * with the same (i.e. {@link ClassLoaderSharing#workflow}) policy. - * The dependencies will be constructed as union of local and artifact dependencies - * of all 'workflow' classloader sharing activities at the point of the first + * with the same (i.e. {@link ClassLoaderSharing#workflow}) policy. + * The dependencies will be constructed as union of local and artifact dependencies + * of all 'workflow' classloader sharing activities at the point of the first * call to {@link #getClassLoader()}. * <p> * If the classloader sharing is {@link ClassLoaderSharing#system}, the - * system classloader will be used. Note that both local and artifact dependencies - * configured on the activity will be ignored. Local dependencies can be set by + * system classloader will be used. Note that both local and artifact dependencies + * configured on the activity will be ignored. Local dependencies can be set by * using <code>-classpath</code> when starting the workbench. * This is useful in combination with JNI based libraries, which would also * require <code>-Djava.library.path</code> and possibly the operating * system's PATH / LD_LIBRARY_PATH / DYLD_LIBRARY_PATH environment variable. - * @param classLoaderSharing - * + * @param classLoaderSharing + * * @return A new or existing {@link ClassLoader} according to the * classloader sharing policy */ protected ClassLoader findClassLoader(DependencyActivityConfigurationBean configurationBean, String workflowRunID) throws RuntimeException{ - + ClassLoaderSharing classLoaderSharing = configurationBean.getClassLoaderSharing(); - + if (classLoaderSharing == ClassLoaderSharing.workflow) { synchronized (workflowClassLoaders) { ClassLoader cl = workflowClassLoaders.get(workflowRunID); @@ -138,7 +148,7 @@ public abstract class AbstractAsynchronousDependencyActivity<ConfigType> extends if (classLoaderSharing == ClassLoaderSharing.system) { // if (systemClassLoader == null) // systemClassLoader = PreLauncher.getInstance().getLaunchingClassLoader(); - + // if (systemClassLoader instanceof BootstrapClassLoader){ // // Add local and artifact dependencies to the classloader // updateBootstrapClassLoader( @@ -163,24 +173,24 @@ public abstract class AbstractAsynchronousDependencyActivity<ConfigType> extends /** * Constructs a classloader capable of finding both local jar and artifact dependencies. * Called when classloader sharing policy is set to 'workflow'. - * + * * @return A {@link ClassLoader} capable of accessing all the dependencies (both local jar and artifact) */ private ClassLoader makeClassLoader( DependencyActivityConfigurationBean configurationBean, String workflowID) { - + // Find all artifact dependencies // HashSet<URL> urls = findDependencies(ARTIFACTS, configurationBean, workflowID); - + // Add all local jar dependencies HashSet<URL> urls = findDependencies(LOCAL_JARS, configurationBean, workflowID); - + // Create the classloader capable of loading both local jar and artifact dependencies ClassLoader parent = this.getClass().getClassLoader(); // this will be a LocalArtifactClassLoader - + return new URLClassLoader(urls.toArray(new URL[0]), parent) { - + // For finding native libraries that have to be stored in TAVERNA_HOME/lib @Override protected String findLibrary(String libname) { @@ -194,18 +204,18 @@ public abstract class AbstractAsynchronousDependencyActivity<ConfigType> extends } }; } - + /** * Adds local or artifact dependencies identified by {@link #findDependencies()} to the * {@link BootstrapClassLoader} system classloader. * Called when classloader sharing policy is set to 'system'. - * + * * @param loader The augmented BootstrapClassLoader system classloader */ // private void updateBootstrapClassLoader(BootstrapClassLoader loader, // DependencyActivityConfigurationBean configurationBean, // String workflowRunID) { -// +// // HashSet<URL> depsURLs = new HashSet<URL>(); // depsURLs.addAll(findDependencies(LOCAL_JARS, configurationBean, workflowRunID)); // depsURLs.addAll(findDependencies(ARTIFACTS, configurationBean, workflowRunID)); @@ -218,12 +228,12 @@ public abstract class AbstractAsynchronousDependencyActivity<ConfigType> extends // logger.info("Registering with system classloader: " + url); // loader.addURL(url); // exists.add(url); -// } +// } // } /** - * Finds either local jar or artifact dependencies' URLs for the given classloader - * sharing policy (passed inside configuration bean) and a workflowRunID (used to + * Finds either local jar or artifact dependencies' URLs for the given classloader + * sharing policy (passed inside configuration bean) and a workflowRunID (used to * retrieve the workflow) that will be added to this activity classloader's list of URLs. */ private HashSet<URL> findDependencies(String dependencyType, @@ -233,7 +243,7 @@ public abstract class AbstractAsynchronousDependencyActivity<ConfigType> extends ClassLoaderSharing classLoaderSharing = configurationBean.getClassLoaderSharing(); // Get the WorkflowInstanceFacade which contains the current workflow WeakReference<WorkflowInstanceFacade> wfFacadeRef = WorkflowInstanceFacade.workflowRunFacades.get(workflowRunID); - WorkflowInstanceFacade wfFacade = null; + WorkflowInstanceFacade wfFacade = null; if (wfFacadeRef != null) { wfFacade = wfFacadeRef.get(); } @@ -252,7 +262,7 @@ public abstract class AbstractAsynchronousDependencyActivity<ConfigType> extends // as this activity for (Processor proc : wf.getProcessors()) { // Nested workflow case - if (!proc.getActivityList().isEmpty() && proc.getActivityList().get(0) instanceof NestedDataflow){ + if (!proc.getActivityList().isEmpty() && proc.getActivityList().get(0) instanceof NestedDataflow){ // Get the nested workflow Dataflow nestedWorkflow = ((NestedDataflow) proc.getActivityList().get(0)).getNestedDataflow(); dependenciesURLs.addAll(findNestedDependencies(dependencyType, configurationBean, nestedWorkflow)); @@ -271,8 +281,8 @@ public abstract class AbstractAsynchronousDependencyActivity<ConfigType> extends logger.warn("Invalid URL for " + jar, ex); continue; } - } -// } else if (dependencyType.equals(ARTIFACTS) && this.getClass().getClassLoader() instanceof LocalArtifactClassLoader){ + } +// } else if (dependencyType.equals(ARTIFACTS) && this.getClass().getClassLoader() instanceof LocalArtifactClassLoader){ // LocalArtifactClassLoader cl = (LocalArtifactClassLoader) this.getClass().getClassLoader(); // this class is always loaded with LocalArtifactClassLoader // // Get the LocalReposotpry capable of finding artifact jar files // LocalRepository rep = (LocalRepository) cl.getRepository(); @@ -295,26 +305,26 @@ public abstract class AbstractAsynchronousDependencyActivity<ConfigType> extends logger.warn("Invalid URL for " + jar, ex); continue; } - } + } // } // else if (dependencyType.equals(ARTIFACTS)){ // if (this.getClass().getClassLoader() instanceof LocalArtifactClassLoader){ // This should normally be the case -// LocalArtifactClassLoader cl = (LocalArtifactClassLoader)this.getClass().getClassLoader(); +// LocalArtifactClassLoader cl = (LocalArtifactClassLoader)this.getClass().getClassLoader(); // LocalRepository rep = (LocalRepository)cl.getRepository(); -// if (rep != null){ +// if (rep != null){ // for (BasicArtifact art : configurationBean.getArtifactDependencies()){ // dependencies.add(rep.jarFile(art)); // } // } // } // else{ -// // Tests will not be loaded using the LocalArtifactClassLoader as athey are loaded +// // Tests will not be loaded using the LocalArtifactClassLoader as athey are loaded // // outside Raven so there is nothing we can do about this - some tests // // with dependencies will probably fail // } // } } - + // Collect the URLs of all found dependencies for (File file: dependencies){ try{ @@ -324,38 +334,38 @@ public abstract class AbstractAsynchronousDependencyActivity<ConfigType> extends logger.warn("Invalid URL for " + file.getAbsolutePath(), ex); continue; } - } - return dependenciesURLs; + } + return dependenciesURLs; } /** - * Finds dependencies for a nested workflow. + * Finds dependencies for a nested workflow. */ private HashSet<URL> findNestedDependencies(String dependencyType, DependencyActivityConfigurationBean configurationBean, Dataflow nestedWorkflow) { - + ClassLoaderSharing classLoaderSharing = configurationBean.getClassLoaderSharing(); // Files of dependencies for all activities in the nested workflow that share the classloading policy HashSet<File> dependencies = new HashSet<File>(); // Urls of all dependencies HashSet<URL> dependenciesURLs = new HashSet<URL>(); - + for (Processor proc : nestedWorkflow.getProcessors()) { // Another nested workflow - if (!proc.getActivityList().isEmpty() && proc.getActivityList().get(0) instanceof NestedDataflow){ + if (!proc.getActivityList().isEmpty() && proc.getActivityList().get(0) instanceof NestedDataflow){ // Get the nested workflow Dataflow nestedNestedWorkflow = ((NestedDataflow) proc.getActivityList().get(0)).getNestedDataflow(); dependenciesURLs.addAll(findNestedDependencies(dependencyType, configurationBean, nestedNestedWorkflow)); } else{ // Not nested - go through all of the processor's activities Activity<?> activity = proc.getActivityList().get(0); - if (activity instanceof AbstractAsynchronousDependencyActivity){ - + if (activity instanceof AbstractAsynchronousDependencyActivity){ + if (((DependencyActivityConfigurationBean) activity .getConfiguration()).getClassLoaderSharing() == classLoaderSharing) { - + // if (dependencyType.equals(LOCAL_JARS)){ // Collect the files of all found local dependencies for (String jar : ((DependencyActivityConfigurationBean)activity.getConfiguration()).getLocalDependencies()) { @@ -374,12 +384,12 @@ public abstract class AbstractAsynchronousDependencyActivity<ConfigType> extends // .getArtifactDependencies()){ // dependencies.add(rep.jarFile(art)); // } -// } +// } } } } } - + // Collect the URLs of all found dependencies for (File file: dependencies){ try{ @@ -389,10 +399,10 @@ public abstract class AbstractAsynchronousDependencyActivity<ConfigType> extends logger.warn("Invalid URL for " + file.getAbsolutePath(), ex); continue; } - } + } return dependenciesURLs; } - + /** * File filter. */ @@ -408,7 +418,7 @@ public abstract class AbstractAsynchronousDependencyActivity<ConfigType> extends return name.endsWith(ext); } } - + /** * @param classLoader the classLoader to set */
