Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to manage shared resources for several web apps in Maven AND Eclipse?

Note: I didn't get any response in the first version of this question, so I modified it to be more generic...

Context

My project is divided into several maven modules and several web-applications. Here is the structure:

my-project
  + pom.xml
  +-- commons
  +-- persistence
  +-- ...
  +-- web-app-1
  +-- web-app-2
  +-- ...

All the web applications share common resources, such as JS, CSS and images files.

Instead of duplicating these resources in each web-app-X, I decided to create another project called web-resources, which is a WAR project. The structure is then the following one:

my-project
  + pom.xml
  +-- commons
  +-- persistence
  +-- ...
  +-- web-app-1
  +-- web-app-2
  +-- ...
  +-- web-resources
       +-- pom.xml
       +-- src/main/webapp
            +-- web.xml (which is almost empty, just need to be present for Maven)
            +-- web_resources
                 +-- css
                 +-- images
                 +-- javascript

Maven

In Maven 2 (or Maven 3, as I just migrated my project to maven 3.0.2), this configuration is easy to manage as all web-app-X declare web-resources as a dependency:

<groupId>foo.bar</groupId>
<artifactId>web-app-1</artifactId>
...
<dependencies>
    <dependency>
        <groupId>foo.bar</groupId>
        <artifactId>web-resources</artifactId>
        <version>${preclosing-version}</version>
        <type>war</type>
    </dependency>
    ...

So when I build my WAR project, it first get the web-resources.war (built just before), unzip it, and build on top of it the web-app-X web-application. This way, my WAR file will contains also a directory called web-resources/ that contains the shared resources.

This is the war overlay principle.

So on a Maven point of view, everything is fine!


Eclipse

Now, here comes the main problem: having a good Eclipse configuration.

Question: How can I use my current configuration to be managed correctly by Eclipse? In particular, when I deploy any web-app-X in Tomcat using Eclipse...

Note that I want to get the more automatizable (?) configuration, and avoid any manual steps, as this configuration should be used by dozens of developers...

For me, the best solution seems to use the linked resources of Eclipse. Thus, I set the following configuration in my web-app-X pom.xml:

<build>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-eclipse-plugin</artifactId>
            <configuration>
                <wtpversion>1.5</wtpversion>
                <linkedResources>
                    <linkedResource>
                        <name>web_resources</name>
                        <type>2</type>
                        <location>${project.basedir}\..\web-resources\src\main\webapp\web_resources</location>
                    </linkedResource>
                </linkedResources>
            </configuration>
        </plugin>
        ...

When I run the mvn eclipse:eclipse configuration, it adds succesfully this information in my .project file:

<projectDescription>
  ...
  <linkedResources>
    <link>
      <name>web_resources</name>
      <type>2</type>
      <location>C:\dev\project\web-resources\src\main\webapp\web_resources</location>
    </link>
  </linkedResources>
<projectDescription>

Now, I import my project in Eclipse. Problem: in Project properties > Java Build Path > Source, I don't see the Link Source present. I only see my four Maven default directories (src/main/java, src/main/resources, src/test/java and src/test/resources). What is strange is that when I try to manually add the linked resources, it refuses and says that it already exists...

So when I deploy my web application on my Tomcat in Eclipse, it does not deploy the web_resources directory, and thus I don't get the CSS / JS / images deployed.

After some tests, it seems that I have to do two modifications:

  1. Add the line <classpathentry kind="src" path="web_resources" output="src/main/webapp/web_resources"/> in my .classpath file;
  2. Remove the <project>preclosing-web-resources</project> in the .project file.

Note that using this configuration, Eclipse will copy (and keep synchronization) the content of web_resources project in my web-app-X/src/main/webapp/web_resources, but this is not a problem (this directory is ignored by the SCM).

The only automated solution I found was to create a simple Maven plugin that do the two previous modification, and then run the following command (or use a .bat file):

mvn eclipse:clean eclipse:eclipse myEclipsePlugin:eclipse

Question

  • Is there a better way to manage such configuration?

Technical information

Java 6, Maven 3.0.2, maven eclipse plugin 2.8, Eclipse 3.3.2 (but I can test with newer version of Eclipse), no m2eclipse plugin.

like image 881
Romain Linsolas Avatar asked Feb 10 '11 11:02

Romain Linsolas


2 Answers

Starting with Servlet 3.0, you can share resources by putting them within the src/main/resources/META-INF/resources directory.

When the webapp deploys, Servlet 3.0 makes those resources available from the context path. For example, in your case...

web-resources
-- src
---- main
------ resources
-------- META-INF
---------- resources
------------ css
-------------- global.css
------------ images
-------------- background.png

Let's assume that my_project has a dependency on web-resources and is deployed to the url http://my.localhost:8080/myProject.

With that configuration, the following URLs will resolve to the correct resources:

  • http://my.localhost:8080/myProject/css/global.css
  • http://my.localhost:8080/myProject/images/background.png

IF you have a name conflict between the resources and your actual application, the application will win.

Be sure your web.xml states you are using Servlet 3.0

<web-app xmlns="http://java.sun.com/xml/ns/javaee"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
    version="3.0">
like image 155
mikesir87 Avatar answered Oct 31 '22 20:10

mikesir87


You might want to take a look at this blog post. It covers a method for sharing resources using maven:

http://www.sonatype.com/people/2008/04/how-to-share-resources-across-projects-in-maven/

like image 1
Ruggs Avatar answered Oct 31 '22 21:10

Ruggs