users@jersey.java.net

Re: [Jersey] Problem when packaging a Jersey App with Maven

From: Chris Carrier <ctcarrier_at_gmail.com>
Date: Mon, 26 Jul 2010 09:07:32 -0700

Yep I package all my projects as standalone jars right now. I've
definitely had to tackle the issue you're having before but your
services directory seems OK so it must be something else. Not sure
what exactly is causing the problem. My Jersey dependencies look
like:

<!--Jersey-->
        <dependency>
            <groupId>com.sun.jersey</groupId>
            <artifactId>jersey-bundle</artifactId>
            <version>1.1.5</version>
        </dependency>
        <dependency>
            <groupId>com.sun.jersey.contribs</groupId>
            <artifactId>jersey-spring</artifactId>
            <version>1.1.5</version>
            <exclusions>
                <exclusion>
                    <groupId>org.springframework</groupId>
                    <artifactId>spring</artifactId>
                </exclusion>
                <exclusion>
                    <groupId>org.springframework</groupId>
                    <artifactId>spring-beans</artifactId>
                </exclusion>
                <exclusion>
                    <groupId>org.springframework</groupId>
                    <artifactId>spring-context</artifactId>
                </exclusion>
                <exclusion>
                    <groupId>org.springframework</groupId>
                    <artifactId>spring-core</artifactId>
                </exclusion>
            </exclusions>
        </dependency>

        <!--JAX-RS-->
        <dependency>
            <groupId>javax.ws.rs</groupId>
            <artifactId>jsr311-api</artifactId>
            <version>1.1.1</version>
        </dependency>

        <!--JAXB -->
        <dependency>
            <groupId>com.sun.xml.bind</groupId>
            <artifactId>jaxb-impl</artifactId>
            <version>2.2</version>
        </dependency>
        <dependency>
            <groupId>javax.xml.bind</groupId>
            <artifactId>jaxb-api</artifactId>
            <version>2.2</version>
        </dependency>

I think I originally started using the Jersey-bundle artifact to get
around the problem you're having. It is probably a heavy handed
approach but I haven't had the time or desire to go mess with it
again. Then my shade plugin for packaging is just:

<plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-shade-plugin</artifactId>
                <version>1.3.1</version>
                <executions>
                    <execution>
                        <phase>package</phase>
                        <goals>
                            <goal>shade</goal>
                        </goals>
                        <configuration>
                            <transformers>
                                <transformer

implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">

<resource>META-INF/spring.handlers</resource>
                                </transformer>
                                <transformer

implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
                                    <resource>META-INF/spring.schemas</resource>
                                </transformer>
                                <transformer

implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
                                    <mainClass>com.some.main.Class</mainClass>
                                </transformer>
                            </transformers>
                            <outputFile>

${project.build.directory}/${project.build.finalName}-jar-with-dependencies.jar
                            </outputFile>
                        </configuration>
                    </execution>
                </executions>
            </plugin>

Hope that helps somewhat.

Chris

On Mon, Jul 26, 2010 at 8:35 AM, Dominique Guinard <dguinard_at_ethz.ch> wrote:
> Hi all,
>
> Any clue on that?
> More generally: did anyone successfully manage to export a maven Jersey
> app as a standalone jar that includes all dependencies? If yes then I'm
> begging for a small "Howto".
>
> Thanks a lot,
>
> Dominique
>
> On Thu, 2010-07-22 at 16:58 +0200, Dominique Guinard wrote:
>> Dear Chris,
>>
>> Thanks a lot for your reply!
>>
>> >How are you packaging your jar? If you're using the assembly plugin
>> Yes that's what I'm using, here is the POM extract:
>>
>>             <!-- Assemble with dependencies -->
>>             <plugin>
>>                 <artifactId>maven-assembly-plugin</artifactId>
>>                 <executions>
>>                     <execution>
>>                         <id>create-executable-jar</id>
>>                         <phase>package</phase>
>>                         <goals>
>>                             <goal>single</goal>
>>                         </goals>
>>                     </execution>
>>                 </executions>
>>                 <configuration>
>>                     <descriptorRefs>
>>
>> <descriptorRef>jar-with-dependencies</descriptorRef>
>>                     </descriptorRefs>
>>                     <archive>
>>                         <manifest>
>>                             <addClasspath>true</addClasspath>
>>
>> <mainClass>com.webofthings.webplogg.web.App</mainClass>
>>                         </manifest>
>>                     </archive>
>>                 </configuration>
>>             </plugin>
>>
>>
>> > the issue could be that the META-INF/services folder from the jersey
>> > dependencies isn't getting included properly in the resulting
>> > artifact.  If that's the case you may be able to use the shade plugin
>> > to sort it out.  There are some suggestions in this bug that could
>> > help:
>> > https://jersey.dev.java.net/issues/show_bug.cgi?id=440
>> >
>> I actually tried that but still get the same result, i.e. it did not
>> work. I'm quite new to Maven so not so sure I did everything correctly.
>>
>> When I try using the shade plugin with:
>>             <plugin>
>>                 <groupId>org.apache.maven.plugins</groupId>
>>                 <artifactId>maven-jar-plugin</artifactId>
>>                 <configuration>
>>                     <archive>
>>                         <manifest>
>>
>> <mainClass>com.webofthings.webplogg.web.App</mainClass>
>>                         </manifest>
>>                     </archive>
>>                 </configuration>
>>             </plugin>
>>
>>             <plugin>
>>                 <groupId>org.apache.maven.plugins</groupId>
>>                 <artifactId>maven-shade-plugin</artifactId>
>>                 <version>1.2</version>
>>                 <executions>
>>                     <execution>
>>                         <phase>package</phase>
>>                         <goals>
>>                             <goal>shade</goal>
>>                         </goals>
>>                         <configuration>
>>                             <artifactSet>
>>                <!-- Use this to in/exclude only specific dependencies
>> -->
>>                                 <includes>
>>
>> <include>commons-codec:commons-codec</include>
>>                                 </includes>
>>                             </artifactSet>
>>                             <transformers>
>>                                 <transformer
>> implementation="org.apache.maven.plugins.shade.resource.ComponentsXmlResourceTransformer" />
>>                             </transformers>
>>                         </configuration>
>>                     </execution>
>>                 </executions>
>>             </plugin>
>>
>> I actually get a jar without any dependencies at all. Am I doing
>> something wrong here?
>>
>> When I use the assembly plugin is the META-INF/services folder seems to
>> be ok... I attached it to this mail.
>>
>> Thanks a lot,
>>
>> Dominique
>>
>>
>> On Tue, 2010-07-20 at 11:18 -0700, Chris Carrier wrote:
>> > How are you packaging your jar?  If you're using the assembly plugin
>> > the issue could be that the META-INF/services folder from the jersey
>> > dependencies isn't getting included properly in the resulting
>> > artifact.  If that's the case you may be able to use the shade plugin
>> > to sort it out.  There are some suggestions in this bug that could
>> > help:
>> >
>> > https://jersey.dev.java.net/issues/show_bug.cgi?id=440
>> >
>> > Chris
>> >
>> > On Tue, Jul 20, 2010 at 11:09 AM, Dominique Guinard <dguinard_at_ethz.ch> wrote:
>> > > Dear Jersey folks,
>> > >
>> > > After a couple of years of Restlet app dev I decided to give a try to
>> > > Jersey. I actually really enjoyed using it but I'm stuck with a problem
>> > > right now.
>> > >
>> > > I embed my Jersey app in Grizzly and develop the whole thing as a maven
>> > > project in netbeans 6.9. So far so good, however when I try packaging
>> > > the app as a standalone project I keep getting the following message,
>> > > whatever resource I ask for, in whatever representation:
>> > >
>> > > ul 20, 2010 3:28:46 PM com.sun.jersey.spi.container.ContainerResponse
>> > > write
>> > > SEVERE: A message body writer for Java class java.lang.String, and Java
>> > > type class java.lang.String, and MIME media type text/plain was not
>> > > found
>> > > Jul 20, 2010 3:28:46 PM com.sun.grizzly.http.servlet.ServletAdapter
>> > > doService
>> > > SEVERE: service exception:
>> > > javax.ws.rs.WebApplicationException
>> > >        at
>> > > com.sun.jersey.spi.container.ContainerResponse.write(ContainerResponse.java:267)
>> > >        at
>> > > com.sun.jersey.server.impl.application.WebApplicationImpl._handleRequest(WebApplicationImpl.java:1043)
>> > >        at
>> > > com.sun.jersey.server.impl.application.WebApplicationImpl.handleRequest(WebApplicationImpl.java:947)
>> > >        at
>> > > com.sun.jersey.server.impl.application.WebApplicationImpl.handleRequest(WebApplicationImpl.java:938)
>> > >        at
>> > > com.sun.jersey.spi.container.servlet.WebComponent.service(WebComponent.java:399)
>> > >        at
>> > > com.sun.jersey.spi.container.servlet.ServletContainer.service(ServletContainer.java:478)
>> > >        at
>> > > com.sun.jersey.spi.container.servlet.ServletContainer.service(ServletContainer.java:663)
>> > >        at javax.servlet.http.HttpServlet.service(HttpServlet.java:820)
>> > >        at
>> > > com.sun.grizzly.http.servlet.FilterChainImpl.doFilter(FilterChainImpl.java:195)
>> > >        at
>> > > com.sun.grizzly.http.servlet.FilterChainImpl.invokeFilterChain(FilterChainImpl.java:139)
>> > >        at
>> > > com.sun.grizzly.http.servlet.ServletAdapter.doService(ServletAdapter.java:376)
>> > >        at
>> > > com.sun.grizzly.http.servlet.ServletAdapter.service(ServletAdapter.java:324)
>> > >        at
>> > > com.sun.grizzly.tcp.http11.GrizzlyAdapter.service(GrizzlyAdapter.java:166)
>> > >        at
>> > > com.sun.grizzly.http.ProcessorTask.invokeAdapter(ProcessorTask.java:791)
>> > >        at
>> > > com.sun.grizzly.http.ProcessorTask.doProcess(ProcessorTask.java:693)
>> > >        at
>> > > com.sun.grizzly.http.ProcessorTask.process(ProcessorTask.java:954)
>> > >        at
>> > > com.sun.grizzly.http.DefaultProtocolFilter.execute(DefaultProtocolFilter.java:170)
>> > >        at
>> > > com.sun.grizzly.DefaultProtocolChain.executeProtocolFilter(DefaultProtocolChain.java:135)
>> > >        at
>> > > com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:102)
>> > >        at
>> > > com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:88)
>> > >        at
>> > > com.sun.grizzly.http.HttpProtocolChain.execute(HttpProtocolChain.java:76)
>> > >        at
>> > > com.sun.grizzly.ProtocolChainContextTask.doCall(ProtocolChainContextTask.java:53)
>> > >        at
>> > > com.sun.grizzly.SelectionKeyContextTask.call(SelectionKeyContextTask.java:57)
>> > >        at com.sun.grizzly.ContextTask.run(ContextTask.java:69)
>> > >        at com.sun.grizzly.util.AbstractThreadPool
>> > > $Worker.doWork(AbstractThreadPool.java:330)
>> > >        at com.sun.grizzly.util.AbstractThreadPool
>> > > $Worker.run(AbstractThreadPool.java:309)
>> > >        at java.lang.Thread.run(Thread.java:619)
>> > >
>> > >
>> > >
>> > > Here is the resource in question (see below), any help is very welcomed,
>> > > I'm clueless right now!
>> > >
>> > >
>> > > package com.webofthings.webplogg.web.resources;
>> > >
>> > > import com.webofthings.webplogg.meter.SmartMeter;
>> > > import com.webofthings.webplogg.meter.ConsumptionData;
>> > > import com.webofthings.webplogg.meter.SmartMeterManager;
>> > > import com.webofthings.webplogg.meter.Status;
>> > > import com.webofthings.webplogg.meter.config.Configurator;
>> > > import com.webofthings.webplogg.meter.plogg.PloggManager;
>> > > import java.net.URI;
>> > > import java.util.ArrayList;
>> > > import java.util.List;
>> > > import javax.ws.rs.Consumes;
>> > > import javax.ws.rs.GET;
>> > > import javax.ws.rs.PUT;
>> > > import javax.ws.rs.Path;
>> > > import javax.ws.rs.PathParam;
>> > > import javax.ws.rs.Produces;
>> > > import javax.ws.rs.core.MediaType;
>> > > import javax.ws.rs.core.UriBuilder;
>> > >
>> > >
>> > > @Path("/smartmeters")
>> > > @Produces({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON,
>> > > MediaType.APPLICATION_ATOM_XML})
>> > > public class SmartMeterResource {
>> > >
>> > >    private static SmartMeterManager ploggMgr =
>> > > PloggManager.getInstance();
>> > >
>> > >    public SmartMeterResource() {
>> > >    }
>> > >
>> > >
>> > >    @GET
>> > >    public List<SmartMeter> getSmartMeters() {
>> > >        return new ArrayList(ploggMgr.getManagedSmartMeters().values());
>> > >    }
>> > >
>> > >    /**
>> > >     * This produces an HTML representation of all the SmartMeters. I.e.
>> > >     * a list with links to the each SmartMeter.
>> > >     * @return The HTML representation of the list of SmartMeters.
>> > >     */
>> > >    @GET
>> > >    @Produces("text/html")
>> > >    public String getSmartMetersHTML() {
>> > >        StringBuilder htmlOut = new StringBuilder("<html><body>");
>> > >        for (SmartMeter currentSmartMeter :
>> > > ploggMgr.getManagedSmartMeters().values()) {
>> > >
>> > >            /* Build URLs to child-resources (SmartMeter) */
>> > >            UriBuilder builder =
>> > > UriBuilder.fromPath("/smartmeters/{id}");
>> > >            int port = Integer.parseInt(Configurator.getInstance().
>> > >                    getProperty("WEB_SERVER_PORT"));
>> > >            String host =
>> > > Configurator.getInstance().getProperty("WEB_SERVER_HOST");
>> > >            builder.scheme("http").port(port).host(host);
>> > >            UriBuilder clone = builder.clone();
>> > >            URI uri = clone.build(currentSmartMeter.getId());
>> > >
>> > >            htmlOut.append("<p>Name: " + currentSmartMeter.getName() +
>> > > "</br>");
>> > >            htmlOut.append("ID: " + "<a href=\"");
>> > >            htmlOut.append(uri.toString());
>> > >            htmlOut.append("\">" + currentSmartMeter.getId() + "</a>");
>> > >            htmlOut.append("</p>");
>> > >        }
>> > >
>> > >        htmlOut.append("</body></hmtl>");
>> > >        return htmlOut.toString();
>> > >    }
>> > >
>> > >    @Path("/{smartMeterId}")
>> > >    @GET
>> > >    public ConsumptionData getMeterData(@PathParam("smartMeterId")
>> > > String smartMeterId) {
>> > >        return ploggMgr.getDataFromMeter(smartMeterId);
>> > >    }
>> > >
>> > >    /**
>> > >     * This produces an HTML representation of a given SmartMeter.
>> > >     * @return The HTML representation of the list of SmartMeters.
>> > >     */
>> > >    @Path("/{smartMeterId}")
>> > >    @GET
>> > >    @Produces("text/html")
>> > >    public String getMeterDataHTML(@PathParam("smartMeterId") String
>> > > smartMeterId) {
>> > >        StringBuilder htmlOut = new StringBuilder("<html><body>");
>> > >        ConsumptionData cons = ploggMgr.getDataFromMeter(smartMeterId);
>> > >
>> > >        /* Build URLs to child-resources (SmartMeter) */
>> > >            UriBuilder builder = UriBuilder.fromPath("/smartmeters/");
>> > >            int port = Integer.parseInt(Configurator.getInstance().
>> > >                    getProperty("WEB_SERVER_PORT"));
>> > >            String host =
>> > > Configurator.getInstance().getProperty("WEB_SERVER_HOST");
>> > >            builder.scheme("http").port(port).host(host);
>> > >            UriBuilder clone = builder.clone();
>> > >            URI uri = clone.build();
>> > >
>> > >        htmlOut.append("<p>Watts: " + cons.getWatt() + "</p>");
>> > >        htmlOut.append("<p><a href=\"");
>> > >        htmlOut.append(uri.toString());
>> > >        htmlOut.append("\"></a>");
>> > >
>> > >
>> > >        htmlOut.append("</body></hmtl>");
>> > >        return htmlOut.toString();
>> > >    }
>> > >
>> > >
>> > >    @Path("/{smartMeterId}/status")
>> > >    @GET
>> > >    public Status getMeterStatus(@PathParam("smartMeterId") String
>> > > smartMeterId) {
>> > >        return ploggMgr.getSmartMeter(smartMeterId).getStatus();
>> > >    }
>> > >
>> > >    @Path("/{smartMeterId}/status")
>> > >    @PUT
>> > >    @Consumes("text/plain")
>> > >    public void setMeterStatus(@PathParam("smartMeterId") String
>> > > smartMeterId, String message) {
>> > >        if (message.toLowerCase().equals("off")) {
>> > >            ploggMgr.turnOffPower(smartMeterId);
>> > >        } else {
>> > >            ploggMgr.turnOnPower(smartMeterId);
>> > >        }
>> > >
>> > >    }
>> > > }
>> > >
>> > >
>> > > ---------------------------------------------------------------------
>> > > To unsubscribe, e-mail: users-unsubscribe_at_jersey.dev.java.net
>> > > For additional commands, e-mail: users-help_at_jersey.dev.java.net
>> > >
>> > >
>> >
>> > ---------------------------------------------------------------------
>> > To unsubscribe, e-mail: users-unsubscribe_at_jersey.dev.java.net
>> > For additional commands, e-mail: users-help_at_jersey.dev.java.net
>> >
>>
>
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe_at_jersey.dev.java.net
> For additional commands, e-mail: users-help_at_jersey.dev.java.net
>
>