Maven Jetty插件,如何在依赖项目中热部署代码更改?

时间:2014-01-04 07:00:43

标签: eclipse maven jetty

我有一个war项目依赖于同一目录中的另一个jar项目。 现在我想用maven在jetty中启动war项目,并希望它在依赖项目中进行热交换更改,以便chagnes立即生效。我的插件配置如下所示:

        <plugin>
            <groupId>org.mortbay.jetty</groupId>
            <artifactId>maven-jetty-plugin</artifactId>
            <configuration>
                <webAppSourceDirectory>${project.basedir}/src/main/resources</webAppSourceDirectory>
                <classesDirectory>${project.basedir}/src/main/java</classesDirectory>

                <webApp>
                    <contextPath>/</contextPath>
                    <descriptor>${basedir}/src/main/resources/WEB-INF/web.xml</descriptor>
                </webApp>

            </configuration>
        </plugin>

我该怎么办?赞赏任何指针。

1 个答案:

答案 0 :(得分:2)

首先要指出的是......

您不希望这样做,因为Java本身很难支持JAR重新加载,它将倾向于在首次使用时缓存JAR及其内容(URLClassLoader的标准行为)。在运行时替换JAR需要额外的工作,有时甚至在不引起某种内存泄漏的情况下也是如此(请参阅the various Leak Preventers that Jetty ships with了解此区域中的一些隐藏的恶意内容)。如果你依赖它,请为OOM或其他问题做好准备。

现在,开始了......

Jetty上的热部署通过检测/扫描webapp中的更改并执行webapp重启来实现。

这适用于内容,如html,js,css等。

项目JAR依赖项将作为WEB-INF/lib结构的一部分结束,它是Jetty WebAppContext的[WebAppClassLoader]的一部分。 此WebAppClassLoader由Maven的工件解析系统提供的信息填充,该系统在正常的命令行构建中通过Maven本地存储库系统解析为内容。如果您正在使用Eclipse中的maven,那么这些工件的解析可能是Eclipse工作区中的其他项目(稍后会详细介绍)

为了演示,这是在webapp上每2秒扫描一次更改的最小配置。

  <plugin>
    <groupId>org.eclipse.jetty</groupId>
    <artifactId>jetty-maven-plugin</artifactId>
    <version>9.1.0.v20131115</version>
    <configuration>
      <scanIntervalSeconds>2</scanIntervalSeconds>
      <webAppConfig>
        <contextPath>/</contextPath>
      </webAppConfig>
    </configuration>
  </plugin>

假设您有一个依赖项目,一个jar文件,位于maven工件坐标com.company:component:jar:1.0-SNAPSHOT下。

这意味着WebAppContext加载了对file://${user.dir}/.m2/repository/com/company/component/1.0-SNAPSHOT/component-1.0-SNAPSHOT.jar URL的WebAppClassLoader引用,只有对该文件的更改才会导致热部署/重新加载。

/component/目录的命令行上,只需发出mvn clean install并查看您的webapp重新加载即可,但在Eclipse及其m2e插件下,代码更改为component项目不会自动表示对本地存储库中jar文件的更改。

实际上,m2e可以配置为通过本地存储库替换eclipse工作区中的maven工件。您需要了解这些设置才能在热部署/重新加载过程中取得成功。

提示您查找有效的WebAppClassloader内容

将以下文件添加到war项目中。

src/main/jetty/dump.xml

<?xml version="1.0"?>
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN"
     "http://www.eclipse.org/jetty/configure_9_0.dtd">

<Configure id="Server" class="org.eclipse.jetty.server.Server">
    <Set name="dumpAfterStart">true</Set>
</Configure>

并更改您的jetty-maven-plugin配置以添加...

  <plugin>
    <groupId>org.eclipse.jetty</groupId>
    <artifactId>jetty-maven-plugin</artifactId>
    <configuration>
      ...
      <jettyXml>src/main/jetty/dump.xml</jettyXml>
    </configuration>
  </plugin>

现在,当您的服务器启动时,请查找额外的输出,尤其是WebAppClassLoader引用。

...(snip)...
 |   |       |
 |   |       +> WebAppClassLoader=Web App Live@39714203
 |   |       |   +- file:/home/joakim/code/stackoverflow/samples/webapp-live/target/classes/
 |   |       |   +- file:/home/joakim/.m2/repository/org/eclipse/jetty/demo/component/1.0-SNAPSHOT/component-1.0-SNAPSHOT.jar
 |   |       |   +- ClassRealm[plugin>org.eclipse.jetty:jetty-maven-plugin:9.1.0.v20131115, parent: sun.misc.Launcher$AppClassLoader@77fe0d66]
...(/snip)...

您可以看到我的jetty:run通过本地存储库引用了component