Reputation: 1690
I am very new to java and on a steep learning curve. I have a legacy ColdFusion 10 application and I am wanting to incrementally use Java classes instead of ColdFusion CFCs as a way to migrate out of CF land. I can get all that to work for the classes I have written so far.
I am now up to the point of testing how to interact with the mySql database using the same java connector that CF is using (mysql-connector-java-commercial-5.1.25-bin.jar in this case, as used on my localhost dev machine).
For the sake of simplicity for the test, both my test class and the connector jar are in the same folder (Windows machine).
The issue is with this statement: Class.forName("com.mysql.jdbc.Driver");
- I am getting Exception in thread "main" java.lang.ClassNotFoundException: com.mysql.jdbc.Driver
.
Now, if I unzip the connector jar so the folders are present in my test folder: com\mysql\jdbc\Driver.class
(as well as all the other files that were in the jar), my test class works fine and records are being inserted into my db table. Cool!
But, if I remove the actual folders and depend upon the jar itself, that is when I get the ClassNotFoundException.
In my other learning / tests (with my self generated jar files) a relevant class is being pulled from the jar as it should. But with this specific jar for this mysql test it is not.
What should I be looking out for - clearly I have missed something?
Thanks. I am really looking forward to moving into Java land. :-)
Murray
Upvotes: 1
Views: 2831
Reputation: 1690
Ok. Thanks for all your fast, helpful and interesting input! :-)
Two things:
The run using java
answer from @schtever works: java -classpath .;mysql-connector-java-commercial-5.1.25-bin.jar MySQLAccessMain
. I did not know about the .;
syntax. Thank you.
Since I will be ultimately executing the class within the ColdFusion context (for now, at least) the following CFM works because, of course, ColdFusion handles the classpath to its pile of jars.
This is the java test class
public class MySQLAccessMain {
public static void main(String[] args) throws Exception {
MySQLAccess dao = new MySQLAccess();
dao.readDataBase(); // Run some fixed SELECT and INSERT tests
}
}
This is the CFM version
var dao = createObject("java","MySQLAccess");
dao.readDataBase();
and of course in application.cfc:
this.javaSettings = {
loadPaths: [
"/myjava" // Where MySQLAccess.class goes
]
,loadColdFusionClassPath: true // If this is true you can also use the coldfusion builtin java classes
,reloadOnChange = true
,watchInterval = 2
};
:-) Happy camper! Thanks again.
Upvotes: 1
Reputation: 338181
I use Postgres & H2 rather than MySQL. So I do not know for sure what your problem may be with regard to MySQL. But I was able to just now create a new project with your MySQL driver made available at runtime. Read on to follow my example.
Java projects nowadays are commonly managed by a dependency management and build automation tool such as Maven, Gradle, or Ivy.
I started a new Java project using the Maven Quickstart Archetype.
In the POM file provided by that archetype, I made two changes:
<maven.compiler.source>
& <maven.compiler.target>
from 1.7
to 11
to use Java 11, the current long-term support version.<!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.22</version>
</dependency>
Then I added a line to the App
class’ main
method.
try
{
Class.forName("com.mysql.jdbc.Driver");
System.out.println("Found class for JDBC driver.");
}
catch ( ClassNotFoundException e )
{
e.printStackTrace();
}
System.out.println( "Hello World!" );
When I ran this, no exception was thrown. So the class seemed to be found successfully.
Complete POM:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns = "http://maven.apache.org/POM/4.0.0"
xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation = "http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>work.basil.example</groupId>
<artifactId>jdbc-driver-in-jar</artifactId>
<version>1.0-SNAPSHOT</version>
<name>jdbc-driver-in-jar</name>
<!-- FIXME change it to the project's website -->
<url>http://www.example.com</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>11</maven.compiler.source>
<maven.compiler.target>11</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.22</version>
</dependency>
</dependencies>
<build>
<pluginManagement><!-- lock down plugins versions to avoid using Maven defaults (may be moved to parent pom) -->
<plugins>
<!-- clean lifecycle, see https://maven.apache.org/ref/current/maven-core/lifecycles.html#clean_Lifecycle -->
<plugin>
<artifactId>maven-clean-plugin</artifactId>
<version>3.1.0</version>
</plugin>
<!-- default lifecycle, jar packaging: see https://maven.apache.org/ref/current/maven-core/default-bindings.html#Plugin_bindings_for_jar_packaging -->
<plugin>
<artifactId>maven-resources-plugin</artifactId>
<version>3.0.2</version>
</plugin>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.0</version>
</plugin>
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.22.1</version>
</plugin>
<plugin>
<artifactId>maven-jar-plugin</artifactId>
<version>3.0.2</version>
</plugin>
<plugin>
<artifactId>maven-install-plugin</artifactId>
<version>2.5.2</version>
</plugin>
<plugin>
<artifactId>maven-deploy-plugin</artifactId>
<version>2.8.2</version>
</plugin>
<!-- site lifecycle, see https://maven.apache.org/ref/current/maven-core/lifecycles.html#site_Lifecycle -->
<plugin>
<artifactId>maven-site-plugin</artifactId>
<version>3.7.1</version>
</plugin>
<plugin>
<artifactId>maven-project-info-reports-plugin</artifactId>
<version>3.0.0</version>
</plugin>
</plugins>
</pluginManagement>
</build>
</project>
Complete app class:
package work.basil.example;
/**
* Hello world!
*
*/
public class App
{
public static void main( String[] args )
{
try
{
Class.forName("com.mysql.jdbc.Driver");
System.out.println("Found class for JDBC driver.");
}
catch ( ClassNotFoundException e )
{
e.printStackTrace();
}
System.out.println( "Hello World!" );
}
}
Some notes:
I noticed in the console output saying that particular JDBC driver is obsolete. You should investigate proper JDBC driver to be using nowadays.
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.
Class.forName
is the old-school way to load a JDBC driver, and is no longer needed. JDBC driver loading was much improved some years back. Today’s JDBC drivers are loaded via Java’s Service Provider Interface (SPI) facility. But that Class.forName
code may still be useful for exploring this problem of yours, to verify the class can be found on your classpath.
Generally best to use a DataSource
for getting database connections. Your JDBC driver likely offers an implementation of DataSource
. This class will hold the info needed to make a connection to the database server, such as address to find the database server, and a username and password to authenticate with the database server.
Upvotes: 1
Reputation: 3250
It's not enough to have the JAR file in your current directory. You have to tell java to include the mysql jar file in the classpath
. This can be done by either specifying it on the java command line with the -cp
parameter, or by the CLASSPATH
environment variable.
Upvotes: 2