简体   繁体   English

Spring 启动 - Java FAT Jar - NoClassFoundError

[英]Spring Boot - Java FAT Jar - NoClassFoundError

In my Java project, I'm having a hard time accessing one of my API's.在我的 Java 项目中,我很难访问我的一个 API。 This API is reached through an external JAR.此 API 通过外部 JAR 到达。 With a regular run of Spring Boot, I am able to access the API and get some data back, but when I run from a JAR, I get NoClassFoundError.通过定期运行 Spring 引导,我能够访问 API 并取回一些数据,但是当我从 JAR 运行时,我得到 NoClassFoundError。 To resolve this issue, I used Maven's shade plugin to create a FAT jar, that will bundle up all my external depenencies, which it has done, but running the program from the shaded jar, I experience the same issue.为了解决这个问题,我使用 Maven 的 shade 插件创建了一个 FAT jar,它将捆绑我所有的外部依赖项,它已经完成了,但是从阴影 jar 运行程序,我遇到了同样的问题。

Below is my pom.xml下面是我的 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>

After launching the shaded jar, here is the exception I get thrown.启动阴影 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)

I've been at this problem for too long now and I'm just not sure what to do.我已经解决这个问题太久了,我只是不知道该怎么办。 I feel like I've tried everything I've seen on Stack Overflow.我觉得我已经尝试了我在 Stack Overflow 上看到的所有内容。

Below is also the source code that is ran when I try to connect to the API下面也是我尝试连接到 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();
        }
    }
}

I believe the true issue at hand here is, I only need 4 external dependencies to run my API.我相信这里真正的问题是,我只需要 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 those dependencies. 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那些依赖。

As a side note: The way I import dependencies into my project is附带说明:我将依赖项导入项目的方式是

  1. Add the external jar in the classpath (Eclipse)在类路径中添加外部 jar (Eclipse)
  2. Include the jar I imported, as a dependency in my pom.xml包括我导入的 jar 作为我 pom.xml 中的依赖项

I'm new to this, so I'm unsure if this is the correct approach.我是新手,所以我不确定这是否是正确的方法。

Have looks like you're trying to access the artifacts from a specific repo which requires authentication??看起来您正在尝试从需要身份验证的特定存储库访问工件?

Check your settings.xml in the.m2 folder, use profile for the repository you're trying to connect.检查 .m2 文件夹中的 settings.xml,使用您尝试连接的存储库的配置文件。

Let me know your thoughts !让我知道你的想法 !

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM