Possible to run two webapps at once when developing with Maven/Eclipse?
Asked Answered
S

5

4

Here's the problem: we build webapps for clients. We also have an "admin" webapp that modifies some client data structures. Because of the nature of the data, both webapps have to run in the same JVM.

This is no problem in production; you just put two webapps in the same app server.

We've recently switched to a Mavenish way of laying out webapps, though, and Maven wants one webapp per project. In Eclipse it's a problem, because if you run the different webapps independently, they'll be in separate JVMs.

We're trying to use the jetty-maven-plugin to do webapp testing, but could switch to something else if it would solve this problem.

Scrutable answered 1/4, 2011 at 21:27 Comment(3)
In eclipse, are you running each webapp on its own app server?Herstein
Separate projects in Eclipse run independently. When you do a Run As... and invoke the maven-jetty-webapp, it launches a copy of the Jetty app server in its own JVM.Scrutable
Same question as How do I deploy multiple peer webapps from a parent pom, which have a good answer.Ostensory
S
0

Answering my own question:

It appears that this just isn't possible. The workaround that we've come up with is to write a little embedded jetty code and launch it from within our app. Jetty allows you to add multiple webapps programmatically. It also allows you to create multiple resource bases, that is, directories, per webapp, which enables overlays. So far, it works great.

Scrutable answered 12/4, 2011 at 21:28 Comment(0)
S
6

Yes, you can :) It's done by identifying one WAR module as the primary, copying all the other WARs into the primary's target dir, making a jetty.xml and telling Maven Jetty Plugin to use the jetty.xml. Here's how to copy the other WARs using Maven dependency plugin:

<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
    <execution>
        <id>copy</id>
        <phase>package</phase>
        <goals>
            <goal>copy</goal>
        </goals>
        <configuration>
            <artifactItems>
                <artifactItem>
                    <groupId>com.foo</groupId>
                    <artifactId>bar</artifactId>
                    <version>${project.version}</version>
                    <type>war</type>
                    <overWrite>true</overWrite>
                    <outputDirectory>target/</outputDirectory>
                </artifactItem>
            </artifactItems>
        </configuration>
    </execution>
</executions>

You'll need to have the com.foo:bar dependency defined in the POM as well. Here's the contents of jetty.xml:

<?xml version="1.0"?>

<!-- =========================================================== -->
<!-- Set handler Collection Structure                            -->
<!-- =========================================================== -->
<Set name="handler">
    <New id="Handlers" class="org.eclipse.jetty.server.handler.HandlerCollection">
        <Set name="handlers">
            <Array type="org.eclipse.jetty.server.Handler">
                <Item>
                    <New class="org.eclipse.jetty.server.handler.ContextHandlerCollection"
                         id="Contexts">
                        <Set name="handlers">
                            <Array type="org.eclipse.jetty.server.Handler">
                                <Item>
                                    <New id="FooWebHandler"
                                         class="org.eclipse.jetty.webapp.WebAppContext"/>
                                </Item>
                            </Array>
                        </Set>
                    </New>
                </Item>
            </Array>
        </Set>
    </New>
</Set>

<Ref id="FooWebHandler">
    <Set name="contextPath">/foo</Set>
    <Set name="war">
        target/bar-${project.version}.war
    </Set>
</Ref>

And here's how to tell Maven Jetty plugin to use the new jetty.xml:

<plugin>
<groupId>org.mortbay.jetty</groupId>
<artifactId>jetty-maven-plugin</artifactId>
<version>${jetty.version}</version>
<configuration>
    <jettyConfig>${basedir}/jetty.xml</jettyConfig>
</configuration>

Now kick off jetty:run-war goal from Eclipse and you should see all WARs deploying in one Maven Jetty plugin instance. I run this from command line and it works there, YMMV with Eclipse.

Singlestick answered 25/5, 2011 at 15:53 Comment(1)
The jetty.xml worked perfectly well for me. I don't use Jetty Maven Plugin but running my webapps directly from eclipse. But one question remaining is: Why the double-collection structure with the ContexthandlerCollection within HandlerCollection? It seems to work fine leaving the HandlerCollection out and using ContextHandlerCollection directly (and vice versa).Tonsorial
F
5

You can do this via the jetty-maven-plugin directly, without modifying jetty.xml:

<plugin>
    <groupId>org.eclipse.jetty</groupId>
    <artifactId>jetty-maven-plugin</artifactId>
    <configuration>
        <scanIntervalSeconds>5</scanIntervalSeconds>
        <webApp>
            <contextPath>/</contextPath>
        </webApp>
       <contextHandlers>
          <contextHandler implementation="org.eclipse.jetty.maven.plugin.JettyWebAppContext">
            <war>${project.basedir}/../secondProject.war</war>
            <contextPath>/cc</contextPath>
          </contextHandler>
        </contextHandlers>  
    </configuration>
    <executions>
        ...
    </executions>
</plugin>

You don't have to modify jetty.xml file(s) at all to use this successfully, and you don't need to copy the war file either. (although you may wish to build the second war as part of this build, see maven-invoker-plugin)

Documentation here: http://www.eclipse.org/jetty/documentation/9.2.2.v20140723/jetty-maven-plugin.html#running-more-than-one-webapp

Flimflam answered 28/11, 2014 at 15:33 Comment(0)
A
3

Here's to give an example for ccleve's answer.

import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.handler.HandlerCollection;
import org.eclipse.jetty.webapp.WebAppContext;
import org.eclipse.jetty.xml.XmlConfiguration;
...
public static void main(String[] args) throws Exception {
...
Server server = new Server(port);
HandlerCollection handlers = new HandlerCollection();

WebAppContext frontEndWebappContext = new WebAppContext(
     "src/main/webapp", "/test"
);
handlers.addHandler(frontEndWebappContext);

String serviceWebappBasePath = {absolute_path_to_other_webapp};
WebAppContext serviceWebappContext = new WebAppContext(
     serviceWebappBasePath + "/main/webapp", "/"
);
handlers.addHandler(serviceWebappContext);
XmlConfiguration conf = new XmlConfiguration(new File(
   serviceWebappBasePath +  "test/webapp/WEB-INF/jetty-web.xml")
.toURI().toURL().openStream());
conf.configure(serviceWebappContext);

server.setHandler(handlers);
server.start();

...

In this case there is front-end webapp that is mounted to "/test" and a service webapp that is mounted on "/". We also include jetty-web.xml of the service app.

In your case, that launcher that you would create should be located in the "src/test" folder since it shouldn't be included in your war because you use want it for test purposes only.

You may also have to add dependency to the service webapp in scope test in the pom file of the front end webapp :

<dependency>
 <groupId>{service_group}</groupId>
 <artifactId>{service_artifact_id}</artifactId>
 <version>{service_version}</version>
 <scope>test</scope>
</dependency>

or/and

<dependency>
  <groupId>{service_group}</groupId>
  <artifactId>{service_artifact_id}</artifactId>     
  <type>test-jar</type>
  <version>{service_version}</version>
  <scope>test</scope>
</dependency>
Aberration answered 11/5, 2013 at 19:38 Comment(0)
H
0

I don't have that much experience with Maven/Jetty; but I do have experience with Tomcat on Eclipse; so we're both at least doing something with servlets on Eclipse.

At any rate, I don't know if you've made projects or not using any of the project templates in Eclipse, but I made mine using the Dynamic Web Project template. I haven't done two web apps before; but if you were to make two of these projects, and then in the Eclipse servers tab, make a new server and add both projects to it, you might be able to accomplish your goals.

When you do Run As...you're basically just running the default run configuration that Eclipse has for your project setup. But if you deploy both of your projects to one server in your dev environment, and then select that server and hit start and it should just start it on the one JVM; similar to your production environment.

Like I said though; I'm not using Jetty and I've never used the server setup guide with Jetty so I wouldn't know if this would work for you or not. So I hope this is helpful - but I won't be too terribly surprised if it isn't.

Herstein answered 3/4, 2011 at 1:26 Comment(1)
Thanks for the suggestion. It would probably work. Trouble is, we're not using WTP, and when we tried to use it it made several other things unworkable in our projects. It's a fairly heavyweight solution. Also, I had trouble getting it to recognize maven artifacts.Scrutable
S
0

Answering my own question:

It appears that this just isn't possible. The workaround that we've come up with is to write a little embedded jetty code and launch it from within our app. Jetty allows you to add multiple webapps programmatically. It also allows you to create multiple resource bases, that is, directories, per webapp, which enables overlays. So far, it works great.

Scrutable answered 12/4, 2011 at 21:28 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.