Add external library .jar to Spring boot .jar internal /lib

I have an external .jar that cannot be imported from public repositories using pom.xml, it's sqljdbc41.jar.

I can run the project locally from my IDE, and everything will work. I referenced the library after downloading it like so:

<dependency>
<groupId>com.microsoft.sqlserver</groupId>
<artifactId>sqljdbc41</artifactId>
<version>4.1</version>
<scope>system</scope>
<systemPath>${basedir}/lib/sqljdbc41.jar</systemPath>
</dependency>

When I run mvn clean package to create my .jar file and try to run the created .jar, a mistake will pop up, which mentions the SQL Server references are not valid. I then extracted my .jar file and true enough, everything that is referenced in the pom.xml file properly gets downloaded and added, however, my SQL Server does not.

I can, in a very hacky way* just manually add the sqljdbc41.jar to my /lib folder after it's been compiled as a .jar, and it'll work, however that seems highly unoptimal. What would be a better approach?


*Opening the .jar file with Winrar, going to the /lib folder, manually selecting my sqljdbc41.jar file, then make sure to select the No Compression option bottom left where Winrar gives you compression options, in case you find this by Google and no one answered.

119137 次浏览

You could install the sqljdbc41.jar in your local repository :

mvn install:install-file -Dfile=path/to/sqljdbc41.jar -DgroupId=com.microsoft.sqlserver -DartifactId=sqljdbc41 -Dversion=4.1 -Dpackaging=jar

And then declare the dependency as a standard dependency :

<dependency>
<groupId>com.microsoft.sqlserver</groupId>
<artifactId>sqljdbc41</artifactId>
<version>4.1</version>
</dependency>

If you use a remote artifact repository (nexus, archiva...) you also need to deploy the artifact on this repository. You can find more here : https://maven.apache.org/guides/mini/guide-3rd-party-jars-remote.html

Another way, you can put it into the resources folder, such as resources/lib/xxx.jar, then config the pom.xml like this:

<dependency>
<groupId>com.microsoft.sqlserver</groupId>
<artifactId>sqljdbc41</artifactId>
<version>4.1</version>
<scope>system</scope>
<systemPath>${basedir}/src/main/resources/lib/sqljdbc41.jar</systemPath>
</dependency>

In my case, the fault was providing a version number without "dot" in tag:

<dependency>
<groupId>jdk.tools</groupId>
<artifactId>jdk.tools</artifactId>
<scope>system</scope>
<version>1</version>
<systemPath>${basedir}/src/main/resources/lib/tools.jar</systemPath>
</dependency>

This one works:

<dependency>
<groupId>jdk.tools</groupId>
<artifactId>jdk.tools</artifactId>
<scope>system</scope>
<version>1.8</version>
<systemPath>${basedir}/src/main/resources/lib/tools.jar</systemPath>
</dependency>

you can set 'includeSystemScope' to true.

<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<includeSystemScope>true</includeSystemScope>
</configuration>
</plugin>

In Spring Boot: I also faced similar issue and below code helped me.

<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>1.5.7.RELEASE</version>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
<configuration>
<includeSystemScope>true</includeSystemScope>
</configuration>
</plugin>
</plugins>
</build>

It works for me:

project {root folder}/libs/ojdbc-11.2.0.3.jar

pom.xml:

<dependency>
<groupId>com.oracle</groupId>
<artifactId>ojdbc</artifactId>
<version>11.2.0.3</version>
<scope>system</scope>
<systemPath>${basedir}/libs/ojdbc-11.2.0.3.jar</systemPath>
</dependency>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<includeSystemScope>true</includeSystemScope>
</configuration>
</plugin>

When Spring-Boot projects are used with maven or gradle plugins they packaged the applicaiton by default as executable jars. These executable jars cannot be used as dependency in any another Spring-Boot project because the executable jar add classes in boot-inf/类 folder. This means that they cannot be found when the executable jar is used as a dependency because the dependency jar will also have the same class path structure as shown below.

enter image description here

如果我们想使用Project-A作为Project-B中的Maven依赖项,那么我们必须有两个工件。要生成两个工件(一个可用作依赖项,另一个可执行),必须指定classifier。此分类器应用于可执行归档文件的名称,保留默认归档文件作为依赖项使用。 To configure a classifier of exec in Maven, you can use the following configuration:

<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<classifier>exec</classifier>
</configuration>
</plugin>
</plugins>
</build>

So the MAJIC WORD here is <classifier>exec</classifier> this will create a jar structure as below and then it could easily be conusmed by spring-boot project as maven dependency jar on class path.

enter image description here

The above plugin need to be add in project-A pom that is going to be used as dependency in project-B. Same is explained in spring documentation section 16.5. as well.

In order to work through the local repository, the target .jar file that we will work with must be in the s2 folder. Several methods can be used for this:

  1. The file can be taken manually and put in the relevant place (not preferred). The same process can be done by installing it via the console.
  2. Relevant Remote URL is written in the .pom file dependencies and automatically places it in the s2 folder when Intellij is refreshed (validate) in the IDE used.
  3. The same process can be done by addressing the .pom file dependencies via the centeral repository.

Attention: ComponentScan should not be forgotten for the related jar work on SpringBot.