I am trying to load a JDBC postgreSQL driver for a Java program. I know this is all over the Internet. I have tried many solutions, but none of them have worked for me.
The problem is that I get this error:
Exception in thread "main" java.lang.NoClassDefFoundError:
classes/com/freire/test/JDBCExample/class
Caused by: java.lang.ClassNotFoundException: classes.com.freire.test.JDBCExample.class
at java.net.URLClassLoader$1.run(URLClassLoader.java:202)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:190)
at java.lang.ClassLoader.loadClass(ClassLoader.java:306)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:301)
at java.lang.ClassLoader.loadClass(ClassLoader.java:247)
And my code looks like this:
package com.freire.test;
import java.sql.DriverManager;
import java.sql.Connection;
import java.sql.SQLException;
public class JDBCExample
{
public static void main(String[] argv)
{
System.out.println("JDBC Connection Testing");
try {
Class.forName("org.postgresql.Driver");
} catch (ClassNotFoundException e) {
System.out.println("PostgreSQL JDBC Driver not included!");
}
}
}
And the structure of my project looks like this:
myProject
src
com
freire
test
JDBCExample.java
classes
com
freire
test
JDBCExample.class
lib
postgresql-9.2-1003.jdbc3.jar
Compiling works fine:
java -d classes/ src/com/freire/test/JDBCExample.java
But executing produces the error:
java classes/com/freire/test/JDBCExample
Worth to say that I am working on a OS X Mountain Lion.
Any help will be appreciated.
Firstly you need to mention the package names using . instead of / while running the java program:
Go to your classes directory and run JDBCExample as :
java com.freire.test.JDBCExample
But it will now cry for the postgres driver class not found because postgres jar is missing in the classpath.So you need to use the classpath option while running the program and add your postgres jar to the classpath:
for windows:
java -cp .;../lib/postgresql-9.2-1003.jdbc3.jar com.freire.test.JDBCExample
for linux:
java -cp .:../lib/postgresql-9.2-1003.jdbc3.jar com.freire.test.JDBCExample
On Linux execute following:
javac -cp '.:postgresql-9.1-901.jdbc4.jar' postgresjavatest.java
java -cp '.:postgresql-9.1-901.jdbc4.jar' postgresjavatest
It will jdbc drivers for you. make sure jar file is on same location
You need to ensure that the postgresql-9.2-1003.jdbc3.jar is within the class path when you compile and run the program
Try using
javac -cp lib/postgresql-9.2-1003.jdbc3.jar -d classes/ src/com/freire/test/JDBCExample.java
to compile the application and
java -cp lib/postgresql-9.2-1003.jdbc3.jar;./classes com.freire.test.JDBCExample
to run it...
nb As Juned has pointed, technically, you don't need the lib/postgresql-9.2-1003.jdbc3.jar references in the classpath, but consider it an demonstration of how to included compile time dependencies within the complication process ;)
Related
This question already has answers here:
Connect Java to a MySQL database
(14 answers)
How to use a wildcard in the classpath to add multiple jars? [duplicate]
(4 answers)
Closed 3 years ago.
I am creating an application that is utilizing JDBC and am currently having problems running the code without getting java.lang.ClassNotFoundException: com.mysql.cj.jdbc.Driver. I have done extensive research into trying to solve this issue and nothing i have tried seems to work.
For one, I would like to note that my code works fine when it is run from my IDE (intellij). The database connection works and all the queries execute as necessary. The problem comes when I try to compile and run using javac and java in the terminal. Becuase this is a school project, I will need to enable my professors to be able to run it locally.
Secondly, I am compiling the application using the same jar files that are also included within intellij:
javac -classpath lib/\* DatabaseDriver.java
The lib folder contains my JDBC jar file. You can find the two jar files in this folder here (json.org) and here (connector j). Everything compiles correctly but it seems that once the following execution occurs in the code (see below for the full code) the is a runtime excetion that says the class can not be found:
Class.forName("com.mysql.cj.jdbc.Driver"); // also tried com.mysql.jdbc.Driver
The following code is what I am trying to compile (not the full DatabaseDriver, just enough to reproduce the issue):
import org.json.JSONObject;
import java.sql.*;
public class DatabaseDriver {
// JDBC driver name and database URL
static final String JDBC_DRIVER = "com.mysql.cj.jdbc.Driver";
public static String runStatement(String sql) throws Exception {
// Register JDBC driver
Class.forName(JDBC_DRIVER);
return "";
}//end main
public static void main(String[] args) throws Exception {
DatabaseDriver.runStatement("SELECT * FROM employees LIMIT 10");
}
}
This is the full stack that I get when I run the code:
Exception in thread "main" java.lang.ClassNotFoundException: com.mysql.cj.jdbc.Driver
at java.net.URLClassLoader.findClass(URLClassLoader.java:381)
at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:335)
at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Class.java:264)
at DatabaseDriver.runStatement(DatabaseDriver.java:15)
at DatabaseDriver.main(DatabaseDriver.java:40)
Problem Summary: I am unable to run this script such that the jar file gets picked up even though it is the same jar file that my IDE is able to properly use. There must be something that I am forgetting or missing to do because all of the solutions I am finding only have to deal with people forgetting to include the correct jar files.
Run your class as given below:
In Unix based systems
java -cp ".:lib/*" DatabaseDriver
In MS Windows
java -cp ".;lib/*" DatabaseDriver
I have a java gradle projectA that references another java gradle projectB, that builds as a lib.
My gradle build configuration seems to be fine, since I can import and use classes from the other project, and it compiles. But when I try to run the application from the command line I get an error...
Exception in thread "main" java.lang.NoClassDefFoundError:
dawcore/SamplerInstrument at DawCLI.main(DawCLI.java:17) Caused by:
java.lang.ClassNotFoundException: dawcore.SamplerInstrument 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
It seems to be complaining that it can't load the classes in the jar at runtime....which makes sense. But I don't know how to have it successfully load those classes.
my current run command that does not reference the jar, is as follows....
/usr/lib/jvm/java-1.8.0-openjdk-amd64/jre/bin/java -ea -cp "build/classes/main/" DawCLI
Running this gives the initially mentioned error.
I then read the docs on java -cp argument. It says to provide additional classpath directories, to separate them by semicolon.
I susequently updated my run command to be as follows....
/usr/lib/jvm/java-1.8.0-openjdk-amd64/jre/bin/java -ea -cp "build/classes/main/;../DawCore/build/libs/DawCore.jar" DawCLI
This gives me the following error....
Error: Could not find or load main class DawCLI
My main function is as follows..
import dawcore.*;
public class DawCLI {
public static void main (String [] args) throws IOException {
SamplerInstrument samplerkick = new SamplerInstrument();
}
}
According to the docs I seem to be doing this correctly, but am still getting errors. Any insight on this would be greatly appreciated!
Thanks
The solution was to replace the delimiting semi-colon with a colon instead. Even though the first line of the javadocs on -cp command indicate that you should use a semi-colon.
This could be because I am running on linux and those docs indicate Windows.
https://docs.oracle.com/javase/7/docs/technotes/tools/windows/java.html
I was trying to connect to MySQL using JDBC API. I have downloaded the MySQL driver which is the "mysql-connector-java-5.1.28-bin jar" file. My OS is Windows 7 and I have set the Classpath of Java to following path:
"E:\Myclass"
I have copied the above jar file to this folder.
Then I have written the following code to test if I can load the driver.
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
public class LoadDriver {
public static void main(String[] args) {
try {
// The newInstance() call is a work around for some
// broken Java implementations
Class.forName("com.mysql.jdbc.Driver").newInstance();
} catch (Exception ex) {
// handle the error
System.out.println("Unable to load Driver Class");
return;
}
}
}
I expect everything should be working fine but I always get the "Unable to load Driver Class". Can anyone point out where was wrong? Thanks
Note: Thanks for all your answers. I have solved the problem. Since I am using Eclipse, I have add the JAR file to the classpath of the Eclipse.
You have to include the JAR in your classpath:
java -jar yourdriver.jar LoadDriver
JARs are filesystems. They should be added to your classpath the same way you add directories. Only classes will be loaded from the classpath you specified.
Use the below cmd to run it
java -cp E:\Myclass\mysql-connector-java-5.1.28-bin.jar; LoadDriver
As mentioned the mysql jar exist # E:\Myclass\mysql-connector-java-5.1.28-bin.jar , just set in the classpath and run it
I am having two problems regarding compiling and running an Eclipse java project from command line. This works fine when I am just running from the eclipse IDE. I tried googling but couldn't really get the thing working. Any help is much appreciated.
Problem 1: When I try to compile from a location different from the directory where the .java file is, it throws the error "cannot read: myfile.java". But if I migrate to this directory then it compiles.
The command that I was giving is (when in some other directory):
javac -cp C:\ABC\src\XYZ myfile.java
The command that I was giving when in XYZ directory:
javac myfile.java
This generated two .class files myfile.class and Testing_Thread.class(I guess this because I have a thread in my code)
Problem 2: After I have compiled by going to its directory, when I try to run the program, I get the error "Exception in thread "main" java.lang.NoClassDefFoundError: myfile (wrong name: XYZ/myfile.java)" even when I am trying to run from the XYZ directory. I get the same error when I try to run from some other place also.
The command that I was giving when in XYZ directory:
java myfile
The command that I was giving when in some other place:
java -cp C:\ABC\src\XYZ myfile
I am also attaching a hierarchy of my directory structure if it is of any help:
These examples assume the following source structure:
C:\temp\compile-test\src\a\b\c\D.java
Where D.java is:
package a.b.c;
public class D { }
The first problem, cannot read: myfile.java, is because it is not correct to use the cp command line option to point to your source code.
C:\temp\compile-test\src>javac -cp c:\temp\compile-test\src\a\b\c D.java
javac: file not found: D.java
Usage: javac <options> <source files>
use -help for a list of possible options
This should instead be the following, where javac is run from your source folder, and we can use relative paths to the source files (NOTE - javac is run from the source folder here):
C:\temp\compile-test\src>javac a\b\c\D.java
Or this, where we specify full paths to the source files, and javac can be run from anywhere (NOTE - javac is run from C:\ here):
C:\>javac temp\compile-test\src\a\b\c\D.java
Both of the above options will result in your class files being created in the same folder as the source. I.e.:
C:\temp\compile-test\src\a\b\c\D.class
For the second problem, if you try and run a class that has a package name from 'inside' the package, this will result in the name being wrong (NOTE - java being run from 'inside' the package here):
C:\temp\compile-test\src\a\b\c>java D
Exception in thread "main" java.lang.NoClassDefFoundError: D (wrong name: a/b/c/D)
at java.lang.ClassLoader.defineClass1(Native Method)
at java.lang.ClassLoader.defineClassCond(ClassLoader.java:631)
at java.lang.ClassLoader.defineClass(ClassLoader.java:615)
at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:141)
at java.net.URLClassLoader.defineClass(URLClassLoader.java:283)
at java.net.URLClassLoader.access$000(URLClassLoader.java:58)
at java.net.URLClassLoader$1.run(URLClassLoader.java:197)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:190)
at java.lang.ClassLoader.loadClass(ClassLoader.java:306)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:301)
at java.lang.ClassLoader.loadClass(ClassLoader.java:247)
Could not find the main class: D. Program will exit.
To run the D class, you should be at the package 'root', and supply the Fully Qualified Class Name. I.e.:
C:\temp\compile-test\src>java a.b.c.D
Exception in thread "main" java.lang.NoSuchMethodError: main
Note I get an exception as the D class doesn't have a main method, and so cannot be run. To fix, we add a main method:
package a.b.c;
public class D {
public static void main(String[] args) {
System.out.println("main");
}
}
and re-run:
C:\temp\compile-test\src>java a.b.c.D
main
I'm trying to use the public methods/classed from a project provided as a jar file (called Hello.jar for instance) wrapped in a package called hello.
package hello;
public class Hello
{
public static void main(String[] args)
{
coucou();
}
public static void coucou()
{
System.out.println("Hello there");
}
}
In a separate project called Tool, I want to be able to call the method Hello.coucou() so I wrote something like this:
import hello.*;
public class Tool
{
public static void main(String[] args)
{
System.out.println("main program running");
Hello.coucou();
}
}
and I compiled Tool.java with the following command (under linux):
$ javac Tool.java -classpath .:./extern/:
where Hello.jar is located in the folder ./extern
This seems to compile fine but when I launch it (i.e. java Tool), I get this:
main program running
Exception in thread "main" java.lang.NoClassDefFoundError: hello/Hello
at Tool.main(Tool.java:9)
Caused by: java.lang.ClassNotFoundException: hello.Hello
at java.net.URLClassLoader$1.run(URLClassLoader.java:217)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:205)
at java.lang.ClassLoader.loadClass(ClassLoader.java:323)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:294)
at java.lang.ClassLoader.loadClass(ClassLoader.java:268)
at java.lang.ClassLoader.loadClassInternal(ClassLoader.java:336)
... 1 more
I am new to Java (C/C++ background) and I don't understand what I'm doing wrong.
Any ideas?
Cheers
David
Edit: I tried adding Hello.jar to the classpath on the command line, but I still get the same error:
$ javac Tool.java -classpath .:./extern/Hello.jar:
$ java Tool -classpath .:./extern/Hello.jar:
main program running
Exception in thread "main" java.lang.NoClassDefFoundError: hello/Hello
at Tool.main(Tool.java:9)
Caused by: java.lang.ClassNotFoundException: hello.Hello
at java.net.URLClassLoader$1.run(URLClassLoader.java:217)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:205)
at java.lang.ClassLoader.loadClass(ClassLoader.java:323)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:294)
at java.lang.ClassLoader.loadClass(ClassLoader.java:268)
at java.lang.ClassLoader.loadClassInternal(ClassLoader.java:336)
... 1 more
You need the Hello.jar on the classpath when you run as well as when you compile.
Actually the trick was in the order of the arguments in the command line:
Is the -cp (or -classpath) is set last, then it doesn't work
java Tool -cp .:extern/Hello.jar
It has to be first like:
java -cp .:extern/Hello.jar Tool
!!!
Java uses dynamic late binding, so putting the JAR in the classpath during compilation is only necessary to ensure that your code is using the classes from it correctly, but it does not actually embed them into your code as the linker would in C/C++. Thus, you need to set the classpath also when executing the code.
However, this:
$ javac Tool.java -classpath .:./extern/:
should not work either, since JARs need to be put into the classpath directly, not just the directory they live in:
$ javac Tool.java -classpath .:./extern/Hello.jar
Finally, you are placing your code in the default nameless package. This is OK for fooling around, but will cause problems in the long run (for one thing, you cannot import classes FROM the default package anywhere else).
When you run Java you must add the jar file too (adding the directory path only does not work).
See classpath information.
It should be something like this:
java -classpath /java/MyClasses/myclasses.jar utility.myapp.Cool
You need to include the Hello.jar file in the classpath when you launch it too.
java -cp xxx.jar hello where xxx is the jar you want to have in your classpath, if you want multiple jars then separate them using ;
karl