11

I have a Java app based on Maven, and want to connect to MySQL server.

My pom has:

<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>5.1.17</version>
    <type>jar</type>
    <scope>runtime</scope>
</dependency>

With runtime, as I want to connect to MySQL server at runtime - have also tried compile and provided, but does not work.

The SQL code is standard:

String dbClass = "com.mysql.jdbc.Driver";

Class.forName(dbClass);
Connection connection = DriverManager.getConnection(dbUrl,
    username, password);
Statement statement = connection.createStatement();
ResultSet resultSet = statement.executeQuery(query);
while (resultSet.next()) {
    String tableName = resultSet.getString(1);
    System.out.println("Table name : " + tableName);
}

When I run this from Eclipse, it works fine and prints table names.

However, from maven, the generated SNAPSHOT always gives an error when executed via >java -jar target\File.jar after running mvn clean install.

java.lang.ClassNotFoundException: com.mysql.jdbc.Driver

What am I missing here to get the maven build to work? Running mvn clean install gives no error and builds fine. It is only when executing the SNAPSHOT exe the error happens.

The MySQL jar is in my .m2 repo, and I tried adding it explicitly via mvn command line, but says it already exists.

2
  • Is the m2 repo on the classpath? Your IDE will generally add it when you launch from it, but if you launch from the command line, you might have to specify it manually. Commented Mar 25, 2015 at 0:12
  • this maven plugin solves the dependency problem, stackoverflow.com/a/574650/9905745 Commented May 6, 2020 at 18:53

5 Answers 5

17

Change the scope to compile:

<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>5.1.17</version>
    <type>jar</type>
    <scope>compile</scope>
</dependency>

Which - since it is the default scope corresponds to leaving away scope definition at all - same counts for the type:

<dependency>
   <groupId>mysql</groupId>
   <artifactId>mysql-connector-java</artifactId>
   <version>5.1.17</version>
</dependency>

Have a look at this: https://maven.apache.org/guides/introduction/introduction-to-dependency-mechanism.html for detailed information on scoping.

Here is a quick info for your background:

You specified the JDBC driver to have a scope runtime. Most IDEs will anyways ignore the scopes and add all of your dependencies to their classpath (e.g. the classpath used when you run something outside of eclipse. By the scope runtime you are telling maven that it must not pack that dependeny into your final jar since the execution environment will "provide that dependency at runtime. E.g. you would either have to manually add it to the classpath when calling your jar or change the scope to compile which will lead to the driver-jar beeing packed inside your jar and available at runtime.

Sign up to request clarification or add additional context in comments.

5 Comments

Thanks, but I tried that and no difference. Answer is below, I needed to build the dependencies into the SNAPSHOT by using a plugin in the pom.
Well it should defently make a difference - check the size and content of your (*-SNAPSHOT).jar with the two scopes - the one built with scope provided will not contain the driver and is less in size than the one built scope compile since it will have the driver-jar packed inside. You maybe want to have a look at this link docs.oracle.com/javase/tutorial/deployment/jar/downman.html since maybe its just not added to your classpath corretly.
And if you are getting a .exe from your build you should add the according plugin definition because Maven cannot pack to a exe by default
JBA, I mean it makes no difference as in the missing class errors are still manifest. The only solution which worked for me was building an uber pom.
The "uberjar" you are building with the Maven shader plugin can be interpreted as "please ignore all scopes i applied to my dependencies and pack them to a single jar - when you're doing that for me anyways please create a correct Manifest file for them as well" - hence I assume as soon as you create a legit Manifest including the classpath definition - including your driver-jar inside your delivery-jar it should work ;)
4

Since you are running the project by "java -jar" and also you have dependencies, so, you have to use two maven plugins. The first one to copy dependencies into a folder inside target folder (e.g. lib/) while packaging and the second one for specifying the classpath which should be same as the first one(lib/). I had the same problem and here is what I did:

<build>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-dependency-plugin</artifactId>
            <executions>
                <execution>
                    <id>copy</id>
                    <phase>package</phase>
                    <goals>
                        <goal>copy-dependencies</goal>
                    </goals>
                    <configuration>
                        <outputDirectory>
                            ${project.build.directory}/lib
                        </outputDirectory>
                    </configuration>
                </execution>
            </executions>
        </plugin>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-jar-plugin</artifactId>
            <configuration>
                <archive>
                    <manifest>
                        <addClasspath>true</addClasspath>
                        <classpathPrefix>lib/</classpathPrefix>

                  <mainClass>com.tihoo.crawler.Application</mainClass>
                    </manifest>
                </archive>
            </configuration>
        </plugin>
    </plugins>
</build>

Comments

3

The answer is here - How can I create an executable JAR with dependencies using Maven?

I needed to build an uber pom, using the answer in the link above - this builds in the dependencies (in this case the mysql jar file) into a single SNAPSHOT jar file.

Just make sure you run it with mvn clean compile assembly:single (not the usual mvn clean package or whatever.

3 Comments

The shader plugin binds itself to the phase package and is executed when running mvn clean package ;) Have a look on how to create a Manifest for a executable jar again - i expect this to be your actual issue - nothing regarding Maven ;)
Thanks, will check shader out so.
I was getting the same problem, as all I needed was to remember the assembly:single bit :)
0

I had this problem as well. I tried using plugins to set the connector to classpath but it didn't work. I tried to change versions, it didn't work. I've spent two nights to find out that i needed to specify in pom.xml that i need my package to be a "war".

Maybe it's because your project doesn't know what type it is, so try to put this:

<packaging>war</packaging>

right next to your project version. Something like this:

<?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>com.example</groupId>
<artifactId>example-app</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>war</packaging> <!-- Here -->

<properties>
    <!-- Some properties here -->
</properties>

<dependencies>
    <!-- Some dependencies here -->
</dependencies>

Maybe it doesn't suit your problem, but maybe somebody else will need it.

Comments

-3

Add this code

    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <version>5.1.6</version>
    </dependency>

to porm.xml file in your maven project

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.