使用Maven来创建“可运行的WAR". [英] Using Maven to create "runnable WAR"

查看:104
本文介绍了使用Maven来创建“可运行的WAR".的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

好的,我正在尝试创建一个可使用Maven从命令行运行的war文件.

Okay, I'm trying to create a war file that is runnable from the command line using Maven.

<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文件时,出现错误:找不到或加载主类class \ ReportToolRunner",我尝试了< \ mainClass>标记的所有不同路径.

When I run the compiled war file, I get "Error: Could not find or load main class classes\ReportToolRunner", I've tried all manner of different paths for the <\mainClass> tag.

我不想使用tomcat或类似的工具进行战争,我只想能够像这样进行战争:

I don't want to run the war using tomcat or anything like that, I just want to be able to run it like:

java -jar reportTool.war

我正在将Jetty用于我的Web服务器.

I'm using Jetty for my web server.

推荐答案

如果您嵌入了像Jetty这样的servlet容器,则有可能: 嵌入式码头可执行战.

It is possible, if you embed a servlet container like Jetty: Embedded Jetty Executable War.

注意:一场可战役的战争并不常见. (例如,詹金斯(Jenkins)这样做-它允许用户决定是独立运行应用程序-也许是为了进行某些产品评估,而不应该安装其他基础结构-还是将其部署在(共享的)servlet容器上,从而对其进行管理和管理.监视)

Note: A runnable war is not very common. (For example Jenkins did this - It allows the user to decide whether to run the application standealone - maybe for some product evaluation, where no further infrastructure should be installed - or to deploy it on a (shared) servlet container, which gets managed and monitored)

解决方案: 以下步骤是必需的,并且可以使用标准Maven插件来实现:

Solution: The following steps are necessary and can be achieved with standard Maven plugins:

  1. 编写一个Main类,该类将启动Jetty服务器并添加webapp上下文
  2. 在prepare-package阶段,将Main类和用于服务器的所有类从$ {project.build.directory}/classes/移至目标war目录,以实现jar布局(在war文件中,这些类是在类"文件夹中,但在jar文件中,这些类在根文件夹中)

<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>

  1. 将所有依赖项打包,这对于Jetty服务器启动是必需的,因此这些类是可执行文件大战的一部分. (您可以跳过此步骤,但是当以jar方式执行war时,这些依赖项必须在类路径上可用:java -cp< your classpath> -jar< your war>.(请注意:依赖项列表取决于在您的Jetty服务器实施中)

<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>

  1. 在清单中指定主类,以便可以将jar文件执行为war文件. (请注意:我还指定了战争名称.此名称在以前的插件配置中用作"move todir"和"outputDirectory"的一部分)

<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()启动和停止该服务器:

Here is the server code (Jetty version 8.1.0.v20120127) I used. It configures a new Jetty server and adds a webapp context (see last code snippet) - if configured correctly the server can be started and stopped with 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上下文代码:

And finally the webapp context code:

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()方法.它使用打包的战争本身作为位置.

Please note the getWarLocation() method. It uses the packaged war itself as location.

这篇关于使用Maven来创建“可运行的WAR".的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆