Java tutorial
/* * JBoss, Home of Professional Open Source. * Copyright 2012, Red Hat, Inc., and individual contributors * as indicated by the @author tags. See the copyright.txt file in the * distribution for a full listing of individual contributors. * * This is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation; either version 2.1 of * the License, or (at your option) any later version. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this software; if not, write to the Free * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA * 02110-1301 USA, or see the FSF site: http://www.fsf.org. */ package org.jboss.as.plugin.server; import java.io.File; import java.io.IOException; import java.util.List; import java.util.concurrent.TimeUnit; import org.apache.maven.plugin.MojoExecutionException; import org.apache.maven.plugin.MojoFailureException; import org.apache.maven.plugin.logging.Log; import org.apache.maven.plugins.annotations.Component; import org.apache.maven.plugins.annotations.Execute; import org.apache.maven.plugins.annotations.LifecyclePhase; import org.apache.maven.plugins.annotations.Mojo; import org.apache.maven.plugins.annotations.Parameter; import org.apache.maven.plugins.annotations.ResolutionScope; import org.jboss.as.controller.client.ModelControllerClient; import org.jboss.as.plugin.common.DeploymentFailureException; import org.jboss.as.plugin.common.Files; import org.jboss.as.plugin.common.PropertyNames; import org.jboss.as.plugin.common.ServerOperations; import org.jboss.as.plugin.deployment.Deploy; import org.jboss.as.plugin.deployment.Deployment; import org.jboss.as.plugin.deployment.standalone.StandaloneDeployment; /** * Starts a standalone instance of JBoss Application Server 7 and deploys the application to the server. * <p/> * This goal will block until cancelled or a shutdown is invoked from a management client. * * @author Stuart Douglas * @author <a href="mailto:jperkins@redhat.com">James R. Perkins</a> */ @Mojo(name = "run", requiresDependencyResolution = ResolutionScope.RUNTIME) @Execute(phase = LifecyclePhase.PACKAGE) public class Run extends Deploy { public static final String JBOSS_DIR = "jboss-as-run"; @Component private ArtifactResolver artifactResolver; /** * The JBoss Application Server's home directory. If not used, JBoss Application Server will be downloaded. */ @Parameter(alias = "jboss-home", property = PropertyNames.JBOSS_HOME) private String jbossHome; /** * A string of the form groupId:artifactId:version[:packaging][:classifier]. Any missing portion of the artifact * will be replaced with the it's appropriate default property value */ @Parameter(property = PropertyNames.JBOSS_ARTIFACT) private String artifact; /** * The {@code groupId} of the artifact to download. Ignored if {@link #artifact} {@code groupId} portion is used. */ @Parameter(defaultValue = Defaults.JBOSS_AS_GROUP_ID, property = PropertyNames.JBOSS_GROUP_ID) private String groupId; /** * The {@code artifactId} of the artifact to download. Ignored if {@link #artifact} {@code artifactId} portion is * used. */ @Parameter(defaultValue = Defaults.JBOSS_AS_ARTIFACT_ID, property = PropertyNames.JBOSS_ARTIFACT_ID) private String artifactId; /** * The {@code classifier} of the artifact to download. Ignored if {@link #artifact} {@code classifier} portion is * used. */ @Parameter(property = PropertyNames.JBOSS_CLASSIFIER) private String classifier; /** * The {@code packaging} of the artifact to download. Ignored if {@link #artifact} {@code packing} portion is used. */ @Parameter(property = PropertyNames.JBOSS_PACKAGING, defaultValue = Defaults.JBOSS_AS_PACKAGING) private String packaging; /** * The {@code version} of the artifact to download. Ignored if {@link #artifact} {@code version} portion is used. */ @Parameter(alias = "jboss-as-version", defaultValue = Defaults.JBOSS_AS_TARGET_VERSION, property = PropertyNames.JBOSS_VERSION) private String version; /** * The modules path or paths to use. A single path can be used or multiple paths by enclosing them in a paths * element. */ @Parameter(alias = "modules-path", property = PropertyNames.MODULES_PATH) private ModulesPath modulesPath; /** * The bundles path to use. */ @Parameter(alias = "bundles-path", property = PropertyNames.BUNDLES_PATH) private String bundlesPath; /** * A space delimited list of JVM arguments. * <p/> * Default value is {@code -Xms64m -Xmx512m -XX:MaxPermSize=256m -Djava.net.preferIPv4Stack=true * -Dorg.jboss.resolver.warning=true -Dsun.rmi.dgc.client.gcInterval=3600000 -Dsun.rmi.dgc.server.gcInterval=3600000} */ @Parameter(alias = "jvm-args", property = PropertyNames.JVM_ARGS) private JavaOpts jvmArgs; /** * The {@code JAVA_HOME} to use for launching the server. */ @Parameter(alias = "java-home", property = PropertyNames.JAVA_HOME) private String javaHome; /** * The path to the server configuration to use. */ @Parameter(alias = "server-config", property = PropertyNames.SERVER_CONFIG) private String serverConfig; /** * The path to the system properties file to load. */ @Parameter(alias = "properties-file", property = PropertyNames.PROPERTIES_FILE) private String propertiesFile; /** * A space delimited list of server arguments. */ @Parameter(alias = "server-args", property = PropertyNames.SERVER_ARGS) private String[] serverArgs; /** * The arguments to be passed to the server. */ @Parameter(alias = "startup-timeout", defaultValue = Defaults.TIMEOUT, property = PropertyNames.STARTUP_TIMEOUT) private long startupTimeout; @Override protected void doExecute() throws MojoExecutionException, MojoFailureException { final Log log = getLog(); final File deploymentFile = file(); final String deploymentName = deploymentFile.getName(); final File targetDir = deploymentFile.getParentFile(); // The deployment must exist before we do anything if (!deploymentFile.exists()) { throw new MojoExecutionException( String.format("The deployment '%s' could not be found.", deploymentFile.getAbsolutePath())); } // Validate the environment final File jbossHome = extractIfRequired(targetDir); if (!jbossHome.isDirectory()) { throw new MojoExecutionException(String.format("JBOSS_HOME '%s' is not a valid directory.", jbossHome)); } final String javaHome; if (this.javaHome == null) { javaHome = SecurityActions.getEnvironmentVariable("JAVA_HOME"); } else { javaHome = this.javaHome; } final List<String> invalidPaths = modulesPath.validate(); if (!invalidPaths.isEmpty()) { throw new MojoExecutionException("Invalid module path(s). " + invalidPaths); } final ServerConfig serverConfig = ServerConfig.of(this, jbossHome).setJavaHome(javaHome) .setModulesDir(modulesPath.get()).setBundlesDir(bundlesPath).setJvmArgs(jvmArgs.getArgs()) .setServerConfig(this.serverConfig).setPropertiesFile(propertiesFile).setServerArgs(serverArgs) .setStartupTimeout(startupTimeout); // Print some server information log.info(String.format("JAVA_HOME=%s", javaHome)); log.info(String.format("JBOSS_HOME=%s%n", jbossHome)); try { // Create the server final Server server = new StandaloneServer(serverConfig); // Add the shutdown hook SecurityActions.registerShutdown(server); // Start the server log.info("Server is starting up. Press CTRL + C to stop the server."); server.start(); // Deploy the application server.checkServerState(); if (server.isRunning()) { log.info(String.format("Deploying application '%s'%n", deploymentFile.getName())); final ModelControllerClient client = server.getClient(); final Deployment deployment = StandaloneDeployment.create(client, deploymentFile, deploymentName, getType(), null, null); switch (executeDeployment(client, deployment)) { case REQUIRES_RESTART: { client.execute(ServerOperations.createOperation(ServerOperations.RELOAD)); break; } case SUCCESS: break; } } else { throw new DeploymentFailureException("Cannot deploy to a server that is not running."); } while (server.isRunning()) { TimeUnit.SECONDS.sleep(1L); } server.stop(); } catch (Exception e) { throw new MojoExecutionException("The server failed to start", e); } } private File extractIfRequired(final File buildDir) throws MojoFailureException, MojoExecutionException { if (jbossHome != null) { //we do not need to download JBoss return new File(jbossHome); } final File result = artifactResolver.resolve(project, createArtifact()); final File target = new File(buildDir, JBOSS_DIR); // Delete the target if it exists if (target.exists()) { Files.deleteRecursively(target); } target.mkdirs(); try { Files.unzip(result, target); } catch (IOException e) { throw new MojoFailureException("Artifact was not successfully extracted: " + result, e); } final File[] files = target.listFiles(); if (files == null || files.length != 1) { throw new MojoFailureException("Artifact was not successfully extracted: " + result); } // Assume the first return files[0]; } @Override public String goal() { return "run"; } private String createArtifact() throws MojoFailureException { String groupId = this.groupId; String artifactId = this.artifactId; String classifier = this.classifier; String packaging = this.packaging; String version = this.version; // groupId:artifactId:version[:packaging][:classifier]. if (artifact != null) { final String[] artifactParts = artifact.split(":"); if (artifactParts.length == 0) { throw new MojoFailureException(String.format("Invalid artifact pattern: %s", artifact)); } String value; switch (artifactParts.length) { case 5: value = artifactParts[4].trim(); if (!value.isEmpty()) { classifier = value; } case 4: value = artifactParts[3].trim(); if (!value.isEmpty()) { packaging = value; } case 3: value = artifactParts[2].trim(); if (!value.isEmpty()) { version = value; } case 2: value = artifactParts[1].trim(); if (!value.isEmpty()) { artifactId = value; } case 1: value = artifactParts[0].trim(); if (!value.isEmpty()) { groupId = value; } } } // Validate the groupId, artifactId and version are not null if (groupId == null || artifactId == null || version == null) { throw new IllegalStateException("The groupId, artifactId and version parameters are required"); } final StringBuilder result = new StringBuilder(); result.append(groupId).append(':').append(artifactId).append(':').append(version).append(':'); if (packaging != null) { result.append(packaging); } result.append(':'); if (classifier != null) { result.append(classifier); } return result.toString(); } }