SSM项目_Eclipse卡进程 一直loading加载spring-xx.xsd/无法加载SpringXSD文件

该文章首发于 https:////www.cnblogs.com/steamer/articles/12500645.html

转载注明出处!

    问题描述:使用了别人整理的applicationContext.xmlspringmvc.xml文件,大概如下(只放了applicationContext.xml

    然后Eclipse自动开始加载一些东西,几分钟后其他都加载完毕,还剩下两个进程迟迟不动,根据以往的经验,肯定是加载不出来了,卡住进程大概如下

还有的人出现报无法加载Spring.xsd的错误(org.sax.SAXParseExptation:Failed to read schema document),我没有遇到

 

  解决办法:将版本号改为你Spring工具包(jar包)内对应的版本即可解决问题

  比如你的Libraries目录下找到spring-xx包打开

 

 

  那么相应的

  改好后关闭eclipse重新打开就好了,至于为什么明明有4.2版本的xsd却还是加载不出来,我也不会是很清楚,猜测应该默认寻找最新的xsd版本,如果

有知道原因的也希望能在评论区留言交流。

  还有一种办法就是把xsd约束文件全部换成本地的,工作量大而且非常麻烦,我不推荐这种办法,这里也不再赘述

  特别说明:如果你的是maven项目遇到这个问题,应当修改为你的maven插件包里下载的相应版本,插件包一般设置在maven安装目录,也有可能你

的是别的目录,反正是自己设置的应该自己能找到。

  接下来是枯燥的原理解释:


   
问题发生的主要原因就是Spring服务器资源访问不到,就像这样

 

 

   要明确的一点是:Spring在加载xsd文件时总是先试图从本地查找xsd文件(Spring的jar包中包含部分必要的xsd文件),如果没有找到,就会转向URL下载指定的路径下载,并不是直接去站点下载,这很合理也很好理解。Spring加载xsd文件的类是PluggableSchemaResolver,你可以查看他的源码来验证。另外可以在log4j中添加下面的代码查看日志来验证:

 

   另外,当你的项目是maven项目时,出现类似的问题其他博主有解释,转载一篇如下http://www.360doc.com/content/15/0113/11/3639038_440376349.shtml(内容有些老,没做验证)

-----------------------这是不怎么看得到的分割线------------------------------
现在基本上都是采用maven来进行开发管理,我有如下需求:
需要把java工程打成可执行的jar包,必需把依赖的jar包也一起打包。
而maven默认的package命令构建的jar包中只包括了工程自身的class文件,并没有包括依赖的jar包。
可以通过配置maven-assembly-plugin插件来打包,pom具体配置如下:

<plugin>
  <groupId>org.apache.maven.plugins</groupId>
  <artifactId>maven-assembly-plugin</artifactId>
  <version>2.4</version>
  <configuration>
    <archive>
      <manifest>
        <!--<addClasspath>true</addClasspath>-->
        <mainClass>com.xxx.MainClass</mainClass>
      </manifest>
    </archive>
    <descriptors>
      <descriptor>src/main/assembly/package.xml</descriptor>
    </descriptors>
  </configuration>
  <executions>
    <execution>
      <id>make-assembly</id>
      <phase>package</phase>
      <goals>
        <goal>single</goal>
      </goals>
    </execution>
  </executions>
</plugin>

其中<mainClass></mainClass>的值表示此工程的入口类,也就是包含main方法的类。

配置完pom后可以通过执行mvn assembly:assembly命令来启动插件进行构建。

构建成功后会生成jar包,这样我们就可以在命令行中通过java -jar XXX.jar来运行jar件了。


不过使用此插件会有一些问题:

工程中依赖了spring框架的jar包,打包成功后使用命令来调用jar包时报错如下(内网环境):
org.xml.sax.SAXParseException: schema_reference.4: 
Failed to read schema document 'http://www.springframework.org/schema/beans/spring-beans-3.0.xsd', 
because 1) could not find the document; 2) the document could not be read; 3) the root element of the document is not <xsd:schema>.


究其原因,在网上找到一篇文章对此有比较详细的解释:

https://www.cnblogs.com/steamer/articles/12500645.html

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

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

 

由于我的工程在内网,所以通过url路径去寻找肯定是找不到的,但是比较奇怪的是既然spring的jar包中都会包含,那为什么还是找不到呢?

原来这是assembly插件的一个bug

该bug产生的原因如下:

工程一般依赖了很多的jar包,而被依赖的jar又会依赖其他的jar包,

这样,当工程中依赖到不同的版本的spring时,在使用assembly进行打包时,只能将某一个版本jar包下的spring.schemas文件放入最终打出的jar包里,这就有可能遗漏了一些版本的xsd的本地映射,所以会报错,所以一般推荐使用另外一个插件(maven-shade-plugin)来打包。

shade插件打包时在对spring.schemas文件处理上,它能够将所有jar里的spring.schemas文件进行合并,

在最终生成的单一jar包里,spring.schemas包含了所有出现过的版本的集合。

maven-shade-plugin插件配置如下:

<plugin>
  <groupId>org.apache.maven.plugins</groupId>
  <artifactId>maven-shade-plugin</artifactId>
  <version>2.4.3</version>
  <executions>
    <execution>
      <phase>package</phase>
      <goals>
        <goal>shade</goal>
      </goals>
      <configuration>
        <transformers>
          <transformer implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
            <resource>META-INF/spring.handlers</resource>
          </transformer>
          <transformer implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
            <resource>META-INF/spring.schemas</resource>
          </transformer>
          <transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
            <mainClass>com.xxx.MainClass</mainClass>
          </transformer>
        </transformers>
      </configuration>
    </execution>
  </executions>
</plugin>

<transformer implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
  <resource>META-INF/spring.schemas</resource>
</transformer>
上面这段配置意思是把spring.handlers和spring.schemas文件以append方式加入到构建的jar包中,这样就不会存在出现xsd找不到的情况。

配置完pom后,调用mvn clean install命令进行构建,构建成功后打开工程target目录,发现生成了2个jar包,

一个为:original-XXX-0.0.1-SNAPSHOT.jar,

另一个为:XXX-0.0.1-SNAPSHOT.jar,

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

我们只需要使用第二个jar包就可以了。

posted @ 2020-03-15 22:48  海底的船  阅读(6712)  评论(0编辑  收藏  举报