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
Related
I'm using java version 11 in Ubuntu and I'm having trouble using pipes for input/output of data. Because of the pipes I can't use the Netbeans IDE. I use the terminal instead.
The question is if I HAVE to use the Princeton specific I/O or if system I/O will work. Specifically it is choice between
BinaryStdOut.write(i);
BinaryStdOut.write(' ');
//System.out.print(i);
//System.out.print(' ');
If I comment out the Princeton BinaryStdOut and use System.out, everything works perfectly on my local machine. I use
java MoveToFront - < abra.txt
However when I send the code to the grader, it fails to print the results so that the grader thinks there are no results. If I uncomment their code and comment out the System.out, I get an error saying that it can't find the jar file.
java MoveToFront - < abra.txt
Exception in thread "main" java.lang.NoClassDefFoundError: edu/princeton/cs/algs4/BinaryStdOut
at MoveToFront.encode(MoveToFront.java:31)
at MoveToFront.main(MoveToFront.java:67)
Caused by: java.lang.ClassNotFoundException: edu.princeton.cs.algs4.BinaryStdOut
at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:581)
I have put MoveToFront.class and algs4.jar in the same folder because I understand the default classpath is the same folder as the class file.
This morning I found on stackoverflow that one should mention the specific jar file, so I changed my command accordingly. It shows definite improvement but not enough.
java -cp "algs4.jar" MoveToFront - < abra.txt
Error: Could not find or load main class MoveToFront
Caused by: java.lang.ClassNotFoundException: MoveToFront
Obviously there is a main class in MoveToFront as it worked perfectly well with System.out. Apparently I am almost there, but I am still missing something important. The question is what??
Just to be complete the main is
public static void main(String[] args) {
if (args[0].equals("-")) encode();
if (args[0].equals("+")) decode();
}
This question already has answers here:
Connect Java to a MySQL database
(14 answers)
Closed 2 years ago.
I am writing a simple program in Java using to demonstrate insertion of data in MySQL table using JDBC. But the program is generating ClassNotFoundException while registering driver.
import java.sql.*;
public class test {
public static void main(String[] args) {
try {
Class.forName("com.mysql.jdbc.Driver");
}
catch(ClassNotFoundException e) {
System.out.println("ClassNotFoundException: "+e.getMessage());
}
}
}
I have added the driver JAR file in the same directory.
To compile the program:
javac -cp ".:~/Programs/D/friends/assignment/driver.jar;" test.java
To execute the program:
java -cp ".:~/Programs/D/friends/assignment/driver.jar;" test
O/p:
ClassNotFoundException: com.mysql.jdbc.Driver
Note: The issue is caused by ; at the end of the driver.jar and also not using fully qualified path.
Windows based OS uses ; separator whereas Unix-based OS uses : separator.
Solution :
First compile the code : javac test.java (Run this command)
Run the code without semi-colon : java -cp .:<fully-qualified-path>/driver.jar test
Sample output :
anish#Anishs-MacBook-Pro ~ % javac Test.java
anish#Anishs-MacBook-Pro ~ % java -cp .:/Users/anish/driver.jar Test
Loading class `com.mysql.jdbc.Driver'. This is deprecated. The new driver class is `com.mysql.cj.jdbc.Driver'. The driver is automatically registered via the SPI and manual loading of the driver class is generally unnecessary.
Note : I'm using mysql-connector-8.0.15.jar. If you are using the same or greater, then change from com.mysql.jdbc.Driver to com.mysql.cj.jdbc.Driver as that class is deprecated.
1.at the end of the classpath there seems to be an extra semi-colon:
/assignment/driver.jar;"
try without it
2. Are you sure driver.jar is the correct file?
normally they are called like mysql-connector-java-8.0.23.jar
I can see that this question has been asked before, but I have not found previous answers useful - specifically my issue is following Princeton University's 'Algorithms' course on Coursera here and using their algs4.jar file to access ostensibly necessary utilities. I have never used Java before but this seemed like such a good course, I'm trying to muddle through rather than switching to a 'worse' course in a language I know. I have also found a thread specifically on this issue here and a Reddit question here, which were equally as useless as the other questions which had this problem, but not with the Princeton's algs4.jar file.
This is my code, I haven't bothered to finish it but it should run. Before anybody asks, I've commented out everything except the first if (StdIn.isEmpty()) check and it still gives me all the same compiler/interpreter errors, so this is nothing to do with it being half-finished - StdIn.isEmpty() and StdIn.readString() are supposed to be provided by algs4.jar:
import edu.princeton.cs.algs4.StdIn;
import edu.princeton.cs.algs4.StdOut;
import edu.princeton.cs.algs4.StdRandom;
class RandomWord
{
public static void main(String[] args)
{
if (StdIn.isEmpty())
{
System.out.println("Nothing to read.");
return;
}
String curr_selected_word;
double curr_probability = 0.0;
int i = 0;
while (!StdIn.isEmpty())
{
String current_string = StdIn.readString();
System.out.println("> " + current_string);
}
}
}
Following the advice of previous threads, I compile like this:
javac -cp "./algs4.jar" RandomWord.java
Which works fine. Running java RandomWord, I get this large messy error:
Exception in thread "main" java.lang.NoClassDefFoundError: edu/princeton/cs/algs4/StdIn
at RandomWord.main(RandomWord.java:13)
Caused by: java.lang.ClassNotFoundException: edu.princeton.cs.algs4.StdIn
at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:583)
at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:178)
at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:521)
... 1 more
The accepted answer on the other question was to reference the .jar file explicitly, like this:
java -cp "C:\Coursera\Algorithms\Part 1\Java Solutions\HelloWorld;C:\Coursera\Algorithms\Part 1\Java Solutions\algs4.jar" RandomWord
Which gives me the exact same error. There is also a comment on the Reddit thread that uses the -classpath instead of -cp flag, which at least gives a different but stranger error:
>java -classpath ./algs4.jar RandomWord
Error: Could not find or load main class RandomWord
Caused by: java.lang.ClassNotFoundException: RandomWord
Putting quotes around the .jar filepath, or providing the absolute filepath, all produce the same error.
I Googled this and predictably it is caused by not having a main entry-point, but... see code above?
Lastly, the installer for the Coursera course apparently installs some Bash commands (see here) called javac-algs4 and java-algs4 which is supposed to sort out all this classpath nonsense for me. So I crack open Bash, and:
>javac-algs4 RandomWord.java
'javac-algs4' is not recognized as an internal or external command,
operable program or batch file.
I have restarted since running the installer. I would add these to my PATH manually, but I don't even know where they are; the C:\Program Files\LIFT-CS folder that their installer installs into only contains a pissing uninstaller. So I'm absolutely losing my rag and at my wits' end after spending over 7 hours just trying to start this course, not even getting stuck on the problems or the content. When will content creators learn we don't want your in-house IDE with no dark mode and libraries that do nothing but rename every function to camel-case?
Anyway, if anyone has encountered this or knows what I could do to fix it, help would be appreciated.
You can try this -
javac -cp .;<insert class path> RandomWord
I was facing the exact same issue, I ran javac -cp .;.lift/algs4.jar RandomWord and it works. (My compiled class was in the same directory as .lift)
This worked for me on a Mac. Copy algs4.jar to the root of your project, then:
javac -cp ".:./algs4.jar" RandomWord.java
java -cp ".:./algs4.jar" RandomWord
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
If I build my own, tinkered version of rt.jar (called my-rt.jar) from the Oracle JDK 7 sources and hook it in with the bootclasspath mechanism, like this,
$ java -Xbootclasspath/p:/path/to/my-rt.jar -cp /path/to/h2-1.3.174.jar main
then, I can't even load the H2 driver at the beginning of my application:
// Application's main.java
public class main {
public static void main(String[] args) {
// ...
Class.forName("org.h2.Driver"); // Line 145
}
}
The above results in the following exception:
Exception in thread "main" java.lang.ClassNotFoundException: org/h2/Driver
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Class.java:190)
at main.main(main.java:415)
However, if I remove the -Xbootclasspath/p switch and with everything else the same as before, I can load the driver fine, and the rest of application too works fine too.
So, is there anything peculiar going on inside the initialization of a JDBC driver (such as H2's) that's preventing me from using the bootclasspath mechanism? Or, is there anything peculiar about the bootclasspath mechanism that it won't allow the loading of a JDBC driver like H2?
I'm out of things to try. For example,
I've even re-built the H2 driver from its sources and made sure that both my application and the driver are using the identical version of javac.
I've tried the above both from Eclipse and from command-line.
I've tried it on 2 different machines.
All yield the same exception.
Btw, my tinkered my-rt.jar has a very simple edit to it: It simply adds a public static int counter to java.lang.Object. Before the Class.forName(...) line above, I'm able to verify that I can indeed print the value of counter when the bootclasspath switch is enabled.
The strange thing is, even if I comment out this counter field in java.lang.Object but continue prepending my-rt.jar (that is as good as the original rt.jar, only recompiled andn prepended), even then I cannot get the H2 driver to be found/loaded!
(I've posted this on the H2 google group too but getting no response there. Maybe, those folks don't think this is an H2 problem, so I'm asking here.)
I've nailed it. Here's what I did.
I first prepended the original rt.jar to the original rt.jar, like so:
$ java -Xbootclasspath/p:/path/to/orig/rt.jar -cp /path/to/h2-1.3.174.jar main
And the exception disappeared! This clearly told me that the bootclasspath/p mechanism was no way interfering with the loading of the H2 driver.
So, I then unjarred the original rt.jar and diff'ed it with the unjarred contents of my-rt.jar, I found around a whopping 8000 files missing from my-rt.jar:
$ wc -l *.list
11285 my-rt.jar.list
19059 rt.jar.list
30344 total
So, obviously, my-rt.jar that I built from the official src.zip had tons of stuff missing from it. No wonder, H2 driver was having loading troubles.
To further confirm, this time I copied over only my tinkered java/lang/Object.class to the unjarred contents of the original rt.jar, and lo and behold, the H2 driver continued to load just fine.
Thus, the name src.zip is a terrible misnomer. Because it does not have everything needed to build rt.jar, it should be called partial-src.zip (or, something like that) instead.