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

MavenSpring Boot

Maven Problem Overview


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.

Maven Solutions


Solution 1 - Maven

you can set 'includeSystemScope' to true.

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

Solution 2 - Maven

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

Solution 3 - Maven

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>

Solution 4 - Maven

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>

Solution 5 - Maven

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>

Solution 6 - Maven

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>

Solution 7 - Maven

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/classes 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

If we want to use project-A as a maven dependency in project-B then we must have two artifacts. To produce the two artifacts, one that can be used as a dependency and one that is executable, a classifier must be specified. This classifier is applied to the name of the executable archive, leaving the default archive for use as a dependency. 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.

Solution 8 - Maven

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.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionErickView Question on Stackoverflow
Solution 1 - MavenallenView Answer on Stackoverflow
Solution 2 - MavenMelouView Answer on Stackoverflow
Solution 3 - MavenClement.XuView Answer on Stackoverflow
Solution 4 - MavenAshu PhaugatView Answer on Stackoverflow
Solution 5 - MavenyuxiaobinView Answer on Stackoverflow
Solution 6 - MavenAndreasView Answer on Stackoverflow
Solution 7 - MavenWaqas AhmedView Answer on Stackoverflow
Solution 8 - MavenHamit YILDIRIMView Answer on Stackoverflow