Author: olamy Date: Mon Oct 17 09:15:57 2011 New Revision: 1185051 URL: http://svn.apache.org/viewvc?rev=1185051&view=rev Log: [MTOMCAT-102] Add a mojo to build a standalone jar to run a web application: add possibility to use a pom project which configured war dependencies to add in the generated exec jar.
Added: tomcat/maven-plugin/trunk/tomcat7-maven-plugin/src/main/java/org/apache/tomcat/maven/plugin/tomcat7/run/WarRunDependency.java (with props) Modified: tomcat/maven-plugin/trunk/tomcat7-maven-plugin/src/main/java/org/apache/tomcat/maven/plugin/tomcat7/run/AbstractExecWarMojo.java tomcat/maven-plugin/trunk/tomcat7-war-runner/NOTES.TXT tomcat/maven-plugin/trunk/tomcat7-war-runner/src/main/java/org/apache/tomcat/maven/runner/Tomcat7Runner.java tomcat/maven-plugin/trunk/tomcat7-war-runner/src/main/java/org/apache/tomcat/maven/runner/Tomcat7RunnerCli.java Modified: tomcat/maven-plugin/trunk/tomcat7-maven-plugin/src/main/java/org/apache/tomcat/maven/plugin/tomcat7/run/AbstractExecWarMojo.java URL: http://svn.apache.org/viewvc/tomcat/maven-plugin/trunk/tomcat7-maven-plugin/src/main/java/org/apache/tomcat/maven/plugin/tomcat7/run/AbstractExecWarMojo.java?rev=1185051&r1=1185050&r2=1185051&view=diff ============================================================================== --- tomcat/maven-plugin/trunk/tomcat7-maven-plugin/src/main/java/org/apache/tomcat/maven/plugin/tomcat7/run/AbstractExecWarMojo.java (original) +++ tomcat/maven-plugin/trunk/tomcat7-maven-plugin/src/main/java/org/apache/tomcat/maven/plugin/tomcat7/run/AbstractExecWarMojo.java Mon Oct 17 09:15:57 2011 @@ -26,10 +26,16 @@ import org.apache.commons.io.FileUtils; import org.apache.commons.io.IOUtils; import org.apache.commons.lang.StringUtils; import org.apache.maven.artifact.Artifact; +import org.apache.maven.artifact.factory.ArtifactFactory; +import org.apache.maven.artifact.repository.ArtifactRepository; +import org.apache.maven.artifact.resolver.ArtifactNotFoundException; +import org.apache.maven.artifact.resolver.ArtifactResolutionException; +import org.apache.maven.artifact.resolver.ArtifactResolver; import org.apache.maven.model.Dependency; import org.apache.maven.plugin.MojoExecutionException; import org.apache.maven.plugin.MojoFailureException; import org.apache.maven.project.MavenProject; +import org.apache.maven.settings.MavenSettingsBuilder; import org.apache.tomcat.maven.plugin.tomcat7.AbstractTomcat7Mojo; import org.apache.tomcat.maven.runner.Tomcat7Runner; import org.apache.tomcat.maven.runner.Tomcat7RunnerCli; @@ -63,7 +69,7 @@ public abstract class AbstractExecWarMoj * @required * @readonly */ - private Artifact artifact; + private Artifact projectArtifact; /** * The maven project. @@ -118,6 +124,40 @@ public abstract class AbstractExecWarMoj */ protected String path; + /** + * @parameter + */ + protected List<WarRunDependency> warRunDependencies; + + /** + * @component + */ + protected ArtifactResolver artifactResolver; + + /** + * Maven Artifact Factory component. + * + * @component + */ + private ArtifactFactory artifactFactory; + + /** + * Location of the local repository. + * + * @parameter expression="${localRepository}" + * @readonly + * @required + */ + private ArtifactRepository local; + + /** + * List of Remote Repositories used by the resolver + * + * @parameter expression="${project.remoteArtifactRepositories}" + * @readonly + * @required + */ + protected List<ArtifactRepository> remoteRepos; public void execute() throws MojoExecutionException, MojoFailureException @@ -142,11 +182,20 @@ public abstract class AbstractExecWarMoj try { - tmpPropertiesFile = File.createTempFile( "war-exec", "properties" ); - tmpPropertiesFile.deleteOnExit(); - tmpManifestFile = File.createTempFile( "war-exec", "manifest" ); - tmpManifestFile.deleteOnExit(); + tmpPropertiesFile = new File( buildDirectory, "war-exec.properties" ); + if ( tmpPropertiesFile.exists() ) + { + tmpPropertiesFile.delete(); + } + tmpPropertiesFile.getParentFile().mkdirs(); + + tmpManifestFile = new File( buildDirectory, "war-exec.manifest" ); + if ( tmpManifestFile.exists() ) + { + tmpManifestFile.delete(); + } tmpPropertiesFileOutputStream = new FileOutputStream( tmpPropertiesFile ); + execWarJar.getParentFile().mkdirs(); execWarJar.createNewFile(); execWarJarOutputStream = new FileOutputStream( execWarJar ); @@ -158,19 +207,53 @@ public abstract class AbstractExecWarMoj //* tomcat jars //* file tomcat.standalone.properties with possible values : // * useServerXml=true/false to use directly the one provided - // * wars=foo.war;bar.war + // * wars=foo.war|contextpath;bar.war ( |contextpath is optionnal if empty use the war name ) //* optionnal: conf/ with usual tomcat configuration files //* MANIFEST with Main-Class + Properties properties = new Properties( ); + os = new ArchiveStreamFactory().createArchiveOutputStream(ArchiveStreamFactory.JAR, execWarJarOutputStream); - // TODO control project packaging is war - os.putArchiveEntry( new JarArchiveEntry( path + ".war" ) ); - IOUtils.copy( new FileInputStream(artifact.getFile()), os ); - os.closeArchiveEntry(); + if ( "war".equals( project.getPackaging() ) ) + { + os.putArchiveEntry( new JarArchiveEntry( path + ".war" ) ); + IOUtils.copy( new FileInputStream(projectArtifact.getFile()), os ); + os.closeArchiveEntry(); + properties.put( Tomcat7Runner.WARS_KEY , path + ".war|" + path ); + } - Properties properties = new Properties( ); + if ( "pom".equals( project.getPackaging() ) && ( warRunDependencies != null && !warRunDependencies.isEmpty() ) ) + { + for (WarRunDependency warRunDependency : warRunDependencies ) + { + if ( warRunDependency.dependency != null ) + { + Dependency dependency = warRunDependency.dependency; + // String groupId, String artifactId, String version, String scope, String type + Artifact artifact = + artifactFactory.createArtifact( dependency.getGroupId(), dependency.getArtifactId(), dependency.getVersion(), dependency.getScope(), dependency.getType() ); + + artifactResolver.resolve( artifact, this.remoteRepos , this.local ); + os.putArchiveEntry( new JarArchiveEntry( artifact.getFile().getName() ) ); + IOUtils.copy( new FileInputStream(artifact.getFile()), os ); + os.closeArchiveEntry(); + String propertyWarValue = properties.getProperty( Tomcat7Runner.WARS_KEY ); + // FIXME check contextPath is not empty or at least only / for root app + if (propertyWarValue != null ) + { + properties.put( Tomcat7Runner.WARS_KEY , propertyWarValue + ";" + artifact.getFile().getName() + "|" + warRunDependency.contextPath ); + } + else + { + properties.put( Tomcat7Runner.WARS_KEY , artifact.getFile().getName() + "|" + warRunDependency.contextPath ); + } + } + } + } + + // FIXME if no war has been added here we must stop with a human readable and user friendly error message if (serverXml != null && serverXml.exists() ) @@ -184,7 +267,7 @@ public abstract class AbstractExecWarMoj properties.put(Tomcat7Runner.USE_SERVER_XML_KEY, Boolean.FALSE.toString() ); } - properties.put( Tomcat7Runner.WARS_KEY , path + ".war" ); + properties.store( tmpPropertiesFileOutputStream, "created by Apache Tomcat Maven plugin" ); tmpPropertiesFileOutputStream.flush(); @@ -240,13 +323,18 @@ public abstract class AbstractExecWarMoj } catch ( ArchiveException e ) { throw new MojoExecutionException( e.getMessage(), e ); + } catch ( ArtifactNotFoundException e ) + { + throw new MojoExecutionException( e.getMessage(), e ); + } catch ( ArtifactResolutionException e ) + { + throw new MojoExecutionException( e.getMessage(), e ); + } finally { IOUtils.closeQuietly( os ); IOUtils.closeQuietly( tmpManifestWriter ); IOUtils.closeQuietly( execWarJarOutputStream ); IOUtils.closeQuietly(tmpPropertiesFileOutputStream); - FileUtils.deleteQuietly(tmpPropertiesFile); - FileUtils.deleteQuietly( tmpManifestFile ); } } } Added: tomcat/maven-plugin/trunk/tomcat7-maven-plugin/src/main/java/org/apache/tomcat/maven/plugin/tomcat7/run/WarRunDependency.java URL: http://svn.apache.org/viewvc/tomcat/maven-plugin/trunk/tomcat7-maven-plugin/src/main/java/org/apache/tomcat/maven/plugin/tomcat7/run/WarRunDependency.java?rev=1185051&view=auto ============================================================================== --- tomcat/maven-plugin/trunk/tomcat7-maven-plugin/src/main/java/org/apache/tomcat/maven/plugin/tomcat7/run/WarRunDependency.java (added) +++ tomcat/maven-plugin/trunk/tomcat7-maven-plugin/src/main/java/org/apache/tomcat/maven/plugin/tomcat7/run/WarRunDependency.java Mon Oct 17 09:15:57 2011 @@ -0,0 +1,39 @@ +package org.apache.tomcat.maven.plugin.tomcat7.run; +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import org.apache.maven.model.Dependency; + +/** + * @author Olivier Lamy + * @since 2.0 + */ +public class WarRunDependency +{ + + public Dependency dependency; + + public String contextPath; + + public WarRunDependency() + { + // no op + } + +} Propchange: tomcat/maven-plugin/trunk/tomcat7-maven-plugin/src/main/java/org/apache/tomcat/maven/plugin/tomcat7/run/WarRunDependency.java ------------------------------------------------------------------------------ svn:eol-style = native Propchange: tomcat/maven-plugin/trunk/tomcat7-maven-plugin/src/main/java/org/apache/tomcat/maven/plugin/tomcat7/run/WarRunDependency.java ------------------------------------------------------------------------------ svn:keywords = Author Date Id Revision Modified: tomcat/maven-plugin/trunk/tomcat7-war-runner/NOTES.TXT URL: http://svn.apache.org/viewvc/tomcat/maven-plugin/trunk/tomcat7-war-runner/NOTES.TXT?rev=1185051&r1=1185050&r2=1185051&view=diff ============================================================================== --- tomcat/maven-plugin/trunk/tomcat7-war-runner/NOTES.TXT (original) +++ tomcat/maven-plugin/trunk/tomcat7-war-runner/NOTES.TXT Mon Oct 17 09:15:57 2011 @@ -21,7 +21,7 @@ The generated standalone jar will contai * file tomcat.standalone.properties with possible values : * useServerXml=true/false to use directly the one provided in the maven plugin configuration - * wars=foo.war;bar.war + * wars=foo.war|contextpath;bar.war ( |contextpath is optionnal if empty use the war name) * optionnal: conf/ with usual tomcat configuration files Modified: tomcat/maven-plugin/trunk/tomcat7-war-runner/src/main/java/org/apache/tomcat/maven/runner/Tomcat7Runner.java URL: http://svn.apache.org/viewvc/tomcat/maven-plugin/trunk/tomcat7-war-runner/src/main/java/org/apache/tomcat/maven/runner/Tomcat7Runner.java?rev=1185051&r1=1185050&r2=1185051&view=diff ============================================================================== --- tomcat/maven-plugin/trunk/tomcat7-war-runner/src/main/java/org/apache/tomcat/maven/runner/Tomcat7Runner.java (original) +++ tomcat/maven-plugin/trunk/tomcat7-war-runner/src/main/java/org/apache/tomcat/maven/runner/Tomcat7Runner.java Mon Oct 17 09:15:57 2011 @@ -29,6 +29,8 @@ import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; +import java.util.HashMap; +import java.util.Map; import java.util.Properties; import java.util.StringTokenizer; @@ -58,12 +60,19 @@ public class Tomcat7Runner public boolean resetExtract; + public boolean debug = false; + public File extractDirectory = new File( ".extract" ); Catalina container; Tomcat tomcat; + /** + * key = context of the webapp, value = war path on file system + */ + Map<String, String> webappWarPerContext = new HashMap<String,String>(); + public Tomcat7Runner() { // no op @@ -83,7 +92,7 @@ public class Tomcat7Runner // start with a server.xml - if ( serverXmlPath != null || Boolean.parseBoolean( runtimeProperties.getProperty( USE_SERVER_XML_KEY )) ) + if ( serverXmlPath != null || useServerXml() ) { container = new Catalina(); // FIXME get this from runtimeProperties ? @@ -150,6 +159,19 @@ public class Tomcat7Runner tomcat.getService().addConnector( ajpConnector ); } + // add webapps + for ( Map.Entry< String, String> entry : this.webappWarPerContext.entrySet() ) + { + if ( entry.getKey().equals( "/" )) + { + tomcat.addWebapp( entry.getKey(), new File( extractDirectory, "webapps/ROOT.war" ).getAbsolutePath() ); + } else + { + tomcat.addWebapp( entry.getKey(), new File( extractDirectory, "webapps/" + entry.getValue() ).getAbsolutePath() ); + } + + } + tomcat.start(); } @@ -205,16 +227,29 @@ public class Tomcat7Runner new File( extractDirectory, "work") .mkdirs(); String wars = runtimeProperties.getProperty( WARS_KEY ); - StringTokenizer st = new StringTokenizer( wars,";" ); - while (st.hasMoreTokens()) + populateWebAppWarPerContext( wars ); + + + for ( Map.Entry<String,String> entry : webappWarPerContext.entrySet() ) { + debugMessage( "webappWarPerContext entry key/value: " + entry.getKey() + "/" + entry.getValue() ); InputStream inputStream = null; try { - String war = st.nextToken(); inputStream = - Thread.currentThread().getContextClassLoader().getResourceAsStream( war ); - expand( inputStream, new File( extractDirectory, "webapps/" + war ) ); + Thread.currentThread().getContextClassLoader().getResourceAsStream( entry.getValue() ); + if ( !useServerXml() ) + { + if ( entry.getKey().equals( "/" )) + { + expand( inputStream, new File( extractDirectory, "webapps/ROOT.war" ) ); + } else + { + expand( inputStream, new File( extractDirectory, "webapps/" + entry.getValue() ) ); + } + } else { + expand( inputStream, new File( extractDirectory, "webapps/" + entry.getValue() ) ); + } } finally { if ( inputStream != null ) { @@ -256,6 +291,35 @@ public class Tomcat7Runner } /** + * @param warsValue we can value in format: wars=foo.war|contextpath;bar.war ( |contextpath is optionnal if empty use the war name) + * so here we return war file name and populate webappWarPerContext + */ + private void populateWebAppWarPerContext( String warsValue ) + { + StringTokenizer st = new StringTokenizer( warsValue,";" ); + while ( st.hasMoreTokens() ) + { + String warValue = st.nextToken(); + debugMessage( "populateWebAppWarPerContext warValue:" + warValue ); + String warFileName = ""; + String contextValue = ""; + int separatorIndex = warValue.indexOf( "|" ); + if ( separatorIndex >= 0 ) + { + warFileName = warValue.substring( 0, separatorIndex ); + contextValue = warValue.substring( separatorIndex + 1, warValue.length() ); + + } else + { + warFileName = contextValue; + } + debugMessage( "populateWebAppWarPerContext contextValue/warFileName:" + contextValue + "/" + warFileName ); + this.webappWarPerContext.put( contextValue, warFileName ); + } + } + + + /** * Expand the specified input stream into the specified file. * * @param input InputStream to be copied @@ -288,4 +352,17 @@ public class Tomcat7Runner } } + public boolean useServerXml() + { + return Boolean.parseBoolean( runtimeProperties.getProperty( USE_SERVER_XML_KEY )); + } + + + public void debugMessage( String message ) + { + if ( debug ) + { + System.out.println(message); + } + } } Modified: tomcat/maven-plugin/trunk/tomcat7-war-runner/src/main/java/org/apache/tomcat/maven/runner/Tomcat7RunnerCli.java URL: http://svn.apache.org/viewvc/tomcat/maven-plugin/trunk/tomcat7-war-runner/src/main/java/org/apache/tomcat/maven/runner/Tomcat7RunnerCli.java?rev=1185051&r1=1185050&r2=1185051&view=diff ============================================================================== --- tomcat/maven-plugin/trunk/tomcat7-war-runner/src/main/java/org/apache/tomcat/maven/runner/Tomcat7RunnerCli.java (original) +++ tomcat/maven-plugin/trunk/tomcat7-war-runner/src/main/java/org/apache/tomcat/maven/runner/Tomcat7RunnerCli.java Mon Oct 17 09:15:57 2011 @@ -61,22 +61,25 @@ public class Tomcat7RunnerCli .create("serverXmlPath"); static Option resetExtract = OptionBuilder.withArgName("resetExtract") - .hasArg() .withDescription("clean previous extract directory") .create("resetExtract"); static Option help = OptionBuilder .withLongOpt( "help" ) - .hasArg() .withDescription("help") .create("h"); + static Option debug = OptionBuilder + .withLongOpt( "debug" ) + .withDescription("debug") + .create("x"); + static Options options = new Options(); static { options.addOption( httpPort ).addOption( httpsPort ).addOption( ajpPort ).addOption( serverXmlPath ) - .addOption( resetExtract ).addOption( help ); + .addOption( resetExtract ).addOption( help ).addOption( debug ); } @@ -129,6 +132,10 @@ public class Tomcat7RunnerCli { tomcat7Runner.resetExtract = true; } + if ( line.hasOption( debug.getOpt() ) ) + { + tomcat7Runner.debug = true; + } // here we go tomcat7Runner.run(); } --------------------------------------------------------------------- To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org For additional commands, e-mail: dev-h...@tomcat.apache.org