搜索
您的当前位置:首页正文

Spring异常Unable to locate Spring

来源:知库网

问题描述

本项目用到spring框架,编辑器为Intellij Idea Ultimate 2016.1.3. 在Intellij Idea中运行项目时没问题,但运行打出的jar包就报spring的异常,如图:

jar包是用Intellij Idea的Build->Rebuild Project命令,maven-compile-plugin编译打的包。

定位问题根源

spring在启动时会加载xsd文件,它首先会到本地查找xsd文件(一般都会包含在spring的jar包中),如果如果找不到则会到xml头部定义的url指定路径中寻找xsd,如果找不到则会报错。

在spring jar包下的META-INF文件夹中都会包含一个spring.schemas文件,其中就包含了对xsd文件的路径的定义:

产生该bug的原因是:工程一般依赖了很多的jar包,而被依赖的jar又会依赖其它的jar包。这样,当工程中依赖到不同版本的spring时,在使用maven默认的打包方式或assembly插件打包时,只能将某一个版本的jar包下的spring.schemas文件放入最终打出的jar包里,这就可能遗漏一些版本的xsd的本地映射,所以会报错。

解决方案

所以推荐使用maven-shade-plugin打包。shade插件打包时在对spring.schemas文件处理上,它能将所有jar里的spring.schemas文件进行合并,在最终生成的单一jar包里,spring.schemas包含了所有出现过的版本的集合。

可执行CLI包

除了常规的jar包、war包、源码包和javadoc包,另一种常被用到的包是在 命令行可直接运行的CLI(Command Line)包。默认默认Maven生成的jar包只包含了编译生成的class文件和项目资源文件,而要得到一个可以直接在命令行通过java命令运行的jar文件,还要满足两个条件:

1)jar包中的/META-INF/MANIFEST.MF元数据文件必须包含Main-Class信息。

2)项目所有的依赖都必须在Classpath中

Maven有好几个插件能帮助用户完成上述任务,不过用起来最方便的还是maven-shade-plugin,它可以让用户配置Main-Class的值,然后在打包时将值填入/META-INF/MANIFEST.MF文件。关于项目的依赖,它很聪明地将依赖JAR文件全部解压后,再将得到的class文件连同当前项目的class文件一起合并到最终的CLI包中,这样,在执行CLI jar文件时,所有需要的类就都在classpath中了。

使用shade插件,在pom.xml中配置:

注意:maven-shade-plugin插件有个配置属性:createDependencyReducedPom,默认值为true。如果用这个插件来deploy,或者发布到中央仓库,这个属性会缩减pom文件,会把你依赖的干掉。正确的做法是把这个值改成false。

打包成功后,在target目录下生成两个jar文件:

1) original-artifactId-version.jar

2) artifactId-version.jar

其中original...jar里只包含了工程自己的class文件,而另外一个jar包则包   含了工程本身以及所有依赖的jar包的class文件。我们只需要第二个jar包就可以了。

参考:

Top