Maven from command line: dependencies don't work - java

I used the following basic Maven command to generate a project:
mvn archetype:generate -DgroupId=it.maven.project -DartifactId=MavenExample -DarchetypeArtifactId=maven-archetype-quickstart -DarchetypeVersion=1.4 -DinteractiveMode=false
The project was correctly created and I could test the automatically generated App class without any problem with this instruction:
java -cp target/MavenExample-1.0-SNAPSHOT.jar:lib/* it.maven.project.App
Later on, I added some dependencies to the POM, obtaining the following file:
<?xml version="1.0" encoding="UTF-8"?>
<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/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>it.maven.project</groupId>
<artifactId>MavenExample</artifactId>
<version>1.0-SNAPSHOT</version>
<name>MavenExample</name>
<!-- FIXME change it to the project's website -->
<url>http://maven.apache.org</url>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.10</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-collections4</artifactId>
<version>4.0</version>
<scope>compile</scope>
</dependency>
</dependencies>
<build>
<sourceDirectory>src</sourceDirectory>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.7.0</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
</plugins>
</build>
</project>
Finally, for testing sake, I modified the App class previously generated by Maven itself:
package it.maven.project;
import org.apache.commons.lang3.RandomStringUtils;
/**
* Hello world!
*
*/
public class App
{
public static void main( String[] args )
{
System.out.println( "Hello World!" );
System.out.println("Stringa generata casualmente: " + RandomStringUtils.random(16, true, true).toUpperCase());
}
}
A series of strange things happen:
even though more recent versions of dependencies are specified in POM, in .m2 folder the downloaded versions seem to be older (for instance I get 2.1 and 2.5 for commons-lang3)
the project is correctly compiled by instruction
mvn clean install -U
when I run again command to execute App, I get the following exception:
Exception in thread "main" java.lang.NoClassDefFoundError: org/apache/commons/lang3/RandomStringUtils
at it.maven.project.App.main(App.java:13)
Caused by: java.lang.ClassNotFoundException: org.apache.commons.lang3.RandomStringUtils
at java.net.URLClassLoader.findClass(URLClassLoader.java:382)
at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:349)
at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
... 1 more
Questions:
how is it possible that project compiles but then errors are returned at compiling time? Why the import in App is accepted but instruction:
System.out.println("Stringa generata casualmente: " + RandomStringUtils.random(16, true, true).toUpperCase());
generates an exception?
what should I correct/execute to allow my program to work and use correctly dependencies?

when you create a simple java project you define a set of dependencies in the pom but if you don't create a java archive file (ejb-jar or war) all the dependencies are not available at runtime if you run the jar compiled in the target directory.
There are two solutions:
Create a uber jar that include all your depenencies in your jar: use stackoverflow solution
when you run the jar from command line you have to add the dependencies to the classpath:
java -cp "/path/dependencies/dep1.jar;/path/dependencies/dep2.jar" -jar myApp.jar

Related

Can launch Spring Boot from Eclipse (STS) but not from CLI

I have a problem that I can't seem to resolve. I have no issues starting a Spring Boot application from Eclipse (Oxygen) with STS 3.9.2, from the Boot Dashboard:
However, when I try to run it from command line, I get an error that files are missing:
Exception in thread "main" java.lang.RuntimeException:
java.lang.reflect.InvocationTargetException at
org.springframework.boot.loader.MainMethodRunner.run(MainMethodRunner.java:62)
at java.lang.Thread.run(Thread.java:748) Caused by:
java.lang.reflect.InvocationTargetException at
sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498) at
org.springframework.boot.loader.MainMethodRunner.run(MainMethodRunner.java:54)
... 1 more Caused by: java.lang.ArrayStoreException:
sun.reflect.annotation.TypeNotPresentExceptionProxy at
sun.reflect.annotation.AnnotationParser.parseClassArray(AnnotationParser.java:724)
at
sun.reflect.annotation.AnnotationParser.parseArray(AnnotationParser.java:531)
at
sun.reflect.annotation.AnnotationParser.parseMemberValue(AnnotationParser.java:355)
at
sun.reflect.annotation.AnnotationParser.parseAnnotation2(AnnotationParser.java:286)
at
sun.reflect.annotation.AnnotationParser.parseAnnotations2(AnnotationParser.java:120)
at
sun.reflect.annotation.AnnotationParser.parseAnnotations(AnnotationParser.java:72)
at java.lang.Class.createAnnotationData(Class.java:3521) at
java.lang.Class.annotationData(Class.java:3510) at
java.lang.Class.getAnnotations(Class.java:3446) at
org.springframework.core.type.StandardAnnotationMetadata.(StandardAnnotationMetadata.java:68)
at
org.springframework.beans.factory.annotation.AnnotatedGenericBeanDefinition.(AnnotatedGenericBeanDefinition.java:56)
at
org.springframework.context.annotation.AnnotatedBeanDefinitionReader.registerBean(AnnotatedBeanDefinitionReader.java:139)
at
org.springframework.context.annotation.AnnotatedBeanDefinitionReader.registerBean(AnnotatedBeanDefinitionReader.java:127)
at
org.springframework.context.annotation.AnnotatedBeanDefinitionReader.register(AnnotatedBeanDefinitionReader.java:122)
at
org.springframework.boot.BeanDefinitionLoader.load(BeanDefinitionLoader.java:158)
at
org.springframework.boot.BeanDefinitionLoader.load(BeanDefinitionLoader.java:134)
at
org.springframework.boot.BeanDefinitionLoader.load(BeanDefinitionLoader.java:126)
at
org.springframework.boot.SpringApplication.load(SpringApplication.java:708)
at
org.springframework.boot.SpringApplication.createAndRefreshContext(SpringApplication.java:357)
at
org.springframework.boot.SpringApplication.run(SpringApplication.java:307)
at
org.springframework.boot.SpringApplication.run(SpringApplication.java:1191)
at
org.springframework.boot.SpringApplication.run(SpringApplication.java:1180)
at se.itab.bos.admin.AdminServer.main(AdminServer.java:37) ... 6
more
I tried commenting out the following from my startup class:
#SpringBootApplication
#Import({
// AppConfig.class
// , ActiveMqServerConfig.class
// , MetricConfig.class
// , AdminConfig.class
// , SystemConfig.class
// , SystemMessageRouterConfig.class
// , CommandConfig.class
// , AdminMessageRouterConfig.class
})
public class AdminServer {
This solves the issue so that I can launch from command line, but I don't understand why. In my pom.xml I have every other module defined, in which these files are contained.
I am using Spring Boot Starter 1.3.5.RELEASE and Java 8.
Any help would be greatly appreciated.
UPDATED
This is my full pom:
<?xml version="1.0" encoding="UTF-8"?>
<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/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>se.bos</groupId>
<artifactId>bos-parent</artifactId>
<version>1.0.0-SNAPSHOT</version>
<relativePath>../bos-parent</relativePath>
</parent>
<artifactId>bos-admin</artifactId>
<packaging>jar</packaging>
<name>BOS Admin</name>
<properties>
<java.version>1.7</java.version>
<start-class>se.bos.admin.AdminServer</start-class>
</properties>
<dependencies>
<!-- operations: spring boot -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-remote-shell</artifactId>
</dependency>
<!-- operations: spring boot admin -->
<dependency>
<groupId>de.codecentric</groupId>
<artifactId>spring-boot-admin-starter-client</artifactId>
</dependency>
<!-- application: bos -->
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>bos-site</artifactId>
</dependency>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>bos-server</artifactId>
</dependency>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>bos-core</artifactId>
</dependency>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>bos-client</artifactId>
</dependency>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>bos-model</artifactId>
</dependency>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>bos-system</artifactId>
</dependency>
<!-- application: spring boot -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- test -->
<!-- -->
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<executable>true</executable>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>${java.version}</source>
<target>${java.version}</target>
</configuration>
</plugin>
</plugins>
</build>
</project>
To start the project from command line, I run:
mvn clean install
java -jar target/admin.jar
After commenting out each import one by one, I also found that the problem stems from imported modules, but have not yet found why.
Running java -version from command line:
openjdk version "1.8.0_151"
OpenJDK Runtime Environment (build 1.8.0_151-8u151-b12-0ubuntu0.16.04.2-b12)
OpenJDK 64-Bit Server VM (build 25.151-b12, mixed mode)
This is the same as what is used in Eclipse and what is in JAVA_HOME
Using mvn clean install will not produce the executable jar file for you, as this will not package the executable spring boot libraries and pom dependencies. It will only produce a jar file containing only your code.
Using the spring-boot-maven-plugin you need to execute the spring-boot:repackage goal and phase in order for the executable jar file to be appropriately packaged with the spring boot/pom dependencies and ready to be executed on the command line. i.e. run mvn package spring-boot:repackage and then run your application on the command line.
Full details on this can be found in the Spring Boot Maven Plugin Documentation and the spring-boot:repackage goal.
Note: It works in Eclipse because Eclispe has setup your classpath appropriately to reference the dependencies in your pom at compile and runtime, whereas your compiled jar file does not.

Issues with javac compilation errors and Maven dependency resolution

I'm a "noob" when it comes to Maven. I've used ANT in the past, but not enough Maven to make it "stick" with me.
Here is my problem. I'm attempting to write a java program that will parse JSON files for relevant information and then generate CSV files for upload using a proprietary tool that only uploads CSV files. I built the project using Maven. The program will use the Google Gson library, which I listed as a dependency in my POM file (included below). When I execute "mvn compile", Maven returns an error indicating that the package Maven should be resolving via its dependency management features doesn't exist.
Specific error:
"error: package com.google.code.gson does not exist"
Here is my POM file:
<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.acumen.app</groupId>
<artifactId>CatalogConverter</artifactId>
<packaging>jar</packaging>
<version>1.0-SNAPSHOT</version>
<name>CatalogConverter</name>
<url>http://maven.apache.org</url>
<build>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.3.2</version>
<configuration>
<source>1.7</source>
<target>1.7</target>
</configuration>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.3.1</version>
<scope>compile</scope>
</dependency>
</dependencies>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
</project>
I have an import statement in my java application class which should be resolvable based upon Maven downloading my dependencies, if my understanding of Maven is correct. Here is the import statement.
import com.google.code.gson.Gson;
So my question is, why will Maven not compile my code? I don't think I have misconfigured the import nor the POM file. Though, that is always debatable! I can go to my local Maven "repo" and see that the jars were, in fact, downloaded. I'm fairly certain that the error is "user error", so where am I making the mistakes?
I don't believe "provided" is the correct dependency because the jar files are needed for successful compilation and must be downloaded (since no container server or other mechanism will resolve them for me). The application will execute as a jar itself.
in your version of gson it must be
import com.google.gson.Gson;

Maven Eclipse and Dependencies

I have an Maven Eclipse project and it runs fine within Eclipse, however if I attempt to run it from the command line it fails to find the dependencies.
The pom.xml file:
<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.something.or.rather.myapp</groupId>
<artifactId>MyApp</artifactId>
<packaging>jar</packaging>
<version>1.0-SNAPSHOT</version>
<name>MyApp</name>
<url>http://maven.apache.org</url>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.cloudant</groupId>
<artifactId>cloudant-client</artifactId>
<version>1.0.1</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.3</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
</plugins>
</build>
</project>
From the project directory (MyApp):
mvn eclipse:eclipse // runs fine
mvn package // runs fine
java -cp target/MyApp-1.0-SNAPSHOT.jar com.something.or.rather.myapp.MyMainClass // fails
...
Exception in thread "main" java.lang.NoClassDefFoundError: com/cloudant/client/api/CloudantClient
...
I notice if I put the full path of the Cloudant JAR file in the java command it resolves that exception only to raise another.
java -cp /full/path/to/cloudant-client-1.0.1jar:target/MyApp-1.0-SNAPSHOT.jar com.something.or.rather.myapp.MyMainClass // still fails
...
Exception in thread "main" java.lang.NoClassDefFoundError: org/apache/http/client/methods/HttpRequestBase
...
Any ideas? This is painful.
By default maven builds thin jars without the project dependencies, only the project classes.
What you want is a fat jar. To do this have a look at:Building a fat jar using maven
Hope this helps

no native library found for maven plugin project

I want to integrate a leap motion app into Weasis Dicom Viewer.
Projects:
Weasis-maven-plugin -> where my leap implementation is
Weasis-framework -> dicom viewer
Weasis-launcher -> This is where I launch the Dicom viewer.
What I've done already:
have m2e with eclipse and added the LeapJava.jar to plugin project and set the location of the native library
installed LeapJava.jar into the .m2/repository folder so that mvn install on my maven plugin build succeeds
added into the pom.xml of maven-plugin
updated maven project
what doesn't work:
when i launch the application, I get no LeapJava in java.library.path
I've seen some other threads that says I need to manually add -Djava.library.path to the VM arguments. However, when I add that to the launcher run config in eclipse the library not found still exists. Should I be adding this somewhere? Any help is greatly appreciated.
This is my pom.xml for the weasis-plugin:
<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">
<parent>
<artifactId>weasis-parent</artifactId>
<groupId>org.weasis</groupId>
<version>2.0.0-SNAPSHOT</version>
<relativePath>../../weasis-parent/pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>LeapPlugin</groupId>
<artifactId>UBC</artifactId>
<packaging>bundle</packaging>
<name>Tool panel sample [${project.artifactId}]</name>
<properties>
<bundle.symbolicName>${project.artifactId}</bundle.symbolicName>
</properties>
<version>0.0.1-SNAPSHOT</version>
<build>
<plugins>
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-scr-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
<configuration>
<instructions>
<Service-Component>OSGI-INF/*.xml</Service-Component>
</instructions>
</configuration>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>org.weasis.core</groupId>
<artifactId>weasis-core-api</artifactId>
<version>${project.parent.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.weasis.core</groupId>
<artifactId>weasis-core-ui</artifactId>
<version>${project.parent.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.weasis.dicom</groupId>
<artifactId>weasis-dicom-viewer2d</artifactId>
<version>${project.parent.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.leapmotion.leap</groupId>
<artifactId>leapMotion</artifactId>
<version>1.0.0</version>
<scope>system</scope>
<systemPath>${basedir}/sdk/LeapJava.jar</systemPath>
</dependency>
</dependencies>
When I add the "systemPath" I can still mvn install properly but when i run the launcher project now I get org.osgi.framework.BundleException: "Unresolved constraint in bundle"
UPDATE 1:
So right now this is what my pom.xml looks like
<groupId>com.leapmotion.leap</groupId>
<artifactId>leapMotion</artifactId>
<version>1.0.0</version>
Exception in thread "Thread-5" java.lang.UnsatisfiedLinkError: no leapMotion-1.0.0 in java.library.path
at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1764)
at java.lang.Runtime.loadLibrary0(Runtime.java:823)
at java.lang.System.loadLibrary(System.java:1044)
at weasisTool.SampleTool$1.run(SampleTool.java:98)
Not sure if this is the actual solution.
But I added:
nativedependency-plugin in my pom.xml
made sure to do mvn package on the plugin project folder (this generated some files under target/ folder
added -Djava.library.path to the VM argument and it compiles and runs!

Spark Java and the classpath

I'm trying to start up with http://www.sparkjava.com/, a small Java web framework. The instructions tell you to add it as a Maven dependency (done), but when I mvn package, I get a class def not found for spark/Route.
I assume this is from Spark not being in my classpath. How can I add it? Would it go in pom.xml?
EDIT: Sorry, here is 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.bernsteinbear.myapp</groupId>
<artifactId>myapp</artifactId>
<packaging>jar</packaging>
<version>1.0-SNAPSHOT</version>
<name>myapp</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>com.sparkjava</groupId>
<artifactId>spark-core</artifactId>
<version>1.1</version>
</dependency>
</dependencies>
</project>
EDIT: Trace
λ chaos myapp → java -cp target/myapp-1.0-SNAPSHOT.jar com.bernsteinbear.myapp.App
Exception in thread "main" java.lang.NoClassDefFoundError: spark/Route
Caused by: java.lang.ClassNotFoundException: spark.Route
at java.net.URLClassLoader$1.run(URLClassLoader.java:202)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:190)
at java.lang.ClassLoader.loadClass(ClassLoader.java:306)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:301)
at java.lang.ClassLoader.loadClass(ClassLoader.java:247)
aaaand the source (the example from the homepage):
λ chaos myapp → cat src/main/java/com/bernsteinbear/myapp/App.java
/**
* Hello world!
*
*/
package com.bernsteinbear.myapp;
import spark.*;
import static spark.Spark.*;
public class App {
public static void main(String[] args) {
get(new Route("/hello") {
#Override
public Object handle(Request request, Response response) {
return "Hello World!";
}
});
}
}
What works for me to make it run:
mvn package
mvn exec:java -Dexec.mainClass="com.your.class.with.main.method"
I was facing the same problem when trying to deploy the application to Heroku. I added the following to my POM.xml. This plugin ensures that the maven dependencies are copied over to your application.
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<version>2.4</version>
<executions>
<execution>
<id>copy-dependencies</id>
<phase>package</phase>
<goals><goal>copy-dependencies</goal></goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
After this you can go ahead and run
java -cp target/classes:"target/dependency/*" com.bernsteinbear.myapp.App
to run your application
Ok, so the maven package itself did not throw the exception; it was execution. The package produced by Maven must not contain everything required to run the app. (You can unzip the jar if you're curious about exactly what it contains.) So now it's a matter of either including Maven dependencies to your packaged classpath (I wouldn't necessarily recommend bothering with that yet), or instead simply including additional JARs in your runtime classpath (for Unix looks like -cp a.jar:b.jar:...). I suspect the spark-dependencies module has all the missing dependencies. (Unfortunately the readme is not very clear on this.)
Assuming the spark-dependencies module is sufficient, you'd just do:
java -cp target/myapp-1.0-SNAPSHOT.jar:lib/jetty-webapp-7.3.0.v20110203.jar:lib/log4j-1.2.14.jar:lib/slf4j-api-1.6.1.jar:lib/servlet-ap‌​i-3.0.pre4.jar:lib/slf4j-log4j12-1.6.1.jar com.bernsteinbear.myapp.App
Note you have to get the paths right. This is assuming the spark-dependencies zip file is unzipped to a lib folder.
If that still doesn't do it, or for additional information or to give feedback, you might also ping the author directly.

Categories