如何从未签名的applet中使用JAXB(不签名)?

时间:2010-01-18 07:08:34

标签: applet jaxb xstream gson

我想在未签名的Applet中将Java对象编组为XML,反之亦然,我无法更改任何安全权限/策略文件或签署应用程序。

我似乎得到了一个安全性异常,因为JAXB试图访问它不能在applet沙箱中的字段或构造函数。

浏览器正在运行JRE 1.6.0_17

我也对基于其他XML(或JSON)库的解决方案持开放态度,但尝试了以下内容并且几乎遇到了类似的问题;   - XStream   - Gson

给出(类似)以下对象:

@XmlType
@XmlRootElement
public class SimpleObject {

    public String sampleText;

    public SimpleObject() {
    }

    public String getSampleText() {
        return sampleText;
    }

    public void setSampleText(String sampleText) {
        this.sampleText = sampleText;
    }
}

以下简单的JAXB代码:

public void actionPerformed(ActionEvent e) {
    try {
        JAXBContext jc = JAXBContext.newInstance(SimpleObject.class);
        Marshaller marshaller = jc.createMarshaller();
        marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);

        SimpleObject object = new SimpleObject();
        object.setSampleText("Hello");

        marshaller.marshal(object, System.out);
    }
    catch (JAXBException e1) {
        throw new RuntimeException(e1);
    }
}

我得到以下异常:

Exception in thread "AWT-EventQueue-2" java.security.AccessControlException: access denied (java.lang.RuntimePermission accessDeclaredMembers)
    at java.security.AccessControlContext.checkPermission(Unknown Source)
    at java.security.AccessController.checkPermission(Unknown Source)
    at java.lang.SecurityManager.checkPermission(Unknown Source)
    at java.lang.SecurityManager.checkMemberAccess(Unknown Source)
    at java.lang.Class.checkMemberAccess(Unknown Source)
    at java.lang.Class.getDeclaredConstructor(Unknown Source)
    at com.sun.xml.internal.bind.v2.model.nav.ReflectionNavigator.hasDefaultConstructor(Unknown Source)
    at com.sun.xml.internal.bind.v2.model.nav.ReflectionNavigator.hasDefaultConstructor(Unknown Source)
    at com.sun.xml.internal.bind.v2.model.impl.ClassInfoImpl.<init>(Unknown Source)
    at com.sun.xml.internal.bind.v2.model.impl.RuntimeClassInfoImpl.<init>(Unknown Source)
    at com.sun.xml.internal.bind.v2.model.impl.RuntimeModelBuilder.createClassInfo(Unknown Source)
    at com.sun.xml.internal.bind.v2.model.impl.RuntimeModelBuilder.createClassInfo(Unknown Source)
    at com.sun.xml.internal.bind.v2.model.impl.ModelBuilder.getClassInfo(Unknown Source)
    at com.sun.xml.internal.bind.v2.model.impl.RuntimeModelBuilder.getClassInfo(Unknown Source)
    at com.sun.xml.internal.bind.v2.model.impl.RuntimeModelBuilder.getClassInfo(Unknown Source)
    at com.sun.xml.internal.bind.v2.model.impl.ModelBuilder.getClassInfo(Unknown Source)
    at com.sun.xml.internal.bind.v2.model.impl.RuntimeModelBuilder.getClassInfo(Unknown Source)
    at com.sun.xml.internal.bind.v2.model.impl.RuntimeModelBuilder.getClassInfo(Unknown Source)
    at com.sun.xml.internal.bind.v2.model.impl.ModelBuilder.getTypeInfo(Unknown Source)
    at com.sun.xml.internal.bind.v2.model.impl.ModelBuilder.getTypeInfo(Unknown Source)
    at com.sun.xml.internal.bind.v2.runtime.JAXBContextImpl.getTypeInfoSet(Unknown Source)
    at com.sun.xml.internal.bind.v2.runtime.JAXBContextImpl.<init>(Unknown Source)
    at com.sun.xml.internal.bind.v2.runtime.JAXBContextImpl$JAXBContextBuilder.build(Unknown Source)
    at com.sun.xml.internal.bind.v2.ContextFactory.createContext(Unknown Source)
    at com.sun.xml.internal.bind.v2.ContextFactory.createContext(Unknown Source)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    at java.lang.reflect.Method.invoke(Unknown Source)
    at javax.xml.bind.ContextFinder.newInstance(Unknown Source)
    at javax.xml.bind.ContextFinder.find(Unknown Source)
    at javax.xml.bind.JAXBContext.newInstance(Unknown Source)
    at javax.xml.bind.JAXBContext.newInstance(Unknown Source)
    at nz.co.zeal.maker.application.actions.build.JAXBTestAction.actionPerformed(JAXBTestAction.java:24)
    at javax.swing.AbstractButton.fireActionPerformed(Unknown Source)
    at javax.swing.AbstractButton$Handler.actionPerformed(Unknown Source)
    at javax.swing.DefaultButtonModel.fireActionPerformed(Unknown Source)
    at javax.swing.DefaultButtonModel.setPressed(Unknown Source)
    at javax.swing.AbstractButton.doClick(Unknown Source)
    at javax.swing.plaf.basic.BasicMenuItemUI.doClick(Unknown Source)
    at javax.swing.plaf.basic.BasicMenuItemUI$Handler.mouseReleased(Unknown Source)
    at java.awt.Component.processMouseEvent(Unknown Source)
    at javax.swing.JComponent.processMouseEvent(Unknown Source)
    at java.awt.Component.processEvent(Unknown Source)
    at java.awt.Container.processEvent(Unknown Source)
    at java.awt.Component.dispatchEventImpl(Unknown Source)
    at java.awt.Container.dispatchEventImpl(Unknown Source)
    at java.awt.Component.dispatchEvent(Unknown Source)
    at java.awt.LightweightDispatcher.retargetMouseEvent(Unknown Source)
    at java.awt.LightweightDispatcher.processMouseEvent(Unknown Source)
    at java.awt.LightweightDispatcher.dispatchEvent(Unknown Source)
    at java.awt.Container.dispatchEventImpl(Unknown Source)
    at java.awt.Component.dispatchEvent(Unknown Source)
    at java.awt.EventQueue.dispatchEvent(Unknown Source)
    at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)
    at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
    at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
    at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
    at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
    at java.awt.EventDispatchThread.run(Unknown Source)

3 个答案:

答案 0 :(得分:2)

我从来没有把这一点弄清楚。我所做的是获取一个名为Flexjson的相当简单的JSON库。它也引发了类似的安全异常,但是库很简单,我能够关闭导致带有布尔标志的Applet中的异常的库代码。

答案 1 :(得分:0)

我也尝试使用JAXB找到解决方案但没有任何成功。

我使用ADB绑定切换到Axis2(1.5.4),但它也尝试访问因安全管理器检查而失败的系统属性。

最后,我通过使用AspectJ和使用重写System.getProperty()调用的方面一起得到了一个可行的解决方案,以便在它们失败时返回null。由于Axis2所需的所有属性都是非关键的,无论如何这都有效。我还需要在org.apache.axiom.util.stax.dialect.StAXDialectDetector.getRootUrlForResource()上应用一个方面来始终返回null,因为它试图在安全管理器下进行ClassLoader.getSystemClassLoader()调用。这似乎是一个非关键的电话。让AspectJ在构建时重写Axis2类,它作为一个未签名的applet运行。

这是一个非常混乱的解决方案,但至少它起作用了。

我无法使用与JAXB相同的AspectJ hack,因为JAXB需要直接访问类的私有字段,如果JAXB与applet捆绑在一起,则不会在安全管理器下运行(如果是AspectJ,我们需要这样做)用于重写类。)

答案 2 :(得分:0)

这可以解决您的问题。我知道它解决了我的问题:)。

public void actionPerformed(ActionEvent e) {
    try {
    JAXBContext jc = AccessController.doPrivileged(new PrivilegedExceptionAction<JAXBContext>() {

        public JAXBContext run() throws JAXBException {

            // needs to run here otherwise throws AccessControlException
            return JAXBContext.newInstance(SimpleObject.class);
        }
    });         
        Marshaller marshaller = jc.createMarshaller();
        marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);

        SimpleObject object = new SimpleObject();
        object.setSampleText("Hello");

        marshaller.marshal(object, System.out);
    }
    catch (JAXBException e1) {
        throw new RuntimeException(e1);
    }
    } catch (PrivilegedActionException e2) {
    throw new RuntimeException(e2);
    }
}

希望有所帮助