2

MoxyのXMLメタデータ拡張機能を使用して以下のインターフェースをマッピングしようとしています。しかし、ロードしようとすると、以下のエラーが発生します。AddressType列挙型であるため、パブリックコンストラクターをに追加できません。

私の質問はAddressType、xmlメタデータで指定しなかったのに、なぜMoxy implが見ているのですか?

public interface TokenizedUnitedStatesAddress
{
    class AddressType extends Enum
    {
        public static final AddressType STREET = new AddressType("street");    
        public static final AddressType PO_BOX = new AddressType("poBox");    
        public static final AddressType RURAL_ROUTE = new AddressType("ruralRoute");

        public static AddressType getEnum(final String type)
        {
            return (AddressType) getEnum(AddressType.class, type);
        }

        protected AddressType(final String name)
        {
            super(name);
        }
    }

    String getApartmentNumber();

    //removed other getters for brevity
}

<xml-bindings xmlns="http://www.eclipse.org/eclipselink/xsds/persistence/oxm" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   xsi:schemaLocation="http://www.eclipse.org/eclipselink/xsds/persistence/oxm http://www.eclipse.org/eclipselink/xsds/eclipselink_oxm_2_4.xsd"
   version="2.4" package-name="com.abc.ic.domain.country.us">
   <java-types>
      <java-type name="TokenizedUnitedStatesAddress">
         <xml-root-element />
         <xml-type
            prop-order="StreetPreDirection StreetNumber StreetName StreetType StreetPostDirection UnitDesignator UnitNumber AddressLine1 AddressLine2 City State PostalCode CarrierRoute LengthAtAddress OwnershipStatus" />
         <java-attributes>
            <xml-element name="StreetPreDirection" java-attribute="preDirectional" />
            <xml-element name="StreetNumber" java-attribute="houseNumber" />
            <xml-element name="StreetName" java-attribute="streetName" />
            <xml-element name="StreetType" java-attribute="streetType" />
            <xml-element name="StreetPostDirection" java-attribute="postDirection" />
            <xml-element name="UnitNumber" java-attribute="apartmentNumber" />
            <xml-element name="AddressLine1" java-attribute="primaryAddress" />
            <xml-element name="AddressLine2" java-attribute="secondaryAddress" />
            <xml-element name="City" java-attribute="cityName" />
            <xml-element name="State" java-attribute="stateAbbreviation" />
            <xml-element name="PostalCode" java-attribute="zipCode" />
         </java-attributes>
      </java-type>
   </java-types>
</xml-bindings>

javax.xml.bind.JAXBException: 
Exception Description: The class com.abc.ic.domain.country.us.TokenizedUnitedStatesAddress$AddressType requires a zero argument constructor or a specified factory method.  Note that non-static inner classes do not have zero argument constructors and are not supported.
 - with linked exception:
[Exception [EclipseLink-50001] (Eclipse Persistence Services - 2.4.0.v20120608-r11652): org.eclipse.persistence.exceptions.JAXBException
Exception Description: The class com.abc.ic.domain.country.us.TokenizedUnitedStatesAddress$AddressType requires a zero argument constructor or a specified factory method.  Note that non-static inner classes do not have zero argument constructors and are not supported.]
    at org.eclipse.persistence.jaxb.JAXBContext$TypeMappingInfoInput.createContextState(JAXBContext.java:908)
    at org.eclipse.persistence.jaxb.JAXBContext.<init>(JAXBContext.java:157)
    at org.eclipse.persistence.jaxb.JAXBContextFactory.createContext(JAXBContextFactory.java:170)
    at org.eclipse.persistence.jaxb.JAXBContextFactory.createContext(JAXBContextFactory.java:157)
    at org.eclipse.persistence.jaxb.JAXBContextFactory.createContext(JAXBContextFactory.java:117)
    at org.eclipse.persistence.jaxb.JAXBContextFactory.createContext(JAXBContextFactory.java:107)
4

2 に答える 2

1

Mxoy impl still introspects the class even though XML is used to provide metadata. This is because, by design, the external mapping file is used to augment metadata supplied by annotations.

The issue however is that the commons-land Enum abstraction requires us to have a non-public single argument constructor for the enums. I fixed this issue by adding a public no-arg constructor that initializes a default enum. This is sufficient for my application. I've however created a bug which can be followed here.

Note: I also looked at the foctory-method option of Moxy but it requires an empty arg method as the factory method which is not the case in case of Enum.

于 2012-08-07T15:06:27.930 に答える
0

私はEclipseLinkMOXyチームの開発者であり、この問題を調査してきました。AddressTypeクラスがイントロスペクトされた理由については正しいですが、回避策があるようです。

別の解決策は、次のように、Apache EnumクラスとそのXML(文字列)表現の間で変換できるXmlAdapterを作成することです。

import javax.xml.bind.annotation.adapters.XmlAdapter;

import org.apache.commons.lang.enums.Enum;

import enumbindings.TokenizedUnitedStatesAddress.AddressType;

public class ApacheEnumAdapter extends XmlAdapter<String, Enum> {

    public ApacheEnumAdapter() {
    }

    @Override
    public Enum unmarshal(String s) throws Exception {
        return AddressType.getEnum(s);
    }

    @Override
    public String marshal(Enum e) throws Exception {
        if (null == e) {
            return null;
        }
        return e.getName();
    }

}

次に、次のようにバインディングファイルにアダプタを接続します。

...
<xml-element name="StreetType" java-attribute="streetType">
    <xml-java-type-adapter value="enumbindings.ApacheEnumAdapter" />
</xml-element>
...

入力したバグに関する限り、EclipseLinkは実際にはこの状況で正しく動作しており、Apache Commonsクラスの特別な処理は行わないため、デフォルトの引数なしコンストラクター(またはその他の処理メカニズム)が引き続き必要です。ただし、バグを更新し、Apache列挙型をすぐにサポートするように拡張リクエストに変更し、評価します。

ありがとう、

リック

于 2012-08-07T19:21:05.063 に答える