Maven not finding apache RandomStringGenerator - java

I am trying to use the new Apache Commons Text new random string generator, but I can't find any usage on the Internet on how to properly import it. Maven builds successfully, but when I try to run my jar file from the command line with the following command
java -cp target/my-app-1.0.jar com.mycompany.app.App
…I get the below error:
Exception in thread "main" java.lang.NoClassDefFoundError: org/apache/commons/text/RandomStringGenerator$Builder
at com.mycompany.app.App.main(App.java:8)
Caused by: java.lang.ClassNotFoundException: org.apache.commons.text.RandomStringGenerator$Builder
at java.net.URLClassLoader.findClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
... 1 more
I also have this warning during the build:
The POM for org.apache.commons:commons-text:jar:1.1 is invalid, transitive dependencies (if any) will not be available, enable debug logging for more detail
Here is the Maven debug version:
[WARNING] The POM for org.apache.commons:commons-text:jar:1.1 is invalid, transitive dependencies (if any) will not be available: 1 problem was encountered while building the effective model
[FATAL] Non-parseable POM C:\Users\me\.m2\repository\org\apache\commons\commons-text\1.1\commons-text-1.1.pom: only whitespace content allowed before start tag and not a (position: START_DOCUMENT seen a... #1:1) # line 1, column 1
Here is my App.java code:
package com.mycompany.app;
import org.apache.commons.text.RandomStringGenerator;
public class App {
public static void main(String[] args) {
// Generates a 20 code point string, using only the letters a-z
RandomStringGenerator generator = new RandomStringGenerator.Builder()
.withinRange('a', 'z').build();
String randomLetters = generator.generate(20);
System.out.println( randomLetters );
}
}
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.mycompany.app</groupId>
<artifactId>my-app</artifactId>
<packaging>jar</packaging>
<version>1.0</version>
<name>my-app</name>
<url>http://maven.apache.org</url>
<dependencies>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-text</artifactId>
<version>1.1</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
</dependencies>
</project>

If you want to run you application from a jar, you will need an exploded jar. The default class loader will not find the apache jar from your jar.
You can use the shade plugin to create an exploded jar. Add something like below to your pom.xml:
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>3.0.0</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<transformers>
<transformer
implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
<manifestEntries>
<Main-Class>com.mycompany.app.App</Main-Class>
</manifestEntries>
</transformer>
</transformers>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
Then, you can run with the following:
java -jar target/my-app-1.0.jar

Related

Can run in Intellij, but jar file fails

Instead of running Quarkus, I'm running OptaPlanner through a Main class entry point in Kotlin.
This works great within Intellij where I have a simple Run Configuration set up for it.
object Main {
lateinit var solverFactory: SolverFactory<VehicleRoutingSolution>
lateinit var solver: Solver<VehicleRoutingSolution>
lateinit var scoreManager: ScoreManager<VehicleRoutingSolution, SimpleLongScore>
#JvmStatic
fun main(args: Array<String>) {
...
However, when I create an Intellij artifact for a jar and try to run it, I get this:
java -jar acme.jar
Apr. 28, 2022 5:21:13 P.M. com.sun.xml.bind.v2.runtime.reflect.opt.Injector <clinit>
SEVERE: null
java.security.PrivilegedActionException: java.lang.NoSuchMethodException: sun.misc.Unsafe.defineClass(java.lang.String,[B,int,int,java.lang.ClassLoader,java.security.ProtectionDomain)
at java.base/java.security.AccessController.doPrivileged(AccessController.java:573)
at com.sun.xml.bind.v2.runtime.reflect.opt.Injector.<clinit>(Injector.java:166)
at com.sun.xml.bind.v2.runtime.reflect.opt.AccessorInjector.prepare(AccessorInjector.java:51)
at com.sun.xml.bind.v2.runtime.reflect.opt.OptimizedAccessorFactory.get(OptimizedAccessorFactory.java:157)
at com.sun.xml.bind.v2.runtime.reflect.Accessor$FieldReflection.optimize(Accessor.java:255)
at com.sun.xml.bind.v2.runtime.property.SingleElementLeafProperty.<init>(SingleElementLeafProperty.java:62)
at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:77)
at java.base/jdk.internal.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.base/java.lang.reflect.Constructor.newInstanceWithCaller(Constructor.java:499)
at java.base/java.lang.reflect.Constructor.newInstance(Constructor.java:480)
at com.sun.xml.bind.v2.runtime.property.PropertyFactory.create(PropertyFactory.java:99)
at com.sun.xml.bind.v2.runtime.ClassBeanInfoImpl.<init>(ClassBeanInfoImpl.java:150)
at com.sun.xml.bind.v2.runtime.JAXBContextImpl.getOrCreate(JAXBContextImpl.java:484)
at com.sun.xml.bind.v2.runtime.JAXBContextImpl.<init>(JAXBContextImpl.java:301)
at com.sun.xml.bind.v2.runtime.JAXBContextImpl.<init>(JAXBContextImpl.java:109)
at com.sun.xml.bind.v2.runtime.JAXBContextImpl$JAXBContextBuilder.build(JAXBContextImpl.java:1126)
at com.sun.xml.bind.v2.ContextFactory.createContext(ContextFactory.java:135)
at com.sun.xml.bind.v2.JAXBContextFactory.createContext(JAXBContextFactory.java:35)
at javax.xml.bind.ContextFinder.find(ContextFinder.java:393)
at javax.xml.bind.JAXBContext.newInstance(JAXBContext.java:691)
at javax.xml.bind.JAXBContext.newInstance(JAXBContext.java:632)
at org.optaplanner.core.impl.io.jaxb.GenericJaxbIO.<init>(GenericJaxbIO.java:88)
at org.optaplanner.core.impl.io.jaxb.GenericJaxbIO.<init>(GenericJaxbIO.java:80)
at org.optaplanner.core.impl.io.jaxb.SolverConfigIO.<init>(SolverConfigIO.java:27)
at org.optaplanner.core.config.solver.SolverConfig.createFromXmlReader(SolverConfig.java:213)
at org.optaplanner.core.config.solver.SolverConfig.createFromXmlInputStream(SolverConfig.java:188)
at org.optaplanner.core.config.solver.SolverConfig.createFromXmlResource(SolverConfig.java:128)
at org.optaplanner.core.config.solver.SolverConfig.createFromXmlResource(SolverConfig.java:103)
at org.optaplanner.core.api.solver.SolverFactory.createFromXmlResource(SolverFactory.java:55)
at org.acme.bootstrap.Main.initOptaPlanner(Main.kt:112)
at org.acme.bootstrap.Main.main(Main.kt:43)
Caused by: java.lang.NoSuchMethodException: sun.misc.Unsafe.defineClass(java.lang.String,[B,int,int,java.lang.ClassLoader,java.security.ProtectionDomain)
at java.base/java.lang.Class.getMethod(Class.java:2227)
at com.sun.xml.bind.v2.runtime.reflect.opt.Injector$3.run(Injector.java:170)
at com.sun.xml.bind.v2.runtime.reflect.opt.Injector$3.run(Injector.java:166)
at java.base/java.security.AccessController.doPrivileged(AccessController.java:569)
... 31 more
Exception in thread "main" java.lang.NullPointerException: Cannot invoke "java.lang.reflect.Method.invoke(Object, Object[])" because "com.sun.xml.bind.v2.runtime.reflect.opt.Injector.defineClass" is null
at com.sun.xml.bind.v2.runtime.reflect.opt.Injector.inject(Injector.java:294)
at com.sun.xml.bind.v2.runtime.reflect.opt.Injector.inject(Injector.java:66)
at com.sun.xml.bind.v2.runtime.reflect.opt.AccessorInjector.prepare(AccessorInjector.java:57)
at com.sun.xml.bind.v2.runtime.reflect.opt.OptimizedAccessorFactory.get(OptimizedAccessorFactory.java:157)
at com.sun.xml.bind.v2.runtime.reflect.Accessor$FieldReflection.optimize(Accessor.java:255)
at com.sun.xml.bind.v2.runtime.property.SingleElementLeafProperty.<init>(SingleElementLeafProperty.java:62)
at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:77)
at java.base/jdk.internal.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.base/java.lang.reflect.Constructor.newInstanceWithCaller(Constructor.java:499)
at java.base/java.lang.reflect.Constructor.newInstance(Constructor.java:480)
at com.sun.xml.bind.v2.runtime.property.PropertyFactory.create(PropertyFactory.java:99)
at com.sun.xml.bind.v2.runtime.ClassBeanInfoImpl.<init>(ClassBeanInfoImpl.java:150)
at com.sun.xml.bind.v2.runtime.JAXBContextImpl.getOrCreate(JAXBContextImpl.java:484)
at com.sun.xml.bind.v2.runtime.JAXBContextImpl.<init>(JAXBContextImpl.java:301)
at com.sun.xml.bind.v2.runtime.JAXBContextImpl.<init>(JAXBContextImpl.java:109)
at com.sun.xml.bind.v2.runtime.JAXBContextImpl$JAXBContextBuilder.build(JAXBContextImpl.java:1126)
at com.sun.xml.bind.v2.ContextFactory.createContext(ContextFactory.java:135)
at com.sun.xml.bind.v2.JAXBContextFactory.createContext(JAXBContextFactory.java:35)
at javax.xml.bind.ContextFinder.find(ContextFinder.java:393)
at javax.xml.bind.JAXBContext.newInstance(JAXBContext.java:691)
at javax.xml.bind.JAXBContext.newInstance(JAXBContext.java:632)
at org.optaplanner.core.impl.io.jaxb.GenericJaxbIO.<init>(GenericJaxbIO.java:88)
at org.optaplanner.core.impl.io.jaxb.GenericJaxbIO.<init>(GenericJaxbIO.java:80)
at org.optaplanner.core.impl.io.jaxb.SolverConfigIO.<init>(SolverConfigIO.java:27)
at org.optaplanner.core.config.solver.SolverConfig.createFromXmlReader(SolverConfig.java:213)
at org.optaplanner.core.config.solver.SolverConfig.createFromXmlInputStream(SolverConfig.java:188)
at org.optaplanner.core.config.solver.SolverConfig.createFromXmlResource(SolverConfig.java:128)
at org.optaplanner.core.config.solver.SolverConfig.createFromXmlResource(SolverConfig.java:103)
at org.optaplanner.core.api.solver.SolverFactory.createFromXmlResource(SolverFactory.java:55)
at org.acme.bootstrap.Main.initOptaPlanner(Main.kt:112)
at org.acme.bootstrap.Main.main(Main.kt:43)
Shutting down
In solverConfig.xml I'm using <domainAccessType>REFLECTION</domainAccessType> because I cannot get Gizmo to work. I'm not sure if that's related or not, but why is there a difference between an Intellij Run Config and the Jar artifact?
Thanks
*** UPDATE ***
I still get the above error message - even when creating a very basic OptaPlanner project.
Here is my pom.xml file:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://maven.apache.org/POM/4.0.0"
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>
<artifactId>foo</artifactId>
<groupId>org.acme</groupId>
<version>1.0-SNAPSHOT</version>
<packaging>jar</packaging>
<name>Foo</name>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<kotlin.version>1.6.21</kotlin.version>
<kotlin.code.style>official</kotlin.code.style>
<kotlin.compiler.jvmTarget>17</kotlin.compiler.jvmTarget>
<optaplanner.version>8.20.0.Final</optaplanner.version>
</properties>
<repositories>
<repository>
<id>mavenCentral</id>
<url>https://repo1.maven.org/maven2/</url>
</repository>
</repositories>
<build>
<finalName>foo</finalName>
<sourceDirectory>src/main/kotlin</sourceDirectory>
<testSourceDirectory>src/test/kotlin</testSourceDirectory>
<plugins>
<plugin>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-maven-plugin</artifactId>
<version>${kotlin.version}</version>
<executions>
<execution>
<id>compile</id>
<phase>compile</phase>
<goals>
<goal>compile</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<version>3.3.0</version>
<configuration>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
<archive>
<manifest>
<addClasspath>true</addClasspath>
<mainClass>org.acme.bootstrap.Main</mainClass>
</manifest>
</archive>
</configuration>
<executions>
<execution>
<id>make-assembly</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.optaplanner</groupId>
<artifactId>optaplanner-bom</artifactId>
<type>pom</type>
<version>${optaplanner.version}</version>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-stdlib-jdk8</artifactId>
<version>${kotlin.version}</version>
</dependency>
<dependency>
<groupId>org.optaplanner</groupId>
<artifactId>optaplanner-core</artifactId>
</dependency>
</dependencies>
</project>
Here's what I run with Maven:
mvn clean compile package
java -jar ./target/foo-jar-with-dependencies.jar
Note: I'm using openjdk-17.0.2
java --version
openjdk 17.0.2 2022-01-18
OpenJDK Runtime Environment (build 17.0.2+8-86)
OpenJDK 64-Bit Server VM (build 17.0.2+8-86, mixed mode, sharing)
It still runs fine within IntelliJ's system, but from Maven it just throws the above error.
Also, here's my solverConfig.xml for reference.
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<solver xmlns="https://www.optaplanner.org/xsd/solver">
<solutionClass>org.acme.domain.MySolution</solutionClass>
<entityClass>org.acme.domain.Visit</entityClass>
<scoreDirectorFactory>
<constraintProviderClass>org.acme.solver.MyConstraintProvider</constraintProviderClass>
</scoreDirectorFactory>
<termination>
<millisecondsSpentLimit>2000</millisecondsSpentLimit>
</termination>
</solver>
And my Main.kt file:
object Main {
lateinit var solverFactory: SolverFactory<MySolution>
lateinit var solver: Solver<MySolution>
lateinit var scoreManager: ScoreManager<MySolution, SimpleLongScore>
#JvmStatic
fun main(args: Array<String>) {
solverFactory = SolverFactory.createFromXmlResource("solverConfig.xml")
solver = solverFactory.buildSolver()
scoreManager = ScoreManager.create(solverFactory)
}
}
An answer to another question suggests you need an extra artifact in your project. Technically, optaplanner-core module brings it, but the scope is runtime - so that dependency may not show up in the JAR with dependencies. (?) You will need to include it yourself; you can confirm that by checking mvn dependency:tree in your project.
That said, I am not sure why we use the runtime scope here. Maybe we need to re-evaluate.
Also, seeing as you are using an uberjar, I'm going to point to another uberjar-related question to perhaps pre-empt more struggle.

com.google.common.base.Preconditions.checkArgument(ZLjava/lang/String;CLjava/lang/Object;)V

I am using the google BETA API: AutoML Natural Language, after training the API, I did tests in a Java SE project obtaining a satisfactory result, however, when I migrated it to a Java EE project I got different problems. About:
-Java -version: 1.8.0_201
-Payara Version: 5.191
-google-cloud-automl dependecy: 0.97.0-beta
When I try to run the entity extraction service (PredictionServiceClient class) it returns the error java.lang.NoSuchMethodError: com.google.common.base.Preconditions.checkArgument (ZLjava / lang / String; CLjava / lang / Object;) V, according to different sources this error is caused by conflicts between different versions of the guava library. I think my particular error is caused because guava's version is 19.0.0 in payara and google-cloud-automl requires a version > 20.
To solve this error payara suggests here modifying the file glassfish-application.xml, "With this, the libraries included in the EAR's lib / directory will take precedence", however this did not work for me.
The code was written with the help of this documentation
glassfish-application.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE glassfish-application PUBLIC "-//GlassFish.org//DTD GlassFish Application Server 3.1 Java EE Application 6.0//EN" "http://glassfish.org/dtds/glassfish-application_6_0-1.dtd">
<glassfish-application>
<classloading-delegate>false</classloading-delegate>
</glassfish-application>
pom[EJB].xml
<?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>
<artifactId>AutoMLTest</artifactId>
<groupId>co.com.group.automl</groupId>
<version>1.0</version>
</parent>
<groupId>co.com.group.automl</groupId>
<artifactId>AutoMLTest-ejb</artifactId>
<version>1.0</version>
<packaging>ejb</packaging>
<name>AutoMLTest-ejb</name>
<properties>
<endorsed.dir>${project.build.directory}/endorsed</endorsed.dir>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>javax</groupId>
<artifactId>javaee-api</artifactId>
<version>7.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.google.cloud</groupId>
<artifactId>google-cloud-automl</artifactId>
<version>0.97.0-beta</version>
</dependency>
</dependencies>
<build>
<resources>
<resource>
<targetPath>META-INF</targetPath>
<directory>src</directory>
<includes>
<include>jax-ws-catalog.xml</include>
<include>wsdl/**</include>
</includes>
</resource>
<resource>
<directory>src/main/resources</directory>
</resource>
</resources>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
<compilerArguments>
<endorseddirs>${endorsed.dir}</endorseddirs>
</compilerArguments>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-ejb-plugin</artifactId>
<version>2.3</version>
<configuration>
<ejbVersion>3.1</ejbVersion>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<version>2.6</version>
<executions>
<execution>
<phase>validate</phase>
<goals>
<goal>copy</goal>
</goals>
<configuration>
<outputDirectory>${endorsed.dir}</outputDirectory>
<silent>true</silent>
<artifactItems>
<artifactItem>
<groupId>javax</groupId>
<artifactId>javaee-endorsed-api</artifactId>
<version>7.0</version>
<type>jar</type>
</artifactItem>
</artifactItems>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
Method AutoML Extraction.xml
public void extracNL(String content) throws Exception {
String googleCredentials = "/path/credentials.json"
GoogleCredentials credentials = GoogleCredentials.fromStream(new FileInputStream(googleCredentials)).createScoped(Lists.newArrayList("https://www.googleapis.com/auth/cloud-platform"));
PredictionServiceSettings settings =
PredictionServiceSettings.newBuilder().setCredentialsProvider(FixedCredentialsProvider.create(credentials)).build();
//The problem is presented in this line of code
PredictionServiceClient serviceClient =
PredictionServiceClient.create(settings);
ModelName modelName = ModelName.of("projectId", "computeRegion", "modelId");
TextSnippet snippet = TextSnippet.newBuilder().setContent(content).setMimeType("text/plain").build();
ExamplePayload payload = ExamplePayload.newBuilder().setTextSnippet(snippet).build();
Map<String, String> params = new HashMap<>();
PredictResponse response = serviceClient.predict(modelName, payload, params);
List<PredictGoogleDTO> predictionsTmp = new ArrayList<>();
for (AnnotationPayload annotationPayload : response.getPayloadList()) {
if (annotationPayload.getDisplayName().equals("Person")) {
System.out.println("DisplayName="+annotationPayload.getDisplayName());
System.out.println("Content="+annotationPayload.getTextExtraction().getTextSegment().getContent());
}
}
}
Is there another way to do this? is it really impossible for my application to use the guava version in the pom and not the payara server? after testing the command line in maven mvn dependecy; tree -Dverbose in the path of my project I do not get any dependencies error. can then guava be the cause of this error really? I feel that I have tried everything and I can not find a possible solution to my problem, in advance thank you.
probably many of them will be presented with this and other errors when using the AutoML Natural Language API in their BETA version, this is normal and we must assume that as a BETA version this type of problem will be present. My solution was to isolate the consumption of the API from my JAVA EE application, implementing for the first time a lambda function in AWS (Amazon Web Service) and consuming the service through a REST call to this function. This worked perfect for me, and it is a clean solution (from my perspective). Regards.

Using AspectJ annotations in maven project: weaving is not working

I am trying to use AspectJ in a simple project without using Spring, and while I have seen similar questions and my code seems to be correct, I don't understand why it's not working. I'm using Eclipse Oxygen 4.7.3 (not using AJDT tools), JDK 7, maven 3.5.2, and my code is as follows:
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/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com</groupId>
<artifactId>aspect-tutorial</artifactId>
<version>0.0.1-SNAPSHOT</version>
<properties>
<maven.compiler.plugin.version>3.5.1</maven.compiler.plugin.version>
</properties>
<dependencies>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjrt</artifactId>
<version>1.8.7</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.8.8</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>aspectj-maven-plugin</artifactId>
<version>1.8</version>
<configuration>
<complianceLevel>1.7</complianceLevel>
<source>1.7</source>
<target>1.7</target>
</configuration>
</plugin>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>${maven.compiler.plugin.version}</version>
<configuration>
<source>1.7</source>
<target>1.7</target>
</configuration>
</plugin>
</plugins>
</build>
</project>
MainApp.java
package com.pkg;
public class MainApp {
public static void main(String[] args) {
// TODO Auto-generated method stub
HelloWorld a = new HelloWorld();
a.printHello();
}
}
HelloWorld.java
package com.pkg;
public class HelloWorld {
private String name;
public void setName(String name) {
this.name = name;
}
public void printHello() {
System.out.println("Print Hello...");
}
}
TestAspect.java
package com.pkg;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
#Aspect
public class TestAspect {
#Before("execution(* com.pkg.HelloWorld.printHello(..))")
public void testBefore2(){
System.out.println("Yeeha");
}
}
Running mvn clean install is successful, but the output only prints the "Print Hello..." part. Should I use a different approach? (Maybe use a .aj file instead, or try load-time-weaving) Any help appreciated.
The problem is the configuration of both AspectJ Maven and Maven Compiler. My POMs for AspectJ usually look a bit different than yours (a few more settings), but here is yours with minimal changes in order to make it work:
<?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>com</groupId>
<artifactId>aspect-tutorial</artifactId>
<version>0.0.1-SNAPSHOT</version>
<properties>
<maven.compiler.plugin.version>3.5.1</maven.compiler.plugin.version>
</properties>
<dependencies>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjrt</artifactId>
<version>1.8.13</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>aspectj-maven-plugin</artifactId>
<version>1.11</version>
<configuration>
<complianceLevel>1.7</complianceLevel>
<source>1.7</source>
<target>1.7</target>
</configuration>
<executions>
<execution>
<!-- IMPORTANT -->
<phase>process-sources</phase>
<goals>
<goal>compile</goal>
<goal>test-compile</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>${maven.compiler.plugin.version}</version>
<configuration>
<source>1.7</source>
<target>1.7</target>
<!-- IMPORTANT -->
<useIncrementalCompilation>false</useIncrementalCompilation>
</configuration>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<version>1.4.0</version>
<configuration>
<mainClass>com.pkg.MainApp</mainClass>
</configuration>
</plugin>
</plugins>
</build>
</project>
See how I set incremental compilation to false for Maven compiler? This is due to an old bug (still unfixed) which actually inverts the switch, so in order to make incremental compilation work you have to "deactivate" it. Very weird.
You also need to define executions for the process-sources phase for AspectJ Maven.
Besides, I upgraded to AspectJ Maven 1.11 and thus also to AspectJ runtime 1.8.13.
I also added Maven Exec plugin in order to easily prove that it is working now. Just call mvn clean compile exec:java and check the output:
(...)
[INFO] --- aspectj-maven-plugin:1.11:compile (default) # aspect-tutorial ---
[INFO] Showing AJC message detail for messages of types: [error, warning, fail]
[INFO]
[INFO] --- maven-compiler-plugin:3.5.1:compile (default-compile) # aspect-tutorial ---
[INFO] Nothing to compile - all classes are up to date
(...)
[INFO] --- exec-maven-plugin:1.4.0:java (default-cli) # aspect-tutorial ---
Yeeha
Print Hello...
(...)
Otherwise I support what Nándor said: Make sure you use AspectJ plugins for Eclipse or IDEA if you also want to run your aspect-enhanced Java code from an IDE.
How you you run your app? Purely from maven or from within Eclipse? Do you have Eclipse to automatically build your projects? If yes, you probably won't have too much success with compile time weaving, because Eclipse will overwrite your Maven built classes with Eclipse built classes. Without the AJDT feature installed, and properly set up workspace project with AspectJ nature, the resulting compiled code won't be "enhanced" by the AspectJ weaver.

Running .jar file using Apache POI in Maven project

I'm struggling to run a simple program that uses Apache POI to create an Excel document. This is also my first time with a Maven project, so that might have something to do with it:
My pom.xml looks like this:
<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.mycompany.app</groupId>
<artifactId>calendar</artifactId>
<packaging>jar</packaging>
<version>1.0-SNAPSHOT</version>
<name>calendar</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.apache.poi</groupId>
<artifactId>poi</artifactId>
<version>3.10-FINAL</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>3.10-FINAL</version>
</dependency>
</dependencies>
</project>
From what I can tell, my dependencies are alright.
This is my java code, I skipped over import statements but they are all there, no errors in this code from what I can tell:
public class App
{
private static final String FILE_NAME = "/tmp/MyFirstExcel.xlsx";
public static void main( String[] args ) throws IOException
{
XSSFWorkbook workbook = new XSSFWorkbook();
XSSFSheet sheet = workbook.createSheet("Datatypes in Java");
Object[][] datatypes = {
{"Datatype", "Type", "Size(in bytes)"},
{"int", "Primitive", 2},
{"float", "Primitive", 4},
{"double", "Primitive", 8},
{"char", "Primitive", 1},
{"String", "Non-Primitive", "No fixed size"}
};
int rowNum = 0;
System.out.println("Creating excel");
for(Object[] datatype : datatypes) {
Row row = sheet.createRow(rowNum++);
int colNum = 0;
for(Object field : datatype) {
Cell cell = row.createCell(colNum++);
if(field instanceof String) {
cell.setCellValue((String) field);
}
else if(field instanceof Integer) {
cell.setCellValue((Integer) field);
}
}
}
try {
FileOutputStream outputStream = new FileOutputStream(FILE_NAME);
workbook.write(outputStream);
//workbook.close()
} catch (FileNotFoundException e) {
System.out.println("Couldn't find file to write out to");
} catch (IOException e) {
System.out.println("IO Exception in printing");
}
}
}
I have workbook.close() commented out since this caused an error (deprecated method?).
With the above code in my source folder, I can run mvn package which builds successfully and generates the .jar file calendar-1.0-SNAPSHOT.jar in the target folder.
I am attempting to run this file using
java -cp target/calendar-1.0-SNAPSHOT.jar com.mycompany.app.App
...and I get the following error message
Error: A JNI error has occurred, please check your installation and try again
Exception in thread "main" java.lang.NoClassDefFoundError: org/apache/poi/ss/usermodel/Workbook
at java.lang.Class.getDeclaredMethods0(Native Method)
at java.lang.Class.privateGetDeclaredMethods(Unknown Source)
at java.lang.Class.privateGetMethodRecursive(Unknown Source)
at java.lang.Class.getMethod0(Unknown Source)
at java.lang.Class.getMethod(Unknown Source)
at sun.launcher.LauncherHelper.validateMainClass(Unknown Source)
at sun.launcher.LauncherHelper.checkAndLoadMain(Unknown Source)
Caused by: java.lang.ClassNotFoundException: org.apache.poi.ss.usermodel.Workbook
at java.net.URLClassLoader.findClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
... 7 more
If this question requires any more information let me know. I'm at a loss here.
You need to create a fat/uber jar with Maven Assembly Plugin. Which means create a Jar together with its dependency Jars into a single executable Jar file. When you run it then it would have all the dependencies available.
Add following plugin inside your POM
<build>
<plugins>
<!-- Maven Assembly Plugin -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<version>2.4.1</version>
<configuration>
<!-- get all project dependencies -->
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
<!-- MainClass in mainfest make a executable jar -->
<archive>
<manifest>
<mainClass>com.your.path.to.main.App</mainClass>
</manifest>
</archive>
</configuration>
<executions>
<execution>
<id>make-assembly</id>
<!-- bind to the packaging phase -->
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
Run following:
mvn package
Two jar files will be created in the target folder.
calendar-1.0-SNAPSHOT.jar – Only your project classes
calendar-1.0-SNAPSHOT-with-dependencies.jar – Project and dependency classes in a single jar.
You can run it follwoing;
java -cp target/calendar-1.0-SNAPSHOT-with-dependencies.jarcom.mycompany.app.App
You can review the contents of calendar-1.0-SNAPSHOT-with-dependencies.jar
jar tf target/calendar-1.0-SNAPSHOT-with-dependencies.jar
You are packaging your maven artifact as a jar and by default a jar packaged by the maven jar plugin doesn't include the dependency jars with the built artifact.
Whereas the missing class at runtime.
If you want to include dependency jars of your application inside your jar, you should use the maven assembly plugin and specify jar-with-dependencies for the descriptorRef parameter.
You could bind the assembly singlegoal execution to the package phase so that the mvn package execution that you are using actually creates automatically the expected jar.
<plugins>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<configuration>
<archive>
<manifest>
<mainClass>YourMainClassPrefixedByItsPackage</mainClass>
</manifest>
</archive>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
</configuration>
<executions>
<execution>
<id>make-assembly</id>
<phase>package</phase> <!-- bind to the packaging phase -->
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
The problem is that at compile time POI libraries are available but not at run time. The reason why they are available is that they are in Maven Dependency. Also I don't see any build wrapper in your pom file. You will need to add a build wrapper to build jar file that you can run outside of your IDE.
Now coming back to your problem, either you need to add POI jar in your CLASSPATH environment variable so that java run-time can access it or build a fat jar including dependencies.
You can use this template to add a build wrapper in pom file to build jar with dependencies.
<build>
<plugins>
<plugin>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
<phase>install</phase>
<goals>
<goal>copy-dependencies</goal>
</goals>
<configuration>
<outputDirectory>${project.build.directory}/lib</outputDirectory>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
Maven package task just packs compiled classes of your project into a single jar file. All 3rd party libraries are not included, that's why you're getting error - POI class is not found.
You should build a runnable jar file that includes all dependencies. Please, refer to this question - you should use some additional maven plugins to achieve that

Cannot find class from jar in maven plugin

I'm making a maven plugin to start, stop and clear a database. I'm using hsqldb for it. I have a class (called ServerStart) to start the database:
import java.io.File;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import org.hsqldb.Server;
import org.hsqldb.util.SqlFile;
public static void main(String[] args) {
System.out.println("Starting server...");
createServer();
try {
createADatabase(dbName);
System.out.println("Server started!");
} catch (Exception e) {
e.printStackTrace();
}
}
When I run the main class in Eclipse (right click and run as JavaApplication), it works. But when I try to run it from the cmd line with my mvn command, I get this error:
Exception in thread "main" java.lang.NoClassDefFoundError: org/hsqldb/Server
at sample.plugin.hello_maven_plugin.ServerStart.createServer(ServerStart
.java:50)
at sample.plugin.hello_maven_plugin.ServerStart.main(ServerStart.java:37)
Caused by: java.lang.ClassNotFoundException: org.hsqldb.Server
at java.net.URLClassLoader$1.run(URLClassLoader.java:200)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:188)
at java.lang.ClassLoader.loadClass(ClassLoader.java:307)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:301)
at java.lang.ClassLoader.loadClass(ClassLoader.java:252)
at java.lang.ClassLoader.loadClassInternal(ClassLoader.java:320)
... 2 more
When I run the mvn command, he tries to start ServerClass externally, by doing this:
startOptions = new String[] {"java", "-cp", System.getProperty("user.dir") + "/target/classes/", ServerStart.class.getName()};
new ProcessBuilder(startOptions).start();
I guess I forgot something to add on my pom.xml file, so he includes the hsqldb.jar, but I don't have any idea what. This 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/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>sample.plugin</groupId>
<artifactId>hsqldb-maven-plugin</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>maven-plugin</packaging>
<name>hsqldb-maven-plugin</name>
<url>http://maven.apache.org</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.maven</groupId>
<artifactId>maven-plugin-api</artifactId>
<version>3.0.3</version>
</dependency>
<dependency>
<groupId>commons-dbcp</groupId>
<artifactId>commons-dbcp</artifactId>
<version>1.4</version>
</dependency>
<dependency>
<groupId>hsqldb</groupId>
<artifactId>hsqldb</artifactId>
<version>1.8.0.10</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>sample.plugin</groupId>
<artifactId>hsqldb-maven-plugin</artifactId>
<version>1.0-SNAPSHOT</version>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.3.2</version>
<configuration>
<source>1.6</source>
<target>1.6</target>
</configuration>
</plugin>
</plugins>
</build>
</project>
I hope my question is clear enough, and I also hope that someone can help me.
Kind regards,
Walle
a) ??? You define the plugin:
<groupId>sample.plugin</groupId>
<artifactId>hsqldb-maven-plugin</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>maven-plugin</packaging>
And reference itself as a plugin in the build section?
<plugin>
<groupId>sample.plugin</groupId>
<artifactId>hsqldb-maven-plugin</artifactId>
<version>1.0-SNAPSHOT</version>
</plugin>
That's not how it works! A plugin is meant for other projects, not for itself!
b)
startOptions = new String[] {"java", "-cp", System.getProperty("user.dir") + "/target/classes/", ServerStart.class.getName()};
new ProcessBuilder(startOptions).start();
You are going to need a lot more than target/classes in your classpath. The easiest way to get a proper classpath is to let Maven build it for you:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<version>2.2</version>
<executions>
<execution>
<id>build-test-classpath</id>
<phase>generate-test-sources</phase>
<goals>
<goal>build-classpath</goal>
</goals>
<configuration>
<outputFile>${project.build.testOutputDirectory}/cp.txt</outputFile>
</configuration>
</execution>
</executions>
</plugin>
Now you'll find a file named cp.txt on your test classpath which contains the classpath you need. Alternatively, you could just use the contents of System.getProperty("java.class.path").
The groupId in your hsqldb dependency is wrong. I had the same problem. Using the following dependency fixed it.
<dependency>
<groupId>org.hsqldb</groupId>
<artifactId>hsqldb</artifactId>
<version>2.0.0</version>
</dependency>

Categories