开发者

How to extend/customize a WAR with another project

We have the following scenario with our project:

  • A core web application packaged as a war file (call it Core project).
  • The need to "customize" or "extend" the core app per customer (call it Customer project). This mostly includes new bean definitions (we're using Spring), ie. replacing service implementations in the core.war with customer-specific implementations.
  • We want to develop the Core and Customer projects independently
  • When the Customer project is developed, we need to be able to run/debug it in Eclipse (on Tomcat) with the Core project as a dependency
  • When the Customer project is built, the resulting war file "includes" the core and customer projects. So this .war is the customer-specific version 开发者_开发技巧of the application

I'm looking for suggestions as to the best way to do this in terms of tooling and project configuration.

We're using Ant currently, but would like to avoid getting buried in more ant. Has anyone done this with Maven?

I've seen a lot of posts on how to build a web application that depends on a java application, but nothing on a web application depending on another web app.

Thanks!


Sounds like Maven WAR overlay does what you want.


In Eclipse there is a "native" WTP way to do this. It mainly using linked folders and a little hack in .settings/org.eclipse.wst.common.component file. You can read the article about it at http://www.informit.com/articles/article.aspx?p=759232&seqNum=3 the chapter called "Dividing a Web Module into Multiple Projects". The problem with this is that the linked folder must be relative to some path variable can be defined in Window/Preferences/General/Workspace/Linked Resources tab. Otherwise the linked folder definition (can be found in .project file in project root) will contain workstation specific path. The path variable practicly should be the workspace root. This solution works great with WTP, deploy and everything else works like it should.

The second solution is to use ant for it. Forget it. You will deeply regret it.

The third solution is to use maven for it. You can forget the comfort of WTP publishing if you dont do some tricks. Use war overlays like others suggested. Be sure to install both m2eclipse, m2eclipse extras. There is an extension plugin released recently, that can help you. Described at this blog. I did not try it, but looks ok. Anyway Maven have nothing to do with linked folders, so I think even the first solution and this maven overlay can live together if necessary.

As for headless builds you can use HeadlessEclipse for the first solution. It is dead (by me) now, but still works :). If you use the maven overlay + eclipse stuff, headless builds are covered by maven.


This is little bit more involved but at a high-level we do it as below. We have the core platform ui divided to multiple war modules based on the features (login-ui,catalog-mgmt-ui etc). Each of these core modules are customizable by the customer facing team.

We merge all of these modules during build time into 1 single war module. The merge rules are based on maven's assembly plugin.


You usually start from the Java source code. WARs don't include the Java source code, just the compiled classes under WEB-INF/classes or JARs under WEB-INF/libs.

What I would do is use Maven and start a brand new empty webapp project with it: http://maven.apache.org/guides/mini/guide-webapp.html

After you have the new empty project structure, copy the Java source code to it (src/main/java) and fill out the dependencies list in pom.xml.

Once you've done all this you can use mvn clean package to create a standard WAR file that you can deploy to Tomcat.


You might want to look into designing your core app with pluggable features based on interfaces.

For example say your core app has some concept of a User object and needs to provide support for common user based tasks. Create a UserStore interface;

public interface UserStore
{
    public User validateUser(String username, String password) throws InvalidUserException;
    public User getUser(String username);
    public void addUser(User user);
    public void deleteUser(User user);
    public void updateUser(User user);
    public List<User> listUsers();
}

You can then code your core app (logon logic, registration logic etc) against this interface. You might want to provide a default implementation of this interface in your core app, such as a DatabaseUserStore which would effectively be a DAO.

You then define the UserStore as a Spring bean and inject it where needed;

<bean id="userStore" class="com.mycorp.auth.DatabaseUserStore">
    <constructor-arg ref="usersDataSource"/>
</bean>

This allows you to customise or extend the core app depending on specific customer's needs. If a customer wants to integrate the core app with their Active Directory server you write a LDAPUserStore class that implements your UserStore interface using LDAP. Configure it as a Spring bean and package the custom class as a dependant jar.

What you are left with is a core app which everyone uses, and a set of customer specific extensions that you can provide and sell seperately; heck, you can even have the customer write their own extensions.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜