Rhino脚本中实例化Java泛型类JAXBElement及JAXB编组问题
解决Rhino JavaScript中JAXBElement构造方法不匹配的问题
嘿,我碰到过类似Rhino和JAXB交互的坑,来帮你捋清楚怎么搞定~
首先,你遇到的问题本质是Rhino作为动态语言,在处理Java泛型构造方法时的类型匹配BUG。JAXBElement的构造方法是泛型定义的:
public <T> JAXBElement(QName name, Class<T> declaredType, T value)
Rhino没法自动推断泛型类型,导致它找不到匹配(QName, Class, MyClass)的构造方法——因为它期望的第三个参数是泛型类型T,但Rhino传递的MyClass实例在动态类型系统里没法被正确识别为对应的泛型参数。
下面给你两种可靠的解决办法:
方法一:用反射创建JAXBElement(最兼容)
通过反射直接获取JAXBElement的原始类型构造方法,绕开泛型类型的限制,这是最稳妥的方式:
importPackage(Packages.javax.xml.bind); importPackage(Packages.javax.xml.namespace); importPackage(Packages.java.io); var myObj = new MyClass(); // 你的wsimport生成类 // 1. 获取JAXBElement的构造方法 var jaxbElementClass = Packages.javax.xml.bind.JAXBElement; var constructor = jaxbElementClass.getConstructor( Packages.javax.xml.namespace.QName, java.lang.Class, java.lang.Object ); // 2. 创建QName和JAXBElement实例 var qName = new QName("xxx", "MyClass"); var jaxbElement = constructor.newInstance(qName, myObj.getClass(), myObj); // 3. 完成编组流程 var jaxbContext = JAXBContext.newInstance(myObj.getClass()); var marshaller = jaxbContext.createMarshaller(); marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true); var strWriter = new StringWriter(); marshaller.marshal(jaxbElement, strWriter); // 输出结果 print(strWriter.toString());
这个方法的核心是用反射拿到接受Object作为第三个参数的构造方法,完全避开了Rhino的泛型类型推断问题,在绝大多数Rhino版本里都能正常工作。
方法二:显式转换参数类型(简化版,视Rhino版本而定)
如果你不想用反射,可以尝试把myObj显式转换成java.lang.Object,强制Rhino匹配正确的构造方法:
var qName = new QName("xxx", "MyClass"); // 显式转换为Object类型 var jaxbElement = new JAXBElement(qName, myObj.getClass(), java.lang.Object(myObj));
不过这个方法的兼容性不如反射,某些Rhino版本可能还是会报错,所以优先推荐反射方案。
另外补充一点:你之前用myObj.getClass().getPackage().getName()初始化JAXBContext是可行的,但换成JAXBContext.newInstance(myObj.getClass())会更直接,避免包下其他无关类干扰JAXB的初始化。
内容的提问来源于stack exchange,提问作者TrapII
相关产品推荐
相关产品推荐

