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名稱空間(實際上沒有)。 –