spring boot jar doesn't work with -cp option - spring-boot

I have always created uber jar with spring-boot and used java -jar springboot.jar command to start container. Now my requirement is changed and I need to point to external classpath as follows which is not fixed. I still create uber jar for spring boot.
java -Dprofile=dev -cp springboot.jar:/usr/local/hadoop/lib/*:/usr/local/hbase/lib/* com.myapp.Application
It throws following:
Exception in thread "main" java.lang.NoClassDefFoundError: org/springframework/scheduling/annotation/AsyncConfigurer
at java.lang.ClassLoader.defineClass1(Native Method)
at java.lang.ClassLoader.defineClass(ClassLoader.java:800)
at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:142)
at java.net.URLClassLoader.defineClass(URLClassLoader.java:449)
at java.net.URLClassLoader.access$100(URLClassLoader.java:71)
at java.net.URLClassLoader$1.run(URLClassLoader.java:361)
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)
at sun.launcher.LauncherHelper.checkAndLoadMain(LauncherHelper.java:482)
Caused by: java.lang.ClassNotFoundException: org.springframework.scheduling.annotation.AsyncConfigurer
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)
... 13 more
My Application class uses org.springframework.scheduling.annotation.AsyncConfigurer
Here's maven:
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<excludeGroupIds>org.apache.hadoop,org.apache.hbase</excludeGroupIds>
<excludeArtifactIds>hadoop-yarn-common,hadoop-yarn-client,hadoop-annotations,hadoop-yarn-api,hadoop-mapreduce-client-jobclient,
hadoop-mapreduce-client-shuffle,hadoop-mapreduce-client-app,hadoop-mapreduce-client-core,hadoop-mapreduce-client-common,
hadoop-yarn-server-common,hadoop-hdfs,hadoop-auth,hadoop-common,parquet-hadoop,hadoop-client</excludeArtifactIds>
</configuration>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<configuration>
<archive>
<manifest>
<addDefaultImplementationEntries>true</addDefaultImplementationEntries>
<addClasspath>true</addClasspath>
<classpathPrefix>lib/</classpathPrefix>
<mainClass>com.myApp.Application</mainClass>
</manifest>
<manifestEntries>
<Build-Scm-Branch>${scmBranch}</Build-Scm-Branch>
<Build-Revision-Number>${buildNumber}</Build-Revision-Number>
<Timestamp>${timestamp}</Timestamp>
</manifestEntries>
</archive>
</configuration>
</plugin>
One thing I notice that spring-boot-maven-plugin keeps all the uber jars inside lib folder instead of extracting every class in put it in flat hierarchy like shade plugin. I don't know if that's the reason -cp is not recognizing any uber classes ?
Thanks

If you use the PropertiesLauncher by setting the <layout>ZIP</laout> for the spring-boot-maven-plugin, you can extend your classpath using the loader.path property. E.g.:
java -Dprofile=dev -Dloader.path=springboot.jar,/usr/local/hadoop/lib,/usr/local/hbase/lib -jar springboot.jar
See http://docs.spring.io/spring-boot/docs/current-SNAPSHOT/reference/htmlsingle/#executable-jar-property-launcher-features in spring boots reference guide.

Related

How to include external jar within package

I have spring boot project which is packaged into jar.
I have external jar(Jasper) add into pom like below
<dependency>
<groupId>net.sf.jasperreports</groupId>
<artifactId>jasperreports</artifactId>
<version>${jasperreports.version}</version>
<scope>system</scope>
<systemPath>${project.basedir}/lib/jasperreports-6.13.0.jar</systemPath>
</dependency>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<executions>
<execution>
<id>install-jasperreports613</id>
<phase>clean</phase>
<configuration>
<file>${project.basedir}/lib/jasperreports-6.13.0.jar</file>
<repositoryLayout>default</repositoryLayout>
<groupId>net.sf.jasperreports</groupId>
<artifactId>jasperreports</artifactId>
<version>6.13.0</version>
<packaging>jar</packaging>
<generatePom>true</generatePom>
</configuration>
<goals>
<goal>install-file</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
When run jar (java -jar myapp.jar) i am gettig classdefNotfound for jasper.
Caused by: java.lang.NoClassDefFoundError: net/sf/jasperreports/engine/JRDataSource
at java.lang.Class.getDeclaredMethods0(Native Method) ~[na:1.8.0_202]
at java.lang.Class.privateGetDeclaredMethods(Unknown Source) ~[na:1.8.0_202]
at java.lang.Class.getDeclaredMethods(Unknown Source) ~[na:1.8.0_202]
at org.springframework.util.ReflectionUtils.getDeclaredMethods(ReflectionUtils.java:463) ~[spring-core-5.2.9.RELEASE.jar!/:5.2.9.RELEASE]
... 29 common frames omitted
Caused by: java.lang.ClassNotFoundException: net.sf.jasperreports.engine.JRDataSource
at java.net.URLClassLoader.findClass(Unknown Source) ~[na:1.8.0_202]
at java.lang.ClassLoader.loadClass(Unknown Source) ~[na:1.8.0_202]
at org.springframework.boot.loader.LaunchedURLClassLoader.loadClass(LaunchedURLClassLoader.java:151) ~[e-statement-core-0.0.1-SNAPSHOT.jar:0.0.1-SNAPSHOT]
at java.lang.ClassLoader.loadClass(Unknown Source) ~[na:1.8.0_202]
... 33 common frames omitted
When i extracted the package and there is no jasper lib is included in package.
How to include the external libraries into package.
The jar jasperreports is on MavenCentral. So if you have internet access, there is no need to handle that manually.

Add maven's output directory to exec:java classpath

I want to add the target/classes directory to maven's exec:java classpath. The compilation and runtime dependencies are handled fine, but the resources copied from src/*/resources are not available during execution. I am almost sure it is because the plugins' classpath includes only the project dependencies and not the target/classes directory. I'd like to be able to run the application during development as mvn clean compile exec:java
while leaving all properties files, and other files in the resources directories.
I've tried several variations of exec configuration but I can't seem to get it right:
my pom.xml:
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<version>1.2.1</version>
<configuration>
<executable>java</executable>
<mainClass>Example</mainClass>
<arguments>
<argument>-cp</argument>
<classpath/>
<argument>%classpath:target/classes</argument>
<argument>someFile.txt</argument>
</arguments>
</configuration>
</plugin>
I don't think this one is correct syntax because I'm getting an ArrayStoreException:
java.lang.ArrayStoreException
at java.lang.System.arraycopy(Native Method)
at java.util.Arrays.copyOf(Arrays.java:2763)
at java.util.ArrayList.toArray(ArrayList.java:305)
at org.codehaus.plexus.component.configurator.converters.composite.ArrayConverter.fromConfiguration(ArrayConverter.java:141)
at org.codehaus.plexus.component.configurator.converters.ComponentValueSetter.configure(ComponentValueSetter.java:247)
at org.codehaus.plexus.component.configurator.converters.composite.ObjectWithFieldsConverter.processConfiguration(ObjectWithFieldsConverter.java:137)
at org.codehaus.plexus.component.configurator.BasicComponentConfigurator.configureComponent(BasicComponentConfigurator.java:56)
at org.apache.maven.plugin.DefaultPluginManager.populatePluginFields(DefaultPluginManager.java:1357)
at org.apache.maven.plugin.DefaultPluginManager.getConfiguredMojo(DefaultPluginManager.java:724)
at org.apache.maven.plugin.DefaultPluginManager.executeMojo(DefaultPluginManager.java:468)
at org.apache.maven.lifecycle.DefaultLifecycleExecutor.executeGoals(DefaultLifecycleExecutor.java:694)
at org.apache.maven.lifecycle.DefaultLifecycleExecutor.executeStandaloneGoal(DefaultLifecycleExecutor.java:569)
at org.apache.maven.lifecycle.DefaultLifecycleExecutor.executeGoal(DefaultLifecycleExecutor.java:539)
at org.apache.maven.lifecycle.DefaultLifecycleExecutor.executeGoalAndHandleFailures(DefaultLifecycleExecutor.java:387)
at org.apache.maven.lifecycle.DefaultLifecycleExecutor.executeTaskSegments(DefaultLifecycleExecutor.java:348)
at org.apache.maven.lifecycle.DefaultLifecycleExecutor.execute(DefaultLifecycleExecutor.java:180)
at org.apache.maven.DefaultMaven.doExecute(DefaultMaven.java:328)
at org.apache.maven.DefaultMaven.execute(DefaultMaven.java:138)
at org.apache.maven.cli.MavenCli.main(MavenCli.java:362)
at org.apache.maven.cli.compat.CompatibleMain.main(CompatibleMain.java:60)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.codehaus.classworlds.Launcher.launchEnhanced(Launcher.java:315)
at org.codehaus.classworlds.Launcher.launch(Launcher.java:255)
at org.codehaus.classworlds.Launcher.mainWithExitCode(Launcher.jav
I used example configuration poms from here and here.
By default the target/classes and all the dependencies are in the classpath when you use exec-maven-plugin plugin.
I have similar setup and following config works for me. In my Test class I read one xml file as Thread.currentThread().getContextClassLoader().getResourceAsStream("mapping.xml"). I have kept the file in src/main/resources which after build is available under target/classes.
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<version>1.2.1</version>
<executions>
<execution>
<goals>
<goal>exec</goal>
</goals>
</execution>
</executions>
<configuration>
<executable>java</executable>
<mainClass>com.Test</mainClass>
</configuration>
</plugin>

hibernate3-maven-plugin generates java.lang.ClassNotFoundException: org.hibernate.util.ReflectHelper

I am trying to generate a schema (ddl) from my orm.xml file. I'm using hibernate3-maven-plugin. I'm using JPA with hibernate as the implementation, but am open to other implementations or maven plugins. The code in my pom.xml is:
<build>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>hibernate3-maven-plugin</artifactId>
<version>3.0</version>
<configuration>
<hibernatetool>
<jpaconfiguration persistenceunit="unitname" />
<hbm2ddl export="false" create="true"
update="true" format="true" outputfilename="schemaDiff.ddl" />
</hibernatetool>
</configuration>
</plugin>
</plugins>
</build>
The command I run is:
mvn hibernate3:hbm2ddl -e
The error I received is:
Caused by: java.lang.NoClassDefFoundError: org/hibernate/util/ReflectHelper
at org.hibernate.tool.ant.JPAConfigurationTask.createConfiguration(JPAConfigurationTask.java:32)
at org.hibernate.tool.ant.ConfigurationTask.getConfiguration(ConfigurationTask.java:54)
at org.hibernate.tool.ant.HibernateToolTask.getConfiguration(HibernateToolTask.java:302)
at org.hibernate.tool.ant.Hbm2DDLExporterTask.createExporter(Hbm2DDLExporterTask.java:51)
at org.hibernate.tool.ant.ExporterTask.execute(ExporterTask.java:39)
at org.hibernate.tool.ant.HibernateToolTask.execute(HibernateToolTask.java:186)
at org.apache.tools.ant.UnknownElement.execute(UnknownElement.java:291)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.apache.tools.ant.dispatch.DispatchUtils.execute(DispatchUtils.java:106)
... 28 more
Caused by: java.lang.ClassNotFoundException: org.hibernate.util.ReflectHelper
at org.codehaus.plexus.classworlds.strategy.SelfFirstStrategy.loadClass(SelfFirstStrategy.java:50)
at org.codehaus.plexus.classworlds.realm.ClassRealm.loadClass(ClassRealm.java:244)
at org.codehaus.plexus.classworlds.realm.ClassRealm.loadClass(ClassRealm.java:230)
... 40 more
George Herolyants presents a solution here.
http://doingenterprise.blogspot.com/2012/05/schema-generation-with-hibernate-4-jpa.html

java.lang.NullPointerException executing accelo with maven

I am trying to execute the acceleo project using maven.
here is the pom configuration:
pom.xml
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<version>1.2.1</version>
<configuration>
<mainClass>src.AcceleoProject.files.Generate</mainClass>
<arguments>
<argument>/${project.basedir}/src/main/java/src/AcceleoProject/files/model.uml</argument>
<argument>/${project.basedir}/src/main/java/src/AcceleoProject/files/out</argument>
</arguments>
</configuration>
</plugin>
Error
When I execute the pom I get the following error:
java.lang.reflect.InvocationTargetException
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.codehaus.mojo.exec.ExecJavaMojo$1.run(ExecJavaMojo.java:297)
at java.lang.Thread.run(Thread.java:662)
Caused by: java.lang.NullPointerException
at org.eclipse.core.internal.runtime.InternalPlatform.getBundle(InternalPlatform.java:861)
at org.eclipse.core.runtime.Platform.getBundle(Platform.java:1185)
at org.eclipse.acceleo.common.internal.utils.workspace.BundleURLConverter.resolveBundle(BundleURLConverter.java:186)
at org.eclipse.acceleo.common.internal.utils.workspace.BundleURLConverter.resolveAsPlatformPlugin(BundleURLConverter.java:137)
at org.eclipse.acceleo.engine.internal.environment.AcceleoEvaluationEnvironment.loadDynamicModules(AcceleoEvaluationEnvironment.java:763)
at org.eclipse.acceleo.engine.internal.environment.AcceleoEvaluationEnvironment.mapDynamicOverrides(AcceleoEvaluationEnvironment.java:899)
at org.eclipse.acceleo.engine.internal.environment.AcceleoEvaluationEnvironment.<init>(AcceleoEvaluationEnvironment.java:139)
at org.eclipse.acceleo.engine.internal.environment.AcceleoEnvironmentFactory.createEvaluationEnvironment(AcceleoEnvironmentFactory.java:124)
at org.eclipse.ocl.internal.evaluation.QueryImpl.getEvaluationEnvironment(QueryImpl.java:286)
at org.eclipse.ocl.ecore.QueryImpl.getEvaluationEnvironment(QueryImpl.java:74)
at org.eclipse.acceleo.engine.generation.AcceleoEngine.doEvaluate(AcceleoEngine.java:268)
at org.eclipse.acceleo.engine.generation.AcceleoEngine.evaluate(AcceleoEngine.java:145)
at org.eclipse.acceleo.engine.service.AcceleoService.doGenerateTemplate(AcceleoService.java:869)
at org.eclipse.acceleo.engine.service.AcceleoService.doGenerate(AcceleoService.java:575)
at org.eclipse.acceleo.engine.service.AbstractAcceleoGenerator.generate(AbstractAcceleoGenerator.java:188)
at org.eclipse.acceleo.engine.service.AbstractAcceleoGenerator.doGenerate(AbstractAcceleoGenerator.java:158)
at src.AcceleoProject.files.Generate.doGenerate(Generate.java:197)
at src.AcceleoProject.files.Generate.main(Generate.java:159)
... 6 more
I think its related with the output file where i want to generate my files.
Anyone has an idea about this?
Thank you in advance.

Maven classpath trouble with Maven-selenium plugin

We're using Maven 3.0.3 and using the Maven Selenium plugin to attempt to start a Selenium server. We have this dependency in our pom ...
<dependency>
<groupId>org.seleniumhq.selenium</groupId>
<artifactId>selenium-server</artifactId>
<version>2.19.0</version>
<classifier>noexe</classifier>
</dependency>
Then in the pre-integration phase we try and start Selenium server ...
<build>
...
<plugins>
...
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>selenium-maven-plugin</artifactId>
<version>1.1</version>
<executions>
<execution>
<id>start</id>
<phase>pre-integration-test</phase>
<goals>
<goal>start-server</goal>
</goals>
<configuration>
<background>true</background>
<logOutput>true</logOutput>
</configuration>
</execution>
</executions>
</plugin>
But the server fails to start with the error ...
java.lang.NoClassDefFoundError: org/openqa/selenium/server/SeleniumServer
Caused by: java.lang.ClassNotFoundException: org.openqa.selenium.server.SeleniumServer
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)
Could not find the main class: org.openqa.selenium.server.SeleniumServer. Program will exit.
Exception in thread "main"
I have verified that the dependency above contains the missing class. How else can I troubleshoot this classpath problem or can you tell what is wrong with the setup I've listed here?
Thanks, - Dave

Resources