JSR-88 introduces unified J2EE API for deployment. You
will see how to use it for deploying/undeploying web applications and
it will be demonstrated using glassfish
Without JSR-88
You have several options how to deploy a web application onto glassfish.
- CLI interface ($GLASSFISH_HOME/bin/asadmin command)
- Admin Console (http://localhost:4848/)
- Autodeployment (place the war directly into filesystem: $GLASSFISH_HOME/domains/domain1/autodeploy)
So for e.g. using CLI interface you can deploy a war file by:
$AS_HOME/bin/asadmin deploy testApp.war
And undeploy it by:
$AS_HOME/bin/asadmin undeploy testApp
Leveraging JSR-88
Yet another option is to use JSR-88 (http://www.jcp.org/en/jsr/detail?id=88) interface.
Please download a simple sample from
http://blogs.sun.com/japod/resource/wardepl-jsr88.tar.gz
which depicts how it works.
After downloading, you can (presuming your glassfish is installed under $AS_HOME and your default domain instance is up and running):
unpack the sample:
$ gzip -dc wardepl-jsr88.tar.gz | tar xvf -
x ., 0 bytes, 0 tape blocks
x ./wardeployment, 0 bytes, 0 tape blocks
x ./wardeployment/Main.java, 8044 bytes, 16 tape blocks
x ./wardeployment.properties, 168 bytes, 1 tape blocks
x ./testApp.war, 3073 bytes, 7 tape blocks
compile it:
$ javac -cp $AS_HOME/lib/javaee.jar wardeployment/Main.java
deploy attached testAppl.war:
$ java -cp .:$AS_HOME/lib/javaee.jar:$AS_HOME/lib/appserv-ext.jar:$AS_HOME/lib/appserv-deployment-client.jar wardeployment.Main deploy testApp.war
Deploying app...
deployment started : 0%
deployment finished : 100%
Deploying application in domain completed successfully
Trying to create reference for application in target server completed successfully
Trying to start application in target server completed successfully
Deployment of application testApp completed successfully
Enable of testApp in target server completed successfully
Enable of application in all targets completed successfully
All operations completed successfully
and undeploy it again:
$ java -cp .:$AS_HOME/lib/javaee.jar:$AS_HOME/lib/appserv-ext.jar:$AS_HOME/lib/appserv-deployment-client.jar wardeployment.Main undeploy testApp
Undeploying app...
While undeploying, trying to stop application in target server completed successfully
While undeploying, trying to remove reference for application in target server completed successfully
Undeploying the application
Trying to undeploy application from domain completed successfully
Undeployment of application testApp completed successfully
All operations completed successfully
Please note attached wardeployment.properties file, which contains settings for glassfish:
jsr88.dm.id=deployer:Sun:AppServer::localhost:4848
jsr88.dm.user=admin
jsr88.dm.passwd=adminadmin
jsr88.df.classname=com.sun.enterprise.deployapi.SunDeploymentFactory
The classname above was taken from $AS_HOME/lib/deployment/sun-as-jsr88-dm.jar:META-INF/MANIFEST.MF file,
where you can find it as J2EE-DeploymentFactory-Implementation-Class in accord with JSR-88.
The settings are then used to obtain appropriate deployment manager:
DeploymentFactoryManager dfm = DeploymentFactoryManager.getInstance();
try {
Class dfClass = Class.forName(getParam("jsr88.df.classname"));
DeploymentFactory dfInstance;
dfInstance = (DeploymentFactory) dfClass.newInstance();
dfm.registerDeploymentFactory(dfInstance);
} catch (ClassNotFoundException ex) {
ex.printStackTrace();
} catch (IllegalAccessException ex) {
ex.printStackTrace();
} catch (InstantiationException ex) {
ex.printStackTrace();
}
try {
deploymentManager =
dfm.getDeploymentManager(
getParam("jsr88.dm.id"),getParam("jsr88.dm.user"),getParam("jsr88.dm.passwd"));
} catch (DeploymentManagerCreationException ex) {
ex.printStackTrace();
}
For deploying the application, distribute method is then invoked:
ProgressObject deplProgress = getDeploymentManager().distribute(getDeploymentManager().getTargets(),
new File(warFilename), null);
Similarly, deploymentManager is used also for appl undeployment:
ProgressObject startProgress = getDeploymentManager().undeploy(myIDs);
Please note the calls are asynchronous and you have to wait till the deployment/undeployment finishes.
Whole source code of the sample please see bellow:
package wardeployment;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.Properties;
import javax.enterprise.deploy.shared.ModuleType;
import javax.enterprise.deploy.shared.factories.DeploymentFactoryManager;
import javax.enterprise.deploy.spi.DeploymentManager;
import javax.enterprise.deploy.spi.TargetModuleID;
import javax.enterprise.deploy.spi.exceptions.DeploymentManagerCreationException;
import javax.enterprise.deploy.spi.exceptions.TargetException;
import javax.enterprise.deploy.spi.factories.DeploymentFactory;
import javax.enterprise.deploy.spi.status.ProgressEvent;
import javax.enterprise.deploy.spi.status.ProgressListener;
import javax.enterprise.deploy.spi.status.ProgressObject;
/**
*
* @author Jakub Podlesak (japod at sun.com)
*/
public class Main {
class DeploymentListener implements ProgressListener {
Main driver;
String warContext;
DeploymentListener(Main driver, String warContext) {
this.driver = driver;
this.warContext = warContext;
}
public void handleProgressEvent(ProgressEvent event) {
System.out.println(event.getDeploymentStatus().getMessage());
if (event.getDeploymentStatus().isCompleted()) {
try {
TargetModuleID[] ids = getDeploymentManager().getNonRunningModules(ModuleType.WAR, getDeploymentManager().getTargets());
TargetModuleID[] myIDs = new TargetModuleID[1];
for (TargetModuleID id : ids) {
if (warContext.equals(id.getModuleID())) {
myIDs[0] = id;
ProgressObject startProgress = driver.getDeploymentManager().start(myIDs);
startProgress.addProgressListener(new ProgressListener() {
public void handleProgressEvent(ProgressEvent event) {
System.out.println(event.getDeploymentStatus().getMessage());
if (event.getDeploymentStatus().isCompleted()) {
driver.setAppStarted(true);
}
}
});
}
}
} catch (IllegalStateException ex) {
ex.printStackTrace();
} catch (TargetException ex) {
ex.printStackTrace();
}
}
}
}
DeploymentManager deploymentManager;
boolean appStarted;
boolean appUndeployed;
String warContext;
String warFilename;
String wsdlUrl;
synchronized void setAppStarted(boolean appStarted) {
this.appStarted = appStarted;
notifyAll();
}
synchronized void setAppUndeployed(boolean appUndeployed) {
this.appUndeployed = appUndeployed;
notifyAll();
}
private String getParam(String param) {
return (null == deploymentProperties) ? null : deploymentProperties.getProperty(param);
}
public DeploymentManager getDeploymentManager() {
if (null == deploymentManager) {
DeploymentFactoryManager dfm = DeploymentFactoryManager.getInstance();
try {
Class dfClass = Class.forName(getParam("jsr88.df.classname"));
DeploymentFactory dfInstance;
dfInstance = (DeploymentFactory) dfClass.newInstance();
dfm.registerDeploymentFactory(dfInstance);
} catch (ClassNotFoundException ex) {
ex.printStackTrace();
} catch (IllegalAccessException ex) {
ex.printStackTrace();
} catch (InstantiationException ex) {
ex.printStackTrace();
}
try {
deploymentManager =
dfm.getDeploymentManager(
getParam("jsr88.dm.id"),getParam("jsr88.dm.user"),getParam("jsr88.dm.passwd"));
} catch (DeploymentManagerCreationException ex) {
ex.printStackTrace();
}
}
return deploymentManager;
}
void runApp(String warFilename, String warContext) {
setAppStarted(false);
ProgressObject deplProgress = getDeploymentManager().distribute(getDeploymentManager().getTargets(),
new File(warFilename), null);
deplProgress.addProgressListener(new DeploymentListener(this, warContext));
waitForAppStart();
}
void undeployApp(String warContext) {
setAppUndeployed(false);
try {
TargetModuleID[] ids = getDeploymentManager().getRunningModules(ModuleType.WAR, getDeploymentManager().getTargets());
TargetModuleID[] myIDs = new TargetModuleID[1];
for (TargetModuleID id : ids) {
if (warContext.equals(id.getModuleID())) {
myIDs[0] = id;
ProgressObject startProgress = getDeploymentManager().undeploy(myIDs);
startProgress.addProgressListener(new ProgressListener() {
public void handleProgressEvent(ProgressEvent event) {
System.out.println(event.getDeploymentStatus().getMessage());
if (event.getDeploymentStatus().isCompleted()) {
setAppUndeployed(true);
}
}
});
}
}
} catch (IllegalStateException ex) {
ex.printStackTrace();
} catch (TargetException ex) {
ex.printStackTrace();
}
waitForAppUndeployment();
}
void releaseDeploymentManager() {
if (null != deploymentManager) {
deploymentManager.release();
}
}
synchronized void waitForAppStart() {
while(!appStarted) {
try {
wait();
} catch (InterruptedException e) {}
}
}
synchronized void waitForAppUndeployment() {
while(!appUndeployed) {
try {
wait();
} catch (InterruptedException e) {}
}
}
/** Creates a new instance of Main */
public Main() {
}
public Main(String filename) {
setProperties(filename);
}
private final static String SyntaxHelp = "syntax:\n\tdeploy \n\tundeploy ";
private final static String PropertiesFilename = "wardeployment.properties";
private Properties deploymentProperties;
private void setProperties(String filename) {
FileInputStream fis = null;
try {
fis = new FileInputStream(filename);
deploymentProperties = new Properties();
deploymentProperties.load(fis);
fis.close();
} catch (FileNotFoundException ex) {
ex.printStackTrace();
} catch (IOException ex) {
ex.printStackTrace();
}
}
private static void printHelpAndExit() {
System.out.println(SyntaxHelp);
System.exit(1);
}
/**
* @param args the command line arguments
*/
public static void main(String[] args) {
if (args.length < 1) {
printHelpAndExit();
}
Main worker = new Main(PropertiesFilename);
if ("deploy".equals(args[0])) {
System.out.println("Deploying app...");
worker.runApp(args[1], args[1].substring(0,args[1].length()-4));
worker.releaseDeploymentManager();
} else if ("undeploy".equals(args[0])) {
System.out.println("Undeploying app...");
worker.undeployApp(args[1]);
worker.releaseDeploymentManager();
}
}
}
Further Info
Please visit
https://glassfish.dev.java.net/javaee5/deployment/
to get a lot more information on the topic.
Comments:
Great Post Jakub !!!
In your example code, deployment manager url is given as below
jsr88.dm.id=deployer:Sun:AppS.erver::localhost:4848 Is there anyway to
specify domain id in the deployment manager's url ? It is required when
there is a different domain than "domain1" .
Posted by
satyaranjan
on February 27, 2007 at 11:25 AM CET
#
Hi, this is really usefull post. I build my Java EE applications and
there isn't any plugin to deploy application on glassfish server. You
post describe deploying of war. Is there any possibility to use this
simple deploy for EJB3 jar, ear? Or even better to deploy jbi service
assembly?
Posted by
Petr Klemsinsky
on April 27, 2007 at 02:45 PM CEST
#
Hi Petr! I have not tried it yet, but it should be at least possible to
reuse some parts of the code. Once I have time, I will give it a try
and let you know.
Posted by
Jakub
on May 03, 2007 at 03:32 PM CEST
#
hi...can u help me??
i want to deploy a application on weblogic with the use of jsr-88
if any other simple way is there then it is also welcome.
plz help me
i need it badly
Posted by
Mitesh
on May 23, 2007 at 06:54 PM CEST
#
Hi Mitesh,
sorry for delayed response.
Regarding weblogic, I unfortunately do not have a chance to run it on
my solaris x86 box (no binaries, no source code provided by weblogic:-(
So i have limited possibilities to try it out. Have you checked docs?
Posted by
japod
on August 10, 2007 at 09:40 AM CEST
#