I have a problem.
I write a Java console app in intelliJ. I add the maven package org.json.json and if i run the project in IntelliJ everything works.
If I start the class in the console with
java Main I get this error:
Exception in thread "main" java.lang.NoClassDefFoundError:
org/json/JSONObject
I have try and search a lot but nothing works
The maven-shade-plugin is a fancy plugin with plenty of options. For creating simpler jars containing jars I use the maven-assembly-plugin. Also verify that the scope within the org.json.json dependency is set to compile.
The details are documented at: https://maven.apache.org/plugins/maven-assembly-plugin/descriptor-refs.html#jar-with-dependencies
For example:
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<executions>
<execution>
<id>jar-with-dependencies</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
<configuration>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
<archive>
<manifest>
<mainClass>your.main.class.package.your_main_class</mainClass>
</manifest>
</archive>
</configuration>
</execution>
</executions>
</plugin>
Just running a class from a console is not enough. You also need to set classpath to point to all of its dependencies including json jars.
Since you are using Maven, my advice is to use its "maven-shade-plugin" in order to create one large jar that has your class and all of json jar classes and run your class with "-jar" option.
Related
I've spent the last 3 hours trying to get my Java program to interface with my Postgres server. I cannot get past the error message "No suitable driver found for jdbc:postgresql://localhost:5432/gis". It is a Bukkit plugin, and I am using IntelliJ IDEA.
The code:
try
{
//Class.forName("org.postgresql.Driver");
c = DriverManager.getConnection("jdbc:postgresql://localhost:5432/gis");
}
catch(Exception e)
{
getLogger().info(e.getMessage());
}
Things I have tried:
java -cp ./path/to/postgresjdbc.jar -jar spigot-1.15.2.jar
adding the jdbc file internals directly to my jar file
adding the jdbc file as a dependency within the IntelliJ project
switching to maven, and putting the following in pom.xml:
<dependencies>
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<version>42.2.1</version>
</dependency>
</dependencies>
I am unable to get past the error I posted. At this point, it has taken over my entire evening.
I've stumbled with this issue several times when developing Bukkit/Spigot plugins that make use of MySQL databases. The process for Postgres should be the same.
Usually, this error happens when your plugin can't find the PostgresqlJDBC driver. You have two workarounds:
Option 1. Adding the .jar to the plugin's classpath:
It's recommended that you set the libraries inside plugins/lib as then your server won't try to load the libraries as a Bukkit plugin. Add the prefix lib/ to your classpath by adding this configuration in your pom.xml:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<configuration>
<archive>
<manifest>
<addClasspath>true</addClasspath> <-- don't know if this is needed -->
<classpathPrefix>lib/</classpathPrefix>
</manifest>
</archive>
</configuration>
</plugin>
Then make sure to put your postgresjdbc.jar inside a folder called lib inside your plugin's folder.
Option 2. Add dependencies directly in your jar:
Note that this option will increase your plugin's jar size.
This can be done via Maven's assembly plugin:
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
<configuration>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
<archive>
<manifest>
<mainClass>your.main.class</mainClass>
</manifest>
</archive>
</configuration>
</plugin>
If you open your plugin's jar with a file compressor like 7-zip you should there should the driver's classes in it apart from your plugin ones.
Let me know if this solved your issue.
I generate jar file with maven-assembly-plugin plugin. I use java -jar to execute jar. I got error message:
log4j: WARN JmDNS or serviceInfo not found
I tried to use path to jar in -classpath, but got same error.
Plugin configuration:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<version>3.1.0</version>
<executions>
<execution>
<id>make-assembly</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
<configuration>
<archive>
<manifest>
<mainClass>test.LeanFTest</mainClass>
</manifest>
</archive>
<finalName>${project.artifactId}-fatjar-${project.version}</finalName>
<appendAssemblyId>false</appendAssemblyId>
<descriptors>
<descriptor>src/main/assembly/leanft-assembly.xml</descriptor>
</descriptors>
</configuration>
</plugin>
Most likely, this boils down to:
Your maven build does not include dependent artefacts into your JAR file. In other words: the JAR you create does not include the logj4 JARs. You can change that with your maven config, see here for details.
As your JAR doesn't contain the dependencies, all JARs you depend on must be in your classpath. Meaning: when you run your new JAR on the command line, all elements that might be required for running it must be present on the classpath.
When I create a jar file I want to fit inside my dependencies. For that, I use maven-assembly-plugin such as follows:
<build>
...
<plugins>
...
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<version>2.4</version>
<configuration>
<finalName>${project.artifactId}-GUI</finalName>
<archive>
<manifest>
<mainClass>gui.MyMainClass</mainClass>
</manifest>
</archive>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
<!-- <appendAssemblyId>false</appendAssemblyId>-->
</configuration>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
This code works OK and it does what it's expected to do. However, this creates a new jar called myjar-GUI-jar-with-dependencies.jar. I would like to eliminate that "jar-with-dependencies" ending. Does anybody knows how to do that?
I have used that commented line you can see on my code, but that produces the following warning that I don't know how to solve it:
[WARNING] Configuration options: 'appendAssemblyId' is set to false, and 'classifier' is missing.
Instead of attaching the assembly file: [myJar-GUI].jar, it will become the file for main project artifact.
NOTE: If multiple descriptors or descriptor-formats are provided for this project, the value of this file will be non-deterministic!
[WARNING] Replacing pre-existing project main-artifact file: [myJar].jar with assembly file: [myJar-GUI].jar
EDITED
After the solution the user Tunaki suggested, I used a different pluggin and maven works as I want it to do it. The code is as follows:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>2.4.2</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
</execution>
</executions>
<configuration>
<transformers>
<transformer
implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
<mainClass>gui.SparkISGUI</mainClass>
</transformer>
</transformers>
</configuration>
</plugin>
First, you need to understand why you are getting this warning.
The Maven convention is that one project should create a single main artifact. For a project of packaging jar, the main artifact is the result of the maven-jar-plugin. This plugin will package as a JAR the classes contained in your project only.
One project can eventually generate additional artifacts that will be distinguished from the main one by their classifier:
Beside the main artifact there can be additional files which are attached to the Maven project. Such attached filed can be recognized and accessed by their classifier.
The classifier is an identifier than will be appended to the main artifact name.
So what happens when you want to create an uber-jar? Somehow, your project needs to generate two jars. The main one will be a JAR containing the classes of your project and the second one will be the uber-jar resulting of maven-assembly-plugin. To distinguish this secondary additional artifact from the main one, the classifier jar-with-dependencies is added.
So when you remove the classifier, you effectively replace the main artifact with the uber-jar. maven-assembly-plugin will emit a warning in this case, and that's the warning you are having. You can ignore it completely: it just reminds you that you are replacing the main artifact of the project by an additional artifact.
Besides the maven-assembly-plugin, do note that you can also generate an uber-jar with the maven-shade-plugin:
This plugin provides the capability to package the artifact in an uber-jar, including its dependencies and to shade - i.e. rename - the packages of some of the dependencies.
Is there a way to add an arbitrary classpath entry to a JAR file manifest using onejar-maven-plugin?
I found the way to configure maven-jar-plugin to do this, but it appears that there is no such option for onejar-maven-plugin.
This is not done to find additional classes (otherwise why use the onejar plugin, right?), but rather to locate a configuration file that must be external to the JAR.
Is there a direct solution or a workaround for this?
Is the usage of the one-jar plugin really required?
You can achieve the same goal (packaging in one single jar your application AND all the required dependencies, including transitive ones, AND add configuration for Class-Path AND using a more stable/standard plugin) applying the following approach:
Configure the Class-Path entry in your application Jar using the Maven Jar Plugin and the approach you mentioned in the question
Use the Maven Assembly Plugin to package one single JAR including dependencies, as explained here, in another stackoverflow question/answer.
An example of one-jar executable file (without using the one-jar plugin) could be as following:
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<configuration>
<!-- your further configuration here -->
</configuration>
</plugin>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<configuration>
<archive>
<manifest>
<mainClass>com.sample.MainApp</mainClass>
<!-- your further configuration here -->
</manifest>
</archive>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
</configuration>
<executions>
<execution>
<id>make-assembly</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
If you need to further play with classpath and Maven, I would suggest to also check this question here on stackoverflow.
Adding arbitrary manifest entries is possible in 1.4.5:
<plugin>
<groupId>org.dstovall</groupId>
<artifactId>onejar-maven-plugin</artifactId>
<version>1.4.5</version>
<executions>
<execution>
<configuration>
<manifestEntries>
<Build-Status>Yes</Build-Status>
</manifestEntries>
</configuration>
<goals>
<goal>one-jar</goal>
</goals>
</execution>
</executions>
</plugin>
The onejar-maven-plugin project doesn't seem to be in active development anymore, so you might want to switch to other solutions (e.g. maven-assembly-plugin) eventually.
The plugin is not available on Maven Central. Someone else put up a version of it to Maven Central with a different group ID.
Additional libraries can be added to the classpath at the time of launch.
The property one-jar.class.path can be used
one-jar.class.path
Extra classpaths to be added to the execution environment. Use platform independent path separator '|'
Example: --one-jar.class.path="./lib/two.jar|/opt/lib/three.jar"
Source: http://one-jar.sourceforge.net/index.php?page=details
I want to create a jar file of a Java project, which compiles. I've looked on the internet but all the examples of how to do this seem to take one java file and work on that. I want to jar the root of the java project. How is this possible?
Thanks
IntelliJ
According to this Stackoverflow topic you can built jar file using
You didn't specify your IDEA version.
Before 9.0 use Build | Build Jars, in
IDEA 9.0 use Project Structure |
Artifacts.
Maven
You should learn to use a build tool like maven. You then could use the maven assembly plugin
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>attached</goal>
</goals>
<phase>package</phase>
<configuration>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
<archive>
<manifest>
<mainClass>*******your main class******</mainClass>
</manifest>
</archive>
</configuration>
</execution>
</executions>
</plugin>
Ant
Or you could use ant(2) to create a jar file.
Here is a link to the tutorial that might help.
The jar command takes either files or directories. So you can simply specify the name of the directory that you want to jar rather than a file name. Once you know the command to jar a single file then you can jar a directory. More details here.
And this tutorial shows an example of jaring a file and a number of directories together.