tomcat XmlBeans.Factory解析方法的ClassCastException不一致

iklwldmw  于 2022-11-13  发布在  其他
关注(0)|答案(3)|浏览(169)

我知道这是一个非常长的机会,但我一直试图弄清楚像两个星期已经,所以任何想法指向正确的方向可能是无价的。
我的任务是从Tomcat 7.0.67迁移到Tomcat 8.5.11,引入Spring会话和Spring安全性,而不是基于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-schema生成的,没有任何命名空间集。类共享名称,但位于不同的包中(发生异常的parse方法位于Factory内部类中,其他方法被省略):

/*
 * 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本地工作,在Heroku上用Tomcat 7工作,但在Heroku上用Tomcat 8不工作吗?
先谢谢你。

yeotifhr

yeotifhr1#

因此,它可以在Tomcat 7上运行。
在Tomcat 8之前,Tomcat的ClassLoader是按字母顺序加载资源的,我们的应用程序正是因为这样才能正常工作。
它在Tomcat 8 + MacOS上本地工作,因为Tomcat 8的类加载器按照OS提供的顺序加载资源,在OSX的情况下,似乎是有序的。

nkhmeac6

nkhmeac62#

此答案也出现在以下错误类别的顶部,因此我在此处添加我的答案:

class org.apache.xmlbeans.impl.values.XmlComplexContentImpl cannot be cast to class <class you generated a schema from>

这是一个非常奇怪的错误,毕竟为什么会发生这种情况呢?无论如何,这是因为我使用maven-shade-plugin minimizeJar功能,它删除了一些东西(我还不知道是什么),如果我弄清楚我到底需要明确地重新添加什么,我会更新这个答案,但现在我只是禁用了minimizeJar。
它似乎删除了模式生成代码的impl部分。
更新:如果你想继续使用minimizeJar,请将此添加到着色插件的过滤器部分:

<filter>                                    
    <artifact>org.apache.xmlbeans:xmlbeans</artifact>
    <includes>
        <include>**</include>
    </includes>
</filter>

更新2:似乎上面的并不总是起作用,我很困惑这里的新问题是什么,但仍然有一点,minimizeJar是非常不稳定的w.r.t依赖关系

ss2ws0br

ss2ws0br3#

我怀疑这个问题的不可预测性(即,有时在重新启动后会发生或不会发生)是由于JVM类加载器的不确定性。如果您有同一个类的两个不同版本,它们将以不确定的顺序加载。
在这种情况下,听起来像是有两个同名的不同类(我说的对吗?)。即使它们是自动生成的,也只有一个会获胜。
我认为您必须找到一种方法来为类指定不同的名称(或包)。

相关问题