这个问题有点像“最佳实践”问题,我的团队是Maven的新手,我正在寻找关于这个主题的最佳方法:
在处理包装为war
的项目时,将其部署到Maven存储库(例如公司范围内的Nexus安装)的最佳方法是什么?
例如,假设您有一个webapp,其中特定于环境的属性文件(例如数据库连接字符串,日志记录配置等,基于dev / QA /生产环境而有所不同)包含在最终打包的应用程序中基于属性或环境变量。在构建这种类型的应用程序时,最有意义的是部署到您的存储库?它应该是具有生产设置的WAR文件,还是所有类的JAR而没有资源?
我要问的原因是,当您构建此类Web应用程序时,您确实拥有一个代码库以及一组特定于环境的资源文件。前者很有意义地部署到您的存储库,因此它可供其他项目使用,但后者没有多大意义分享并提供给其他人。
答案 0 :(得分:3)
我建议您构建一个原始war项目,其中可能包含一些用于开发的默认文件,并将其部署到存储库。
然后,您可以构建多个依赖于war项目的项目,并提供自己的特定资源。
JavaOne 2009演示文稿Getting Serious About Build Automation: Using Maven in the Real World就如何做到这一点有一个很好的例子
在部署项目中,引用war项目
<dependency>
<groupId>myorg.myapp</groupId>
<groupId>myapp-web</groupId>
<version>${webapp.version}</version>
<type>war</type>
</dependency>
在部署项目中,使用叠加层从Web项目导入文件
<plugin>
<artifactId>maven-war-plugin</artifactId>
<configuration>
<warName>myapp-web</warName>
<overlays>
<overlay>
<groupId>myorg.myapp</groupId>
<artifactId>myapp-web</artifactId>
<excludes>
<exclude>WEB-INF/classes/config.properties</exclude>
</excludes>
</overlay>
</overlays>
<!-- some config elements not shown here -->
</plugin>
在部署项目中,将部署项目中的额外资源包含到Web项目中
<plugin>
<artifactId>maven-war-plugin</artifactId>
<configuration>
<!-- some config elements not shown here -->
<webResources>
<resource>
<directory>${patch.path}</directory>
</resource>
</webResources>
</configuration>
</plugin>
答案 1 :(得分:1)
我认为你应该建立一场战争。对于覆盖层而言,对于开发人员来说,“只是放弃了针对该环境的修复”是一种诱惑。
对环境变量和JNDI resources外部JNDI资源文件使用attach(如果需要,可以为每种类型的环境附加一个)。
当然,您需要一个进程来检索正确的资源文件并将其应用到您的环境中(使用密码和其他敏感变量进行调整),但这是一个相当简单的脚本练习。
答案 2 :(得分:1)
我把属性放在我的maven pom.xml中。首先,我整理了整个网络应用程序,以便为不同的层提供单独的罐子; persistenc / db,service,web(例如,spring mvc的控制器)和war。 war项目在src / main / resources中有jsps和properties / config / xml文件。
例如,我的父pom就是这样开始的:
<project
xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://maven.apache.org/POM/4.0.0
http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>edu.berkeley.ist.waitlist</groupId>
<artifactId>waitlist-parent</artifactId>
<modules>
<module>../waitlist-core</module>
<module>../waitlist-db</module>
<module>../waitlist-web</module>
<module>../waitlist-war</module>
<module>../waitlistd</module>
</modules>
和
<build>
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
</resource>
<resource>
<directory>src/main/hbm</directory>
<filtering>true</filtering>
</resource>
</resources>
和
<dependencyManagement>
<!-- dependencies with exclusions -->
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>${version.springframework}</version>
<exclusions>
<exclusion>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
然后我有一堆配置文件,用于各种构建:
<profiles>
<!-- ========================================================== -->
<!-- local, hsql -->
<!-- ========================================================== -->
<profile>
<id>localhost-hsql</id>
<activation>
<activeByDefault>false</activeByDefault>
</activation>
<properties>
<!-- need to specify ${basedir} so that hsql creates its files in the right place -->
<db2.url>jdbc:hsqldb:file:${basedir}/target/waitlistv2;shutdown=true</db2.url>
<db2.user>sa</db2.user>
<db2.password />
<jdbc-db2.driverClass>org.hsqldb.jdbcDriver</jdbc-db2.driverClass>
<db2.schema>public</db2.schema>
<db2.hibernate.default_schema>public</db2.hibernate.default_schema>
<db2.hibernate.dialect>org.hibernate.dialect.HSQLDialect</db2.hibernate.dialect>
<dbunit.dataTypeFactoryName>org.dbunit.ext.hsqldb.HsqldbDataTypeFactory</dbunit.dataTypeFactoryName>
<hbmtool.haltOnError>false</hbmtool.haltOnError>
<log.filename>/tmp/waitlist.log</log.filename>
</properties>
</profile>
例如,在waitlist-war / src / main / resources中是文件logback.xml,它以
开头<configuration debug="true">
<appender class="ch.qos.logback.core.rolling.RollingFileAppender" name="RootFileAppender">
<!-- set in the pom.xml file -->
<file>${log.filename}</file>
因此,您可以看到由于maven的过滤,如何使用pom中的log.filename属性。
(我正在指定父pom中的所有版本,而子项目只是指定他们使用的依赖项,但是没有版本号。我不确定这是否是正确的方法,最佳实践等。
此外,waitlist-war依赖于waitlist-web,waitlist-web依赖于waitlist-core(我的服务层),waitlist-core依赖于waitlist-db。 Waitlistd是一个单独的应用程序,没有ui可以说,它取决于waitlist-core。)
答案 3 :(得分:0)
我非常喜欢只有一个版本的每个可部署版本。如果您有生产版本,测试版本等,这将通过必要的检查和重建减慢您的速度。 建立战争一次并对每个环境使用相同的战争。
这引出了一个问题,您如何处理特定于环境的属性。我通常采用混合方法。在可能的情况下,所有环境所需的所有属性都打包在战争中。然后战争根据它所处的环境加载正确的属性。应用程序可以确定使用系统属性的环境。
请参阅此处获取使用spring的示例:http://www.developer.com/java/ent/article.php/3811931
这可以很容易地适用于没有弹簧的情况。
某些属性不适合在战争中打包,例如生产密码。对于这些,上面链接的方法可以很容易地用于从外部文件路径加载属性。