2017-04-12 84 views
0

我知道这是一个非常远景,但我一直试图弄清楚已经有两个星期了,所以任何指向正确方向的想法都可能是无价的。XmlBeans.Factory解析方法不一致ClassCastException

所以,我有一个使用XmlBeans的非常旧的应用程序。我的任务是从Tomcat 7.0.67迁移到Tomcat 8.5.11,引入Spring Sessions和Spring Security,而不是基于Realm的认证。在迁移之前,所有工作都在本地(MacOS,Oracle JDK 8)和Heroku(Ubuntu,OpenJDK 8)上正常工作,但迁移后一切工作在我的本地环境上,但在Heroku上,有时,当应用程序试图解析字符串到适当的XMLBean,出现这种ClassCastException异常:

java.lang.ClassCastException: foo.bar.2.impl.PreferencesDocumentImpl cannot be cast to foo.bar.1.PreferencesDocument 
    at foo.bar.1.PreferencesDocument$Factory.parse(Unknown Source) 

我有两个自动生成的XMLBeans类,它从两个XSD的模式产生的,没有任何的命名空间集中。类共享名称,但位于不同的包(其中发生异常时位于工厂内部类的解析方法,省略其他方法):

/* 
* An XML document type. 
* Localname: Preferences 
* Namespace: 
* Java type: foo.bar.1.PreferencesDocument 
* 
* Automatically generated - do not modify. 
*/ 
package foo.bar.1; 

public interface PreferencesDocument extends org.apache.xmlbeans.XmlObject { 
    public static final org.apache.xmlbeans.SchemaType type = (org.apache.xmlbeans.SchemaType) 
     org.apache.xmlbeans.XmlBeans.typeSystemForClassLoader(PreferencesDocument.class.getClassLoader(), "schemaorg_apache_xmlbeans.system.s2D5798E4F4AFDA8394735C8512CDCBC7").resolveHandle("preferencesa8bfdoctype"); 

    public static final class Factory { 
     public static foo.bar.1.PreferencesDocument parse(java.lang.String xmlAsString) throws org.apache.xmlbeans.XmlException { 
      return (foo.bar.PreferencesDocument) org.apache.xmlbeans.XmlBeans.getContextTypeLoader().parse(xmlAsString, type, null); 
     } 
    } 
} 

/* 
* An XML document type. 
* Localname: Preferences 
* Namespace: 
* Java type: foo.bar.1.PreferencesDocument 
* 
* Automatically generated - do not modify. 
*/ 
package foo.bar.1.impl; 

public class PreferencesDocumentImpl extends org.apache.xmlbeans.impl.values.XmlComplexContentImpl implements foo.bar.1.PreferencesDocument { 
    public PreferencesDocumentImpl(org.apache.xmlbeans.SchemaType sType) { 
     super(sType); 
    } 

    private static final javax.xml.namespace.QName PREFERENCES$0 = new javax.xml.namespace.QName("", "Preferences"); 
} 

/* 
* An XML document type. 
* Localname: Preferences 
* Namespace: 
* Java type: foo.bar.2.PreferencesDocument 
* 
* Automatically generated - do not modify. 
*/ 
package foo.bar.2; 

public interface PreferencesDocument extends org.apache.xmlbeans.XmlObject { 
    public static final org.apache.xmlbeans.SchemaType type = (org.apache.xmlbeans.SchemaType) 
     org.apache.xmlbeans.XmlBeans.typeSystemForClassLoader(PreferencesDocument.class.getClassLoader(), "schemaorg_apache_xmlbeans.system.sC8953008EC716AA258D3951B84AB1CB7").resolveHandle("preferencesa8bfdoctype"); 

    public static final class Factory { 
     public static foo.bar.2.PreferencesDocument parse(java.lang.String xmlAsString) throws org.apache.xmlbeans.XmlException { 
      return (foo.bar.2.PreferencesDocument) org.apache.xmlbeans.XmlBeans.getContextTypeLoader().parse(xmlAsString, type, null); } 

    } 
} 

/* 
* An XML document type. 
* Localname: Preferences 
* Namespace: 
* Java type: foo.bar.2.PreferencesDocument 
* 
* Automatically generated - do not modify. 
*/ 
package foo.bar.2.impl; 

public class PreferencesDocumentImpl extends org.apache.xmlbeans.impl.values.XmlComplexContentImpl implements foo.bar.2.PreferencesDocument { 

    public PreferencesDocumentImpl(org.apache.xmlbeans.SchemaType sType) { 
     super(sType); 
    } 

    private static final javax.xml.namespace.QName PREFERENCES$0 = 
     new javax.xml.namespace.QName("", "Preferences"); 
    } 
} 

有时候,部署到Heroku的应用程序重新启动时,问题不复存在,但在重新启动后又回来了。

根据this,根本原因是没有导致碰撞的名称空间。但由于我们的要求,我无法添加或更改xsds的命名空间。那么你有什么想法,为什么它在Tomcat 7本地工作,Tomcat 8本地工作,Tomcat 7 Heroku工作,但在Tomcat 8 Heroku上无法工作?

在此先感谢。

回答

0

它适用于Tomcat 7,因为this

之前的Tomcat 8 Tomcat的ClassLoader按字母顺序加载资源。我们的应用程序只是因为这个。

它在Tomcat 8 + MacOS本地工作,因为Tomcat 8的类加载器按照OS提供的顺序加载资源,在OSX的情况下,它似乎是有序的。

0

我怀疑问题的不可预测性(即有时在重新启动后确实或不会发生)是由于JVM类加载器的非确定性本质。如果你有同一个类的两个不同版本,它们将以非确定性顺序加载。

在这种情况下,这听起来像你有两个不同的类具有相同的名称(我是否正确?)。即使它们是自动生成的,只有一个会获胜。

我认为你必须找到一种方法给这些类不同的名称(或包)。

+0

这些类确实有不同的包,只有名称相同,以及xsd名称空间(实际上没有)。 –