Jersey 2 client with maven

14,902

Solution 1

You need to copy the dependencies to from your local repo into you project (or anywhere really, wherever you want to -cp to). For this, you can use the maven-dependency-plugin. Just add this to the <plugins>

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-dependency-plugin</artifactId>
    <version>2.9</version>
    <executions>
        <execution>
            <id>copy-dependencies</id>
            <phase>package</phase>
            <goals>
                <goal>copy-dependencies</goal>
            </goals>
            <configuration>
                <outputDirectory>${project.build.directory}/lib</outputDirectory>
                <overWriteReleases>false</overWriteReleases>
                <overWriteSnapshots>false</overWriteSnapshots>
                <overWriteIfNewer>true</overWriteIfNewer>
            </configuration>
        </execution>
    </executions>
</plugin>

What the above plugin configuration will do is copy all the dependencies to target/lib.

The easiest way to run the jar as an executable is to also set the Class-Path in the MANIFEST.MF, through Maven. For that we can use the maven-jar-plugin. So add this to the <plugins>

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-jar-plugin</artifactId>
    <version>2.5</version>
    <configuration>
        <archive>
            <index>true</index>
            <manifest>
                <addClasspath>true</addClasspath>
                <classpathPrefix>lib/</classpathPrefix>
                <mainClass>com.client.App</mainClass>
            </manifest>
        </archive>
    </configuration>
</plugin>

Also you will need to get rid of the <scope>provided</scope> for the Jersey client dependency. With this scope, Maven will not add the jars to the classpath.

After doing this, you can simply run java -jar your-jar.jar, without the need to -cp anything, as all the jars are specified in the Manifest. It should look something like

Manifest-Version: 1.0
Archiver-Version: Plexus Archiver
Built-By: XxxxXxxxx
Class-Path: lib/jersey-client-2.13.jar lib/jersey-common-2.13.jar lib/
 javax.annotation-api-1.2.jar lib/jersey-guava-2.13.jar lib/osgi-resou
 rce-locator-1.0.1.jar lib/javax.ws.rs-api-2.0.1.jar lib/hk2-api-2.3.0
 -b10.jar lib/hk2-utils-2.3.0-b10.jar lib/aopalliance-repackaged-2.3.0
 -b10.jar lib/javax.inject-2.3.0-b10.jar lib/hk2-locator-2.3.0-b10.jar
  lib/javassist-3.18.1-GA.jar
Created-By: Apache Maven 3.0.5
Build-Jdk: 1.8.0_20
Main-Class: com.client.App

Solution 2

You marked your jersey dependency as provided, therefore it won't be included in the output, because when the dependency is provided, it is assumed that it is available in the environment (for example by application server).

Try removing the <scope>provided</scope> from your Maven dependency or include the jersey jar on the classpath using the -cp parameter when you run your program.

Share:
14,902

Related videos on Youtube

jiri463
Author by

jiri463

Updated on June 04, 2022

Comments

  • jiri463
    jiri463 almost 2 years

    I want to create simple Jersey 2 Client app with Maven (Server app is also implemented and runs).

    My pom.xml

    <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
        <modelVersion>4.0.0</modelVersion>
        <groupId>com.client</groupId>
        <artifactId>RestClient</artifactId>
        <packaging>jar</packaging>
        <version>1.0-SNAPSHOT</version>
        <name>RestClient</name>
        <url>http://maven.apache.org</url>
        <dependencies>
            <dependency>
                <groupId>junit</groupId>
                <artifactId>junit</artifactId>
                <version>3.8.1</version>
                <scope>test</scope>
            </dependency>
            <dependency>
                <groupId>org.glassfish.jersey.core</groupId>
                <artifactId>jersey-client</artifactId>
                <version>2.13</version>
                <scope>provided</scope>
            </dependency>
        </dependencies>
    
        <build>
            <plugins>
                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-compiler-plugin</artifactId>
                    <version>2.3.2</version>
                    <configuration>
                        <source>1.7</source>
                        <target>1.7</target>
                    </configuration>
                </plugin>
            </plugins>
        </build>
    </project>
    

    java code

    package com.client;
    
    import javax.ws.rs.client.Client;
    import javax.ws.rs.client.ClientBuilder;
    import javax.ws.rs.client.Entity;
    import javax.ws.rs.core.GenericType;
    import javax.ws.rs.core.MediaType;
    import javax.ws.rs.client.WebTarget;
    import javax.ws.rs.core.Response;
    import javax.ws.rs.client.Invocation.Builder;        
    
    public class App 
    {
        public static void main( String[] args )
        {
    
            Client client = ClientBuilder.newClient();
            WebTarget target = client.target("http://localhost:8080").path("simple-service-webapp/rest/myresource");
    
            Builder builder =   target.request();
            //Response response  = builder.get();
            String result  = builder.get(String.class);
            System.out.println(target.getUri().toString());
            System.out.println("Result=" + result);
    
        }
    }
    

    I build app by command mvn package and everything pass. Then, I run app by java -cp target/RestClient-1.0-SNAPSHOT.jar com.client.App and then error occurs:

    Exception in thread "main" java.lang.NoClassDefFoundError: javax/ws/rs/client/ClientBuilder
            at com.client.App.main(App.java:20)
    Caused by: java.lang.ClassNotFoundException: javax.ws.rs.client.ClientBuilder
            at java.net.URLClassLoader$1.run(URLClassLoader.java:366)
            at java.net.URLClassLoader$1.run(URLClassLoader.java:355)
            at java.security.AccessController.doPrivileged(Native Method)
            at java.net.URLClassLoader.findClass(URLClassLoader.java:354)
            at java.lang.ClassLoader.loadClass(ClassLoader.java:425)
            at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:308)
            at java.lang.ClassLoader.loadClass(ClassLoader.java:358)
            ... 1 more
    

    It seems that libraries are not included, because files tree of projeckt looks:

    .
    ├── pom.xml
    ├── src
    │   ├── main
    │   │   └── java
    │   │       └── com
    │   │           └── client
    │   │               └── App.java
    │   └── test
    │       └── java
    │           └── com
    │               └── client
    │                   └── AppTest.java
    └── target
        ├── classes
        │   └── com
        │       └── client
        │           └── App.class
        ├── generated-sources
        │   ├── annotations
        │   └── test-annotations
        ├── maven-archiver
        │   └── pom.properties
        ├── RestClient-1.0-SNAPSHOT.jar
        ├── surefire
        ├── surefire-reports
        │   ├── com.client.AppTest.txt
        │   └── TEST-com.client.AppTest.xml
        └── test-classes
            └── com
                └── client
                    └── AppTest.class
    

    Where did I mistake? Thanks.

  • jiri463
    jiri463 over 9 years
    Thanks, it works. I am starting with Maven. May I have last question. I have no plugins/parameters in my server app's pom.xml, but it still copies libs in app's lib dir without any special setting. Is it because, it is a server app, which is considered to cooperate with app server, so it is defaultly set to create a lib dir and copy necessary libs into it? Or is there any other purpose? Thanks