You are viewing a plain text version of this content. The canonical link for it is here.
Posted to scm@geronimo.apache.org by jb...@apache.org on 2008/11/11 21:41:57 UTC
svn commit: r713156 -
/geronimo/server/trunk/framework/modules/geronimo-deployment/src/main/java/org/apache/geronimo/deployment/DeploymentContext.java
Author: jbohn
Date: Tue Nov 11 12:41:56 2008
New Revision: 713156
URL: http://svn.apache.org/viewvc?rev=713156&view=rev
Log:
GERONIMO-3316 Enhance manifest classpath processing to be more permissive if -DXorg.apache.geronimo.deployment.LenientMFCP=true is specified in JAVA_OPTS
Modified:
geronimo/server/trunk/framework/modules/geronimo-deployment/src/main/java/org/apache/geronimo/deployment/DeploymentContext.java
Modified: geronimo/server/trunk/framework/modules/geronimo-deployment/src/main/java/org/apache/geronimo/deployment/DeploymentContext.java
URL: http://svn.apache.org/viewvc/geronimo/server/trunk/framework/modules/geronimo-deployment/src/main/java/org/apache/geronimo/deployment/DeploymentContext.java?rev=713156&r1=713155&r2=713156&view=diff
==============================================================================
--- geronimo/server/trunk/framework/modules/geronimo-deployment/src/main/java/org/apache/geronimo/deployment/DeploymentContext.java (original)
+++ geronimo/server/trunk/framework/modules/geronimo-deployment/src/main/java/org/apache/geronimo/deployment/DeploymentContext.java Tue Nov 11 12:41:56 2008
@@ -42,6 +42,9 @@
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
import org.apache.geronimo.common.DeploymentException;
import org.apache.geronimo.deployment.util.DeploymentUtil;
import org.apache.geronimo.gbean.AbstractName;
@@ -65,6 +68,9 @@
* @version $Rev:385232 $ $Date$
*/
public class DeploymentContext {
+
+ private static final Logger log = LoggerFactory.getLogger(DeploymentContext.class);
+
private final File baseDir;
private final File inPlaceConfigurationDir;
private final ResourceContext resourceContext;
@@ -76,6 +82,32 @@
private final List<ConfigurationData> additionalDeployment = new ArrayList<ConfigurationData>();
protected final AbstractName moduleName;
+ // values for lenience vs. strict manifest classpath interpretation
+ private final static int manifestClassLoaderMode;
+ private final static String manifestClassLoaderMessage;
+ private final static int MFCP_LENIENT = 1;
+ private final static int MFCP_STRICT = 2;
+
+ static {
+ // Extract the LenientMFCP value if specified. If not, default to strict..
+ String mode = System.getProperty("Xorg.apache.geronimo.deployment.LenientMFCP");
+ int mfcpMode = MFCP_STRICT; // Default to strict
+ String mfcpModeMessage = "Strict Manifest Classpath";
+ if (mode != null) {
+ if (mode.equals("true")) {
+ mfcpMode = MFCP_LENIENT;
+ mfcpModeMessage = "Lenient Manifest Classpath";
+ }
+ }
+
+ manifestClassLoaderMode = mfcpMode;
+ manifestClassLoaderMessage = mfcpModeMessage;
+ LoggerFactory.getLogger(DeploymentContext.class).info(
+ "The "+manifestClassLoaderMessage+" processing mode is in effect.\n"+
+ "This option can be altered by specifying -DXorg.apache.geronimo.deployment.LenientMFCP=true|false\n"+
+ "Specify =\"true\" for more lenient processing such as ignoring missing jars and references that are not spec compliant.");
+ }
+
public DeploymentContext(File baseDir, File inPlaceConfigurationDir, Environment environment, AbstractName moduleName, ConfigurationModuleType moduleType, Naming naming, ConfigurationManager configurationManager, Collection repositories) throws DeploymentException {
this(baseDir, inPlaceConfigurationDir, environment, moduleName, moduleType, naming, createConfigurationManager(configurationManager, repositories));
}
@@ -288,7 +320,7 @@
if (problems.size() == 1) {
throw problems.get(0);
}
- throw new DeploymentException("Determining complete manifest classpath unsuccessful:", problems);
+ throw new DeploymentException("Determining complete manifest classpath unsuccessful: ", problems);
}
}
@@ -330,24 +362,39 @@
try {
pathUri = new URI(path);
} catch (URISyntaxException e) {
- problems.add(new DeploymentException(printInfo("Invalid manifest classpath entry, path=" + path, moduleBaseUri, classpath, exclusions)));
+ problems.add(new DeploymentException(printInfo("Invalid manifest classpath entry, path= " + path, moduleBaseUri, classpath, exclusions)));
continue;
}
if (!pathUri.getPath().endsWith(".jar")) {
- problems.add(new DeploymentException(printInfo("Manifest class path entries must end with the .jar extension (J2EE 1.4 Section 8.2): path=" + path, moduleBaseUri, classpath, exclusions)));
+ if (manifestClassLoaderMode == MFCP_STRICT) {
+ problems.add(new DeploymentException(printInfo("Manifest class path entries must end with the .jar extension (J2EE 1.4 Section 8.2): path= " + path, moduleBaseUri, classpath, exclusions)));
+ }
+ else {
+ LoggerFactory.getLogger(DeploymentContext.class).info(
+ "The "+manifestClassLoaderMessage+" processing mode is in effect.\n"+
+ "Therefore, a manifest classpath entry which does not end with .jar, " + pathUri + " is being permitted and ignored.");
+ }
continue;
}
if (pathUri.isAbsolute()) {
- problems.add(new DeploymentException(printInfo("Manifest class path entries must be relative (J2EE 1.4 Section 8.2): path=" + path, moduleBaseUri, classpath, exclusions)));
+ problems.add(new DeploymentException(printInfo("Manifest class path entries must be relative (J2EE 1.4 Section 8.2): path= " + path, moduleBaseUri, classpath, exclusions)));
continue;
}
URI targetUri = moduleBaseUri.resolve(pathUri);
if (targetUri.getPath().endsWith("/")) {
- problems.add(new DeploymentException(printInfo("target path must not end with a '/' character: path=" + path + ", resolved to targetURI=" + targetUri, moduleBaseUri, classpath, exclusions)));
+ if (manifestClassLoaderMode == MFCP_STRICT) {
+ problems.add(new DeploymentException(printInfo("target path must not end with a '/' character: path= " + path + ", resolved to targetURI= " + targetUri, moduleBaseUri, classpath, exclusions)));
+ }
+ else {
+ LoggerFactory.getLogger(DeploymentContext.class).info(
+ "The "+manifestClassLoaderMessage+" processing mode is in effect.\n"+
+ "Therefore, a manifest classpath entry " + targetUri + " which does not end with a '/' character is being ignored.");
+ }
continue;
}
+
String targetEntry = targetUri.toString();
if (exclusions.contains(targetEntry)) {
continue;
@@ -364,7 +411,14 @@
try {
classPathJarFile = factory.newJarFile(targetUri);
} catch (IOException e) {
- problems.add(new DeploymentException(printInfo("Manifest class path entries must be a valid jar file (JAVAEE 5 Section 8.2): path=" + path + ", resolved to targetURI=" + targetUri, moduleBaseUri, classpath, exclusions), e));
+ if (manifestClassLoaderMode == MFCP_STRICT) {
+ problems.add(new DeploymentException(printInfo("Manifest class path entries must be a valid jar file (JAVAEE 5 Section 8.2): path= " + path + ", resolved to targetURI= " + targetUri, moduleBaseUri, classpath, exclusions), e));
+ }
+ else {
+ LoggerFactory.getLogger(DeploymentContext.class).info(
+ "The "+manifestClassLoaderMessage+" processing mode is in effect.\n"+
+ "Therefore, an IOException resulting from manifest classpath " + targetUri + " is being ignored.");
+ }
continue;
}
@@ -380,27 +434,38 @@
return buf.toString();
}
+ public void addManifestClassPath(JarFile moduleFile, URI moduleBaseUri) throws DeploymentException {
+ List<DeploymentException> problems = new ArrayList<DeploymentException>();
+ addManifestClassPath(moduleFile, moduleBaseUri, new DefaultJarFileFactory(), problems);
+ if (!problems.isEmpty()) {
+ if (problems.size() == 1) {
+ throw problems.get(0);
+ }
+ throw new DeploymentException("Determining complete manifest classpath unsuccessful: ", problems);
+ }
+ }
+
/**
* Import the classpath from a jar file's manifest. The imported classpath
* is crafted relative to <code>moduleBaseUri</code>.
*
* @param moduleFile the jar file from which the manifest is obtained.
* @param moduleBaseUri the base for the imported classpath
+ * @param factory the factory for constructing JarFiles and the way to extract the manifest classpath from a JarFile. Introduced to make
+ * testing plausible, but may be useful for in-IDE deployment.
+ * @param problems List to save all the problems we encounter.
* @throws DeploymentException if there is a problem with the classpath in
* the manifest
*/
- public void addManifestClassPath(JarFile moduleFile, URI moduleBaseUri) throws DeploymentException {
- Manifest manifest;
+ public void addManifestClassPath(JarFile moduleFile, URI moduleBaseUri, JarFileFactory factory, List<DeploymentException> problems) throws DeploymentException {
+ String manifestClassPath;
try {
- manifest = moduleFile.getManifest();
+ manifestClassPath = factory.getManifestClassPath(moduleFile);
} catch (IOException e) {
- throw new DeploymentException("Could not read manifest: " + moduleBaseUri);
- }
-
- if (manifest == null) {
+ problems.add(new DeploymentException("Could not read manifest: " + moduleBaseUri, e));
return;
}
- String manifestClassPath = manifest.getMainAttributes().getValue(Attributes.Name.CLASS_PATH);
+
if (manifestClassPath == null) {
return;
}
@@ -412,23 +477,52 @@
try {
pathUri = new URI(path);
} catch (URISyntaxException e) {
- throw new DeploymentException("Invalid manifest classpath entry: module=" + moduleBaseUri + ", path=" + path);
+ problems.add(new DeploymentException("Invalid manifest classpath entry: module= " + moduleBaseUri + ", path= " + path));
+ continue;
}
if (!pathUri.getPath().endsWith(".jar")) {
- throw new DeploymentException("Manifest class path entries must end with the .jar extension (J2EE 1.4 Section 8.2): module=" + moduleBaseUri);
+ if (manifestClassLoaderMode == MFCP_STRICT) {
+ problems.add(new DeploymentException("Manifest class path entries must end with the .jar extension (J2EE 1.4 Section 8.2): path= " + path + ", module= " + moduleBaseUri));
+ }
+ else {
+ LoggerFactory.getLogger(DeploymentContext.class).info(
+ "The "+manifestClassLoaderMessage+" processing mode is in effect.\n"+
+ "Therefore, a manifest classpath entry which does not end with .jar, " + pathUri + " is being permitted and ignored.");
+ }
+ continue;
}
+
if (pathUri.isAbsolute()) {
- throw new DeploymentException("Manifest class path entries must be relative (J2EE 1.4 Section 8.2): moduel=" + moduleBaseUri);
+ problems.add(new DeploymentException("Manifest class path entries must be relative (J2EE 1.4 Section 8.2): path= " + path + ", module= " + moduleBaseUri));
+ continue;
+ }
+
+ URI targetUri = moduleBaseUri.resolve(pathUri);
+ if (targetUri.getPath().endsWith("/")) {
+ if (manifestClassLoaderMode == MFCP_STRICT) {
+ problems.add(new DeploymentException("target path must not end with a '/' character: path= " + path + ", resolved to targetURI= " + targetUri));
+ }
+ else {
+ LoggerFactory.getLogger(DeploymentContext.class).info(
+ "The "+manifestClassLoaderMessage+" processing mode is in effect.\n"+
+ "Therefore, a manifest classpath entry " + targetUri + " which does not end with a '/' character is being ignored.");
+ }
+ continue;
}
try {
- URI targetUri = moduleBaseUri.resolve(pathUri);
- if (targetUri.getPath().endsWith("/"))
- throw new IllegalStateException("target path must not end with a '/' character: " + targetUri);
configuration.addToClassPath(targetUri.toString());
} catch (IOException e) {
- throw new DeploymentException(e);
+ if (manifestClassLoaderMode == MFCP_STRICT) {
+ problems.add(new DeploymentException("Failure to add targetURI to configuration classpath: " + targetUri, e));
+ }
+ else {
+ LoggerFactory.getLogger(DeploymentContext.class).info(
+ "The "+manifestClassLoaderMessage+" processing mode is in effect.\n"+
+ "Therefore, an IOException resulting from manifest classpath " + targetUri + " is being ignored.");
+ }
+ continue;
}
}
}