如何从上游Web App创建JAR作为下游Web App的依赖关系

时间:2016-11-30 11:17:08

标签: maven netbeans web-applications netbeans-8

我(在其他模块中)有一个NetBeans8.1 Maven Web应用程序项目CoreWeb(已解析其他模块依赖项)独立运行,并且在任何情况下都应该至少构建其默认WAR并独立运行。

我有第二个依赖于CoreWeb的NetBeans8.1 Maven Web应用程序项目SpecWeb;它是重用CoreWeb中的两个JSF托管bean,也是利用CoreWeb的XHTML复合组件JSF资源。

但是在构建SpecWeb时它没有解析CoreWeb依赖关系,因为CoreWeb没有(默认情况下)构建一个JAR:

Failed to execute goal on project SpecWeb: Could not resolve dependencies 
for project com.example.multi:SpecWeb:war:1.0-SNAPSHOT: Could not find
artifact com.example.multi:CoreWeb:jar:1.0-SNAPSHOT -> [Help 1]

(我的项目的Ant版本存在多个模块的问题,并使用一小段Ant任务脚本解决它,从CoreWeb构建额外的JAR以便在SpecWeb中使用,运行得非常好。)

问:如何从CoreWeb生成JAR(以及WAR)以在SpecWeb中使用?

Project > Actions: Build Project下,我尝试为install操作添加了Build Project的各种其他目标(使用NetBeans提示功能)。

使用install jar:jar无效。它确实创建了一个JAR(以及WAR),但是JAR只包含托管bean类,而不是资源,而且从“下游”SpecWeb构建它仍然无法找到它:

$ jar tf target/CoreWeb-1.0-SNAPSHOT.jar 
META-INF/
META-INF/MANIFEST.MF
com/
com/example/
com/example/multi/
.. Java managed bean classes ..

META-INF/maven/
META-INF/maven/com.example.multi/
META-INF/maven/com.example.multi/CoreWeb/
META-INF/maven/com.example.multi/CoreWeb/pom.xml
META-INF/maven/com.example.multi/CoreWeb/pom.properties

如果我手动将pom.xml中的包装更改为jar,我会构建相同的JAR结构(没有JSF XHTML复合组件Web资源):

<groupId>com.example.multi</groupId>
<artifactId>CoreWeb</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>jar</packaging>
<!--
<packaging>war</packaging>
-->

编辑:重叠也无效(在NetBeans中)

我也尝试使用Overlays,但它没有按预期工作。尽快 当我将依赖项转换为类型war时NetBeans无法解析从SpecWeb导入到类中的CoreWeb中的类,甚至无法编译(并且由于导入失败,类文件具有NetBeans Java警告):< / p>

    <dependency>
        <groupId>${project.groupId}</groupId>
        <artifactId>CoreWeb</artifactId>
        <version>${project.version}</version>
        <type>war</type>
    </dependency>

此外,一旦我输入<type>war</type>,CoreWeb项目就会从项目导航器节点SpecWeb > Dependencies下的列表中消失。

还尝试了Warpath插件

NetBeans仍然没有看到CoreWeb中的类导入SpecWeb中的类,因此SpecWeb不会编译。

1 个答案:

答案 0 :(得分:0)

经过大量研究(主要是在Maven主站点上)和反复试验,我发现了一个与NetBeans兼容的强大解决方案。

战略的一般描述。诀窍是创建一个额外的“客户端”JAR版本的CoreWeb项目供SpecWeb项目临时使用(使NetBeans编辑器“看到”CoreWeb的类),并将其声明为仅“提供”范围的附加依赖项(因此它不会进入最终的SpecWeb WAR)。然后还使用overlays将CoreWeb的复合组件和CoreWeb的托管bean与SpecWeb项目组合到最终的WAR中,小心地从CoreWeb中排除index.xhtml。

<强>步骤

在CoreWeb的pom.xml中包括:

        <!-- Also make JAR form using classifier during package phase -->
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-jar-plugin</artifactId>
            <version>3.0.2</version>
            <executions>
                <execution>
                    <phase>package</phase>
                    <goals>
                        <goal>jar</goal>
                    </goals>
                    <configuration>                
                        <classifier>client</classifier>
                    </configuration>
                </execution>
            </executions>
        </plugin>

在构建时,这将创建:

 $ ls -1 CoreWeb/target/CoreW*
 CoreWeb/target/CoreWeb-1.0-SNAPSHOT-client.jar
 CoreWeb/target/CoreWeb-1.0-SNAPSHOT.war

 CoreWeb/target/CoreWeb-1.0-SNAPSHOT:
 META-INF/
 WEB-INF/
 index.xhtml
 resources/

(注意NetBeans可以直接在CoreWeb/target/CoreWeb-1.0-SNAPSHOT上使用自己的index.xhtml独立运行CoreWeb。)

然后,SpecWeb可以在其pom.xml中使用CoreWeb-1.0-SNAPSHOT-client.jar:

<dependencies>

   ...

    <!-- This is needed for the editor and for the compilation only (not at runtime) -->
    <dependency>
        <groupId>${project.groupId}</groupId>
        <artifactId>CoreWeb</artifactId>
        <version>${project.version}</version>
        <type>jar</type>
        <classifier>client</classifier>
        <scope>provided</scope> <!-- To prevent being written even to target folder -->
    </dependency>

    <!-- This is needed for the overlay -->
    <dependency>
        <groupId>${project.groupId}</groupId>
        <artifactId>CoreWeb</artifactId>
        <version>${project.version}</version>
        <type>war</type>
        <scope>runtime</scope>
    </dependency>

请注意SpecWeb在CoreWeb上有两种不同类型的依赖关系:

  • 使用分类器CoreWeb-1.0-SNAPSHOT-client.jar和范围clientruntime的依赖(因此它根本不会包含在/ target下)。 这将显示在特殊节点非路径依赖性下的NetBeans项目窗口中,并清楚地表明它仅适用于[runtime]

  • 要使用的叠加层CoreWeb-1.0-SNAPSHOT.war的依赖关系。这将显示在节点依赖关系下的NetBeans项目窗口中。

然后在SpecWeb的pom.xml中指定叠加层(不包括CoreWeb的index.html)和打包(确保excluding任何“客户端”罐子):

  <build>
     <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-war-plugin</artifactId>
            <version>3.0.0</version>
            <configuration>
                <failOnMissingWebXml>false</failOnMissingWebXml>

                <packagingExcludes>WEB-INF/lib/*-client.jar</packagingExcludes>

                <overlays>
                    <overlay>
                        <groupId>${project.groupId}</groupId>
                        <artifactId>CoreWeb</artifactId>
                        <excludes>
                            <exclude>index.xhtml</exclude>
                        </excludes>                            
                    </overlay>
                    <overlay>
                        <!-- empty groupId/artifactId represents the current build -->
                    </overlay>
                </overlays>
            </configuration>
        </plugin>

SpecWeb项目在NetBeans编辑器中行为正常(可以看到来自CoreWeb的类),编译正常,可以通过SpecWeb/target/SpecWeb-1.0-SNAPSHOT运行index.html,同时可以访问两个JSF托管bean和CoreWeb的JSF复合组件。

CAVEAT:当从SpecWeb编辑JSF页面时,NetBeans XHTML编辑器会抱怨CoreWeb提供的复合组件由于这个已知的NetBeans Bug 257684 - JSF 2 composite components in JAR are not recognized 而不存在,但该项目仍然可以运行。