[英]Spring Boot - Java FAT Jar - NoClassFoundError
在我的 Java 項目中,我很難訪問我的一個 API。 此 API 通過外部 JAR 到達。 通過定期運行 Spring 引導,我能夠訪問 API 並取回一些數據,但是當我從 JAR 運行時,我得到 NoClassFoundError。 為了解決這個問題,我使用 Maven 的 shade 插件創建了一個 FAT jar,它將捆綁我所有的外部依賴項,它已經完成了,但是從陰影 jar 運行程序,我遇到了同樣的問題。
下面是我的 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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.4.5</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.edm</groupId>
<artifactId>EDMProd</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>EDMProd</name>
<description>EDM API Service</description>
<properties>
<java.version>11</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<exclusions>
<exclusion>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!-- Mentor Dependencies -->
<dependency>
<groupId>com.mentor.datafusion.oi</groupId>
<artifactId>com.mentor.datafusion.oi</artifactId>
<version>1.0.0</version>
</dependency>
<dependency>
<groupId>dfo</groupId>
<artifactId>dfo</artifactId>
<version>1.0.0</version>
</dependency>
<dependency>
<groupId>dfutils</groupId>
<artifactId>dfutils</artifactId>
<version>1.0.0</version>
</dependency>
<dependency>
<groupId>com.mentor.datafusion.dfo.is3</groupId>
<artifactId>com.mentor.datafusion.dfo.is3</artifactId>
<version>1.0.0</version>
</dependency>
<dependency>
<groupId>com.mentor.is3.edm.login.api</groupId>
<artifactId>com.mentor.is3.edm.login.api</artifactId>
<version>1.0.0</version>
</dependency>
<dependency>
<groupId>apache-logging-log4j</groupId>
<artifactId>apache-logging-log4j</artifactId>
<version>1.0.0</version>
</dependency>
<dependency>
<groupId>com.mentor.datafusion.dfo.is3.api</groupId>
<artifactId>com.mentor.datafusion.dfo.is3.api</artifactId>
<version>1.0.0</version>
</dependency>
<dependency>
<groupId>com.mentor.datafusion.dfo.is3.common</groupId>
<artifactId>com.mentor.datafusion.dfo.is3.common</artifactId>
<version>1.0.0</version>
</dependency>
<dependency>
<groupId>DFTunnelClient</groupId>
<artifactId>DFTunnelClient</artifactId>
<version>1.0.0</version>
</dependency>
<dependency>
<groupId>is3-server-api</groupId>
<artifactId>is3-server-api</artifactId>
<version>1.0.0</version>
</dependency>
<dependency>
<groupId>com.mentor.is3.server.dms.api</groupId>
<artifactId>com.mentor.is3.server.dms.api</artifactId>
<version>1.0.0</version>
</dependency>
</dependencies>
<build>
<finalName>EDM Library Web Service</finalName>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<executions>
<execution>
<id>shade-my-jar</id>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<transformers>
<transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
<mainClass>com.edm.EdmProdApplication</mainClass>
</transformer>
</transformers>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
啟動陰影 jar 后,這是我拋出的異常。
Picked up _JAVA_OPTIONS: -Djava.net.preferIPv4Stack=true
SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder".
SLF4J: Defaulting to no-operation (NOP) logger implementation
SLF4J: See http://www.slf4j.org/codes.html#StaticLoggerBinder for further details.
. ____ _ __ _ _
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot :: (v0.0.1-SNAPSHOT)
May 10, 2021 9:26:02 AM org.apache.catalina.core.StandardService startInternal
INFO: Starting service [Tomcat]
May 10, 2021 9:26:02 AM org.apache.catalina.core.StandardEngine startInternal
INFO: Starting Servlet engine: [Apache Tomcat/9.0.45]
May 10, 2021 9:26:02 AM org.apache.catalina.core.ApplicationContext log
INFO: Initializing Spring embedded WebApplicationContext
May 10, 2021 9:26:16 AM org.apache.catalina.core.ApplicationContext log
INFO: Initializing Spring DispatcherServlet 'dispatcherServlet'
log4j:WARN No appenders could be found for logger (com.mentor.datafusion.utils.resources.MGResourceBundle).
log4j:WARN Please initialize the log4j system properly.
log4j:WARN See http://logging.apache.org/log4j/1.2/faq.html#noconfig for more info.
May 10, 2021 9:26:16 AM org.apache.catalina.core.StandardWrapperValve invoke
SEVERE: Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Handler dispatch failed; nested exception is java.lang.NoClassDefFoundError: com/mentor/is3/client/login/Login] with root cause
java.lang.ClassNotFoundException: com.mentor.is3.client.login.Login
at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:581)
at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:178)
at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:521)
at com.mentor.datafusion.dfo.is3.login.IS3LoginUtil.performBatchLoginToIS3Server(IS3LoginUtil.java:232)
at com.mentor.datafusion.dfo.is3.login.IS3BatchAuthenticate.loginImpl(IS3BatchAuthenticate.java:64)
at com.mentor.datafusion.dfo.login.BatchAuthenticateImpl.login(BatchAuthenticateImpl.java:100)
at com.mentor.datafusion.dfo.login.BatchAuthenticate.login(BatchAuthenticate.java:51)
at com.mentor.datafusion.oi.internal.login.AuthenticateWrapper.login(AuthenticateWrapper.java:24)
at com.intel.Connect.ConnectToEDM(Connect.java:59)
at com.intel.IntelProd.getAllComponents(IntelProd.java:21)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:566)
at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:197)
at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:141)
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:106)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:894)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:808)
at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1060)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:962)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1006)
at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:898)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:626)
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:883)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:733)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:227)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:202)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:97)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:542)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:143)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:78)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:357)
at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:374)
at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65)
at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:893)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1707)
at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.base/java.lang.Thread.run(Thread.java:834)
我已經解決這個問題太久了,我只是不知道該怎么辦。 我覺得我已經嘗試了我在 Stack Overflow 上看到的所有內容。
下面也是我嘗試連接到 API 時運行的源代碼
package com.edm;
import com.mentor.datafusion.oi.OIObjectManager;
import com.mentor.datafusion.oi.OIObjectManagerFactory;
import com.mentor.datafusion.oi.login.OIAuthenticate;
import com.mentor.datafusion.oi.login.OIAuthenticateFactory;
import com.mentor.datafusion.oi.login.OILoginData;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Properties;
public class Connect {
static OIObjectManagerFactory omf;
static OIObjectManager om;
static String SERVER_URL;
static String SERVER_USERNAME;
static String SERVER_PASSWORD;
static String PRODUCTION_LIBRARY;
static String OSAT_LIBRARY;
static String CAPACITOR_CLASS;
static String RESISTOR_CLASS;
static String INDUCTOR_CLASS;
public Connect() throws IOException {
// Read Configuration File
String currentDirectory = System.getProperty("user.dir");
Path configurationFile_path= Paths.get(currentDirectory).getParent();
FileInputStream inputStream = new FileInputStream(configurationFile_path + "/src/main/resources/configuration.properties");
Properties prop = new Properties();
prop.load(inputStream);
// Initialize Server Variables
this.CAPACITOR_CLASS = prop.getProperty("CAPACITOR_CLASS");
this.RESISTOR_CLASS = prop.getProperty("RESISTOR_CLASS");
this.INDUCTOR_CLASS = prop.getProperty("INDUCTOR_CLASS");
this.PRODUCTION_LIBRARY = prop.getProperty("PRODUCTION_LIBRARY");
this.SERVER_URL = prop.getProperty("SERVER_URL");
this.OSAT_LIBRARY = prop.getProperty("OSAT_LIBRARY");
this.SERVER_USERNAME = prop.getProperty("SERVER_USERNAME");
this.SERVER_PASSWORD = prop.getProperty("SERVER_PASSWORD");
}
public static void ConnectToEDM(String libraryName) {
try {
OILoginData loginData = OIAuthenticateFactory.createLoginData("myLoginConfig");
loginData.setServer(SERVER_URL);
loginData.setUsername(SERVER_USERNAME);
loginData.setPassword(SERVER_PASSWORD);
loginData.setProdLib(PRODUCTION_LIBRARY);
String applicationName = "Component Library";
OIAuthenticate auth = OIAuthenticateFactory.createBatchAuthenticate(loginData);
omf = auth.login(applicationName);
System.out.println("Connected to library: " + libraryName);
}
catch (Exception e) {
System.out.println("Connection failed");
e.printStackTrace();
}
try {
om = omf.createObjectManager();
om.setLibraryConfiguration(libraryName);
System.out.println("Successfully connected to " + libraryName + " EDM Library.");
}
catch (Exception e) {
System.out.println("Error: " + e.toString());
e.printStackTrace();
}
}
}
我相信這里真正的問題是,我只需要 4 個外部依賴項來運行我的 API。 Locally it is okay, but when I package into JAR, I believe those dependencies rely on other dependencies, so when ran locally, I believe my system knows where to go to get those dependencies, but when packaged into a jar, can't find那些依賴。
附帶說明:我將依賴項導入項目的方式是
我是新手,所以我不確定這是否是正確的方法。
看起來您正在嘗試從需要身份驗證的特定存儲庫訪問工件?
檢查 .m2 文件夾中的 settings.xml,使用您嘗試連接的存儲庫的配置文件。
讓我知道你的想法 !
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.