Статические фабричные методы в JAXB MOXy - PullRequest
1 голос
/ 05 ноября 2011

Я определяю статический фабричный метод с помощью:

@XmlType(factoryClass=DummyFactory.class, factoryMethod="createNew")
public abstract MyClass() {
}

Причина, по которой я использую фабричные методы, заключается в том, что MyClass является абстрактным, и способ его получения зависит от определенных аннотаций класса. Эта логика встроена в фабричный метод createNew.

Кроме того, фабричный класс DummyFactory является абстрактным. Насколько я понимаю, фабричные классы не должны предоставлять конструктор по умолчанию, если их фабричный метод является статическим (http://download.oracle.com/javaee/6/api/javax/xml/bind/annotation/XmlType.html).

Это грубое упрощение того, как выглядит класс фабрики:

public abstract class DummyFactory {
    public static MyClass createNew() {
        // code for returning a new instance of MyClass
    }   
}

Однако, когда я пытаюсь разархивировать XML-документ, я получаю следующее исключение:

Exception [EclipseLink-171] (Eclipse Persistence Services - 2.3.0.v20110604-r9504): org.eclipse.persistence.exceptions.DescriptorException
Exception Description: The factory class does not define a public default constructor, or the constructor raised an exception.
Internal Exception: java.lang.InstantiationException

Сначала я подумал, что что-то не правильно понял при объяснении фабричных классов и методов, но потом я попытался с помощью JAXB RI, и это работает нормально. Итак, мой вопрос:

Есть ли способ заставить MOXy работать с абстрактными фабричными классами?

(JAXB RI вызывает у меня другие проблемы, поэтому я бы предпочел не использовать его).

1 Ответ

2 голосов
/ 09 ноября 2011

Благодарим Вас за сообщение об этой проблеме (https://bugs.eclipse.org/362984).). Проблема была исправлена ​​в потоке EclipseLink 2.4 и будет перенесена сегодня (9 ноября 2011 г.) в поток EclipseLink 2.3.2. можете попробовать починить получение ночной загрузки от:

Теперь, если вы указали фабричный класс, используя аннотацию @XmlType, например:

@XmlType(factoryClass=DummyFactory.class, factoryMethod="createNew")
public abstract MyClass() {
}

Поддерживаются следующие типы фабричных классов:

Фабрика со статическими методами

С этим исправлением ошибки, когда MOXy использует фабричный метод для создания экземпляра MyClass, экземпляр DummyFactory не создается.

public abstract class DummyFactory {
    public static MyClass createNew() {
        // code for returning a new instance of MyClass
    }   
}

Фабрика с методами экземпляра

Помимо статических методов, MOXy позволяет вам указывать методы создания на уровне экземпляра. Для этих методов MOXy создаст экземпляр класса фабрики.

public class DummyFactory {
    public MyClass createNew() {
        // code for returning a new instance of MyClass
    }   
}

Эта конфигурация недопустима в JAXB RI, и вы получите следующее исключение:

Exception in thread "main" com.sun.xml.internal.bind.v2.runtime.IllegalAnnotationsException: 1 counts of IllegalAnnotationExceptions
Factory class "forum8022136.DummyFactory" does not have static zero args factory method "createNew".
    this problem is related to the following location:
        at forum8022136.MyClass

    at com.sun.xml.internal.bind.v2.runtime.IllegalAnnotationsException$Builder.check(IllegalAnnotationsException.java:91)
    at com.sun.xml.internal.bind.v2.runtime.JAXBContextImpl.getTypeInfoSet(JAXBContextImpl.java:436)
    at com.sun.xml.internal.bind.v2.runtime.JAXBContextImpl.<init>(JAXBContextImpl.java:277)
    at com.sun.xml.internal.bind.v2.runtime.JAXBContextImpl$JAXBContextBuilder.build(JAXBContextImpl.java:1100)
    at com.sun.xml.internal.bind.v2.ContextFactory.createContext(ContextFactory.java:143)
    at com.sun.xml.internal.bind.v2.ContextFactory.createContext(ContextFactory.java:110)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)
    at javax.xml.bind.ContextFinder.newInstance(ContextFinder.java:202)
    at javax.xml.bind.ContextFinder.find(ContextFinder.java:376)
    at javax.xml.bind.JAXBContext.newInstance(JAXBContext.java:574)
    at javax.xml.bind.JAXBContext.newInstance(JAXBContext.java:522)
    at forum8022136.Demo.main(Demo.java:14)
...