好的,我正在尝试创建一个可以使用Maven从命令行运行的war文件。
<plugin>
<artifactId>maven-war-plugin</artifactId>
<version>2.6</version>
<configuration>
<warName>${project.artifactId}-${project.version}</warName>
<warSourceDirectory>src\main\java\META-INF\webapp\WEB-INF</warSourceDirectory>
<webXml>src\main\java\META-INF\webapp\WEB-INF\web.xml</webXml>
<archive>
<manifest>
<mainClass>classes\ReportToolRunner</mainClass>
<addClasspath>true</addClasspath>
</manifest>
</archive>
</configuration>
<executions>
<execution>
<id>default-war</id>
<phase>package</phase>
<goals>
<goal>war</goal>
</goals>
</execution>
</executions>
</plugin>
当我运行已编译的war文件时,我得到“错误:无法找到或加载主类类\ ReportToolRunner”,我已经为&lt; \ mainClass&gt;尝试了各种不同的路径。标签
我不想使用tomcat或类似的东西来运行战争,我只是希望能够像以下一样运行它:
java -jar reportTool.war
我正在使用Jetty作为我的网络服务器。
答案 0 :(得分:4)
如果您嵌入像Jetty这样的servlet容器,那么这是可能的: Embedded Jetty Executable War
注意:可运行的战争并不常见。 (例如Jenkins这样做 - 它允许用户决定是否运行standealone应用程序 - 可能用于某些产品评估,不应安装其他基础结构 - 或者将其部署在(共享)servlet容器上,该容器将被管理并且监测)
<强>解决方案:强> 以下步骤是必要的,可以使用标准Maven插件实现:
<plugin>
<artifactId>maven-antrun-plugin</artifactId>
<executions>
<execution>
<id>classes-copy</id>
<phase>prepare-package</phase>
<configuration>
<tasks>
<move todir="${project.build.directory}/${project.artifactId}-${project.version}/">
<fileset dir="${project.build.directory}/classes/">
<include name="your.package.Main.class" />
</fileset>
</move>
</tasks>
</configuration>
<goals>
<goal>run</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<version>2.3</version>
<executions>
<execution>
<id>jetty-classpath</id>
<phase>prepare-package</phase>
<goals>
<goal>unpack-dependencies</goal>
</goals>
<configuration>
<includeGroupIds>org.eclipse.jetty,javax.servlet</includeGroupIds>
<outputDirectory>
${project.build.directory}/${project.artifactId}-${project.version}
</outputDirectory>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<artifactId>maven-war-plugin</artifactId>
<version>2.1.1</version>
<configuration>
<warName>${project.artifactId}-${project.version}</warName>
<archive>
<manifest>
<mainClass>your.package.Main</mainClass>
</manifest>
</archive>
</configuration>
<executions>
<execution>
<id>default-war</id>
<phase>package</phase>
<goals>
<goal>war</goal>
</goals>
</execution>
</executions>
</plugin>
这是我使用的服务器代码(Jetty版本8.1.0.v20120127)。它配置一个新的Jetty服务器并添加一个webapp上下文(参见最后的代码片段) - 如果配置正确,可以使用server.start()/ server.stop()启动和停止服务器:
// Create connector
SocketConnector connector = new SocketConnector();
connector.setMaxIdleTime(1000 * 60 * 60);
connector.setSoLingerTime(-1);
connector.setPort(8080);
// Create handler collection
ContextHandlerCollection contextHandlerCollection = new ContextHandlerCollection();
HandlerCollection handlerCollection = new HandlerCollection();
handlerCollection.setHandlers(new Handler[] { contextHandlerCollection });
// Add webapp context
context.setServer(server);
contextHandlerCollection.addHandler(context);
server.setConnectors(new Connector[] { connector });
server.setHandler(handlerCollection);
最后是webapp上下文代码:
public class ServerContextImpl extends WebAppContext {
private static final Logger LOGGER = Logger.getLogger(ServerContextImpl.class);
protected static final String[] JETTY_PLUS_CONFIGURATION_CLASSES;
static {
JETTY_PLUS_CONFIGURATION_CLASSES = new String[7];
JETTY_PLUS_CONFIGURATION_CLASSES[0] = "org.eclipse.jetty.webapp.WebInfConfiguration";
JETTY_PLUS_CONFIGURATION_CLASSES[1] = "org.eclipse.jetty.webapp.WebXmlConfiguration";
JETTY_PLUS_CONFIGURATION_CLASSES[2] = "org.eclipse.jetty.webapp.MetaInfConfiguration";
JETTY_PLUS_CONFIGURATION_CLASSES[3] = "org.eclipse.jetty.webapp.FragmentConfiguration";
JETTY_PLUS_CONFIGURATION_CLASSES[4] = "org.eclipse.jetty.plus.webapp.EnvConfiguration";
JETTY_PLUS_CONFIGURATION_CLASSES[5] = "org.eclipse.jetty.plus.webapp.PlusConfiguration";
JETTY_PLUS_CONFIGURATION_CLASSES[6] = "org.eclipse.jetty.webapp.JettyWebXmlConfiguration";
}
ServerContextImpl() {
setConfigurationClasses(JETTY_PLUS_CONFIGURATION_CLASSES);
setContextPath("/");
setWar(getWarLocation());
}
/**
* Returns the location of the war (a trick, which is necessary for executable
* wars please see: <a target="_blank" href=
* "http://uguptablog.blogspot.de/2012/09/embedded-jetty-executable-war-with.html"
* >Embedded Jetty with executable WAR</a>).
*
* @return The war location.
*/
protected String getWarLocation() {
ProtectionDomain protectionDomain = ServerImpl.class.getProtectionDomain();
URL location = protectionDomain.getCodeSource().getLocation();
return location.toExternalForm();
}
}
请注意getWarLocation()方法。它使用打包的战争本身作为位置。
答案 1 :(得分:3)
我最近对此进行了一些研究,并发现了大多数方法的缺陷(要么减慢构建(阴影,装配,依赖jar),要么过于冗长,要么不是自包含。
我发现这样做的好方法是spring-boot-maven-plugin
,它提供了最好的结果(快速构建,自包含,简单的设置)。就这么简单:
<packaging>war</packaging>
<build>
<outputDirectory>${basedir}/src/main/webapp/WEB-INF/classes</outputDirectory>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>1.4.3.RELEASE</version>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
<configuration>
<mainClass>com.MyMainClass</mainClass>
</configuration>
</plugin>
</plugins>
</build>
通过一些简单的调整,它甚至可以构建一个可以部署和执行的战争。
即使您的项目不使用Spring Boot,也可以使用此插件。
答案 2 :(得分:1)
我认为您使用<mainClass>
来自:http://maven.apache.org/shared/maven-archiver/examples/classpath.html
如果要创建可执行jar文件,则需要进行配置 相应的Maven Archiver。你需要告诉它哪个主类 使用。这是通过配置元素完成的。这是 一个示例pom.xml,配置为添加类路径并使用该类 fully.qualified.MainClass作为主类:
<project> ... <build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
...
<configuration>
<archive>
<manifest>
<addClasspath>true</addClasspath>
<mainClass>fully.qualified.MainClass</mainClass>
</manifest>
</archive>
</configuration>
...
</plugin>
</plugins> </build> ... <dependencies>
<dependency>
<groupId>commons-lang</groupId>
<artifactId>commons-lang</artifactId>
<version>2.1</version>
</dependency>
<dependency>
<groupId>org.codehaus.plexus</groupId>
<artifactId>plexus-utils</artifactId>
<version>1.1</version>
</dependency> </dependencies> ... </project>
使用上述配置生成的清单看起来像 这样:
清单 - 版本:1.0 Archiver-版本:Plexus Archiver创建者: Apache Maven $ {maven.version}内置:$ {user.name} Build-Jdk: $ {java.version} Main-Class:fully.qualified.MainClass Class-Path: plexus-utils-1.1.jar commons-lang-2.1.jar