Spring/Java错误:命名空间元素“annotation-config”... 在JDK 1.5及更高版本上

72

我有一个使用编译器兼容级别1.5编译的Spring/Java应用程序。

我有一个新的Linux设置,在那里我下载了Apache Tomcat 8.0.8

我下载了JDK 8u5

我在bash中设置了路径如下:

PATH=$PATH:$HOME/jdk1.8.0_05/bin
export PATH

Java -version报告:

java version "1.8.0_05"
Java(TM) SE Runtime Environment (build 1.8.0_05-b13)
Java HotSpot(TM) 64-Bit Server VM (build 25.5-b02, mixed mode)

并在setnenv.sh文件中进行设置(针对Tomcat):

JDK_HOME=/home/userid/jdk1.8.0_05

当我部署WAR文件时,出现如下错误。 我认为Tomcat似乎没有使用我安装的Java。 我遵循了设置说明。 附注:我也尝试过JRE而不是JDK,但问题仍然存在。

22-May-2014 11:34:54.070 INFO [http-nio-8080-exec-4] org.apache.catalina.core.ApplicationContext.log Initializing Spring root WebApplicationContext
22-May-2014 11:34:54.512 SEVERE [http-nio-8080-exec-4] org.apache.catalina.core.StandardContext.listenerStart Exception sending context initialized event to listener instance of class org.springframework.web.context.ContextLoaderListener
 org.springframework.beans.factory.BeanDefinitionStoreException: Unexpected exception parsing XML document from file [/home/userid/apache-tomcat-8.0.8/webapps/myApplication-QA/WEB-INF/classes/config/spring/securityContext.xml]; nested exception is **java.lang.IllegalStateException: Context namespace element 'annotation-config' and its parser class [org.springframework.context.annotation.AnnotationConfigBeanDefinitionParser] are only available on JDK 1.5 and higher**
    at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.doLoadBeanDefinitions(XmlBeanDefinitionReader.java:420)
    at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.loadBeanDefinitions(XmlBeanDefinitionReader.java:342)
    at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.loadBeanDefinitions(XmlBeanDefinitionReader.java:310)
    at org.springframework.beans.factory.support.AbstractBeanDefinitionReader.loadBeanDefinitions(AbstractBeanDefinitionReader.java:143)
    at org.springframework.beans.factory.support.AbstractBeanDefinitionReader.loadBeanDefinitions(AbstractBeanDefinitionReader.java:178)
    at org.springframework.beans.factory.support.AbstractBeanDefinitionReader.loadBeanDefinitions(AbstractBeanDefinitionReader.java:149)
    at org.springframework.web.context.support.XmlWebApplicationContext.loadBeanDefinitions(XmlWebApplicationContext.java:124)
    at org.springframework.web.context.support.XmlWebApplicationContext.loadBeanDefinitions(XmlWebApplicationContext.java:92)
    at org.springframework.context.support.AbstractRefreshableApplicationContext.refreshBeanFactory(AbstractRefreshableApplicationContext.java:123)
    at org.springframework.context.support.AbstractApplicationContext.obtainFreshBeanFactory(AbstractApplicationContext.java:423)
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:353)
    at org.springframework.web.context.ContextLoader.createWebApplicationContext(ContextLoader.java:255)
    at org.springframework.web.context.ContextLoader.initWebApplicationContext(ContextLoader.java:199)
    at org.springframework.web.context.ContextLoaderListener.contextInitialized(ContextLoaderListener.java:45)
    at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:4750)
    at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5170)
    at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150)
    at org.apache.catalina.manager.ManagerServlet.start(ManagerServlet.java:1270)
    at org.apache.catalina.manager.HTMLManagerServlet.start(HTMLManagerServlet.java:673)
    at org.apache.catalina.manager.HTMLManagerServlet.doPost(HTMLManagerServlet.java:221)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:644)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:725)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:301)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
    at org.apache.catalina.filters.CsrfPreventionFilter.doFilter(CsrfPreventionFilter.java:213)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
    at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
    at org.apache.catalina.filters.SetCharacterEncodingFilter.doFilter(SetCharacterEncodingFilter.java:108)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:219)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:106)
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:615)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:136)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:78)
    at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:610)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:88)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:526)
    at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1033)
    at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:652)
    at org.apache.coyote.http11.Http11NioProtocol$Http11ConnectionHandler.process(Http11NioProtocol.java:222)
    at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1566)
    at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.run(NioEndpoint.java:1523)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
    at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
    at java.lang.Thread.run(Unknown Source)
Caused by: java.lang.IllegalStateException: Context namespace element 'annotation-config' and its parser class [org.springframework.context.annotation.AnnotationConfigBeanDefinitionParser] are only available on JDK 1.5 and higher
    at org.springframework.context.config.ContextNamespaceHandler$1.parse(ContextNamespaceHandler.java:65)
    at org.springframework.beans.factory.xml.NamespaceHandlerSupport.parse(NamespaceHandlerSupport.java:69)
    at org.springframework.beans.factory.xml.BeanDefinitionParserDelegate.parseCustomElement(BeanDefinitionParserDelegate.java:1253)
    at org.springframework.beans.factory.xml.BeanDefinitionParserDelegate.parseCustomElement(BeanDefinitionParserDelegate.java:1243)
    at org.springframework.beans.factory.xml.DefaultBeanDefinitionDocumentReader.parseBeanDefinitions(DefaultBeanDefinitionDocumentReader.java:135)
    at org.springframework.beans.factory.xml.DefaultBeanDefinitionDocumentReader.registerBeanDefinitions(DefaultBeanDefinitionDocumentReader.java:92)
    at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.registerBeanDefinitions(XmlBeanDefinitionReader.java:507)
    at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.doLoadBeanDefinitions(XmlBeanDefinitionReader.java:398)
    ... 49 more

22-May-2014 11:34:54.518 INFO [http-nio-8080-exec-4] org.apache.catalina.core.ApplicationContext.log Closing Spring root WebApplicationContext

1
尝试在 setenv.sh 中设置:JAVA_HOME=/home/userid/jdk1.8.0_05 - Andrei Stefan
1
谢谢Stefan,我尝试了那个方法,但还是没有成功。 顺便说一下:在Tomcat启动时,我得到了以下信息。 bash startup.sh 使用CATALINA_BASE:/home/userid/apache-tomcat-8.0.8 使用CATALINA_HOME:/home/userid/apache-tomcat-8.0.8 使用CATALINA_TMPDIR:/home/userid/apache-tomcat-8.0.8/temp 使用JRE_HOME:/home/userid/jdk1.8.0_05 使用CLASSPATH:/home/userid/apache-tomcat-8.0.8/bin/bootstrap.jar:/home/userid/apache-tomcat-8.0.8/bin/tomcat-juli.jar 使用CATALINA_PID:/home/userid/apache-tomcat-8.0.8/tomcat.pid Tomcat已启动。 - user3665944
你正在使用Spring 2.5吗? - Andrei Stefan
是的,这是一个旧应用程序。 - user3665944
1
@AndreiStefan请将jdk1.8替换为jdk 5、6或7。感谢您指引我正确的方向。我遇到了这个问题,因为我在同一台机器上运行了两个应用程序——一个需要java 8,另一个是依赖于spring 2.5的旧应用程序。 - eigil
11个回答

144

抛出异常的类正在使用此代码检查 Java 版本:

static {
        javaVersion = System.getProperty("java.version");
        // version String should look like "1.4.2_10"
        if (javaVersion.indexOf("1.7.") != -1) {
            majorJavaVersion = JAVA_17;
        }
        else if (javaVersion.indexOf("1.6.") != -1) {
            majorJavaVersion = JAVA_16;
        }
        else if (javaVersion.indexOf("1.5.") != -1) {
            majorJavaVersion = JAVA_15;
        }
        else {
            // else leave 1.4 as default (it's either 1.4 or unknown)
            majorJavaVersion = JAVA_14;
        }
    }

因此,当Spring 2.5首次发布时,代码并没有假设它会在Java版本1.7之后运行。对于Java 8及更高版本,上面的代码将假定默认版本为1.4。因此,注释部分将会报错。

我认为您需要升级Spring版本或使用Java 7。Spring 2.5已经很久以前被EOL了


3
Stefan,就这样了。 我下载了JRE 1.7,一切正常。 感谢你的帮助。 Robert - user3665944
1
似乎在Spring >= 3.2.3中添加了对Java 8的支持。请参阅JdkVersion.class中的code change - djule5
1
哎呀,这个解决方案比我想象中的简单。谢谢! - Pieter De Bie
这个帮了我省下了很多麻烦,谢谢! - Richard H

20

我有类似的问题。旧的Spring MVC/Spring Faces应用程序在spring 2.5.5下无法在Java 8上运行。

我花了几天时间试图找到解决方案,因为我们需要运行Java 8。

第一个想法是:将完整的Spring包升级到4.1.6。我使用了Maven。这种方法的问题在于,之后必须重新编写几乎整个项目。这是因为例如在Spring 4中删除了JSF实现和一些特殊的标签库,比如<sf:..>。还有一些更重要和次要的配置、适配器、处理程序、映射等问题。

第二种方法是部分替换Spring JARs。一个接一个地替换,但仍然没有成功。任何jar都不可能被替换而不触及依赖关系。

我相信,在几周或几个月的努力后,我可以在这两种方法上获得成功。但是我没有那么多时间。所以我放弃了。

我的解决方案是:

我找到了来自org.springframework.core包的源文件JdkVersion.java。http://www.java2s.com/Code/Jar/o/Downloadorgspringframeworkcoresources300releasejar.htm。我在我的项目中创建了org.springframework.core包,只有一个类JdkVersion。之后,对代码进行了简单的更改以检查Java 8版本。像这样:

public static final int JAVA_18 = 5;

...

        javaVersion = System.getProperty("java.version");
    // version String should look like "1.4.2_10"
    if (javaVersion.contains("1.8.")) {
        majorJavaVersion = JAVA_18;         
        System.out.println("JAVA_VERSION: "+javaVersion);

    } else if (javaVersion.contains("1.7.")) {
        majorJavaVersion = JAVA_17;
    }

即使这个代码变更并不是真正必要的,只是为了好玩而已。这是因为这个源码来自Spring 3.0.0包,其中Spring的开发人员已经更改了Java版本检查。高于7的版本不再被视为旧版Java。

现在应用程序可以正常启动。它从我的项目中调用JdkVersion类,而不是jar文件。

到目前为止一切都很顺利!感谢本帖中提出这个想法的所有人。

谢谢!


1
我已经将这种方法应用到我的项目中,该项目包含多个模块/子项目。所以我在服务器目录上搜索了spring-xxx-version.jar(我正在使用tomcat)。我将一个包含Java 8检查的JdkVersion.class文件添加到spring-xxx-version.jar中,并重新启动了服务器。这解决了我的问题。 - pushya
1
这也很好,你只是修补了原始的Spring Jars。无论如何,这个版本的Spring已经停止服务了。 - Dmitry

16

我需要在Java 8上支持Spring 2.5.5,因此我使用这个答案中的方法,尽可能少地产生副作用提供了一个未来兼容的替代JdkVersion.class的解决方案(没有其他人发布完整的类,我也不想劫持其他答案)。无需检查Java 8,只需默认为Java 7,这是该类关心的最高版本:

提取jar文件:

mkdir spring
cd spring
jar xvf ../spring.jar

检查 META-INF/MANIFEST.MF 中的 Spring 版本(应该会看到像 version=2.5.5 这样的内容)。查找相应版本的 JdkVersion.java 并以此作为起点(下面的示例是针对 Spring 2.5.5 的,您不想更改任何与您正在使用的版本不同的方法签名)。

检查 JdkVersion.class 文件的主要和次要版本:

javap -verbose org/springframework/core/JdkVersion.class

我们看到该类最初是编译为目标48.0查找,发现这是 Java 1.4):

Classfile /tmp/spring/org/springframework/core/JdkVersion.class
  Last modified Jun 23, 2008; size 1286 bytes
  MD5 checksum 98e6ea08ce9186c50cc71d14465fc3dd
  Compiled from "JdkVersion.java"
public abstract class org.springframework.core.JdkVersion
  minor version: 0
  major version: 48
  flags: ACC_PUBLIC, ACC_SUPER, ACC_ABSTRACT
Constant pool:
...

创建org/springframework/core/JdkVersion.java,其内容如下:

package org.springframework.core;

public abstract class JdkVersion
{
    public static final int JAVA_13 = 0;
    public static final int JAVA_14 = 1;
    public static final int JAVA_15 = 2;
    public static final int JAVA_16 = 3;
    public static final int JAVA_17 = 4;

    private static final String javaVersion;
    private static final int majorJavaVersion;

    static
    {
        javaVersion = System.getProperty("java.version");

        if (javaVersion.indexOf("1.7.") != -1)
        {
            majorJavaVersion = JAVA_17;
        } else if (javaVersion.indexOf("1.6.") != -1) {
            majorJavaVersion = JAVA_16;
        } else if (javaVersion.indexOf("1.5.") != -1) {
            majorJavaVersion = JAVA_15;
        } else if (javaVersion.indexOf("1.4.") != -1) { // new
            majorJavaVersion = JAVA_14;                 // new
        } else {
            majorJavaVersion = JAVA_17;                 // changed from JAVA_14
        }
    }

    public static String getJavaVersion()
    {
        return javaVersion;
    }

    public static int getMajorJavaVersion()
    {
        return majorJavaVersion;
    }

    public static boolean isAtLeastJava14()
    {
        return true;
    }

    public static boolean isAtLeastJava15()
    {
        return getMajorJavaVersion() >= JAVA_15;
    }

    public static boolean isAtLeastJava16()
    {
        return getMajorJavaVersion() >= JAVA_16;
    }
}

然后将新的类编译为Java 1.4:

javac -source 1.4 org/springframework/core/JdkVersion.java

如有需要,您可以再次按上述方法检查主要和次要版本号。

创建修改后的JAR文件(不覆盖原始清单):

jar Mcf ../spring-modified.jar *

将修改后的JAR文件复制到需要的位置(如spring.jar或适当的位置)。


@SunilShevante 没问题,很高兴能帮助到你! - Parker

10
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring</artifactId>
<version>2.5.6</version>

=>

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-core</artifactId>
    <version>4.1.4.RELEASE</version>
</dependency>
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-context</artifactId>
    <version>4.1.4.RELEASE</version>
</dependency>

或者

  1. 右键单击项目属性。
  2. 转到/单击“Java构建路径”。
  3. 选择库选项卡,双击“JRE系统库”
  4. 在弹出窗口中选择JDK 1.7(如果您没有JDK 1.7,请先安装它,然后从“执行环境”中选择它)

Property


5
我有同样的问题,但我有解决方案:
在你的项目文件pom.xml中替换以下内容:
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring</artifactId>
    <version>2.5.6</version>
</dependency>

为:
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-core</artifactId>
    <version>4.1.4.RELEASE</version>
</dependency>

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-context</artifactId>
    <version>4.1.4.RELEASE</version>
</dependency>

“和告别你的问题吧!!”
“这两个依赖项在很大程度上可以替代第一个依赖项。”

3

我恰巧也是另一个不幸的用户,使用一个非常旧的项目(在2008年开发!),它仍然使用Spring 2.5。而且这也不是一个Maven项目,因此升级到后来的Spring版本需要很长时间,依赖会失败并出现构建错误。我将Tomcat JRE降级为1.7,就可以正常工作了。

只是记录如何在eclipse中操作,以防有人需要帮助:

  1. 如果您还没有Java 7,请下载JDK 7并将其安装在某个地方,例如C:\Program Files\Java\jdk1.7.0_71

  2. 然后转到eclipse,并双击Servers > Tomcat vX.Y server

  3. 单击Runtime Environment,然后单击Installed JREs

  4. 然后选择Add > Standard VM并单击Next。你会看到一个窗口像这样:

    Adding a new JRE

  5. 单击“Directory ...”并浏览到安装JDK的文件夹(即C:\Program Files\Java\jdk1.7.0_71。JDK就行了,不需要JRE)。单击Finish

  6. 然后确保选择Java 7的JRE即可。


3

将您的Spring版本从2.5迁移到>=3.2.3。

对于Spring迁移,您需要进行以下更改 -

1)在您的pom.xml中删除spring 2.5.6的依赖项,并添加新版本的spring依赖项。

2)更新应用程序contet.xml文件中beans标签中的“xsi:schemaLocation”。

例如,将http://www.springframework.org/schema/beans/spring-beans-2.5.xsd更新为http://www.springframework.org/schema/beans/spring-beans-3.2.xsd以获取Spring 3.2.3版本。

3)清理,构建和重新部署您的项目。


2
尽管这个问题已经被完美回答了,但在某些情况下,升级Java版本或Spring版本是不可取或不可能的。在我们的情况下,我们必须使用JDK 8才能与Sonar(从Jenkins)通信,而且我们不想改变spring版本,因为我们没有测试能力来测试这个升级。我们的解决方案是在构建时简单地覆盖Java版本,使用:
-Djava.version=1.6.45

2
我创建了一个完全自动化版本的这个答案。请先阅读那篇文章,了解他所提到的细节。
  • 创建一个包含以下内容的ant构建文件
  • spring.jar复制到build.xml文件旁边
  • 运行补丁目标
  • 完成了,文件已经打了补丁

build.xml文件内容:

<project name="spring-patch" default="patch">
    <target name="patch">
        <mkdir dir="src/org/springframework/core"/>
        <get dest="src/org/springframework/core/JdkVersion.java"
                src="http://grepcode.com/file_/repo1.maven.org/maven2/org.springframework/spring/2.5.5/org/springframework/core/JdkVersion.java/?v=source&amp;disposition=attachment" />
        <replace dir="src" value="majorJavaVersion = JAVA_17">
          <replacetoken>majorJavaVersion = JAVA_14</replacetoken>
        </replace>
        <javac srcdir="src" />
        <zip destfile="spring.jar" update="true">
            <fileset dir="src" includes="**/*.class" />
        </zip>
        <delete dir="src" />
    </target>
</project>

2

我遇到了同样的问题,但是经过很多尝试,我发现这是由于使用了Java 1.8造成的。我将它更改为1.6后问题得以解决。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接