`
wangyujie0431
  • 浏览: 2769 次
社区版块
存档分类
最新评论

Maven 项目SuchNoMethod等报错

阅读更多
对于maven项目经常会出现,项目引入一堆依赖,最后项目运行的时候出现

NoSuchMethod

ClassNotFound

NoClassDefFound

这些exception,这个时候就要怀疑是不是引包的姿势不对,导致了项目启动出现问题!

Root Cause:

一般出现以上exception的根本原因是,a,b不同的依赖之间依赖了同一个依赖c的不同版本,在A版本中某个类还在,但是在B版本中对应的类已经被删除了,maven依赖的时候根据自身的规则依赖了B版本,导致了应用在调用a的方法时,出现了NoSuchMethodException


ps:这里稍微提一下maven的依赖加载机制,我们都知道classloader是根据全路径名去加载一个类的,所以maven在依赖jar包时不可能对同一个jar包依赖多次,maven在加载jar时会根据加载的依赖复杂度去决定加载哪一个版本依赖,例如应用-->A-->B-->C(1.0.2), 应用-->D-->C(1.0.1),maven在向项目导入依赖的时候只会导入C(1.0.1),因为其依赖的复杂度(层数)比较低;那如果出现复杂度一样的情况,maven又是怎么做的呢,maven会根据pom文件中的顺序导入依赖,比较靠前的先导入


下面我们来人工模拟下NoSuchMethodException的出现情况:
首先是底层依赖的包,对应root cause中提到的c

/**
 * Created by Roy on 16/9/11.
 */
public class DependencyBeanB {

    public void dependMethodA(){
        System.out.println("You depend on method A");
    }

//    public void dependMehtodB(){
//        System.out.println("You depend on method B");
//    }

}


maven install 到本地仓库 版本是1.0.1

/**
 * Created by Roy on 16/9/11.
 */
public class DependencyBeanB {

//    public void dependMethodA(){
//        System.out.println("You depend on method A");
//    }

   public void dependMehtodB(){
        System.out.println("You depend on method B");
    }

}


maven install 到本地仓库 版本是1.0.2

二层依赖,对应root cause中提到的a
/**
 * Created by Roy on 16/9/11.
 */
public class SecondInvokerA {

    public void invoke(){
        DependencyBean dependencyBean = new DependencyBean();
        dependencyBean.dependMethodA();
    }

}


<dependencies>
        <dependency>
            <groupId>com.roy</groupId>
            <artifactId>maven-test-jar</artifactId>
            <version>1.0.1</version>
        </dependency>
    </dependencies>


对应root cause 中提到的b
/**
 * Created by Roy on 16/9/11.
 */
public class SecondInvokerB{

    public void invoke(){
        DependencyBean dependencyBean = new DependencyBean();
        dependencyBean.dependMehtodB();
    }

}


<dependencies>
        <dependency>
            <groupId>com.roy</groupId>
            <artifactId>maven-test-jar</artifactId>
            <version>1.0.2</version>
        </dependency>
    </dependencies>


应用
public class DependencyInvoker {

    public static void main(String[] args) {
        System.out.println("Invoker main method invoke.");
        SecondInvokerB secondInvoker = new SecondInvokerB();
        secondInvoker.invoke();
    }
}


<dependencies>
        <dependency>
            <groupId>com.roy</groupId>
            <artifactId>depend-project-a</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>

        <dependency>
            <groupId>com.roy</groupId>
            <artifactId>depend-project-b</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>
    </dependencies>

运行应用 错误出现:
Invoker main method invoke.
Exception in thread "main" java.lang.NoSuchMethodError: com.roy.test.DependencyBean.dependMehtodB()V
at com.roy.SecondInvokerB.invoke(SecondInvokerB.java:12)
at com.roy.DependencyInvoker.main(DependencyInvoker.java:11)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:483)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:144)

知道了是由于重复依赖导致了问题,我们就要解决问题了

两种方式,
一,通过http://maven.apache.org/plugins/maven-dependency-plugin/ 插件在项目未运行前就发现问题,防患于未然
二,如果没有依赖这个插件,问题发生了怎么办,方法一,可以借助IDE的依赖图找到重复依赖,然后exclude掉(实际项目中出现方法,类找不到一般都是传递依赖了版本较低的包,跟以上举的例子不太一样),方法二,通过mvn dependency:tree -Dverbose 命令直接找到被忽略依赖的包,然后exclude掉出现问题jar(一般都是引入低版本包出的问题,因为高版本的包一般都会做向下兼容)

[INFO] Building maven-classload 1.0-SNAPSHOT
[INFO] ------------------------------------------------------------------------
[INFO]
[INFO] --- maven-dependency-plugin:2.8:tree (default-cli) @ maven-classload ---
[INFO] com.roy:maven-classload:jar:1.0-SNAPSHOT
[INFO] +- com.roy:depend-project-a:jar:1.0-SNAPSHOT:compile
[INFO] |  \- com.roy:maven-test-jar:jar:1.0.1:compile
[INFO] \- com.roy:depend-project-b:jar:1.0-SNAPSHOT:compile
[INFO]    \- (com.roy:maven-test-jar:jar:1.0.2:compile - omitted for conflict with 1.0.1)
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 1.782 s
[INFO] Finished at: 2016-09-11T22:27:21+08:00
[INFO] Final Memory: 11M/155M
[INFO] ------------------------------------------------------------------------

红色部分指出,当前依赖的jar被另一个版本的取代了,这个时候你就要根据实际情况exclude掉一个
分享到:
评论

相关推荐

    eclipse导入maven项目报错解决办法

    ### Eclipse导入Maven项目报错解决办法 在开发过程中,我们常常会遇到使用Eclipse导入Maven项目时出现的各种报错情况。本文旨在系统地介绍如何解决这些常见问题,包括但不限于配置环境、设置JDK版本、配置Maven库...

    Eclipse导入Maven项目pom.xml报错的解决办法.doc

    然而,在实际操作中,有时会在导入Maven项目时遇到pom.xml报错的问题。这个问题可能是由于Eclipse与Maven的集成不完全或者配置不当导致的。下面我们将详细探讨如何解决这种问题。 首先,当Eclipse中导入的Maven项目...

    maven更新本地私服报错

    失败报错如下: Failed to execute goal org.apache.maven.plugins:maven-help-plugin:3.1.0:system &#40;default-cli&#41; on project standalone-pom: Execution default-cli of goal org.apache.maven.plugins:...

    maven web项目配置

    Maven是由Apache软件基金会开发的项目管理工具,它通过一个项目对象模型(Project Object Model, POM)来管理项目,POM包含了项目的配置信息,如依赖、构建目标、插件等。Maven使用约定优于配置的原则,这意味着它有...

    maven项目转换WEB项目

    5. `pom.xml`:这是Maven项目的配置文件,包含了项目信息、依赖管理、构建指令等。 如果你不熟悉Maven,但想要在Eclipse中使用一个基于Maven的Web项目,可以遵循以下步骤: 1. **导入Maven项目到Eclipse**:在...

    解决IDEA中maven导入jar包一直报错问题

    本文详细地介绍了解决IDEA中maven导入jar包一直报错问题的方法,包括重新导入maven的module、下载pom.xml文件中所配置的jar包、在pom.xml文件中新增jar包和搜索和下载jar包等。希望本文能够为读者提供一定的参考价值...

    Eclipse开发的maven项目,导入Idea ~~ 超简单

    今日,将原先在eclipse上开发的Maven项目导入idea中,启动报错,项目在eclipse中启动百分百是没有问题,误以为是IDEA打开项目的动作错误,在网上查了很多资料,各种操作五花八门,尝试了遍,结果还是不行。...

    解决maven启动Spring项目报错的问题

    解决 Maven 启动 Spring 项目报错的问题 Maven 是一个流行的 Java 项目管理和构建工具,而 Spring 是一个广泛使用的 Java 框架。然而,在使用 Maven 启动 Spring 项目时,可能会遇到一些报错的问题。今天,我们将...

    maven项目转动态web项目,部署到tomcat

    "Maven 项目转动态 Web 项目并部署到 Tomcat" Maven 项目转动态 Web 项目并部署到 Tomcat 是一个常见的操作,特别是在 Eclipse 和 Tomcat 环境下。本文将详细介绍如何将 Maven 项目转换为动态 Web 项目,并将其部署...

    Maven在eclipse中的项目启动命令

    - **Maven的POM文件**: `pom.xml`是Maven的核心配置文件,其中包含了项目的依赖关系、构建目标、构建规则等信息。 - **仓库系统**: Maven通过一个层次化的仓库系统来管理各种构件。这个系统包括中央仓库、私有仓库和...

    maven项目eclipse导入步骤(可以让你的maven项目正常运行)

    ### Maven项目Eclipse导入步骤详解 #### 一、前言 在进行软件开发时,Maven作为一款自动化构建工具,能够极大地提高项目的构建效率。而在实际工作中,我们常常需要将Maven项目导入到Eclipse IDE中进行开发。本文将...

    在IDEA的maven项目中连接并使用MySQL8.0的方法教程

    1.使用骨架创建maven项目,此处选择:maven-archetype-quickstart 2.填入GroupId和ArtifactId 3.第一个选中maven安装的文件夹,第二个选中maven安装文件夹中的conf/settings.xml,第三个如果settings.xml中配置了...

    关于maven打包时的报错: Return code is: 501 , ReasonPhrase:HTTPS Required

    主要介绍了关于maven打包时的报错: Return code is: 501 , ReasonPhrase:HTTPS Required,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

    maven离线插件

    Maven是Java开发中广泛使用的构建工具,它通过项目对象模型(Project Object Model,POM)来管理和构建项目。离线插件则是针对那些在没有网络连接或者网络环境不稳定的情况下,仍需进行Maven构建的开发者设计的。...

    基于elasticjob的入门maven项目

    基于elasticjob的入门maven项目 基于elasticjob的入门maven项目 基于elasticjob的入门maven项目 基于elasticjob的入门maven项目 基于elasticjob的入门maven项目 基于elasticjob的入门maven项目 基于elasticjob的入门...

    IDEA中Maven依赖包报错的问题解决方案汇总.docx

    IDEA中Maven依赖包报错的问题解决方案汇总.docx

    idea使用maven创建web项目详细教程

    本教程将指导您使用 IDEA 创建一个 Maven Web 项目,从安装 Maven 到配置 Maven 环境、创建 Maven 工程、pom.xml 文件配置、依赖管理等。 1. 安装 Maven 在 IDEA 中使用 Maven 之前,需要先安装 Maven。在 Maven ...

    Maven项目整合Kafka

    使用Maven整合Kafka 包括生产者,消费者 Kafka各种配置 //1.设置参数 Properties props = new Properties(); props.put(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG, "81.68.232.188:9092,81.68.232.188:9093,81...

    maven中 引入jar报错:Missing artifact net.sf.json-lib:json-lib:jar:2.4

    &lt;groupId&gt;net.sf.json-lib&lt;/groupId&gt; &lt;artifactId&gt;json-lib &lt;version&gt;2.4 &lt;classifier&gt;jdk15 或者直接下载这个包

Global site tag (gtag.js) - Google Analytics