I was working on a project involving reading from another process when I noticed that it kept throwing java.util.NoSuchElementException: No line found, so I made a Maven test application to check that it was Heroku's fault instead of my program's.
src/main/java/com/test/App.java:
package com.test;
import java.util.Arrays;
import java.util.Scanner;
import java.io.IOException;
public class App{
public static void main(String[] args) throws IOException{
System.out.println(new Scanner(new ProcessBuilder(Arrays.asList("java", "A")).start().getInputStream()).nextLine());
}
}
A.java:
public class A{
public static void main(String[] args){
System.out.println("Test");
}
}
pom.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>
<groupId>com.test</groupId>
<artifactId>test</artifactId>
<version>1.0</version>
<name>test</name>
<!-- FIXME change it to the project's website -->
<url>http://www.example.com</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.7</maven.compiler.source>
<maven.compiler.target>1.7</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<pluginManagement><!-- lock down plugins versions to avoid using Maven defaults (may be moved to parent pom) -->
<plugins>
<!-- clean lifecycle, see https://maven.apache.org/ref/current/maven-core/lifecycles.html#clean_Lifecycle -->
<plugin>
<artifactId>maven-clean-plugin</artifactId>
<version>3.1.0</version>
</plugin>
<!-- default lifecycle, jar packaging: see https://maven.apache.org/ref/current/maven-core/default-bindings.html#Plugin_bindings_for_jar_packaging -->
<plugin>
<artifactId>maven-resources-plugin</artifactId>
<version>3.0.2</version>
</plugin>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.0</version>
</plugin>
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.22.1</version>
</plugin>
<plugin>
<artifactId>maven-jar-plugin</artifactId>
<version>3.0.2</version>
<configuration>
<archive>
<manifest>
<mainClass>com.test.App</mainClass>
</manifest>
</archive>
</configuration>
</plugin>
<plugin>
<artifactId>maven-install-plugin</artifactId>
<version>2.5.2</version>
</plugin>
<plugin>
<artifactId>maven-deploy-plugin</artifactId>
<version>2.8.2</version>
</plugin>
<!-- site lifecycle, see https://maven.apache.org/ref/current/maven-core/lifecycles.html#site_Lifecycle -->
<plugin>
<artifactId>maven-site-plugin</artifactId>
<version>3.7.1</version>
</plugin>
<plugin>
<artifactId>maven-project-info-reports-plugin</artifactId>
<version>3.0.0</version>
</plugin>
</plugins>
</pluginManagement>
</build>
</project>
After javac A.java, mvn install, and java -jar target/test-1.0.jar, it prints "Test" on my computer, but throws a NoSuchElementException in Heroku.
Full Stacktrace:
Exception in thread "main" java.util.NoSuchElementException: No line found
at java.util.Scanner.nextLine(Scanner.java:1540)
at com.test.App.main(App.java:7)
Does anyone know what's causing this and how to fix it?
Edit: Attatched Github repo to hopefully make it clearer
Edit Edit: Oddly, if I put A.java in src/main/java and use the command from #Malax's answer, it works, but I still don't get why Heroku isn't seeing the java file outside of src. Maybe it's trimming them out to save space?
The issue occurs because you're calling nextLine on Scanner without checking if there even is a line. You need to check with hasNext to ensure nextLine will not fail.
The underlying reason why you get no lines is that you're not specifying a classpath when invoking java. java will not be able to find your compiled A class without it and fail with something like
Error: Could not find or load main class A
Caused by: java.lang.ClassNotFoundException: A
on STDERR which you don't capture with getInputStream. You will be able to read the error message when you use getErrorStream instead (but then you won't get the STDOUT messages).
This has nothing to do with Heroku and I can only speculate why this is working for you locally. To provide java a classpath, you can use -cp:
ProcessBuilder processBuilder = new ProcessBuilder(Arrays.asList("java", "-cp", "target/classes", "A"));
Scanner scanner = new Scanner(processBuilder.start().getInputStream());
while (scanner.hasNext()) {
System.out.println(scanner.nextLine());
}
Related
I am trying to run my tests but I am facing an issue where I cannot run my tests when I run the following command:
mvn clean test
my project contain 3 modules (see image attached):
Every module in the project contains pom.xml file which contains only the dependencies relevant for the module.
the main pom.xml (the reactor) is the file which run the test and control the project, and this is its content:
<?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.hackeruso</groupId>
<artifactId>neo</artifactId>
<packaging>pom</packaging>
<version>1.0</version>
<modules>
<module>automation-ui</module>
<module>automation-api</module>
<module>morpheus</module>
</modules>
<name>neo</name>
<!-- FIXME change it to the project's website -->
<url>http://www.example.com</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
<aspectj.version>1.8.10</aspectj.version>
<testng.version>7.3.0</testng.version>
</properties>
<dependencies>
<dependency>
<groupId>io.qameta.allure</groupId>
<artifactId>allure-testng</artifactId>
<version>2.13.6</version>
</dependency>
<dependency>
<groupId>org.testng</groupId>
<artifactId>testng</artifactId>
<version>${testng.version}</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<pluginManagement><!-- lock down plugins versions to avoid using Maven defaults (may be moved to parent pom) -->
<plugins>
<plugin>
<artifactId>maven-clean-plugin</artifactId>
<version>3.1.0</version>
</plugin>
<!-- default lifecycle, jar packaging: see https://maven.apache.org/ref/current/maven-core/default-bindings.html#Plugin_bindings_for_jar_packaging -->
<plugin>
<artifactId>maven-resources-plugin</artifactId>
<version>3.0.2</version>
</plugin>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.0</version>
</plugin>
<plugin>
<artifactId>maven-jar-plugin</artifactId>
<version>3.0.2</version>
</plugin>
<plugin>
<artifactId>maven-install-plugin</artifactId>
<version>2.5.2</version>
</plugin>
<plugin>
<artifactId>maven-deploy-plugin</artifactId>
<version>2.8.2</version>
</plugin>
<!-- site lifecycle, see https://maven.apache.org/ref/current/maven-core/lifecycles.html#site_Lifecycle -->
<plugin>
<artifactId>maven-site-plugin</artifactId>
<version>3.7.1</version>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.20</version>
<configuration>
<argLine>
-javaagent:"${settings.localRepository}/org/aspectj/aspectjweaver/${aspectj.version}/aspectjweaver-${aspectj.version}.jar"
</argLine>
</configuration>
<dependencies>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>${aspectj.version}</version>
</dependency>
</dependencies>
</plugin>
</plugins>
</pluginManagement>
</build>
</project>
when I run the command mvn test I am getting the following message:
No tests to run.
And this image shows where I hold my tests:
src/test/java/com/hackeruso/automation/ui/LoginTest
This is an example for my test class:
--------------------EDIT-------------------------------------------
package com.hackeruso.automation.ui;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;
public class LoginTest extends BaseTest{
#Test(dataProvider = "userDetailsProvider")
public void loginTest(String username, String password){
signIn(username, password);
}
#DataProvider(name = "userDetailsProvider")
public Object[][] userDetailsProvider(){
return new Object[][] {
{"user#mail.com", "*******"}
};
}
}
From documentation:
For example, a project that is purely metadata (packaging value is
pom) only binds goals to the install and deploy phases (for a complete
list of goal-to-build-phase bindings of some of the packaging types,
refer to the Lifecycle Reference).
As you can see, only install and deploy phases (not test) are valid for a pom packaged project.
The Java code should be not there, since a pom project should be purely metadata.
The parent project has a packaging of <packaging>pom</packaging>. This means this is a meta-project and should not contain any source code.
What you need to do is to move the tests in any of the existing modules or create a new one for these tests. By looking at the package structure of the tests, I guess it would be automation-ui in your case.
Then use the following command to run the tests from all the modules
mvn test -am
Where -am will make all the submodules.
If you want to run tests for a single module, use
mvn test -pl <submodule-name>
So eventually what I did was creating another module for testing and the main project module will contain only Metadata as #Yasin suggested, I also deleted the 'src' package from my main project module leaving it just with a pom.xml file which will manage the other modules (the reactor).
Now everything is working as expected.
Thanks!
Background: I am using VS Code and the VS Code Java extension pack (which includes a maven extension) to write a project that uses htmlunit. Currently, I'm just using someone else's code just to see if I can get my environment working. I am a total noob to maven and VS Code and a semi-noob to Java.
When I run my program using the VS Code run tab, it runs as expected*. When I use the maven package command to build an executable jar, the jar builds fine but when I run it with java -jar ___.jar I get an error:
Exception in thread "main" java.lang.NoClassDefFoundError: com/gargoylesoftware/htmlunit/FailingHttpStatusCodeException
at reliant.Main.main(Main.java:44)
Caused by: java.lang.ClassNotFoundException: com.gargoylesoftware.htmlunit.FailingHttpStatusCodeException
at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:581)
at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:178)
at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:522)
... 1 more
Here is the code that uses htmlunit:
package reliant; //I know now this is not how package naming conventions work, but I don't think it causes a problem
import java.io.IOException;
import com.gargoylesoftware.htmlunit.BrowserVersion;
import com.gargoylesoftware.htmlunit.FailingHttpStatusCodeException; //the import that seems to be buggy
import com.gargoylesoftware.htmlunit.WebClient;
import com.gargoylesoftware.htmlunit.html.HtmlForm;
import com.gargoylesoftware.htmlunit.html.HtmlPage;
public class RedditClient {
private final WebClient CLIENT = new WebClient(BrowserVersion.CHROME);
private final String username;
private char[] password;
public RedditClient(String username, char[] password) {
this.username = username;
this.password = password;
CLIENT.getCookieManager().setCookiesEnabled(true);
}
public void checkLogin() {
System.out.println(username + ", " + new String(password));
}
public void login() {
String loginURL = "https://www.reddit.com/login";
try {
HtmlPage loginPage = CLIENT.getPage(loginURL);
HtmlForm loginForm = loginPage.getFirstByXPath("//form[#id='login-form']");
//System.out.println(loginPage.getWebResponse().getContentAsString());
loginForm.getInputByName("user").setValueAttribute(username);
loginForm.getInputByName("passwd").setValueAttribute(new String(password));
loginForm.getElementsByTagName("button").get(0).click();
} catch (FailingHttpStatusCodeException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
public String getHTML(String url) {
try {
return CLIENT.getPage(url).getWebResponse().getContentAsString();
} catch (FailingHttpStatusCodeException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
public void close() {
CLIENT.close();
}
}
And here is line 44 of Main.java:
RedditClient c = new RedditClient(username, password);
This seems to look right to me, I added htmlunit to my maven dependencies. I can show you a screeenshot of the maven dependencies if you want, but I omitted it for now since it's kind of long/hard to read.
Here is the pom 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>reliant</groupId>
<artifactId>redditlogin</artifactId>
<version>2.0</version>
<name>redditlogin</name>
<!-- FIXME change it to the project's website -->
<url>http://www.example.com</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>11</maven.compiler.source>
<maven.compiler.target>11</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>htmlunit</groupId>
<artifactId>htmlunit</artifactId>
<version>1.14</version>
</dependency>
<dependency>
<groupId>org.jsoup</groupId>
<artifactId>jsoup</artifactId>
<version>1.13.1</version>
</dependency>
<dependency>
<groupId>net.sourceforge.htmlunit</groupId>
<artifactId>htmlunit</artifactId>
<version>2.41.0</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<pluginManagement><!-- lock down plugins versions to avoid using Maven defaults (may be moved to parent pom) -->
<plugins>
<!-- clean lifecycle, see https://maven.apache.org/ref/current/maven-core/lifecycles.html#clean_Lifecycle -->
<plugin>
<artifactId>maven-clean-plugin</artifactId>
<version>3.1.0</version>
</plugin>
<!-- default lifecycle, jar packaging: see https://maven.apache.org/ref/current/maven-core/default-bindings.html#Plugin_bindings_for_jar_packaging -->
<plugin>
<artifactId>maven-resources-plugin</artifactId>
<version>3.0.2</version>
</plugin>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.0</version>
</plugin>
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.22.1</version>
</plugin>
<plugin>
<artifactId>maven-jar-plugin</artifactId>
<version>3.0.2</version>
<configuration>
<archive>
<manifest>
<addClasspath>true</addClasspath>
<mainClass>reliant.Main</mainClass>
</manifest>
</archive>
</configuration>
</plugin>
<plugin>
<artifactId>maven-install-plugin</artifactId>
<version>2.5.2</version>
</plugin>
<plugin>
<artifactId>maven-deploy-plugin</artifactId>
<version>2.8.2</version>
</plugin>
<!-- site lifecycle, see https://maven.apache.org/ref/current/maven-core/lifecycles.html#site_Lifecycle -->
<plugin>
<artifactId>maven-site-plugin</artifactId>
<version>3.7.1</version>
</plugin>
<plugin>
<artifactId>maven-project-info-reports-plugin</artifactId>
<version>3.0.0</version>
</plugin>
</plugins>
</pluginManagement>
</build>
</project>
The fact that the jar file errors out but running in VS Code proceeds as expected* makes no sense to me whatsoever.
Also, on an unrelated note, why is a "class not found" error a run-time error? Why is maven able to successfully build the package?
*I say "as expected" because there is a bug in the code I'm using, but it is a very-specific runtime error. Basically, the code I'm using was designed to log in to reddit before reddit got the OAuth thing so now the line that tries to get the login form returns null and that breaks the rest of it. The point is, I see no reason for why running in VS Code vs running the jar should have any different outcomes. I don't even know where to begin with something like this.
Thank you for help, please let me know if there is anything I can add to make this question easier to answer.
Ok so turns out this was pretty silly. Basically, the classpath listed my dependencies (because of how I set up the pom) but that doesn't mean that it specified the path to those dependencies. In fact, it didn't specify a path at all, so whenever java tried to run the jar, it looked for the dependencies in the current directory. I know that because when I put the dependencies in the same directory as the jar, it worked. The better solution here would be to modify the pom to add a prefix to the classpath so that the java knows where to find the dependencies. Unfortunately, my dependencies are in different places so that's not really an option for me; instead, I'm going to try to find out how to make a fat/uber jar.
I am getting a java.lang.NoClassDefFoundError: com/zaxxer/hikari/HikariDataSource error when launching my Java plugin on spigot. from what I can tell I have correctly imported it.
I know this question has been posted multiple times but by looking through 3-4 I do not see any clear answer to what is wrong.
The code crashes at hikari = new HikariDataSource() which is also the first hikari statement used.
My Pom
<groupId>drhampust.github.io</groupId>
<artifactId>Blank</artifactId>
<version>1.0-SNAPSHOT</version>
<repositories>
<repository>
<id>spigot-repo</id>
<url>https://hub.spigotmc.org/nexus/content/repositories/snapshot/</url>
</repository>
</repositories>
<dependencies>
<dependency>
<groupId>org.spigotmc</groupId>
<artifactId>spigot-api</artifactId>
<version>1.14.4-R0.1-SNAPSHOT</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.17</version>
</dependency>
<dependency>
<groupId>com.zaxxer</groupId>
<artifactId>HikariCP</artifactId>
<version>3.4.0</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
</plugins>
</build>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
it seems like hikari does not compile into jar but I can use its assets whilst coding.
Code:
import com.zaxxer.hikari.HikariDataSource;
import org.bukkit.plugin.java.JavaPlugin;
import org.bukkit.scheduler.BukkitRunnable;
import java.sql.*;
public class Main extends JavaPlugin {
//DataBase vars.
public String username, password, database, host, properties, table; //db variables
public int port; //db variable
//Connection vars
private HikariDataSource hikari;
#Override
public void onEnable() {
getLogger().info("onEnable is called!");
loadConfig();
new BukkitRunnable(){
#Override
public void run(){
connectToDatabase();
}
}.runTaskAsynchronously(this);
this.getServer().getPluginManager().registerEvents(new SetterGetter(), this);
}
#Override
public void onDisable() {
getLogger().info("onDisable is called!");
}
public synchronized void connectToDatabase() {
//Database details
String address = getConfig().getString("Database.address");
String name = getConfig().getString("Database.Name");
String username = getConfig().getString("Database.username");
String password = getConfig().getString("Database.password");
int port = getConfig().getInt("Database.port");
//Initialise hikari instace
hikari = new HikariDataSource();
//Setting Hikari properties
hikari.setMaximumPoolSize(10);
hikari.setDataSourceClassName("com.mysql.jdbc.jdbc2.optional.MysqlDataSource");
hikari.addDataSourceProperty("serverName", address);
hikari.addDataSourceProperty("port", port);
hikari.addDataSourceProperty("databaseName", name);
hikari.addDataSourceProperty("user", username);
hikari.addDataSourceProperty("password", password);
}
public void loadConfig() {
getConfig().options().copyDefaults(true);
saveConfig();
}
}
full crash report in a paste bin to make it easier to see:
https://pastebin.com/JEMz0f6T
My attempt to create a standalone program using hikaricp:
Code:
package test;
import com.zaxxer.hikari.HikariDataSource;
public class Main
{
public static void main(String[] args) {
HikariDataSource hikari = new HikariDataSource();
//Setting Hikari properties
hikari.setMaximumPoolSize(10);
hikari.setDriverClassName("com.mysql.jdbc.Driver");
hikari.setJdbcUrl("jdbc:mysql://" + "localhost" + ":" + "3306" + "/" + "plugin");
hikari.setUsername("Server1");
hikari.setPassword("227VU07dickCQjav");
}
}
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>Test</groupId>
<artifactId>Test</artifactId>
<version>1.0-SNAPSHOT</version>
<dependencies>
<!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.17</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.zaxxer/HikariCP -->
<dependency>
<groupId>com.zaxxer</groupId>
<artifactId>HikariCP</artifactId>
<version>3.4.0</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<!-- Build an executable JAR -->
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>3.1.0</version>
<configuration>
<archive>
<manifest>
<addClasspath>true</addClasspath>
<classpathPrefix>lib/</classpathPrefix>
<mainClass>test.Main</mainClass>
</manifest>
</archive>
</configuration>
</plugin>
</plugins>
</build>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
</project>
stacktrace: https://pastebin.com/fNQ7EFnQ
I hav posted an issue on the Hikaricp Github, it might not fit on there as it seems to be a problem only for me, but hey! maybe he can help.
I do not know why this is happening, i suspect that other people can complie HikariCP just fine, the question is why dosen't it work for me...
Edit: it seems like something similar has happend before:
https://www.spigotmc.org/threads/hikaricp-with-spigot-not-importing-with-the-jar.246851/ Checking if I can get my problem to fix itself using this information.
Okay By adding the new arguments to my pom.xml i have now removed the
NoClassDefFoundError and have now gotten this: https://pastebin.com/9DU9Tqra
But hey its a warning not a crash dump. meaning that it worked yay!
Missing details? Ask and I will see what i can do.
#Hampus, I have tried and check that in the version 3.4.0 of Hicari Pool, the class com.zaxxer.hikari.HikariDataSource is available in the package com/zaxxer/hikari. You can see the screenshot below. What I doubt is the repository you have added. Please remove the following from pom.xml and try.
<repositories>
<repository>
<id>spigot-repo</id>
<url>https://hub.spigotmc.org/nexus/content/repositories/snapshot/</url>
</repository>
</repositories>
I know that you may be using your your nexus, this jar file is available in maven central. I provide below the mvn repository link for this.
https://mvnrepository.com/artifact/com.zaxxer/HikariCP/3.4.0
Problem is NoClassDefFoundError.
What fixed it? I fixed it following a post on spigotmc:
https://www.spigotmc.org/threads/hikaricp-with-spigot-not-importing-with-the-jar.246851/
and added:
<build>
<finalName>${project.name}</finalName>
<defaultGoal>clean package</defaultGoal>
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
<includes>
<include>*</include>
</includes>
</resource>
</resources>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.5.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>2.4.3</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
</execution>
</executions>
<configuration>
<createDependencyReducedPom>false</createDependencyReducedPom>
</configuration>
</plugin>
</plugins>
</build>
to my pom.xml after adding it I used "clean" then "package" using maven and tried it and it worked. however i do get a warning:
[23:02:45] [Craft Scheduler Thread - 0/WARN]: SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder".
[23:02:45] [Craft Scheduler Thread - 0/WARN]: SLF4J: Defaulting to no-operation (NOP) logger implementation
[23:02:45] [Craft Scheduler Thread - 0/WARN]: SLF4J: See http://www.slf4j.org/codes.html#StaticLoggerBinder for further details.
However this is beside the original question.
I will select this as the answer unless someone finds a better solution.
I am new to spring and maven. I have a simple hello world project using Spring . The project builds successfully but i face the following error at runtime:
Error: A JNI error has occurred, please check your installation and try again
Exception in thread "main" java.lang.NoClassDefFoundError: org/springframework/context/ApplicationContext
This is the main app: App.java
package com.test.SpringMaven2;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
/**
* Hello world!
*
*/
public class App
{
public static void main( String[] args )
{
System.out.println( "Hello World!" );
System.out.println( "Hello World!" );
ApplicationContext context = new AnnotationConfigApplicationContext(HelloWorldConfig.class);
HelloWorld hello = (HelloWorld) context.getBean("helloWorld");
hello.setName("Adnan");
hello.getName();
}
}
This is the HelloWorld bean
package com.test.SpringMaven2;
public class HelloWorld{
private String name;
public void setName(String name){
this.name = name;
}
public void getName(){
System.out.println("Hello, " + name);
}
}
This is the annotation based configuration file:
package com.test.SpringMaven2;
import org.springframework.context.annotation.*;
#Configuration
public class HelloWorldConfig{
#Bean
public HelloWorld helloWorld(){
return new HelloWorld();
}
}
This 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/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.test</groupId>
<artifactId>SpringMaven2</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>SpringMaven2</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.springframework</groupId>
<artifactId>spring-context-support</artifactId>
<version>4.3.3.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>4.3.3.RELEASE</version>
</dependency>
</dependencies>
</project>
I am running the following command in CMD to run the application:
java -cp {nameofresultjarfile} com.test.SpringMaven2.App
But getting the error messsage above
Any advice?
Thanks
Your pom.xml creates a jar file which contains only the classes defined in your project. But all the other dependencies (spring-core, spring-context-support) which are required by your application aren't included.
If your application is started within eclipse, eclipse integrates these required jar files to the classpath of the application and so it is able to run.
If your application is started from CMD the spring classes can't be found in the classpath and you get a java.lang.NoClassDefFoundError.
It's possible to name all the required jars manually when the application is started from CMD (classpath), but is much easier to created a so called self contained jar file, which has all of them already included. This can be done using maven-assembly-plugin.
An example how to create a self contained jar file can be found here.
The application in a self contained jar can be started now from CMD:
java -jar name_of_your_project-jar-with-dependencies.jar
I was getting the same error when running from Intellij as a main class (In Spring Boot project)
After opening Module settings, In the Deopendencies tab I saw that for spring-context for some reason the scope was provided, changing to compile/ even removing the scope fixed the issue for for me
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>## Put your desired version here ##</version>
</dependency>
In my similar case both #jaysee answer or:
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<configuration>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
<archive>
<manifest>
<mainClass>com.example.MyMainClass </mainClass>
</manifest>
</archive>
</configuration>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
or
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>2.5.0</version>
helped.
The below fixed similar issue for me.
build plugins section should be put right after /dependencies:
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>2.5.4</version>
<configuration>
<layout>ZIP</layout>
</configuration>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
I was facing the same issue. I am using the intellij 2021 but the above solution didn't work. Also in eclipse it was working fine . The solution that worked for me was:
1)Go to edit run/debug configuraiton
2)Modify option
3)Check "include dependency with provided scope"
I am trying to use NATTY by including it as a maven dependency. I just did the Hello, World Maven tutorial -- but am otherwise unfamiliar with Maven. The instructions on the natty site say to include natty as a dependency in the pom.xml. I have done so 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>my-app</artifactId>
<packaging>jar</packaging>
<version>1.0-SNAPSHOT</version>
<name>my-app</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.joestelmach</groupId>
<artifactId>natty</artifactId>
<version>0.9</version>
</dependency>
</dependencies>
</project>
I then run $mvn package and the project builds successfully. I see one jar file in my /target: my-app-1.0-SNAPSHOT.jar so I assume that the natty dependencies are baked into that jar.
To test, I create a simple class in a file called Temporary.java to hold the natty demo code:
import com.joestelmach.natty.*;
import com.joestelmach.natty.generated.*;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
public class Temporary{
public static void main(String [] args) {
Parser parser = new Parser();
List groups = parser.parse("the day before next thursday");
for (DateGroup group : groups) {
List dates = group.getDates();
int line = group.getLine();
int column = group.getPosition();
String matchingValue = group.getText();
String syntaxTree = group.getSyntaxTree().toStringTree();
Map parseMap = group.getParseLocations();
boolean isRecurreing = group.isRecurring();
Date recursUntil = group.getRecursUntil();
}
}
}
But when I run $ javac -cp target/my-app-1.0-SNAPSHOT.jar Temporary.java I get
Temporary.java:1: error: package com.joestelmach.natty does not exist
import com.joestelmach.natty.*;
What am I doing wrong?
You need to make sure that when you package your jar using maven that your dependencies are included.
I believe you need to add this to your pom.xml
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<configuration>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
<archive>
<manifest>
<mainClass></mainClass>
</manifest>
</archive>
</configuration>
<executions>
<execution>
<id>make-assembly</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
Make sure when running it you use the .jar that has the "jar-with-dependencies.jar" at the end. This will ensure that your natty dependency is included.