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.
Related
When I run the project as a java application in eclipse it works perfectly but running a java -jar on windows cmd throws the SQL exception (No suitable driver found)
I have used maven(maven-assembly) to create the executable jar, a jar-with-dependencies is created in project\target.
The postgresql jar (postgresql-42.2.5.jar) exists in the project\lib folder.
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<configuration>
<archive>
<manifest>
<mainClass>com.project.Main</mainClass>
</manifest>
</archive>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
</configuration>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
After running mvn clean package :
A manifest file (project\src\main\resources\MANIFEST.mf) is copied into project\target\classes folder. The manifest file contains Class-Path: lib/postgresql-42.2.5.jar.
I have added the dependency in my pom.xml as well.
<dependencies>
<dependency>
<groupId>postgresql</groupId>
<artifactId>postgresql</artifactId>
<version>${postgres.driver.version}</version>
</dependency>
</dependencies>
I was hoping that the Class-Path in manifest file would take care of this issue but it did not.
Might be a duplicate post but none of the existing solutions fixed my problem.
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.
I'm using Intellij Java 2016.2.2 and Maven to create a very simple Java console application.
I want to add an external library, so I add my dependency in Maven like this:
<dependency>
<groupId>jline</groupId>
<artifactId>jline</artifactId>
<version>2.12</version>
</dependency>
It works fine when I run it in the IDE, but not in an external console (I have the following error: java.lang.NoClassDefFoundError).
I checked and for some reason, the external JAR is not added in the JAR I just generated. I also tried many things in "File -> Project Structure", but still not working...
I just want to build my JAR with my dependencies in it, so I can simply run my application in a console using:
java -jar myproject.jar
How can I do that? Thanks for your help!
I finally managed to generate this JAR with Intellij Java, here is how I do:
add the dependencies in the pom.xml file
go to File -> Project Structure -> Artifacts -> New -> JAR -> From module with dependencies
choose the Main class and click OK
in your project, in src/main, create the "resources" folder
move the "META-INF" (with MANIFEST.MF in it) folder in this "resources" folder
go to Build -> build artifacts to build the JAR
EDIT
A better (and easier way) to do it is adding the following lines in the pom.xml file :
<build>
<plugins>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<configuration>
<archive>
<manifest>
<mainClass>your.MainClass</mainClass>
</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>
then use the "clean" and "package" maven commands.
The last 3 steps above (about MANIFEST.MF) still seem to be mandatory.
Okay, so you basically want to create a "fat jar" (sometimes called assembly), that contains all its own dependencies (usually, the dependencies are external).
You need to use a Maven plugin for that. Below is a sample assembly plugin configuration jar-with-dependencies:
<project>
...
<build>
...
<plugins>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<version>2.6</version>
<configuration>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
</configuration>
...
</project>
then, simply run
mvn package
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 have a question concerning Maven. I have created a Jar file the name "MyFinalFarFileName_1.0.0-SNAPHOT_20140730.jar". Here is a small code snippet from my pom.xml file:
<groupId>myGroupId</groupId>
<artifactId>myArtifactId</artifactId>
<version>1.0.0-SNAPSHOT</version>
<properties>
<timestamp>${maven.build.timestamp}</timestamp>
<maven.build.timestamp.format>yyyyMMdd</maven.build.timestamp.format>
</properties>
<build>
<finalName>MyFinalJarFile_${project.version}_${timestamp}</finalName>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<configuration>
<descriptorRefs>
<descriptorRef>
jar-with-dependencies
</descriptorRef>
</descriptorRefs>
<archive>
<addMavenDescriptor>false</addMavenDescriptor>
<manifestEntries>
<source-jdk>1.6</source-jdk>
<target-jdk>1.6</target-jdk>
</manifestEntries>
<manifest>
<addClasspath>true</addClasspath>
<classpathPrefix>lib/</classpathPrefix>
<mainClass>myMainClass</mainClass>
</manifest>
</archive>
<appendAssemblyId>false</appendAssemblyId>
</configuration>
<executions>
<execution>
<id>assembly-jar-Id</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
</build>
Currently I´m set a manual build timestamp and project version number in a Java Interface like this:
public MyInterface {
public String versionNumber = "My Project Version: 1.0.0-SNAPSHOT";
public String versionBuildTimeStamp = "My Project BuildTimeStamp: 20140730 11:34";
}
Is it possible to set these kind of information by using maven? Or it is necessary to create a propertie file with these kind of information by using maven and combine this popertie file with my Java Interface?
It is not enough to set this information in the manifest file of my created Jar file.
How can I solve this problem?
It is possible however not at all suitable, better to write a maven plugin that will write these properties to a properties file and then you can fill in your constant values reading that properties file
There are tons of ways to do this, take a look on the Maven release plugin.
The easiest way in your specific case could be to read a property file that is updated by the Maven resources plugin with the current version number and timestamp (it can process files and replace variables easily).
Maybe the Build Number Maven Plugin can help you.