User: schulze
Date: 00/10/02 17:08:17
Added: src/main/org/jboss/deployment Deployment.java
J2eeApplicationMetaData.java J2eeDeployer.java
J2eeDeployerMBean.java J2eeDeploymentException.java
J2eeModuleMetaData.java README.html URLWizzard.java
Log:
the first version of a j2ee compliant deployer mbean (see README for details)
Revision Changes Path
1.1 jboss/src/main/org/jboss/deployment/Deployment.java
Index: Deployment.java
===================================================================
/*
* jBoss, the OpenSource EJB server
*
* Distributable under GPL license.
* See terms of license at gnu.org.
*/
package org.jboss.deployment;
import java.net.URL;
import java.net.MalformedURLException;
import java.util.Iterator;
import java.util.Vector;
/** Represents a J2EE application or module (EJB.jar, Web.war or App.ear). <br>
*/
public class Deployment
implements java.io.Serializable
{
// the applications name
protected String name;
// the url from which this app is downloaded and under which it is deployed
protected URL downloadUrl;
// the local position of the apps root directory
protected URL localUrl;
// the Modules for jBoss and Tomcat
protected Vector ejbModules;
protected Vector webModules;
/** Creates a new Deployment object.
*/
Deployment ()
{
ejbModules = new Vector ();
webModules = new Vector ();
}
public Module newModule ()
{
return new Module ();
}
/** Returns the admin context of this url.
* @param the download URL
* @return the administrator context as path fragment
*/
public static String getAdminCtx (URL _url)
{
StringBuffer sb = new StringBuffer ();
if (_url.getProtocol ().equals ("file"))
{
String s = _url.getFile ();
sb.append (s.substring (1, Math.max (0, s.lastIndexOf ("/"))));
}
else
{
sb.append (_url.getHost ());
if (_url.getPort () != -1)
{
sb.append ("/");
sb.append (_url.getPort ());
}
}
return sb.toString ();
}
/** the name of the application.
* @param the download URL
* @return the app context as filename
*/
public static String getAppName (URL _url)
{
String s = _url.getFile ();
// if it is a jar:<something>!/path/file url
if (_url.getProtocol ().equals ("jar"))
{
int p = s.lastIndexOf ("!");
if (p != -1)
s = s.substring (0, p);
}
return s.substring (Math.max (0, Math.min (s.length (), s.lastIndexOf ("/") +
1)));
}
/** returns app name with relative path in case of url is jar url.
jar:<something>!/
* @param the download URL
* @return wether file:|http:<bla>/<RETURNVALUE> or
jar:<something>!/<RETURNVALUE>
*/
public static String getFileName (URL _url)
{
String s = _url.getFile ();
int p = s.lastIndexOf ("!");
if (p != -1)
// jar url...
s = s.substring (Math.min (p + 2, s.length ()));
else
s = s.substring (Math.max (0, Math.min (s.length (), s.lastIndexOf
("/") + 1)));
return s;
}
/** tries to compose a webcontext for WAR files from the given war file url */
public static String getWebContext (URL _downloadUrl)
{
String s = getFileName (_downloadUrl);
// truncate the file extension
int p = s.lastIndexOf (".");
if (p != -1)
s = s.substring (0, p);
return "/" + s.replace ('.', '/');
}
/** Represents a J2ee module.
* the downloadURL (in case of ear something like:
jar:applicationURL!/packagename)
* the localURL where the downloaded file is placed
* the downloadURL for an alternative dd
* in case of a web package the optional web root context
*/
class Module
implements java.io.Serializable
{
// a short name for the module
String name;
// the url from which it is downloaded
// (in case of ear module like: jar:<app.downloadUrl>!/<module>
URL downloadUrl;
// the local url under which it is deployed by the special deployer
URL localUrl;
// the web root context in case of war file
String webContext;
}
}
1.1 jboss/src/main/org/jboss/deployment/J2eeApplicationMetaData.java
Index: J2eeApplicationMetaData.java
===================================================================
/*
* jBoss, the OpenSource EJB server
*
* Distributable under GPL license.
* See terms of license at gnu.org.
*/
package org.jboss.deployment;
import java.util.Vector;
import java.util.Iterator;
import org.jboss.ejb.DeploymentException;
import org.jboss.metadata.MetaData;
import org.w3c.dom.Element;
/**
* <description>
*
* @see <related>
* @author <firstname> <lastname> (<email>)
* @version $Revision: 1.1 $
*/
public class J2eeApplicationMetaData
extends MetaData
{
// Constants -----------------------------------------------------
// Attributes ----------------------------------------------------
String displayName;
String description;
String smallIcon;
String largeIcon;
Vector modules;
// Static --------------------------------------------------------
// Constructors --------------------------------------------------
public J2eeApplicationMetaData (Element rootElement) throws DeploymentException
{
importXml (rootElement);
}
// Public --------------------------------------------------------
public String getDisplayName ()
{
return displayName;
}
public String getDescription ()
{
return description;
}
public String getSmallIcon ()
{
return smallIcon;
}
public String getLargeIcon ()
{
return largeIcon;
}
public Iterator getModules ()
{
return modules.iterator ();
}
public void importXml (Element element) throws DeploymentException {
String rootTag =
element.getOwnerDocument().getDocumentElement().getTagName();
if (rootTag.equals("application")) {
// get some general info
displayName = getElementContent (getUniqueChild (element, "display-name"));
Element e = getOptionalChild (element, "description");
description = e != null ? getElementContent (e) : "";
e = getOptionalChild (element, "icon");
if (e != null)
{
Element e2 = getOptionalChild (element, "small-icon");
smallIcon = e2 != null ? getElementContent (e2) : "";
e2 = getOptionalChild (element, "large-icon");
largeIcon = e2 != null ? getElementContent (e2) : "";
} else
{
smallIcon = "";
largeIcon = "";
}
// extract modules...
modules = new Vector ();
Iterator it = getChildrenByTagName (element, "module");
while (it.hasNext ())
{
modules.add (new J2eeModuleMetaData ((Element)it.next
()));
}
} else
throw new DeploymentException("Unrecognized root tag in EAR
deployment descriptor: "+ element);
}
// Y overrides ---------------------------------------------------
// Package protected ---------------------------------------------
// Protected -----------------------------------------------------
// Private -------------------------------------------------------
// Inner classes -------------------------------------------------
}
1.1 jboss/src/main/org/jboss/deployment/J2eeDeployer.java
Index: J2eeDeployer.java
===================================================================
/*
* jBoss, the OpenSource EJB server
*
* Distributable under GPL license.
* See terms of license at gnu.org.
*/
package org.jboss.deployment;
import java.net.URL;
import java.net.MalformedURLException;
import java.io.File;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Iterator;
import java.util.Hashtable;
import java.util.Vector;
import javax.management.MBeanServer;
import javax.management.MBeanException;
import javax.management.JMException;
import javax.management.ObjectName;
import org.jboss.logging.Log;
import org.jboss.util.MBeanProxy;
import org.jboss.util.ServiceMBeanSupport;
import org.jboss.metadata.XmlFileLoader;
import org.jboss.ejb.DeploymentException;
import org.jboss.ejb.ContainerFactoryMBean;
import org.jboss.tomcat.EmbededTomcatServiceMBean;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
/** J2eeDeployer allows to deploy single EJB.jars as well as Web.wars
* (if Tomcat runs within the same VM as jBoss) or even Application.ears. <br>
* The deployment is done by determining the file type of the given url.
* The file must be a valid zip file and must contain either a META-INF/ejb-jar.xml
* or META-INF/application.xml or a WEB-INF/web.xml file.
* Depending on the file type, the whole file (EJBs, WARs)
* or only the relevant packages (EAR) becoming downloaded. <br>
* <i> replacing alternative DDs and validation is not yet implementet! </i>
* The uploaded files are getting passed through to the responsible deployer
* (ContainerFactory for jBoss and EmbededTomcatService for Tomcat).
* The state of deployments is persistent and becomes recovered after shutdown
* or crash.
*
* @author Daniel Schulze ([EMAIL PROTECTED])
* @version $Revision: 1.1 $
*/
public class J2eeDeployer
extends ServiceMBeanSupport
implements J2eeDeployerMBean
{
// Constants -----------------------------------------------------
public String DEPLOYMENT_DIR = "/home/deployment"; // default?
public String CONFIG = "deployments.conf";
// Attributes ----------------------------------------------------
// my server to lookup for the special deployers
MBeanServer server;
// names of the specials deployers
ObjectName jBossDeployer;
ObjectName tomcatDeployer;
// The logger for this service
Log log = new Log(getName());
// the deployments
Hashtable deployments = new Hashtable ();
// Static --------------------------------------------------------
/** only for testing...*/
public static void main (String[] _args) throws Exception
{
new J2eeDeployer ("").deploy (_args[0]);
}
// Constructors --------------------------------------------------
/** */
public J2eeDeployer (String _deployDir)
{
DEPLOYMENT_DIR = _deployDir;
}
// Public --------------------------------------------------------
/** Deploys the given URL independent if it is a EJB.jar, Web.war
* or Application.ear. In case of already deployed, it performes a
* redeploy.
* @param _url the url (file or http) to the archiv to deploy
* @throws MalformedURLException in case of a malformed url
* @throws J2eeDeploymentException if something went wrong...
*/
public void deploy (String _url) throws MalformedURLException,
J2eeDeploymentException
{
URL url = new URL (_url);
// undeploy first if it is a redeploy
if (deployments.containsKey (url))
undeploy (_url);
// now try to deploy
log.log ("deploy j2ee application: " + _url);
Deployment d = installApplication (url);
deployments.put (d.downloadUrl, d);
storeConfig ();
log.log ("j2ee application: " + _url + " is deployed.");
}
/** Undeploys the given URL (if it is deployed).
* @param _url the url to to undeploy
* @throws MalformedURLException in case of a malformed url
* @throws J2eeDeploymentException if something went wrong (but should have
removed all files)
*/
public void undeploy (String _url) throws MalformedURLException,
J2eeDeploymentException
{
URL url = new URL (_url);
log.log ("undeploy j2ee application: " + _url);
Deployment d = (Deployment)deployments.get (url);
if (d != null)
{
try
{
uninstallApplication (d);
}
catch (J2eeDeploymentException e)
{
throw e;
}
finally
{
deployments.remove (url);
storeConfig ();
log.log ("j2ee application: " + _url + " is undeployed.");
}
} else
log.warning (_url + " is NOT deployed!");
}
/** Checks if the given URL is currently deployed or not.
* @param _url the url to to check
* @return true if _url is deployed
* @throws MalformedURLException in case of a malformed url
* @throws J2eeDeploymentException if the app seems to be deployed, but some of
its modules
* are not.
*/
public boolean isDeployed (String _url) throws MalformedURLException,
J2eeDeploymentException
{
URL url = new URL (_url);
boolean deployed = deployments.containsKey (url);
if (deployed)
{
try
{
// check all modules ...
Deployment d = (Deployment)deployments.get (url);
// jBoss
Iterator i = d.ejbModules.iterator ();
while (i.hasNext () && deployed)
{
Deployment.Module m = (Deployment.Module)i.next ();
// Call the ContainerFactory that is loaded in the JMX server
Object result = server.invoke(jBossDeployer, "isDeployed",
new Object[] { m.localUrl.toString ()
}, new String[] { "java.lang.String" });
deployed = ((Boolean)result).booleanValue ();
}
// Tomcat
i = d.webModules.iterator ();
if (i.hasNext () && !withTomcat ())
throw new J2eeDeploymentException ("the application containes web
modules but the tomcat service isn't running?!");
while (i.hasNext () && deployed)
{
Deployment.Module m = (Deployment.Module)i.next ();
Object result = server.invoke(tomcatDeployer, "isDeployed",
new Object[] { m.localUrl.toString ()
}, new String[] { "java.lang.String" });
deployed = ((Boolean)result).booleanValue ();
}
if (!deployed)
throw new J2eeDeploymentException ("The application is not
correct deployed!");
}
catch (MBeanException _mbe) {
throw new J2eeDeploymentException ("error while interacting with
deployer MBeans... " + _mbe.getTargetException ().getMessage ());
} catch (JMException _jme){
throw new J2eeDeploymentException ("fatal error while interacting with
deployer MBeans... " + _jme.getMessage ());
}
}
return deployed;
}
// ServiceMBeanSupport overrides ---------------------------------
public String getName()
{
return "J2ee deployer";
}
protected ObjectName getObjectName(MBeanServer server, ObjectName name)
throws javax.management.MalformedObjectNameException
{
this.server = server;
return new ObjectName(OBJECT_NAME);
}
/** */
protected void initService()
throws Exception
{
// Save JMX name of the deployers
jBossDeployer = new ObjectName(ContainerFactoryMBean.OBJECT_NAME);
tomcatDeployer= new ObjectName(EmbededTomcatServiceMBean.OBJECT_NAME);
//set the deployment directory
DEPLOYMENT_DIR = new File (DEPLOYMENT_DIR).getCanonicalPath ();
// load the configuration
loadConfig ();
}
/** tries to redeploy all deployments before shutdown.*/
protected void startService()
throws Exception
{
if (!withTomcat ())
log.log ("No EmbededTomcat found - only EJB deployment available...");
log.log ("trying to redeploy all applications that were running before
shutdown...");
Iterator it = deployments.values ().iterator ();
while (it.hasNext ())
{
Deployment d = (Deployment) it.next ();
try
{
deploy (d.downloadUrl.toString ());
}
catch (J2eeDeploymentException _e)
{
log.warning ("unable to redeploy application "+d.name+" -> delete
it.");
}
}
log.log ("deployment state recovered.");
}
/** */
protected void stopService()
{
/* // Uncomment method body to get redeploy only on server crash
log.log ("undeploy all applications...");
Iterator it = deployments.values ().iterator ();
while (it.hasNext ())
{
Deployment d = (Deployment) it.next ();
try
{
undeploy (d.downloadUrl.toString ());
}
catch (J2eeDeploymentException _e)
{
log.warning ("hmmm... "+d.name+" dont wants to become undeployed?!");
}
}
storeConfig ();
log.log ("all applications undeployed.");
*/ }
// Private -------------------------------------------------------
/** Deploys all packages of the given deployment. <br>
* This means download the needed packages do some validation and/or
* other things and pass the references to the special deployers.
* <i> Validation and do some other things is not yet implemented </i>
* @param _d the deployment (= a J2ee application or module)
*/
Deployment installApplication (URL _downloadUrl) throws J2eeDeploymentException
{
// determine the file type by trying to access one of the possible
// deployment descriptors...
Element root = null;
String[] files = {"META-INF/ejb-jar.xml", "META-INF/application.xml",
"WEB-INF/web.xml"};
for (int i = 0; i < files.length && root == null; ++i)
{
try
{
root = XmlFileLoader.getDocument (new URL ("jar:" +
_downloadUrl.toString () + "!/" + files[i])).getDocumentElement ();
} catch (Exception _e) {}
}
// create a Deployment
Deployment d = new Deployment ();
try {
// if we found a deployment descriptor
if (root != null)
{
d.name = d.getAppName (_downloadUrl);
d.downloadUrl = _downloadUrl;
StringBuffer sb = new StringBuffer ("file:");
sb.append (DEPLOYMENT_DIR);
sb.append ("/");
// sb.append (d.getAdminCtx (d.downloadUrl));
// sb.append ("/");
sb.append (d.name);
d.localUrl = new URL (sb.toString ()); // should never throw an URLEx
log.log ("create application " + d.name);
// do the app type dependent stuff...
if ("ejb-jar".equals (root.getTagName ()))
{
// its a EJB.jar... just take the package
Deployment.Module m = d.newModule ();
// localUrl: file:<download_dir> / <adminCtx> / <appName> / <appName>
m.downloadUrl = d.downloadUrl;
m.name = d.getFileName (m.downloadUrl);
m.localUrl = new URL (d.localUrl.toString () + "/" + m.name);//
should never throw an URLEx
log.log ("downloading module " + m.name);
URLWizzard.download (m.downloadUrl, m.localUrl);
d.ejbModules.add (m);
}
else if ("web-app".equals (root.getTagName ()))
{
// its a WAR.jar... just take the package
if (!withTomcat ())
throw new J2eeDeploymentException ("Tomcat is not
available!");
Deployment.Module m = d.newModule ();
m.downloadUrl = d.downloadUrl;
m.name = d.getFileName (m.downloadUrl);
m.localUrl = new URL (d.localUrl.toString () + "/" + m.name);//
should never throw an URLEx
m.webContext = d.getWebContext (m.downloadUrl);
log.log ("downloading module " + m.name);
URLWizzard.downloadAndInflate (m.downloadUrl, m.localUrl);
d.webModules.add (m);
}
else if ("application".equals (root.getTagName ()))
{
// its a EAR.jar... hmmm, its a little more
// create a MetaData object...
J2eeApplicationMetaData app;
app = new J2eeApplicationMetaData (root);
// currently we only take care for the modules
// no security stuff, no alternative DDs
// no dependency and integrity checking... !!!
J2eeModuleMetaData mod;
Iterator it = app.getModules ();
while (it.hasNext ())
{
mod = (J2eeModuleMetaData) it.next ();
// iterate the ear modules
if (mod.isEjb () || mod.isWeb ())
{
// a EJB or WEB package...
Deployment.Module m = d.newModule ();
try
{
m.downloadUrl = new URL ("jar:" + _downloadUrl.toString () +
"!/" + mod.getFileName ());// chould throw an URLEx
m.name = d.getFileName (m.downloadUrl);
m.localUrl = new URL (d.localUrl.toString () + "/" +
m.name);// chould throw an URLEx
} catch (MalformedURLException _mue) {
throw new J2eeDeploymentException ("syntax error in module
section in application DD : " + _mue.getMessage ());
}
if (mod.isWeb ())
{
if (!withTomcat ())
throw new J2eeDeploymentException ("Tomcat is not
available!");
m.webContext = mod.getWebContext ();
if (m.webContext == null)
m.webContext = d.getWebContext (m.downloadUrl);
log.log ("downloading and inflating module " + m.name);
URLWizzard.downloadAndInflate (m.downloadUrl, m.localUrl);
d.webModules.add (m);
}
else
{
log.log ("downloading module " + m.name);
URLWizzard.download (m.downloadUrl, m.localUrl);
d.ejbModules.add (m);
}
// here the code for checking and DD replacment...
// ...
}
}
// other packages we dont care about (currently)
}
// redirict all modules to the responsible deployer
Deployment.Module m = null;
try
{
// jBoss
Iterator it = d.ejbModules.iterator ();
while (it.hasNext ())
{
m = (Deployment.Module)it.next ();
log.log ("deploying module " + m.name);
// Call the ContainerFactory that is loaded in the JMX server
server.invoke(jBossDeployer, "deploy",
new Object[] { m.localUrl.toString () }, new
String[] { "java.lang.String" });
}
// Tomcat
it = d.webModules.iterator ();
while (it.hasNext ())
{
m = (Deployment.Module)it.next ();
log.log ("deploying module " + m.name);
// Call the TomcatDeployer that is loaded in the JMX server
server.invoke(tomcatDeployer, "deploy",
new Object[] { m.webContext, m.localUrl.toString
()}, new String[] { "java.lang.String", "java.lang.String" });
}
}
catch (MBeanException _mbe) {
log.log ("deploying failed!");
uninstallApplication (d);
throw new J2eeDeploymentException ("error while interacting with
deployer MBeans... " + _mbe.getTargetException ().getMessage ());
} catch (JMException _jme){
log.log ("deploying failed!");
uninstallApplication (d);
throw new J2eeDeploymentException ("fatal error while interacting with
deployer MBeans... " + _jme.getMessage ());
}
return d;
}
else
throw new J2eeDeploymentException (_downloadUrl.toString ()+" points not
to a valid j2ee application (app.ear/ejb.jar/web.war)!");
} catch (IOException _ioe) {
uninstallApplication (d);
throw new J2eeDeploymentException ("Error in downloading module: "
+ _ioe.getMessage ());
} catch (DeploymentException _de) {
uninstallApplication (d);
throw new J2eeDeploymentException ("Unable scan .ear file: " +
_de.getMessage ());
} catch (Exception _e) {
_e.printStackTrace ();
uninstallApplication (d);
throw new J2eeDeploymentException ("FATAL ERROR!");
}
}
void uninstallApplication (Deployment _d) throws J2eeDeploymentException
{
log.log ("destroying application " + _d.name);
String error = "";
Iterator it = _d.ejbModules.iterator ();
while (it.hasNext ())
{
Deployment.Module m = (Deployment.Module)it.next ();
log.log ("uninstalling module " + m.name);
//jBoss
try
{
// Call the ContainerFactory that is loaded in the JMX server
server.invoke(jBossDeployer, "undeploy",
new Object[] { m.localUrl.toString () }, new String[] {
"java.lang.String" });
}
catch (MBeanException _mbe) {
log.warning ("unable to undeploy module " + m.name + ": " +
_mbe.getTargetException ().getMessage ());
} catch (JMException _jme){
error += "[fatal error while interacting with deployer MBeans... " +
_jme.getMessage () + "]";
}
}
it = _d.webModules.iterator ();
while (it.hasNext ())
{
Deployment.Module m = (Deployment.Module)it.next ();
log.log ("uninstalling module " + m.name);
// tomcat
if (withTomcat ())
{
try
{
server.invoke(tomcatDeployer, "undeploy",
new Object[] { m.localUrl.toString () }, new String[]
{ "java.lang.String" });
}
catch (MBeanException _mbe) {
log.warning ("unable to undeploy module " + m.name + ": " +
_mbe.getTargetException ().getMessage ());
} catch (JMException _jme){
error += "[fatal error while interacting with deployer MBeans... " +
_jme.getMessage () + "]";
}
}
}
try
{
URLWizzard.deleteTree (_d.localUrl);
log.log ("file tree "+_d.localUrl.toString ()+" deleted.");
} catch (IOException _ioe) {
throw new J2eeDeploymentException ("Error in removing local
application files ("+_d.localUrl+"): " + _ioe.getMessage ());
}
if (!error.equals (""))
throw new J2eeDeploymentException (error);
}
private void loadConfig ()
{
try {
ObjectInputStream in = new ObjectInputStream (new FileInputStream
(DEPLOYMENT_DIR + File.separator + CONFIG));
deployments = (Hashtable)in.readObject ();
in.close ();
} catch (Exception e)
{
log.log ("no config file found...");
}
}
private void storeConfig ()
{
try {
ObjectOutputStream out = new ObjectOutputStream (new FileOutputStream
(DEPLOYMENT_DIR + File.separator + CONFIG));
out.writeObject (deployments);
out.close ();
} catch (IOException e)
{
log.warning ("storing config failed...");
}
}
private boolean withTomcat ()
{
return server.isRegistered (tomcatDeployer);
}
}
1.1 jboss/src/main/org/jboss/deployment/J2eeDeployerMBean.java
Index: J2eeDeployerMBean.java
===================================================================
/*
* jBoss, the OpenSource EJB server
*
* Distributable under GPL license.
* See terms of license at gnu.org.
*/
package org.jboss.deployment;
import java.net.MalformedURLException;
import org.jboss.util.ServiceMBean;
/**
* @see
* @author Daniel Schulze ([EMAIL PROTECTED])
* @version $Revision: 1.1 $
*/
public interface J2eeDeployerMBean
extends ServiceMBean
{
// Constants -----------------------------------------------------
public static final String OBJECT_NAME = "J2EE:service=J2eeDeployer";
// Public --------------------------------------------------------
public void deploy (String url) throws MalformedURLException,
J2eeDeploymentException;
public void undeploy (String url) throws MalformedURLException,
J2eeDeploymentException;
public boolean isDeployed (String url) throws MalformedURLException,
J2eeDeploymentException;
}
1.1 jboss/src/main/org/jboss/deployment/J2eeDeploymentException.java
Index: J2eeDeploymentException.java
===================================================================
/*
* jBoss, the OpenSource EJB server
*
* Distributable under GPL license.
* See terms of license at gnu.org.
*/
package org.jboss.deployment;
/**
* <description>
*
* @author Daniel Schulze [EMAIL PROTECTED]
* @version $Revision: 1.1 $
*/
public class J2eeDeploymentException
extends Exception
{
// Constructors --------------------------------------------------
public J2eeDeploymentException (String message)
{
super (message);
}
}
1.1 jboss/src/main/org/jboss/deployment/J2eeModuleMetaData.java
Index: J2eeModuleMetaData.java
===================================================================
/*
* jBoss, the OpenSource EJB server
*
* Distributable under GPL license.
* See terms of license at gnu.org.
*/
package org.jboss.deployment;
import org.jboss.ejb.DeploymentException;
import org.jboss.metadata.MetaData;
import org.w3c.dom.Element;
/**
* <description>
*
* @see <related>
* @author Daniel Schulze [EMAIL PROTECTED]
* @version $Revision: 1.1 $
*/
public class J2eeModuleMetaData
extends MetaData
{
// Constants -----------------------------------------------------
public static final int EJB = 0;
public static final int WEB = 1;
public static final int CLIENT = 2;
public static final int CONNECTOR = 3;
private static final String[] tags = {"ejb", "web", "java", "connector"};
// Attributes ----------------------------------------------------
int type;
String fileName;
String alternativeDD;
String webContext;
// Static --------------------------------------------------------
// Constructors --------------------------------------------------
public J2eeModuleMetaData (Element moduleElement) throws DeploymentException
{
importXml (moduleElement);
}
// Public --------------------------------------------------------
public boolean isEjb ()
{
return (type == EJB);
}
public boolean isWeb ()
{
return (type == WEB);
}
public boolean isJava ()
{
return (type == CLIENT);
}
public boolean isConnector ()
{
return (type == CONNECTOR);
}
public String getFileName ()
{
return fileName;
}
public String getAlternativeDD ()
{
return alternativeDD;
}
public String getWebContext ()
{
if (type == WEB)
return webContext;
else
return null;
}
public void importXml (Element element) throws DeploymentException
{
if (element.getTagName ().equals("module"))
{
boolean done = false; // only one of the tags can hit!
for (int i = 0; i < tags.length; ++i)
{
Element child = getOptionalChild (element, tags[i]);
if (child == null)
continue;
if (done)
throw new DeploymentException ("malformed
module definition in application dd: "+ element);
type = i;
switch (type)
{
case EJB:
case CLIENT:
case CONNECTOR:
fileName = getElementContent (child);
alternativeDD = getElementContent
(getOptionalChild (element, "alt-dd"));
break;
case WEB:
fileName = getElementContent
(getUniqueChild (child, "web-uri"));
webContext = getElementContent
(getOptionalChild (child, "context-root"));
alternativeDD = getElementContent
(getOptionalChild (element, "alt-dd"));
}
done = true;
}
} else
throw new DeploymentException ("unrecognized module tag in
application dd: "+ element);
}
// Y overrides ---------------------------------------------------
// Package protected ---------------------------------------------
// Protected -----------------------------------------------------
// Private -------------------------------------------------------
// Inner classes -------------------------------------------------
}
1.1 jboss/src/main/org/jboss/deployment/README.html
Index: README.html
===================================================================
<html>
<head>
<title>J2EE Deployer read me</title>
</head>
<body bgcolor="#ffffff">
<h1>J2EE Deployer</h1>
<div align="right"><font size="-3" color="#555555"> by <A
href="mailto:[EMAIL PROTECTED]"> Daniel Schulze </A> </font></div>
<hr>
<h3>The idea</h3>
<p> The j2ee deployer is made to delpoy j2ee compilant applications which means
.ear,
ejb.jar and web.war files as well.
</p>
<p> This MBean references the
<code><b>org.jboss.ejb.ContainerFactoryBMBean</b></code> and
<code><b>org.jboss.tomcat.EmbededTomcatServiceMBean</b></code>. Both beans
have to run
in the same server and since the deployer in his start service method tries
to deploy
all apps that were deployed before shutdown, these both services must be
started before
the j2ee deployer! To make this sure, there must be a service entry for the
j2ee deployer
in the jboss.dependencies file.
</p>
<hr>
<h3>How it works</h3>
<p> <dl>
<dt><b>deploy ()</b></dt>
<dd> The deployer takes the given url and tries to determine the type of the
given file
(this is done by seeking one of the possible deployment descriptors in this
file
(application.xml, ejb-jar.xml, web.xml)). If a valid file type was
determined, all
for the deployment needed files (modules, libs, alternative DDs, ...) are
downloaded
to a local directory of the app server. Once this is done the ejb and war
deployers
(ContainerFactory and EmbeddedTomcat) are called to deploy the single
modules. <br>
If this was successful, the current url is stored to the deployments
collection. If
one of the ejb/war deployer calls fails, the deployment becomes canceled and
all
downloaded files are deleted.</dd>
<dt><b>isDeployed ()</b></dt>
<dd> Looks in the collection of deployments for the given url. If the url is
found, the
ejb/war deployer for each module of this app is asked for isDeployed () and
only
if all modules are correct deployed, the method returns true. If there is an
inconsistence in the deployments an exception is thrown.</dd>
<dt><b>undeploy ()</b></dt>
<dd>Undeployes all modules of this application,removes all server local files
of this
app and removes this url from the collection of deployed urls. (This method
should
always succeed).</dd>
</dl>
</p>
<hr>
<h3>What is done</h3>
<p><ul>
<li> download of ejb.jar and web.war modules</li>
<li> deployment of these modules </li>
<li> <code>isDeployed ()</code> - method added to ContainerFactory
</ul>
</p>
<hr>
<h3>What is to do</h3>
<p><ul>
<li> extracting web.wars on download </li>
<li> replacing module DDs with alternative DDs </li>
<li> integrity check in case of ear files
<ul>
<li> unify security roles </li>
<li> <i>things I ve missed ... </i></li>
</ul>
</li>
<li> find common libraries, download them and add them to the classpath(s)
of the modules </li>
<li> move the verification stuff from the ContainerFactory to here?
</ul>
</p>
</body>
</html>
1.1 jboss/src/main/org/jboss/deployment/URLWizzard.java
Index: URLWizzard.java
===================================================================
/*
* jBoss, the OpenSource EJB server
*
* Distributable under GPL license.
* See terms of license at gnu.org.
*/
package org.jboss.deployment;
import java.net.URL;
import java.net.URLConnection;
import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.BufferedReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.BufferedWriter;
import java.io.IOException;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
/**
* Encapsulates URL bases copy and jar file operations.
* Very scratchy! Any improvements are welcome!
*
* @author Daniel Schulze <[EMAIL PROTECTED]>
* @version $Revision: 1.1 $
*/
public class URLWizzard
{
// Static --------------------------------------------------------
public static void main (String[] _args) throws Exception
{
downloadAndInflate (new URL (_args[0]), new URL (_args[1]));
}
/** copies the source to the destination url. As destination
are currently only file:/... urls supported */
public static void download (URL _src, URL _dest) throws IOException
{
InputStream in;
OutputStream out;
/*
URLConnection urlCon = _src.openConnection ();
urlCon.setDoInput (true);
in = urlCon.getInputStream ();
*/
in = _src.openStream ();
boolean jar = false;
String jarPath = "";
String filePath;
String fileName;
String s = _dest.toString ();
if (_dest.getProtocol ().equals ("jar"))
{
// get the path in the jar
int pos = s.indexOf ("!");
jarPath = s.substring (pos + 1);
s = s.substring (0, pos);
}
// get the FileName
int pos = s.lastIndexOf ("/");
fileName = s.substring (pos + 1);
s = s.substring (0, pos);
// get the FilePath
pos = Math.max (0, s.lastIndexOf (":"));
filePath = s.substring (pos + 1);
filePath = filePath.replace ('/', File.separatorChar);
if (jar)
{
// open jarFile
throw new IOException ("write into a jar file NOT yet implemented!");
}
else
{
File dir = new File (filePath);
if (!dir.exists ())
dir.mkdirs ();
out = new FileOutputStream (filePath + File.separator + fileName);
}
write (in, out);
out.close ();
in.close ();
}
/** inflates the given zip file into the given directory */
public static void downloadAndInflate (URL _src, URL _dest) throws IOException
{
InputStream in;
OutputStream out;
in = _src.openStream ();
boolean jar = false;
String jarPath = "";
String filePath;
String fileName;
String s = _dest.toString ();
if (!_dest.getProtocol ().equals ("file"))
throw new IOException ("only file:/ is as destination allowed!");
File base = new File (_dest.getFile ());
if (base.exists ())
deleteTree (_dest);
base.mkdirs ();
ZipInputStream zin = new ZipInputStream (in);
ZipEntry entry;
while ((entry = zin.getNextEntry ()) != null)
{
String name = entry.getName ();
if (!entry.isDirectory ()) // there are not all directories listed (?!)- so
this way...
{
// create directory structure if necessary
// System.out.println ("entry: "+name);
int x = name.lastIndexOf ("/");
if (x != -1)
{
File dir = new File (base.getCanonicalPath () + File.separator +
name.substring (0, x));
if (!dir.exists ())
dir.mkdirs ();
}
// and extract...
out = new FileOutputStream (base.getCanonicalPath () + File.separator +
name);
write (zin, out);
out.close ();
}
}
zin.close ();
}
/** deletes the given file:/... url recursively */
public static void deleteTree (URL _dir) throws IOException
{
if (!_dir.getProtocol ().equals ("file"))
throw new IOException ("Protocol not supported");
File f = new File (_dir.getFile ());
if (!delete (f))
throw new IOException ("deleting " + _dir.toString () + "recursively
failed!");
}
/** deletes a file recursively */
private static boolean delete (File _f) throws IOException
{
if (_f.exists ())
{
if (_f.isDirectory ())
{
File[] files = _f.listFiles ();
for (int i = 0, l = files.length; i < l; ++i)
if (!delete (files[i]))
return false;
}
return _f.delete ();
}
return true;
}
/** writes the content of the InputStream into the OutputStream */
private static void write (InputStream _in, OutputStream _out) throws IOException
{
int b;
while ((b = _in.read ()) != -1)
_out.write ((byte)b);
_out.flush ();
}
}