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.

pokero
  • 1,009
  • 3
  • 13
  • 27
  • 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. – Adrian Leonhard Mar 25 '15 at 00:12
  • this maven plugin solves the dependency problem, https://stackoverflow.com/a/574650/9905745 – Yossarian42 May 06 '20 at 18:53

5 Answers5

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.

JBA
  • 2,769
  • 5
  • 24
  • 40
  • 1
    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. – pokero Mar 25 '15 at 19:15
  • 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 http://docs.oracle.com/javase/tutorial/deployment/jar/downman.html since maybe its just not added to your classpath corretly. – JBA Mar 26 '15 at 07:06
  • 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 Mar 26 '15 at 07:07
  • 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. – pokero Mar 26 '15 at 14:27
  • 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 ;) – JBA Mar 26 '15 at 14:44
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>
Khosro Makari
  • 171
  • 2
  • 4
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.

Community
  • 1
  • 1
pokero
  • 1,009
  • 3
  • 13
  • 27
  • 1
    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 ;) – JBA Mar 26 '15 at 14:47
  • Thanks, will check shader out so. – pokero Mar 27 '15 at 16:41
  • I was getting the same problem, as all I needed was to remember the `assembly:single` bit :) – Svend Hansen Jan 15 '22 at 19:40
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.

Chris
  • 165
  • 3
  • 12
-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

Community
  • 1
  • 1
Fakhriddin Abdullaev
  • 4,169
  • 2
  • 35
  • 37