ClassNotFoundException的:org.springframework.context.support.ClassPathXmlApplicationContext
我工作的一个独立的应用程序构建与行家,我在使用一个lib文件夹添加依赖到目标罐子 maven-dependency-plugin与maven-assembly-plugin该应用程序在eclipse中运行良好,没有问题,但是当试图从命令行运行生成的jar文件时,出现以下异常:ClassNotFoundException的:org.springframework.context.support.ClassPathXmlApplicationContext
Exception in thread "main" java.lang.NoClassDefFoundError: org/springframework/context/support/ClassPathXmlApplicationContext
at com.spring.sample.MainClass.main(MainClass.java:11)
Caused by: java.lang.ClassNotFoundException: org.springframework.context.support.ClassPathXmlApplicationContext
at java.net.URLClassLoader$1.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
... 1 more
我看着生成的JAR lib文件夹里面,我发现弹簧上下文support.jar已经在那里,所以我想知道为什么我收到这样的例外。
这里是我的Maven构建配置:
<build>
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
</resource>
</resources>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
<id>copy-dependencies</id>
<phase>prepare-package</phase>
<goals>
<goal>copy-dependencies</goal>
</goals>
<configuration>
<outputDirectory>${project.build.directory}/classes/lib</outputDirectory>
<overWriteReleases>false</overWriteReleases>
<overWriteSnapshots>false</overWriteSnapshots>
<overWriteIfNewer>true</overWriteIfNewer>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<configuration>
<archive>
<manifest>
<addClasspath>true</addClasspath>
<classpathPrefix>lib/</classpathPrefix>
<mainClass>com.myapp.MainClass</mainClass>
</manifest>
</archive>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.6</source>
<target>1.6</target>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
<id>install</id>
<phase>install</phase>
<goals>
<goal>sources</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-resources-plugin</artifactId>
<version>2.5</version>
<configuration>
<encoding>UTF-8</encoding>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<executions>
<execution>
<id>create-my-bundle</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
<configuration>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
你已经有了一堆POM,你正在建造两个罐子。
其中一个瓶子是通过首先将您的依赖关系复制到target/classes/lib
- 一个有问题的做法开始的 - 并让jar插件的默认执行构建它的普通jar来构建的。这个jar包含所有你的代码,就像一个普通的jar文件一样,但是它里面的所有依赖jar也在/lib
之间。它还有一个清单,指定Main-Class
和Class-Path
列出相对路径为lib/...jar
的所有需要的罐子。听起来这是你试图运行的那个。它找不到需要的类的原因是,独立Java应用程序的类路径是文件系统上包含类文件的文件夹或jar文件的列表。换句话说,它不会在另一个jar文件里面找到jar文件,这就是你所拥有的。为了达到这个目标,你需要一个lib
目录,紧邻你的jar文件,它具有所有的依赖关系。这是什么导致你现在的问题。
另一个jar由程序集插件构建。由于你之前的依赖插件的滑稽动作,这个应该在/lib
中也有所有的依赖关系罐,我已经解释过它不会完成任何事情,但是由于描述符是如何工作的,它也会被提取所有的罐子,并把他们的所有课程和你自己的课程一起放到你的罐子里。如果你要运行这个jar,你可能会超过ClassNotFoundException,但是像这样的“fat jars”存在众所周知的问题,这意味着你不应该这样做,除非你有一些非常有说服力的理由。一个这样的问题,在以下问题描述:
Maven and Spring = Unable to create application context: Unable to locate Spring NamespaceHandler
类位于弹簧context.jar。在pom.xml中添加该依赖项。
不,这是在已经加入弹簧上下文support.jar http://static.springsource.org/spring/docs/2.5.x /api/org/springframework/context/support/ClassPathXmlApplicationContext.html – 2011-12-24 02:50:07
感谢这样宝贵的答案,所以我从它到目前为止得到的是,maven无法从jar中加载依赖关系,而是从外部文件夹中文件系统,为了做到这一点,我需要使用这个库http://one-jar.sourceforge.net/? – 2011-12-24 12:53:36
并且为了清楚所有内容,在文件系统中收集外部lib文件夹中的所有依赖项所需的最低配置是多少。 – 2011-12-24 12:54:41
这不是Maven加载依赖关系。这是Java。 Java总是这样工作。 One-JAR是从一个jar中打包和运行应用程序的一种方式。至于你的第二个评论,maven assembly插件会做到这一点。您只需编写一个描述符,将所有编译范围的依赖关系放入一个'lib'文件夹中。请参见[dependencySet](http://maven.apache.org/plugins/maven-assembly-plugin/assembly.html#class_dependencySet)。 – 2011-12-24 17:44:17