macourtney7
macourtney7

Reputation: 541

Maven not including dependencies in Jar file

I'm trying to connect to a Neo4j 2.2.10 server using the neo4j-jdbc-driver v3.0. I am able to connect without any problems within the IDE but when I try to do the same from a Jar file I get a no suitable driver found exception as if the dependency isn't available.

java.sql.SQLException: No suitable driver found for jdbc:neo4j:http://localhost
    at java.sql.DriverManager.getConnection(DriverManager.java:689)
    at java.sql.DriverManager.getConnection(DriverManager.java:270)
    ....

Here is the relevant part of my my pom.xml:

<dependencies>    
  <dependency>
    <groupId>org.neo4j</groupId>
    <artifactId>neo4j-jdbc-driver</artifactId>
    <version>3.0</version>
  </dependency>
</dependencies>

<build>    
  <plugins>
    <plugin>
      <artifactId>maven-assembly-plugin</artifactId>
      <executions>
        <execution>
          <phase>package</phase>
          <goals>
            <goal>single</goal>
          </goals>
        </execution>
      </executions>
      <configuration>
        <descriptorRefs>
          <descriptorRef>jar-with-dependencies</descriptorRef>
        </descriptorRefs>
      </configuration>
    </plugin>
  </plugins>
</build>

I looked into including dependencies with Maven elsewhere on the forum and so that is where the plugin is taken from. However, I don't think it is including the dependency based on the error.

Previously, I was using:

<dependency>
  <groupId>org.neo4j.driver</groupId>
  <artifactId>neo4j-java-driver</artifactId>
  <version>1.0.4</version>
</dependency>

I was able to interact with a v3.0.3 Neo4j server via bolt from a Jar with no issues.

What am I doing wrong?

Thanks for any advice!

Upvotes: 0

Views: 3041

Answers (1)

Frank Pavageau
Frank Pavageau

Reputation: 11705

You can verify yourself if the driver is included in the resulting artifact (supposing its name is assembly.jar):

jar tf target/assembly.jar | fgrep jdbc

It probably is, though.

I think the problem comes from the fact that the driver is automatically registered using the Service Provider Interface (SPI), by listing the classes in META-INF/services/java.sql.Driver. However, because the assembly plugin packages the dependency jars inside the assembly jar instead of exploding them and creating an uber-jar (like the shade plugin can), the SPI files are not scanned. See this blog post for example.

I suggest you try the shade plugin instead, configured with a ServicesResourceTransformer.


Update

If the SPI mechanism doesn't work in your context (jar loaded as a plugin by a container application), you can register the driver yourself if there's a place in the code you know will be called before the driver is used (some initialization service for the plugin, for example, maybe by implementing Plugin.onLoad()?): just create a instance of the driver, it will register itself.

try {
    new org.neo4j.jdbc.http.HttpDriver();
} catch (SQLException e) {
    logger.error("Could not load HttpDriver for Neo4j", e);
}

Upvotes: 1

Related Questions