简体   繁体   中英

Create two artifacts (war) for a single maven project

I have a Java web project that we deploy on the server of two different customers, 99% of the code is the same, right now I have two ApplicationBuilders, which is the class that contains the customization for each customer.

Anytime I want to deploy the new version I have to manually comment a line, build (with maven), uncomment that line, comment the other one and build again.

public class ApplicationBuilderFactory {
    private static final IApplicationBuilder app;

    static {
//            app = new Customer1ApplicationBuilder()
            app = new Customer2ApplicationBuilder();
        }
    }

    public static IApplicationBuilder get() { return app; }
}

I want to avoid all this and the best thing would probably just create two different wars.

What's a good way to do this? I don't use (nor like) dependency injection frameworks and it seems overkill to add one just for a single class, but I may consider it.

Create 2 different Maven Profiles, one for each customer, that copies a version of class ApplicationBuilderFactory to the right directory before compile stage.

<build>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-antrun-plugin</artifactId>
            <version>1.7</version>
            <executions>
                <execution>
                    <id>copy-files</id>
                    <phase>generate-sources</phase>
                    <goals>
                        <goal>run</goal>
                    </goals>
                    <configuration>
                        <target name="copy files">
                            <copy file="${project.build.sourceDirectory}/pkg/ApplicationBuilderFactory.java.${extension}" tofile="${project.build.sourceDirectory}/pkg/ApplicationBuilderFactory.java" />
                        </target>
                    </configuration>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>

<profiles>
     <profile>
        <id>customer1</id>
        <properties>
                <extension>customer1</extension>
        </properties>
 </profile>
     <profile>
        <id>customer2i</id>
        <properties>
                <extension>customer2</extension>
        </properties>
     </profile>

Instead of having only one src/main/java/pkg/ApplicationBuilderFactory.java, we have:

  • src/main/java/pkg/ApplicationBuilderFactory.java.customer1
  • src/main/java/pkg/ApplicationBuilderFactory.java.customer2.

So before compiling java code, we copy one of these versions to the src/main/java/pkg/ApplicationBuilderFactory.java.

So generate 2 different .wars using 2 different profiles.

One way to approach this is to use the Maven WAR Plugin Overlays feature.

Instead of trying to build multiple artifacts from one project (which can become unwieldy after a while), you create one base WAR project, and then a separate WAR project for each customer that only contains the components that need to be different.

Each customer specific WAR will be overlaid with the base WAR. This will make it easier to customise not only the ApplicationBuilderFactory but also specific web content and assets.

This also has the following benefits

  • customer specific features are guaranteed to be isolated from each other;

  • different customers can have their own release cycle and source control repository

  • it's easy to add subsequent customers

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM