I've been trying to run my Maven Kotlin Ktor project with command line. The project contains the MySQL configuration too. Every time I tried to hit the following command, I got the following error.
Here is my command.
kotlin -cp mysql-connector-java-8.0.30.jar:dev_meet_dev_api.jar MainClassKt
The dev_meet_dev_api.jar file is my project jar and mysql-connector-java-8.0.30 is for MySQL connection with the database. My project is dependent on MySQL connector that's why I added the external dependency for MySQL connector.
As soon I hit the above command on terminal I've got the following error.
Caused by: java.lang.ClassNotFoundException: java.sql.Driver
at java.base/java.net.URLClassLoader.findClass(URLClassLoader.java:445)
at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:588)
at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:521)
Edit 1: Added the maven file.
<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>spartons.com.devMeetdevApi</groupId>
<artifactId>KtorTesting</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<kotlin.version>1.7.10</kotlin.version>
<ktor.version>2.1.1</ktor.version>
<junit.version>4.12</junit.version>
<serialization.version>1.4.0</serialization.version>
<coroutines.version>1.6.4</coroutines.version>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<kotlin.compiler.incremental>true</kotlin.compiler.incremental>
<kotlin.compiler.jvmTarget>11</kotlin.compiler.jvmTarget>
<kotlin.code.style>official</kotlin.code.style>
<kotlin.compiler.incremental>true</kotlin.compiler.incremental>
</properties>
<dependencies>
<!-- Kotlin language dependencies -->
<dependency>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-stdlib</artifactId>
<version>${kotlin.version}</version>
</dependency>
<dependency>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-reflect</artifactId>
<version>${kotlin.version}</version>
<scope>runtime</scope>
</dependency>
<!-- Kotlin's coroutines dependency -->
<dependency>
<groupId>org.jetbrains.kotlinx</groupId>
<artifactId>kotlinx-coroutines-core</artifactId>
<version>${coroutines.version}</version>
</dependency>
<!-- Ktor dependencies -->
<dependency>
<groupId>io.ktor</groupId>
<artifactId>ktor-server-core-jvm</artifactId>
<version>${ktor.version}</version>
</dependency>
<dependency>
<groupId>io.ktor</groupId>
<artifactId>ktor-server-jetty-jvm</artifactId>
<version>${ktor.version}</version>
</dependency>
<dependency>
<groupId>io.ktor</groupId>
<artifactId>ktor-server-content-negotiation-jvm</artifactId>
<version>${ktor.version}</version>
</dependency>
<dependency>
<groupId>io.ktor</groupId>
<artifactId>ktor-serialization-kotlinx-json-jvm</artifactId>
<version>${ktor.version}</version>
</dependency>
<dependency>
<groupId>io.ktor</groupId>
<artifactId>ktor-server-status-pages-jvm</artifactId>
<version>${ktor.version}</version>
</dependency>
<dependency>
<groupId>io.ktor</groupId>
<artifactId>ktor-server-cors-jvm</artifactId>
<version>${ktor.version}</version>
</dependency>
<!-- Kotlin serialization version -->
<dependency>
<groupId>org.jetbrains.kotlinx</groupId>
<artifactId>kotlinx-serialization-json</artifactId>
<version>${serialization.version}</version>
</dependency>
<!-- MySQL connector dependency -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.30</version>
</dependency>
</dependencies>
<build>
<resources>
<resource>
<directory>src/main/resources</directory>
</resource>
</resources>
<finalName>dev_meet_dev_api</finalName>
<plugins>
<plugin>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-maven-plugin</artifactId>
<version>${kotlin.version}</version>
<executions>
<execution>
<id>compile</id>
<phase>compile</phase>
<goals>
<goal>compile</goal>
</goals>
</execution>
</executions>
<configuration>
<compilerPlugins>
<plugin>kotlinx-serialization</plugin>
</compilerPlugins>
<args>
<arg>-opt-in=kotlin.RequiresOptIn</arg>
</args>
</configuration>
<dependencies>
<dependency>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-maven-serialization</artifactId>
<version>${kotlin.version}</version>
</dependency>
</dependencies>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.10.1</version>
<executions>
<execution>
<id>compile</id>
<phase>compile</phase>
<goals>
<goal>compile</goal>
</goals>
</execution>
<execution>
<id>default-compile</id>
<phase>none</phase>
</execution>
<execution>
<id>default-testCompile</id>
<phase>none</phase>
</execution>
</executions>
<configuration>
<release>11</release>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>3.3.0</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
</execution>
</executions>
<configuration>
<artifactSet>
<excludes>
<exclude>mysql:mysql-connector-java:jar:</exclude>
</excludes>
</artifactSet>
<filters>
<filter>
<artifact>*:*</artifact>
<excludes>
<exclude>META-INF/*.SF</exclude>
<exclude>META-INF/*.DSA</exclude>
<exclude>META-INF/*.RSA</exclude>
</excludes>
</filter>
</filters>
</configuration>
</plugin>
</plugins>
</build>
</project>
Edit 2: Added the java-11 modules
P.S I'm using Java 11. Projects works fine if I try to run with the IntelliJ.
You can do this directly in Maven! In your pom.xml add the driver as a dependency.
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.30</version>
</dependency>
Then you shade the dependency into the jar
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>2.4.3</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<artifactSet>
<includes>
<include>mysql:mysql-connector-java</include>
</includes>
</artifactSet>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
Then directly execute the jar. If this does not help may I know which Java version you are using?
Kotlin applications need the Kotlin runtime to run (mainly kotlin-stdlib.jar). It can be included
in the application jar or not.
If the runtime is not included, you must add it to the classpath:
java -cp /path/to/kotlin-stdlib.jar:app.jar MainClassKt
You can also use the kotlin script, which automatically adds it:
kotlin -cp app.jar MainClassKt
In your case, the runtime is included thanks to the maven-shade-plugin, so you can run the app like this:
java -cp mysql-connector-java-8.0.30.jar:dev_meet_dev_api.jar MainClassKt
Possibility 1
It is possible that some dependency that you manually added has a different version of java.sql.Driver.
It is overriding the java.sql.Driver dependency version that your code flow needs.
To debug if this is actually the cause of your problem, you can use IntelliJ maven dependency plugin.
It can show if there is any conflict in dependency causing the needed class to not load.
https://www.jetbrains.com/help/idea/work-with-maven-dependencies.html#maven_dependency_diagram
Also, please note that in my experience, If multiple dependencies are loading different versions of same class, then you may get different results in different setup, since order of class loading may differ. This can result in your code working in IntellijIdea, but not when running from terminal.
Possibility 2
Check if the jdbc driver version is compatible with java and database versions that you are using. Try upgrading or downgrading the jdbc version to see if that resolves issue.
Debug approach 1: if above ways don't fix the issue
Since you say that your code works in Intellij, start your application in debug mode and put a debug point in java.sql.Driver.
See which the library which contains this class and the dependency which contains this library.
That can help you debug the cause of problem.
Debug approach 2: if above ways don't fix the issue
Use remote debugging.
Start your jar application in console with remote debug enabled.
Refer this on steps to do it.
https://www.jetbrains.com/help/idea/tutorial-remote-debug.html#ecd9fef1
Using this, you can find the code flow and the cause of problem for program that runs in console.
I hope that this helps you.
Related
This is a weird error. After adding the selenium dependencies to the pom of my maven project and upload it to a lambda, it says it is unable to unzip the file. However after removing the dependencies, the lambda is able to unzip the file just fine (however it comes up with a class not found afterwards). I have tried removing the dependencies one by one but each one triggers the error.
Any ideas on how to solve this?
Class not found error
org/openqa/selenium/WebDriver: java.lang.NoClassDefFoundError
java.lang.NoClassDefFoundError: org/openqa/selenium/WebDriver
lambda cannot zip error
Calling the invoke API action failed with this message: Lambda was not able to unzip the file
The dependencies causing the issue
<dependency>
<groupId>org.seleniumhq.webdriver</groupId>
<artifactId>webdriver-common</artifactId>
<version>0.9.7376</version>
</dependency>
<dependency>
<groupId>org.seleniumhq.selenium</groupId>
<artifactId>selenium-chrome-driver</artifactId>
<version>3.141.59</version>
</dependency>
<dependency>
<groupId>org.seleniumhq.selenium</groupId>
<artifactId>selenium-java</artifactId>
<version>3.141.59</version>
</dependency>
updated dependancies (for Vishal)
<dependency>
<groupId>org.seleniumhq.webdriver</groupId>
<artifactId>webdriver-common</artifactId>
<version>0.9.7376</version>
</dependency>
<dependency>
<groupId>org.seleniumhq.selenium</groupId>
<artifactId>selenium-chrome-driver</artifactId>
<version>3.141.59</version>
</dependency>
<dependency>
<groupId>org.seleniumhq.selenium</groupId>
<artifactId>selenium-java</artifactId>
<version>3.141.59</version>
</dependency>
<dependency>
<groupId>org.seleniumhq.selenium</groupId>
<artifactId>selenium-api</artifactId>
<version>2.0rc2</version>
</dependency>
<dependency>
<groupId>org.seleniumhq.selenium</groupId>
<artifactId>selenium-remote-driver</artifactId>
<version>3.141.59</version>
</dependency>
<dependency>
<groupId>org.seleniumhq.selenium</groupId>
<artifactId>selenium-support</artifactId>
<version>3.141.59</version>
</dependency>
Configuration
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.6.0</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
<encoding>UTF-8</encoding>
<forceJavacCompilerUse>true</forceJavacCompilerUse>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>3.0.0</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
The shade plugin combines all dependencies with the developed code and plops them in one Uber JAR. The downside is that it can overwrite resource files, and doesn't play well with signed jars (in my experience at least).
I would recommend moving away from the shade plugin if at all possible.
That said, if you have to use it - you're issue may be with the combining the jar resources. There are many transformers that you can use to resolve this, and you'll need to investigate which one is really needed. I would start with something like this
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>2.4.3</version>
<configuration>
<shadedArtifactAttached>true</shadedArtifactAttached>
<shadedClassifierName>${executable.classifier}</shadedClassifierName>
<filters>
<filter>
<artifact>*:*</artifact>
<excludes>
<exclude>META-INF/*.SF</exclude>
<exclude>META-INF/*.DSA</exclude>
<exclude>META-INF/*.RSA</exclude>
</excludes>
</filter>
</filters>
</configuration>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<transformers>
<transformer
implementation="org.apache.maven.plugins.shade.resource.ServicesResourceTransformer" />
<transformer
implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
<mainClass>fully.qualified.ClassName</mainClass>
</transformer>
</transformers>
</configuration>
</execution>
</executions>
</plugin>
You can find more tranformers on the Apache plugin here
The alternative that I would suggest is Spring Boot, which uses the Jar-in-Jar structure with a custom ClassLoader to load classes from the internal jar(s).
This is the easier method due to not having to re-write files as the Shade plugin approach and it handles the dependencies a little better.
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>1.3.6.RELEASE</version>
<configuration>
<classifier>${executable.classifier}</classifier>
<layout>ZIP</layout>
<mainClass>fully.qualified.ClassName</mainClass>
</configuration>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
Seriously, look at the simpler configuration!
NOTE: Most of this came from my own notes - version numbers may be a little old...
Try to tell your dependencies to output zip, maybe jar is messing up with things
Add this to maven-assembly-plugin configuration:
<formats>
<format>zip</format>
</formats>
For example:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
...
<configuration>
...
<formats>
<format>zip</format>
</formats>
</configuration>
</plugin>
Same is suggested here
I figured it out. The java selenium seemed to cause the major issue. Downgrading to 3.10 fixed the issue although I have no idea why.
I have a project which includes the S3 dependency from AWS's Java v2 SDK and builds a shaded jar. I am hitting this problem when running my integration tests from the terminal. The problem is that the interceptors are added twice because the classpath contains two jars with the S3 jar: once in my shaded jar and once from the local .m2 repository. Unfortunately I don't have any control of the code that contains this issue so I need to find a workaround until the issue is fixed.
I have replicated the problem with the following pom and test class:
pom.xml
<?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.stu</groupId>
<artifactId>duplicate-jars-classpath</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<aws.sdk.version>2.5.62</aws.sdk.version>
<junit.version>5.4.2</junit.version>
<maven.failsafe.plugin.version>2.22.0</maven.failsafe.plugin.version>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>software.amazon.awssdk</groupId>
<artifactId>bom</artifactId>
<version>${aws.sdk.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
<version>${junit.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-engine</artifactId>
<version>${junit.version}</version>
<scope>test</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>software.amazon.awssdk</groupId>
<artifactId>s3</artifactId>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-engine</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>2.3</version>
<configuration>
<createDependencyReducedPom>false</createDependencyReducedPom>
</configuration>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>8</source>
<target>8</target>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-failsafe-plugin</artifactId>
<version>${maven.failsafe.plugin.version}</version>
<configuration>
<includes>
<include>**/*Test.java</include>
</includes>
</configuration>
<executions>
<execution>
<id>run-tests</id>
<phase>integration-test</phase>
<goals>
<goal>integration-test</goal>
<goal>verify</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
Test class - src/test/java/com/stu/S3DuplicateJarTest.java
package com.stu;
import java.util.Collections;
import org.junit.jupiter.api.Test;
import software.amazon.awssdk.core.interceptor.ClasspathInterceptorChainFactory;
public class S3DuplicateJarTest {
#Test
void check_for_duplicate_jars() throws Exception {
System.out.println("********** AWS execution interceptors:");
Collections.list(
new ClasspathInterceptorChainFactory().getClass().getClassLoader()
.getResources("software/amazon/awssdk/services/s3/execution.interceptors")
).forEach(System.out::println);
}
}
If I run the tests in my IDE then this is the output:
********** AWS execution interceptors:
jar:file:/Users/<name>/.m2/repository/software/amazon/awssdk/s3/2.5.48/s3-2.5.48.jar!/software/amazon/awssdk/services/s3/execution.interceptors
From the terminal this is the output when running mvn clean verify:
[INFO] Running com.stu.S3DuplicateJarTest
********** AWS execution interceptors:
jar:file:/Users/<name>/Development/duplicate-jars-classpath/target/duplicate-jars-classpath-1.0-SNAPSHOT.jar!/software/amazon/awssdk/services/s3/execution.interceptors
jar:file:/Users/<name>/.m2/repository/software/amazon/awssdk/s3/2.5.62/s3-2.5.62.jar!/software/amazon/awssdk/services/s3/execution.interceptors
As you can see the terminal has found two resources matching the path.
Is there anything I can do to avoid this? Is there something wrong with my configuration?
It's due to your maven configuration, shade plugin packs all dependencies into a single jar file.
Your failsafe plugin runs tests using class path from both the project dependencies (.m2/...) and that single jar file, hence the duplicated resources.
This seems to be only happening when using failsafe in command line, though. And it's fairly easy to get around, you can simply tell failsafe to not load that dependency. (It'll be available in that single jar file anyway)
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-failsafe-plugin</artifactId>
<version>${maven.failsafe.plugin.version}</version>
<configuration>
<includes>
<include>**/*Test.java</include>
</includes>
<classpathDependencyExcludes>
<classpathDependencyExcludes>software.amazon.awssdk:s3</classpathDependencyExcludes>
</classpathDependencyExcludes>
</configuration>
<executions>
<execution>
<id>run-tests</id>
<phase>integration-test</phase>
<goals>
<goal>integration-test</goal>
<goal>verify</goal>
</goals>
</execution>
</executions>
</plugin>
I have created executable Jar using Maven dependencies for connecting multiple database at runtime by passing the parameters.
I added dependencies as below:
<dependency>
<groupId>com.oracle.jdbc</groupId>
<artifactId>ojdbc7</artifactId>
<version>12.1.0.2</version>
</dependency>
<dependency>
<groupId>com.microsoft.sqlserver</groupId>
<artifactId>mssql-jdbc</artifactId>
<version>6.1.7.jre8-preview</version>
</dependency>
In my case, when I ran executable jar it connected successfully to Oracle database but gives No suitable driver not found for SQL server database.
When I changed the order of dependency shown above to SQL server first and Oracle second and built new executable jar and ran it, I could able to connect to SQL server database successfully but this time it gives error No suitable driver not found for Oracle database.
When I compared both the extracted executable jars, it has exactly same structure, numbers of files and size of files and didn't find any single difference. Hence not able to found what could be the problem while building executable jar so that a single jar would work for both databases.
Any suggestion would be really help me to resolve this strange behavior...
Thanks in advance.
The .pom file is as below.
<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.mycompany.dataload</groupId>
<artifactId>DataLoadUtilities</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>DataLoadUtilities</name>
<description>A utility project that started with fetching table metadata from SQL Server and Oracle</description>
<properties>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>com.oracle.jdbc</groupId>
<artifactId>ojdbc7</artifactId>
<version>12.1.0.2</version>
</dependency>
<dependency>
<groupId>com.microsoft.sqlserver</groupId>
<artifactId>mssql-jdbc</artifactId>
<version>6.1.7.jre8-preview</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-api</artifactId>
<version>2.7</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>2.7</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>2.3</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<transformers>
<transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
<mainClass>com.mycompany.dataload.main.TableMetadataGeneratorForHive</mainClass>
</transformer>
</transformers>
<filters>
<filter>
<artifact>*:*</artifact>
<excludes>
<exclude>META-INF/*.SF</exclude>
<exclude>META-INF/*.DSA</exclude>
<exclude>META-INF/*.RSA</exclude>
</excludes>
</filter>
</filters>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<version>2.6</version>
<executions>
<execution>
<id>unpack-dependencies</id>
<phase>package</phase>
<goals>
<goal>unpack-dependencies</goal>
</goals>
<configuration>
<excludeScope>system</excludeScope>
<excludes>META-INF/*.SF</excludes>
<excludes>META-INF/*.DSA</excludes>
<excludes>META-INF/*.RSA</excludes>
<excludeGroupIds>junit,org.mockito,org.hamcrest</excludeGroupIds>
<outputDirectory>${project.build.directory}/classes</outputDirectory>
</configuration>
</execution>
</executions></plugin>
</plugins>
</build></project>
You are encountering this problem because of the way you have created your executable jar.
Each of ojdbc7-12.1.0.2.jar and mssql-jdbc-6.1.7.jre8-preview.jar contains a META-INF/services/java.sql.Driver file containing the name of the respective java.sql.Driver implementation classes for each vendor. It seems like you only get the first one that is encountered in the dependency list.
This is described in the javadoc for java.sql.DriverManager.
The Java 8 JAR File Specification - Service Provider provides more information that states that the META-INF/services/java.sql.Driver file:
... should contain a newline-separated list of unique concrete provider-class names
Therefore you can probably configure an AppendingTransformer in your configuration to merge the content of these files during shading.
Something along the lines of
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>3.2.1</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<transformers>
<transformer implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
<resource>META-INF/services/java.sql.Driver</resource>
</transformer>
</transformers>
</configuration>
</execution>
</executions>
</plugin>
I am an inexperienced Java and Maven developer, although I have got karaf-assembly builds to work a couple of years ago using the Karaf 3.0.1 release.
When attempting to generating a karaf-assemby 4.0.5 for a customised product build, the zip and tar.gz files are not created at the end of the maven build. The ../target/assembly directory is created each time the maven build is run and the completion status is always "BUILD SUCCESS".
I suspect this this is because the POM file has an error highlighted by the Eclipse IDE at the section for the karaf-maven-plugin directly on the line, which is as follows:
Plugin execution not covered by lifecycle configuration: org.apache.karaf.tooling:karaf-maven-plugin:4.0.5:assembly (execution: default-assembly, phase: process-
resources)
I can resolve this error in the IDE on the line by removing the "extensions" line, but then I get a "Project build error: Unknown packaging: karaf-assembly" error on the "packaging" line.
<plugins>
<plugin>
<groupId>org.apache.karaf.tooling</groupId>
<artifactId>karaf-maven-plugin</artifactId>
**<!-- <extensions>true</extensions> -->**
<configuration>
<startupFeatures></startupFeatures>
<bootFeatures>
<feature>standard</feature>
<feature>management</feature>
<feature>jms</feature>
</bootFeatures>
<installedFeatures>
</installedFeatures>
</configuration>
</plugin>
The POM file I am using is as follows:
http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>my.custom</groupId>
<artifactId>my.distribution</artifactId>
<version>1.0</version>
<packaging>karaf-assembly</packaging>
<!-- PIP Operations Aspect Assembly properties -->
<properties>
<maven-compiler-plugin-version>2.3.2</maven-compiler-plugin-version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<assembly.directory>${project.build.directory}/assembly/karaf-4.0.5</assembly.directory>
<karaf.name>karaf</karaf.name>
<karaf.version>4.0.5</karaf.version>
<pip.name>Operations Aspect</pip.name>
</properties>
<dependencies>
<dependency>
<groupId>org.apache.karaf.features</groupId>
<artifactId>framework</artifactId>
<version>4.0.5</version>
<type>kar</type>
</dependency>
<dependency>
<groupId>org.apache.karaf.features</groupId>
<artifactId>framework</artifactId>
<version>4.0.5</version>
<classifier>features</classifier>
<type>xml</type>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.apache.karaf.features</groupId>
<artifactId>standard</artifactId>
<classifier>features</classifier>
<version>4.0.5</version>
<type>xml</type>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.apache.karaf.features</groupId>
<artifactId>enterprise</artifactId>
<classifier>features</classifier>
<version>4.0.5</version>
<type>xml</type>
<scope>runtime</scope>
</dependency>
</dependencies>
<build>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-resources-plugin</artifactId>
<version>2.7</version>
<executions>
<execution>
<id>process-resources</id>
<goals>
<goal>resources</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.karaf.tooling</groupId>
<artifactId>karaf-maven-plugin</artifactId>
<version>4.0.5</version>
<extensions>true</extensions>
<configuration>
<startupFeatures></startupFeatures>
<bootFeatures>
<feature>standard</feature>
<feature>management</feature>
<feature>jms</feature>
</bootFeatures>
<installedFeatures>
</installedFeatures>
</configuration>
</plugin>
</plugins>
</build>
Any suggestions would be gratefully received.
You might be missing the execution settings:
<executions>
<execution>
<phase>compile</phase>
<goals>
<goal>assembly</goal>
</goals>
</execution>
<execution>
<id>package</id>
<goals>
<goal>archive</goal>
</goals>
</execution>
</executions>
UPDATE: here is my maven-compiler-plugin configuration:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.3.2</version>
<configuration>
<source>1.6</source>
<target>1.6</target>
</configuration>
I work on a multi-project application that I build with Maven. We decided to add AspectJ so I added the following code to pom.xml in the top level project: (from the official documentation)
<project>
...
<dependencies>
...
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjrt</artifactId>
<version>1.7.3</version>
</dependency>
...
</dependencies>
...
<build>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>aspectj-maven-plugin</artifactId>
<version>1.5</version>
<executions>
<execution>
<goals>
<goal>compile</goal> <!-- use this goal to weave all your main classes -->
<goal>test-compile</goal> <!-- use this goal to weave all your test classes -->
</goals>
</execution>
</executions>
</plugin>
...
</plugins>
<build>
...
</project>
and the following fragments to each subordinate projects:
</project>
...
<build>
....
<plugins>
...
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>aspectj-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
<dependencies>
...
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjrt</artifactId>
</dependency>
....
</dependencies>
...
</project>
Somehow this modification has overridden the Java version I use. If I run build I get multiple errors like this:
Syntax error, annotations are only available if source level is 1.5 or greater
That gives me the suspicion that my Java version (originally 1.6) was somehow reverted to 1.4. I did nothing - at least not knowingly - that could influence the Java version, so I suspect that the above mentioned AspectJ related code is responsible for the change.
My question is how can AspectJ change the Java version and what should I do to fix this problem. Or do I misunderstand something completely and am I on the wrong track?
I think the problem is with the default source, target and complianceLevel settings of the aspectj-maven-plugin (according to the documentation linked previously, 1.4, 1.2 and 1.4 respectively). You should set these explicitly in your parent pom:
<build>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>aspectj-maven-plugin</artifactId>
<version>1.5</version>
<!-- new configuration is here -->
<configuration>
<complianceLevel>1.6</complianceLevel>
<source>1.6</source>
<target>1.6</target>
</configuration>
<executions>
<execution>
<goals>
<goal>compile</goal>
<goal>test-compile</goal>
</goals>
</execution>
</executions>
</plugin>
...
</plugins>
<build>
I was missing
<complianceLevel>${java.level}</complianceLevel>
in my pom.xml
If you don't have define the version, the compiler plugin assumes that your Java source conforms to Java 1.3 and that you are targeting a Java 1.1 JVM.
Maybe, you should define it:
http://maven.apache.org/plugins/maven-compiler-plugin/examples/set-compiler-source-and-target.html
You can find last versions of dependecy and plugin for aspectj.
I was missing the java version with jdk version at the top of my pom properties.
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>aspectj-maven-plugin</artifactId>
<version>1.2</version> <!-- 1.5 dint work for me -->
<dependencies>
<!-- You must use Maven 2.0.9 or above or these are ignored (see MNG-2972) -->
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjrt</artifactId>
<version>${aspectj.version}</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjtools</artifactId>
<version>${aspectj.version}</version>
</dependency>
</dependencies>
<executions>
<execution>
<phase>process-sources</phase> <!-- or any phase before compile -->
<goals>
<goal>compile</goal>
<goal>test-compile</goal>
</goals>
</execution>
</executions>
<configuration>
<outxml>true</outxml>
<source>${jdk.version}</source> <!-- I was missing this -->
<target>${jdk.version}</target> <!-- jdk.version property -->
</configuration>
</plugin>
and at the top of my pom.xml I had set jdk.version property like,
<properties>
<jdk.version>1.7</jdk.version>
</properties>