ClassNotFoundException for main-class running an executable jar with dependencies - java

I cannot find the issue here:
I created a jar using a maven plugin, but the dog won't hunt.
The class:
package com.foo.baitshop;
public class Design {
public static void main(String args[]) throws IOException {
int argLength = args.length;
}
}
I unzipped the jar to peek inside and the META-INF folder is in the root and contains the manifest (MANIFEST.MF).
It looks like this:
Manifest-Version: 1.0
Archiver-Version: Plexus Archiver
Created-By: Apache Maven
Built-By: lwhite
Build-Jdk: 9.0.4
Main-Class: com.foo.baitshop.Design;
To Run, i execute the following in the directory holding the jar:
java -jar baitshop2-1.0-SNAPSHOT-jar-with-dependencies.jar
There is no classpath set externally in this environment.
The error message is:
fm-mltp140:target lwhite$ java -jar baitshop2-1.0-SNAPSHOT-jar-with-dependencies.jar
Error: Could not find or load main class com.foo.baitshop.Design;
Caused by: java.lang.ClassNotFoundException: com/foo/baitshop/Design;
Any help would be greatly appreciated.

I think it's the semi-colon:
Main-Class: com.foo.baitshop.Design;
It needs to be removed to be:
Main-Class: com.foo.baitshop.Design
If Maven is generating this, the Maven configuration needs to be debugged to prevent adding the semi-colon. Likely there is a semi-colon in the configuration somewhere.
The associated doc from Oracle.

Related

How do I export SQLJDBC into JAR correctly in Intellij?

I'm setting up a SQL connector for my bukkit plugin, but whenever I compile into a jar file and try running from the server I get
java.sql.SQLEXCEPTION: No suitable driver found.
I have tried adding in the line
Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver");
Whenever I put that I get
SQLEXCEPTION: com.microsoft.sqlserver.jdbc.SQLServerDriver
This problem only occurs when I put it into a jar file and not when I test it in my IDE.
I currently use Intellij.
This is my current Jar setup:
https://gyazo.com/94341b7bb47121a0416deaee6279dd30
public ConnectionUtils(String url, String us, String pa) throws SQLException
{
SQLServerDriver dr = new SQLServerDriver();
user = us;
pass = pa;
con = DriverManager.getConnection(url, us, pa);
isConnected = true;
this.url = url;
}
Solution using Project Structure
Outside of using maven, you can look at your Project Structure in IntelliJ and examine your dependencies. Make sure the "export" box next that jar is checked.
Maven Solution
I recommend using maven to handle your dependencies, as you can define the scope of the dependency, as explained here.
For the JDBC dependency, you could use the following dependency declaration in your pom:
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.17</version>
</dependency>
This would inherit the default scope which, as stated in the article, is compile.
3.1. Compile
This is the default scope when no other scope is provided.
Dependencies with this scope are available on the classpath of the
project in all build tasks and they're propagated to the dependent
projects.
Manifest
It seems some people online are talking about exactly this issue, and the solution is one that #Bohemian mentioned for ensuring that the required class is packaged with the jar. However, that solution only works if you are executing the jar from the command line, which is not the case with spigot plugins. I suggest creating a MANIFEST.txt and including the driver class-path in there, as suggested by Terence Gronowski on CodeRanch
Creating a Manifest.txt file with the following contents in the
program folder:
Manifest-Version: 1.0 Class-Path: sqljdbc4.jar Main-Class:
ParkplatzVerwaltung (Newline)
Don't forget to end with a newline. The important thing is
"Class-Path: sqljdbc4.jar", showing where the driver is.
Source: https://coderanch.com/t/529484/databases/Jdbc-driver-putting-application-jar

Getting a java.lang.ClassNotFoundException: org.testng.TestNG Error

I'm trying to execute my testng.xml file from main method using the code below. But getting a NoClassDefFoundError. Any idea what may have caused this issue?
public static void main( String[] args )
{
TestNG testng = new TestNG();
List<String> suites = Lists.newArrayList();
suites.add("testng.xml");
testng.setTestSuites(suites);
testng.run();
}
Exception in thread "main" java.lang.NoClassDefFoundError: org/testng/TestNG
at com.automation.app.App.main(App.java:21)
Caused by: java.lang.ClassNotFoundException: org.testng.TestNG
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
The issue here is that you are missing the dependent libraries on your class path when you are executing the jar because the jar only has the classes from you project.
What you need here is either
build an executable jar with all the dependencies
or
specify the dependencies on command line
e.g.
java -cp your.jar:lib/*
where libs/* is a path to your dependency JARs
I would recommend option one as you can run that jar any where if it has all the dependencies included in jar.
I was able to fix this issue by using "maven-assembly-plugin" and "maven-dependency-plugin", Then creating the manifest.mf file in resources/meta-inf folder and adding the following information.
Manifest-Version: 1.0
Class-Path: .
Main-Class: {PROVIDE THE MAIN CLASS HERE}
Its related to the Testng Library.
Add library:
Right click project -> Build path -> Configure build path ->Java Build Path -> Library -> Add library-> select TestNG -> Apply and close.
It worked for me.

Package.getImplementationVersion() returns NULL

Thanks in advance for any help.
What I want to achieve is project version (Implementation-Version) is printed in a class when it is initiated so that I can trace the version from log file.
I build a JAR file containing the following classes:
com.company.core.common.ClassA
com.company.core.security.ClassB
com.company.core.sql.ClassC
In constructor of com.company.core.sql.ClassC, I want to call System.out.println() to print out the Implementation-Version stored in META-INF/MANIFEST.MF file by calling this.class.getPackage().getImplementationVersion(), but it is getting null value when the class is initiated via Maven test class.
My MANIFEST.MF file contains the following details:
Manifest-Version: 1.0
Implementation-Title: Company Core Library
Implementation-Version: 1.0
Archiver-Version: Plexus Archiver
Built-By: simon
Implementation-Vendor-Id: com.company.core
Build-Time: 2017-02-18T15:07:33Z
Class-Path: lib/sqljdbc42-4.2.jar lib/log4j-api-2.7.jar lib/log4j-core
-2.7.jar lib/json-20160810.jar lib/junit-4.12.jar lib/hamcrest-core-1
.3.jar
Created-By: Apache Maven 3.3.9
Build-Jdk: 1.8.0_102
Implementation-Vendor: Company
Name: com/company/core/
Implementation-Vendor-Id: com.company.core
Implementation-Title: Company Core Library
Implementation-Version: 1.0
Implementation-Vendor: Company
Would I be able to get the Implementation-Version in Maven test class?
If yes, what have I missed out here?
Thanks.
Regards,
Simon.
Within the development environment all class files are found in a named folder target (e.g. within Eclipse). The package path is represented as a directory structure. For a directory structure the existance of a Manifest is not defined. Therefore the dedicated class loader will ignore all requests for a Manifest. This is the reason the call returns null.
Running in the productive environment your product is packed within a jar-file. In this case it is defined, that there is a Manifest-file. The jar file class loader knows about the manifest file and will display version information correctly.
We helped us, by providing a default of "Implementation Version" if the version is retrieved within the development environment.

NoClassDefFoundError in jackcess

I am working on an RCP application which is based on eclipse plugins. In one of my plugin project I add another plugin project as dependency. Let say Project A has Project B as a dependency defined under its manifest. Project B contains jackcess.jar file as referenced library.
In Project B I have a class called Mirror.java
public Mirror(String source, String template, String target) throws SQLException, IOException {
this.sourceString=source;
this.templateFileString=template;
this.targetFileString=target;
}
inside from project A when I try to create an object of class Mirror
Mirror m = new Mirror(connectionString, "EABase_JET4_empty.eap",platformDB.getAbsolutePath());
I get the following error
java.lang.NoClassDefFoundError:
com/healthmarketscience/jackcess/ImportFilter
build.properties of Project B (containing jackcess.jar)
bin.includes = META-INF/,\
src/main/resources/lib/jackcess-1.2.6.af3.jar
The MANIFEST.MF
Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: MirrorDbToEap
Bundle-SymbolicName: MirrorDbToEap
Bundle-Version: 1.0.0
Export-Package: .,
com.example.jetdb.mirror
Require-Bundle: CommonsIo;bundle-version="2.0.0",
org.apache.commons.lang;bundle-version="2.6.0",
org.apache.commons.logging;bundle-version="1.0.4"
Anyone having any idea what's going wrong here?
Thanks
You are not including the jackcess.jar in the bin.includes in the build.properties file so it is not being included in the RCP build.
Open the build.properties editor and select the jar in the 'Binary Build' selection.
The jar must also appear in the Bundle-ClassPath in the MANIFEST.MF. In the manifest editor in the Runtime tab add the jar to the 'Classpath' section (you should also have '.' for normal plugin code).
It seems the class which is available in compile time, is not available in run time.

Jetty with a custom JUL logger

I feel this should be easier, or I am missing something obvious.
I am trying to use our custom JUL logging library with Jetty. No matter where I put the JAR file for the custom logger, it is not found. I have tried the usual suspects; /lib/, /lib/ext/, /WEB-INF/lib/ and even manually added it to the classpath.
2011-06-29 15:27:34.518::INFO: Started SelectChannelConnector#0.0.0.0:8080
Can't load log handler "net.aw20.logshot.client.LogShotHandler"
java.lang.ClassNotFoundException: net.aw20.logshot.client.LogShotHandler
java.lang.ClassNotFoundException: net.aw20.logshot.client.LogShotHandler
at java.net.URLClassLoader$1.run(URLClassLoader.java:217)
I am starting up Jetty using "-jar start.jar" technique. Searching around, I have spotted a couple of threads that talk about this problem, but with no resolution. Or if there was, they didn't answer with their solution.
Can anyone help on this front?
Thanks
If you start a Java application with "-jar", the normal classpath-arguments are not used any more. What you can do instead is to list the .jar file in a META-INF/MANIFEST.MF file. I.e. I have the following in one of my jar-files:
Manifest-Version: 1.0
Ant-Version: Apache Ant 1.7.1
Created-By: 20.6-b01 (Sun Microsystems Inc.)
Built-By: user1
Bundle-Vendor: myCompany
Bundle-Version: 1.0.0.1
Implementation-Version: 1.0.0.1
Class-Path: commons.jar lib/hibernate3.jar
and this way the jars are available as part of the Classpath.

Categories