Java tutorial
/* * JBoss, Home of Professional Open Source. * Copyright 2013, 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 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.Mojo; import org.apache.maven.plugins.annotations.Parameter; import org.apache.maven.plugins.annotations.ResolutionScope; import org.apache.maven.project.MavenProject; import org.jboss.as.plugin.common.AbstractServerMojo; import org.jboss.as.plugin.common.Files; import org.jboss.as.plugin.common.PropertyNames; /** * Starts a standalone instance of JBoss Application Server 7. * <p/> * The purpose of this goal is to start a JBoss Application Server for testing during the maven lifecycle. This can * start a remote server, but the server will be shutdown when the maven process ends. * * @author <a href="mailto:jperkins@redhat.com">James R. Perkins</a> */ @Mojo(name = "start", requiresDependencyResolution = ResolutionScope.RUNTIME) public class Start extends AbstractServerMojo { public static final String JBOSS_DIR = "jboss-as-run"; /** * The project */ @Parameter(defaultValue = "${project}", readonly = true, required = true) protected MavenProject project; /** * The target directory the application to be deployed is located. */ @Parameter(defaultValue = "${project.build.directory}", readonly = true, required = true) private File targetDir; @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 public void execute() throws MojoExecutionException, MojoFailureException { final Log log = getLog(); if (isSkip()) { log.debug("Skipping server start"); return; } // 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."); server.start(); server.checkServerState(); } 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 "start"; } 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(); } }