如何用Spring Boot构建含所有依赖与源码的可执行Fat Jar?
Hey there, sorry to hear you've been stuck on this for days—let's get that fat jar working with all your Spring code, custom sources, and nested dependencies like OpenCV. Here's a step-by-step breakdown tailored to your setup:
1. Fix the Spring Boot Maven Plugin Configuration
Your pom already uses the Spring Boot parent, but you need to ensure the spring-boot-maven-plugin is properly configured to package all dependencies (including nested ones) into the executable jar. Add this plugin section to your <build><plugins> block:
<build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> <version>2.0.1.RELEASE</version> <executions> <execution> <goals> <goal>repackage</goal> </goals> </execution> </executions> <!-- Optional: Handle system-scope dependencies or explicit nested jars --> <configuration> <includeSystemScope>true</includeSystemScope> <!-- Explicitly include OpenCV if it's not being picked up automatically --> <includes> <include> <groupId>org.opencv</groupId> <artifactId>opencv</artifactId> </include> </includes> </configuration> </plugin> </plugins> </build>
The repackage goal is critical—it takes the standard Maven jar and repackages it into an executable fat jar with all dependencies embedded.
2. Handle OpenCV's Native Libraries (If Applicable)
OpenCV often includes platform-specific native libraries (.dll, .so, .dylib), which need special handling to be accessible at runtime:
- Maven-hosted OpenCV dependency: Specify a classifier matching your target OS to pull in the correct native artifacts:
<dependency> <groupId>org.opencv</groupId> <artifactId>opencv</artifactId> <version>4.5.5</version> <classifier>windows-x86_64</classifier> <!-- Use linux-x86_64 or macosx-x86_64 for other platforms --> </dependency> - Local OpenCV jar: Add it as a system dependency (the plugin's
<includeSystemScope>trueensures it gets packaged):<dependency> <groupId>org.opencv</groupId> <artifactId>opencv</artifactId> <version>4.5.5</version> <scope>system</scope> <systemPath>${project.basedir}/lib/opencv-4.5.5.jar</systemPath> </dependency>
To load the native library at runtime, add a static block to your main Spring Boot application class:
@SpringBootApplication public class MyTestProjectApplication { static { // Load OpenCV's native library System.loadLibrary(Core.NATIVE_LIBRARY_NAME); } public static void main(String[] args) { SpringApplication.run(MyTestProjectApplication.class, args); } }
3. Check for Dependency Scope Issues
Make sure none of your dependencies (including OpenCV) have a <scope> set to provided or test—these scopes exclude dependencies from the packaged jar, which will cause runtime errors unless you're supplying those dependencies externally.
4. Build and Test the Jar
Run this Maven command to build the fat jar:
mvn clean package
You'll find the executable jar in the target directory (look for a file like mytestproject-0.1.jar). Test it with:
java -jar target/mytestproject-0.1.jar
Troubleshooting Tips
- If you get
NoClassDefFoundErrorfor OpenCV classes: Runmvn dependency:treeto verify the dependency is included in your project, and check that the plugin's<includes>section is correctly targeting OpenCV. - If native library loading fails: Unzip the jar to confirm the native library files are present, and ensure you're running the jar on the same platform you specified in the dependency classifier.
内容的提问来源于stack exchange,提问作者user2480714

