User: d_jencks
Date: 02/04/13 18:19:54
Modified: src/main/org/jboss/deployment JARDeployer.java
MainDeployer.java SARDeployer.java
SubDeployerSupport.java
Log:
Larry Sanderson's patch to enable deploying unpacked directories
Revision Changes Path
1.3 +21 -9 jboss-system/src/main/org/jboss/deployment/JARDeployer.java
Index: JARDeployer.java
===================================================================
RCS file:
/cvsroot/jboss/jboss-system/src/main/org/jboss/deployment/JARDeployer.java,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- JARDeployer.java 3 Apr 2002 08:18:59 -0000 1.2
+++ JARDeployer.java 14 Apr 2002 01:19:54 -0000 1.3
@@ -14,6 +14,7 @@
import java.net.JarURLConnection;
import java.net.URL;
import java.net.URLConnection;
+import java.net.URLClassLoader;
import java.util.Enumeration;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
@@ -90,11 +91,26 @@
return false;
} // end of if ()
- URL ddDir = di.localCl.getResource("META-INF/");
- if (ddDir == null)
+ // Since a META-INF directory exists within rt.jar, we can't just do a
+ // getResource (it will always return rt.jar's version).
+ // The method we want is findResource, but it is marked protected in
+ // ClassLoader. Fortunately, URLClassLoader exposes it which makes
+ // this hack possible. Anybody have a better way to check a URL
+ // for the existance of a META-INF??
+ URL ddDir;
+ try
{
- log.debug("no META-INF or WEB-INF found, this is for us");
- return true;
+ ddDir = ((URLClassLoader)di.localCl).findResource("META-INF/");
+ if (ddDir == null)
+ {
+ log.debug("no META-INF or WEB-INF found, this is for us");
+ return true;
+ }
+ }
+ catch (ClassCastException e)
+ {
+ // assume there is a META-INF...
+ ddDir = new URL(di.url, "META-INF/");
}
if (ddDir.getProtocol().equals("file"))
@@ -119,16 +135,12 @@
} // end of if ()
else if (ddDir.getProtocol().equals("jar") ||
ddDir.getProtocol().equals("njar"))
{
- //trying to open ddDir as a jarFile seems to result in listing
- //the entire contents of the JRE!!!
log.trace("jar or njar protocol: " + ddDir.getProtocol());
JarFile jarFile =null;
- String jarURLString = "njar:"+di.localUrl.toString()+"^/";
try
{
- URL jarURL = new URL(jarURLString);
- URLConnection con = jarURL.openConnection();
+ URLConnection con = ddDir.openConnection();
JarURLConnection jarConn = (JarURLConnection)con;
jarFile = jarConn.getJarFile();
}
1.26 +36 -163 jboss-system/src/main/org/jboss/deployment/MainDeployer.java
Index: MainDeployer.java
===================================================================
RCS file:
/cvsroot/jboss/jboss-system/src/main/org/jboss/deployment/MainDeployer.java,v
retrieving revision 1.25
retrieving revision 1.26
diff -u -r1.25 -r1.26
--- MainDeployer.java 13 Apr 2002 17:16:08 -0000 1.25
+++ MainDeployer.java 14 Apr 2002 01:19:54 -0000 1.26
@@ -45,6 +45,7 @@
import org.jboss.system.server.ServerConfig;
import org.jboss.system.server.ServerConfigLocator;
import org.jboss.util.Counter;
+import org.jboss.util.file.JarUtils;
import org.jboss.util.jmx.MBeanProxy;
import org.jboss.util.stream.Streams;
import java.util.LinkedList;
@@ -57,7 +58,7 @@
* @author <a href="mailto:[EMAIL PROTECTED]">Marc Fleury</a>
* @author <a href="mailto:[EMAIL PROTECTED]">Scott Stark</a>
* @author <a href="mailto:[EMAIL PROTECTED]">David Jencks</a>
- * @version $Revision: 1.25 $
+ * @version $Revision: 1.26 $
*
* @jmx:mbean name="jboss.system:service=MainDeployer"
* extends="org.jboss.system.ServiceMBean,
org.jboss.deployment.DeployerMBean"
@@ -90,9 +91,6 @@
/** The string naming the tempDir **/
private String tempDirString;
- /** The temporary directory where native libs are unpacked. */
- private File tempNativeDir;
-
/**
* Holds the native library <em>prefix</em> for this system.
* Determined by examining the result of System.mapLibraryName("XxX").
@@ -254,7 +252,6 @@
File basedir = config.getServerTempDir();
tempDir = new File(basedir, "deploy");
- tempNativeDir = new File(basedir, "native");
// used in isWatched
tempDirString = tempDir.toURL().toString();
@@ -428,6 +425,10 @@
deploymentList.remove(deploymentList.lastIndexOf(di));
}
}
+ synchronized (waitingDeployments)
+ {
+ waitingDeployments.remove(di);
+ }
// Nuke my stuff, this includes the class loader
di.cleanup(log);
@@ -554,7 +555,7 @@
}
catch (Exception e)
{
- log.info("Exception notifying class removed", e);
+ log.info("Exception notifying classloader added", e);
}
//serviceController.newClassLoaderNotification();
} // end of if ()
@@ -575,7 +576,7 @@
deployment.deployer.init(deployment);
// create subdeployments as needed
- unpackSubPackages(deployment);
+ parseManifestLibraries(deployment);
log.debug("found " + deployment.subDeployments.size() + " subpackages of "
+ deployment.url);
for (Iterator lt = sorter.sort(deployment.subDeployments).listIterator();
lt.hasNext();)
{
@@ -744,161 +745,6 @@
}
/**
- * extractPackages
- *
- * TODO marcf: support directories as well right now depends on the jar format
- *
- * In case of identifiable sub-deployment we recursively call the deploy method
- * on the deployer
- */
- protected void unpackSubPackages(DeploymentInfo di)
- throws DeploymentException
- {
- // If XML only no subdeployment to speak of. We also do not
- // break a war into subdeployments as this opens the door to
- // servlet 2.3 classloading stuff we don't want to deal with here
- // FIXME do the sub deploy for directory and the move to
- if (di.isXML || di.isDirectory || di.shortName.endsWith(".war") )
- {
- return ;
- }
- // J2EE legacy goo in manifest
- parseManifestLibraries(di);
-
- JarFile jarFile =null;
-
- // Then the packages inside the package being deployed
-
- // marcf FIXME FIXME FIXME add support for directories not just jar files
-
- // Do we have a jar file jar:<theURL>!/..
- String jarURLString = "njar:"+di.localUrl.toString()+"^/";
- try
- {
- URL jarURL = new URL(jarURLString);
- URLConnection con = jarURL.openConnection();
- JarURLConnection jarConn = (JarURLConnection)con;
- jarFile = jarConn.getJarFile();
- }
- catch (Exception e)
- {
- log.warn("operation failed; ignoring", e);
-
- //maybe this is not a jar nor a directory...
- log.info("deploying non-jar/xml file: " + di.url);
- return;
- }
-
- for (Enumeration e = jarFile.entries(); e.hasMoreElements();)
- {
- JarEntry entry = (JarEntry)e.nextElement();
- String name = entry.getName();
-
- // Everything that is not
- // a- an XML file
- // b- a class in a normal directory structure
- // is a "package" and will be deployed
- if (name.endsWith(".jar")
- || name.endsWith(".sar")
- || name.endsWith(".ear")
- || name.endsWith(".rar")
- || name.endsWith(".zip")
- || name.endsWith(".wsr"))
- {
- try
- {
- // It is a sub-deployment
- URL subURL = new URL("njar:" + di.localUrl.toString() + "^/" + name);
- DeploymentInfo sub = new DeploymentInfo(subURL, di);
-
- // And deploy it, this call is recursive
- di.subDeployments.add(sub);
- }
- catch (Exception ex)
- {
- log.error("Error in subDeployment with name "+name, ex);
- throw new DeploymentException
- ("Could not deploy sub deployment "+name+" of deployment
"+di.url, ex);
- }
- }
-
- // WARNING: Do not close the jarFile let it hang until undeployment
- // The reason is that if you close the jarFile you cannot open streams
- // to files inside. The bug can be seen as follow
- // Thread.currentThread().getContextClassLoader().getResource("a text file
in jar").openStream())
- // Doesn't work while
- // Thread.currentThread().getContextClassLoader().loadClass("a class in
the jar")
- // works
- // We should encapsulate "opening and closing of the jarFile" in the
DeploymentInfo
- // Here we let it be open and cached
- else if (name.endsWith(".war"))
- {
- /**we need to copy wars to a real file, no one else will understand our
njar:...^/
- * protocol... not even jetty
- */
- try
- {
- URL subUrl = new URL("njar:" + di.localUrl.toString() + "^/" + name);
- //!!!!!!!!!!!!!!!!NONONONONO FIXME TODO etc etc
- //this is not where the dest file should be
- File destFile = new File(tempDir, name);
- URL destUrl = destFile.toURL();
- //System.out.println("war copy: subUrl: " + subUrl);
- //System.out.println("war copy: destFile: " + destFile);
-
- log.debug("copying war to: " + destUrl.toString());
- copy(subUrl, destUrl);
- DeploymentInfo sub = new DeploymentInfo(destUrl, di);
- }
- catch (Exception ware)
- {
- throw new DeploymentException("Problem copying war: " + di.localUrl,
ware);
- } // end of try-catch
- } // end of if ()
- else
- {
- //is it a native library?
- if (nativeSuffix == null)
- {
- String nativex = System.mapLibraryName("XxX");
- int xPos = nativex.indexOf("XxX"); //hope "XxX' is not part of any
native lib goo!
- nativePrefix = nativex.substring(0, xPos);
- nativeSuffix = nativex.substring(xPos + 3);
- } // end of if ()
-
- if (name.endsWith(nativeSuffix))
- {
- int i = name.lastIndexOf("/");
- if (name.substring(Math.max(i, 0)).startsWith(nativePrefix))
- {
- try
- {
- //it's a native library for our system (we hope!), copy it.
- URL subUrl = new URL("njar:" + di.localUrl.toString() + "^/" +
name);
- File destFile = new File(tempNativeDir, name);
- log.info("Loading native library: " + destFile.toString());
- URL destUrl = destFile.toURL();
- copy(subUrl, destUrl);
- System.load(destFile.toString());
- }
- catch (Exception nativee)
- {
- throw new DeploymentException("error with native library! " +
di.localUrl, nativee);
- } // end of try-catch
-
-
- } // end of if ()
-
-
- } // end of if ()
-
-
- } // end of else
- }
- }
-
-
- /**
* The <code>parseManifestLibraries</code> method looks into the manifest for
classpath
* goo, and tries to deploy referenced packages.
*
@@ -967,7 +813,6 @@
* Downloads the jar file or directory the src URL points to.
* In case of directory it becomes packed to a jar file.
*
- * @todo Add support for Directory copying over.
* @todo FIXME: $JBOSS_HOME/tmp/deploy is not a valid reference.
*
* @return a File object representing the downloaded module
@@ -1043,6 +888,19 @@
dir.mkdirs();
}
+ if (_src.getProtocol().equals("file"))
+ {
+ File srcFile = new File(_src.getFile());
+ if (srcFile.isDirectory())
+ {
+ log.debug("Making zip copy of: " + srcFile);
+ // make a jar archive of the directory
+ OutputStream out = new BufferedOutputStream(new FileOutputStream(file));
+ JarUtils.jar(out, srcFile.listFiles());
+ out.close();
+ return;
+ }
+ }
InputStream in = new BufferedInputStream(_src.openStream());
OutputStream out = new BufferedOutputStream(new FileOutputStream(file));
Streams.copy(in, out);
@@ -1090,6 +948,7 @@
*
* @param url an <code>URL</code> value
* @return a <code>DeploymentInfo</code> value
+ * @jmx:managed-operation
*/
public DeploymentInfo getDeployment(URL url)
{
@@ -1097,6 +956,20 @@
{
return (DeploymentInfo) deploymentMap.get(url);
}
+ }
+
+ /**
+ * The <code>getWatchUrl</code> method returns the URL that, when modified,
+ * indicates that a redeploy is needed.
+ *
+ * @param url an <code>URL</code> value
+ * @return a <code>URL</code> value
+ * @jmx:managed-operation
+ */
+ public URL getWatchUrl(URL url)
+ {
+ DeploymentInfo info = getDeployment(url);
+ return info == null ? null : info.watch;
}
}
1.7 +7 -3 jboss-system/src/main/org/jboss/deployment/SARDeployer.java
Index: SARDeployer.java
===================================================================
RCS file:
/cvsroot/jboss/jboss-system/src/main/org/jboss/deployment/SARDeployer.java,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -r1.6 -r1.7
--- SARDeployer.java 12 Apr 2002 05:01:39 -0000 1.6
+++ SARDeployer.java 14 Apr 2002 01:19:54 -0000 1.7
@@ -72,7 +72,7 @@
* @author <a href="mailto:[EMAIL PROTECTED]">David Maplesden</a>
* @author <a href="mailto:[EMAIL PROTECTED]">David Jencks</a>
* @author <a href="mailto:[EMAIL PROTECTED]">Jason Dillon</a>
- * @version $Revision: 1.6 $
+ * @version $Revision: 1.7 $
*
* <p><b>20010830 marc fleury:</b>
* <ul>
@@ -143,8 +143,9 @@
*/
public boolean accepts(DeploymentInfo di)
{
- return (di.url.toString().endsWith(".sar")
- || di.url.toString().endsWith("service.xml"));
+ String urlStr = di.url.toString();
+ return urlStr.endsWith("sar") || urlStr.endsWith("sar/") ||
+ urlStr.endsWith("service.xml");
}
/**
@@ -217,6 +218,9 @@
log.error("Problem in init", e);
throw new DeploymentException(e);
}
+
+ // invoke super-class initialization
+ processNestedDeployments(di);
}
/**
1.2 +239 -4
jboss-system/src/main/org/jboss/deployment/SubDeployerSupport.java
Index: SubDeployerSupport.java
===================================================================
RCS file:
/cvsroot/jboss/jboss-system/src/main/org/jboss/deployment/SubDeployerSupport.java,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- SubDeployerSupport.java 3 Apr 2002 08:18:02 -0000 1.1
+++ SubDeployerSupport.java 14 Apr 2002 01:19:54 -0000 1.2
@@ -10,6 +10,24 @@
package org.jboss.deployment;
import org.jboss.system.ServiceMBeanSupport;
+import java.net.URL;
+import java.util.ArrayList;
+import java.io.File;
+import java.net.URLConnection;
+import java.net.JarURLConnection;
+import java.util.jar.JarFile;
+import java.util.Enumeration;
+import java.util.jar.JarEntry;
+import java.net.MalformedURLException;
+import java.util.List;
+import org.jboss.system.server.ServerConfigLocator;
+import org.jboss.system.server.ServerConfig;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.BufferedInputStream;
+import java.io.BufferedOutputStream;
+import java.io.FileOutputStream;
+import org.jboss.util.stream.Streams;
/**
* An abstract {@link SubDeployer}.
@@ -17,13 +35,54 @@
* <p>Provides registration with {@link MainDeployer} as well as empty
* implementations of init, create, start, stop and destroy.
*
- * @version <tt>$Revision: 1.1 $</tt>
+ * @version <tt>$Revision: 1.2 $</tt>
* @author <a href="mailto:[EMAIL PROTECTED]">Jason Dillon</a>
*/
public abstract class SubDeployerSupport
extends ServiceMBeanSupport
implements SubDeployer, SubDeployerMBean
{
+
+ /**
+ * Holds the native library <em>suffix</em> for this system.
+ * Determined by examining the result of System.mapLibraryName("XxX").
+ */
+ protected static final String nativeSuffix;
+
+ /**
+ * Holds the native library <em>prefix</em> for this system.
+ * Determined by examining the result of System.mapLibraryName("XxX").
+ */
+ protected static final String nativePrefix;
+
+ /** The temporary directory where native libs are unpacked. */
+ private File tempNativeDir;
+
+ static
+ {
+ String nativex = System.mapLibraryName("XxX");
+ int xPos = nativex.indexOf("XxX"); //hope "XxX' is not part of any native lib
goo!
+ nativePrefix = nativex.substring(0, xPos);
+ nativeSuffix = nativex.substring(xPos + 3);
+ }
+
+ /**
+ * The <code>createService</code> method is one of the ServiceMBean lifecyle
operations.
+ * (no jmx tag needed from superinterface)
+ * @exception Exception if an error occurs
+ */
+ protected void createService() throws Exception
+ {
+ // watch the deploy directory, it is a set so multiple adds
+ // (start/stop) only one entry is present
+ // get the temporary directory to use
+
+ ServerConfig config = ServerConfigLocator.locate();
+ File basedir = config.getServerTempDir();
+
+ tempNativeDir = new File(basedir, "native");
+ }
+
/**
* Performs SubDeployer registration.
*/
@@ -52,11 +111,15 @@
* Sub-classes should override this method to provide
* custom 'init' logic.
*
- * <p>This method is empty, and is provided for convenience
- * when concrete service classes do not need to perform
- * anything specific for this state change.
+ * <p>This method calls the processNestedDeployments(di) method. This behaviour
+ * can overridden by concrete sub-classes. If further initialization
+ * needs to be done, and you wish to preserve the functionality, be sure
+ * to call super.init(di) at the end of your implementation.
*/
- public void init(DeploymentInfo di) throws DeploymentException {}
+ public void init(DeploymentInfo di) throws DeploymentException
+ {
+ processNestedDeployments(di);
+ }
/**
* Sub-classes should override this method to provide
@@ -97,4 +160,176 @@
* anything specific for this state change.
*/
public void destroy(DeploymentInfo di) throws DeploymentException {}
+
+ /**
+ * The <code>processNestedDeployments</code> method searches for any nested and
+ * deployable elements. Only Directories and Zipped archives are processed,
+ * and those are delegated to the addDeployableFiles and addDeployableJar
+ * methods respectively. This method can be overridden for alternate
+ * behaviour.
+ */
+ protected void processNestedDeployments(DeploymentInfo di) throws
DeploymentException
+ {
+ if (di.isXML) {
+ // no nested archives in an xml file
+ return;
+ }
+ if (di.isDirectory)
+ {
+ File f = new File(di.url.getFile());
+ if (!f.isDirectory())
+ {
+ // something is screwy
+ throw new DeploymentException("Deploy file incorrectly reported " +
+ "as a directory: " + di.url);
+ }
+ addDeployableFiles(di, f);
+ }
+ else
+ {
+ // Do we have a jar file jar:<theURL>!/..
+ String jarURLString = "njar:"+di.localUrl.toString()+"^/";
+ try
+ {
+ URL jarURL = new URL(jarURLString);
+ URLConnection con = jarURL.openConnection();
+ JarURLConnection jarConn = (JarURLConnection)con;
+ JarFile jarFile = jarConn.getJarFile();
+ addDeployableJar(di, jarFile);
+ }
+ catch (Exception e)
+ {
+ log.warn("operation failed; ignoring", e);
+ //maybe this is not a jar nor a directory...
+ log.info("deploying non-jar/xml file: " + di.url);
+ return;
+ }
+ }
+ }
+
+ /**
+ * This method returns true if the name is a recognized archive file.
+ * This can be overridden for alternate behaviour.
+ *
+ * @param name The "short-name" of the URL. It will have any trailing '/'
+ * characters removed, and any directory structure has been removed.
+ * @param url The full url.
+ *
+ * @return true iff the name ends in a known archive extension: jar, sar,
+ * ear, rar, zip, wsr, war, or if the name matches the native
+ * library conventions.
+ */
+ protected boolean isDeployable(String name, URL url)
+ {
+ return name.endsWith(".jar")
+ || name.endsWith(".sar")
+ || name.endsWith(".ear")
+ || name.endsWith(".rar")
+ || name.endsWith(".zip")
+ || name.endsWith(".wsr")
+ || name.endsWith(".war")
+ || (name.endsWith(nativeSuffix) && name.startsWith(nativePrefix));
+ }
+
+ /**
+ * This method recursively searches the directory structure for any files
+ * that are deployable (@see isDeployable). If a directory is found to
+ * be deployable, then its subfiles and subdirectories are not searched.
+ *
+ * @param di the DeploymentInfo
+ * @param dir The root directory to start searching.
+ */
+ protected void addDeployableFiles(DeploymentInfo di, File dir)
+ throws DeploymentException
+ {
+ File[] files = dir.listFiles();
+ for (int i = 0; i < files.length; i++)
+ {
+ File file = files[i];
+ String name = file.getName();
+ try
+ {
+ URL url = file.toURL();
+ if (isDeployable(name, url))
+ {
+ deployUrl(di, url, name);
+ // we don't want deployable units processed any further
+ continue;
+ }
+ }
+ catch (MalformedURLException e)
+ {
+ log.warn("File name invalid. Ignoring: " + file, e);
+ }
+ if (file.isDirectory())
+ {
+ addDeployableFiles(di, file);
+ }
+ }
+ }
+
+ /**
+ * This method searches the entire jar file for any deployable files
+ * (@see isDeployable).
+ *
+ * @param di the DeploymentInfo
+ * @param jarFile the jar file to process.
+ */
+ protected void addDeployableJar(DeploymentInfo di, JarFile jarFile)
+ throws DeploymentException
+ {
+ for (Enumeration e = jarFile.entries(); e.hasMoreElements();)
+ {
+ JarEntry entry = (JarEntry)e.nextElement();
+ String name = entry.getName();
+ try
+ {
+ URL url = new URL("njar:"+di.localUrl.toString()+"^/"+name);
+ if (isDeployable(name, url)) {
+ deployUrl(di, url, name);
+ }
+ }
+ catch (MalformedURLException mue)
+ {
+ log.warn("Jar entry invalid. Ignoring: " + name, mue);
+ }
+ }
+ }
+
+ protected void deployUrl(DeploymentInfo di, URL url, String name)
+ throws DeploymentException
+ {
+ try
+ {
+ if (name.endsWith(nativeSuffix) && name.startsWith(nativePrefix))
+ {
+ File destFile = new File(tempNativeDir, name);
+ log.info("Loading native library: " + destFile.toString());
+
+ File parent = destFile.getParentFile();
+ if (!parent.exists()) {
+ parent.mkdirs();
+ }
+
+ InputStream in = new BufferedInputStream(url.openStream());
+ OutputStream out = new BufferedOutputStream(new
FileOutputStream(destFile));
+ Streams.copy(in, out);
+ out.flush();
+ out.close();
+ in.close();
+
+ System.load(destFile.toString());
+ }
+ else
+ {
+ DeploymentInfo sub = new DeploymentInfo(url, di);
+ }
+ }
+ catch (Exception ex)
+ {
+ log.error("Error in subDeployment with name "+name, ex);
+ throw new DeploymentException
+ ("Could not deploy sub deployment "+name+" of deployment "+di.url, ex);
+ }
+ }
}
_______________________________________________
Jboss-development mailing list
[EMAIL PROTECTED]
https://lists.sourceforge.net/lists/listinfo/jboss-development