Author: dain Date: Wed Sep 29 22:25:00 2004 New Revision: 47555 Modified: geronimo/trunk/modules/client-builder/src/java/org/apache/geronimo/client/builder/AppClientModuleBuilder.java geronimo/trunk/modules/j2ee/src/java/org/apache/geronimo/j2ee/deployment/EARContext.java Log: Added support for manifest classpath entires in an application client
Modified: geronimo/trunk/modules/client-builder/src/java/org/apache/geronimo/client/builder/AppClientModuleBuilder.java ============================================================================== --- geronimo/trunk/modules/client-builder/src/java/org/apache/geronimo/client/builder/AppClientModuleBuilder.java (original) +++ geronimo/trunk/modules/client-builder/src/java/org/apache/geronimo/client/builder/AppClientModuleBuilder.java Wed Sep 29 22:25:00 2004 @@ -251,6 +251,7 @@ // get the app client main class JarFile moduleFile = module.getModuleFile(); String mainClasss = null; + String classPath = null; try { Manifest manifest = moduleFile.getManifest(); if (manifest == null) { @@ -260,6 +261,10 @@ if (mainClasss == null) { throw new DeploymentException("App client module jar does not have Main-Class defined in the manifest: " + moduleFile.getName()); } + classPath = manifest.getMainAttributes().getValue(Attributes.Name.CLASS_PATH); + if (module.isStandAlone() && classPath != null) { + throw new DeploymentException("Manifest class path entry is not allowed in a standalone jar (J2EE 1.4 Section 8.2)"); + } } catch (IOException e) { throw new DeploymentException("Could not get manifest from app client module: " + moduleFile.getName()); } @@ -341,7 +346,8 @@ // extract the client Jar file into a standalone packed jar file and add the contents to the output File appClientJarFile = JarUtil.extractToPackedJar(moduleFile); - appClientDeploymentContext.addInclude(URI.create(module.getTargetPath()), appClientJarFile.toURL()); + URI moduleBase = new URI(appClientModule.getTargetPath()); + appClientDeploymentContext.addInclude(moduleBase, appClientJarFile.toURL()); // add the includes GerDependencyType[] includes = geronimoAppClient.getIncludeArray(); @@ -373,6 +379,9 @@ appClientDeploymentContext.addDependency(getDependencyURI(dependencies[i])); } + appClientDeploymentContext.addManifestClassPath(appClientModule.getEarFile(), appClientModule, moduleFile, moduleBase); + + // get the classloader ClassLoader appClientClassLoader = appClientDeploymentContext.getClassLoader(repository); @@ -399,7 +408,7 @@ connectorFile = new JarFile(pathURL.getFile()); } else { path = resource.getInternalRar(); - connectorFile = new NestedJarFile(appClientModule.getEarFile(), path); + connectorFile = new NestedJarFile(appClientModule.getEarFile(), path); } XmlObject connectorPlan = resource.getConnector(); Module connectorModule = connectorModuleBuilder.createModule(connectorPlan, connectorFile, path, null); Modified: geronimo/trunk/modules/j2ee/src/java/org/apache/geronimo/j2ee/deployment/EARContext.java ============================================================================== --- geronimo/trunk/modules/j2ee/src/java/org/apache/geronimo/j2ee/deployment/EARContext.java (original) +++ geronimo/trunk/modules/j2ee/src/java/org/apache/geronimo/j2ee/deployment/EARContext.java Wed Sep 29 22:25:00 2004 @@ -17,15 +17,23 @@ package org.apache.geronimo.j2ee.deployment; import java.net.URI; +import java.net.URISyntaxException; import java.util.HashMap; import java.util.Map; import java.util.Properties; +import java.util.StringTokenizer; import java.util.jar.JarOutputStream; +import java.util.jar.JarFile; +import java.util.jar.Manifest; +import java.util.jar.Attributes; +import java.io.IOException; +import java.io.File; import javax.management.MalformedObjectNameException; import javax.management.ObjectName; import org.apache.geronimo.deployment.DeploymentContext; import org.apache.geronimo.deployment.DeploymentException; +import org.apache.geronimo.deployment.util.JarUtil; import org.apache.geronimo.kernel.Kernel; import org.apache.geronimo.kernel.config.ConfigurationModuleType; @@ -156,4 +164,48 @@ public String getResourceAdapterModule(String resourceAdapterName) { return (String) resourceAdapterModules.get(resourceAdapterName); } + + public void addManifestClassPath(JarFile earFile, Module module, JarFile jarFile, URI baseUri) throws DeploymentException, URISyntaxException, IOException { + String classPath = null; + try { + Manifest manifest = jarFile.getManifest(); + if (manifest == null) { + return; + } + classPath = manifest.getMainAttributes().getValue(Attributes.Name.CLASS_PATH); + if (classPath == null) { + return; + } + } catch (IOException e) { + throw new DeploymentException("Could not get manifest from app client module: " + jarFile.getName()); + } + + for (StringTokenizer tokenizer = new StringTokenizer(classPath, " "); tokenizer.hasMoreTokens();) { + URI uri = new URI(tokenizer.nextToken()); + if (!uri.getPath().endsWith(".jar")) { + throw new DeploymentException("Manifest class path entries must end with the .jar extension (J2EE 1.4 Section 8.2)"); + } + if (uri.isAbsolute()) { + throw new DeploymentException("Manifest class path entries must be relative (J2EE 1.4 Section 8.2)"); + } + + URI path = baseUri.resolve(uri); + File classPathFile = JarUtil.toFile(earFile, path.getPath()); + + // before going to the work of adding this file, let's make sure it really is a jar file + JarFile classPathJar; + try { + classPathJar = new JarFile(classPathFile); + } catch (IOException e) { + throw new DeploymentException("Manifest class path entries must be a valid jar file (J2EE 1.4 Section 8.2)", e); + } + + // add this class path jar to the output context + addInclude(path, classPathFile.toURL()); + + // add the client jars of this class path jar + addManifestClassPath(earFile, module, classPathJar, path); + } + } + }