users@jaxb.java.net

Re: [java.lang.InstantiationException] at unmarshal step

From: Raphaël Flores <raf64flo_at_gmail.com>
Date: Thu, 29 Oct 2009 01:04:02 +0100

Hi Dmitry,

I know abstract class can cause some problem, it is for this reason I
give its subclass to JAXBContext as Kohsuke Kawaguchi suggested on this
article:
http://weblogs.java.net/blog/kohsuke/archive/2006/04/why_doesnt_jaxb.html

Adding subclass in parameter made unmarshall of Biosource OK. So why not
with List<Biosource>? But I have to check if Biosource is unmarshalled
only based on ClientBiosource or if the Biosource class is necessary. In
first case, it would change my approach because currently, I need
Biosource class to be abstract because the method getBiosource()
implementation may vary upon the location from where the subclass is
created (client or server side).

If you have another suggestion, let me know. In all case, I'll look for
these checkings tomorrow morning when I'll come back office and I will
let you informed.

Thanks,

Raphaël.


Dmitry a écrit :
> Hello Raphaël,
>
> I think the problem is that you have your Biosource class abstract.
> Either remove "abstract" or add @XmlTransient in it.
>
> Cheers,
>
> D.
>
> Raphaël Flores wrote:
>> Hi,
>>
>> I come back this evening with a linked problem. I resolved the above
>> one by setting the class to unmarshal AND its inherited class in
>> JAXBContext.newInstance() parameters like :
>> JAXBContext.newInstance(clazz, subClazz);
>>
>> My problem now concerns the case when I use a object collection class
>> (named BiosourceList) to unmarshall. Here is the BisourceList class :
>> =====================
>> @XmlRootElement(name="biosources")
>> @XmlAccessorType(XmlAccessType.FIELD)
>> public class BiosourcesList {
>> @XmlElement(name = "biosource")
>> private List<Biosource> biosource = new ArrayList<Biosource>();
>>
>> public BiosourcesList() {
>> }
>>
>> public BiosourcesList(List<Biosource> biosources) {
>> this.biosource = biosources;
>> } // getter and setter
>> // ...
>> }
>> =====================
>>
>>
>> The Biosource class contains mainly:
>> =====================
>> @XmlRootElement(name = "biosource")
>> @XmlAccessorType(XmlAccessType.FIELD)
>> public abstract class Biosource extends ProticObject {
>> protected String biosourceName;
>> protected Date sowingDate;
>> protected String remark;
>> protected Long startingMaterialTermId;
>> protected boolean isPrivate;
>>
>> public Biosource() {
>> }
>> // getters and setters...
>> =====================
>>
>>
>> And the ClientBiosource class is currently empty but I need to have
>> it extending Biosource for other stuff:
>> =====================
>> @XmlRootElement(name = "biosource")
>> public class ClientBiosource extends Biosource {
>> public ClientBiosource() {
>> }
>> }
>> =====================
>>
>>
>> The ProticObject class contains few integer fields which need to be
>> marshalled too, no jaxb annotation here.
>> I try to unmarshal my stream as follows :
>> =====================
>> JAXBContext jc = JAXBContext.newInstance(collectionClazz,
>> subClazz); //collectionClazz is BiosourceList.class, clazz is
>> Biosource.class, and subClazz. is ClientBiosource.class
>> Unmarshaller u = jc.createUnmarshaller();
>>
>> Object object = (Object) u.unmarshal(inputStream);
>> =====================
>>
>>
>> The exception occurs on last line at unmarshal step, it says :
>> Unable to create an instance of
>> main.java.fr.inra.moulon.proticport.model.entities.Biosource
>>
>> The XML inputStream generated by CXF with Jaxb is like this:
>> =====================
>> <biosources>
>> <biosource>
>> <dbId>123</dbId>
>> <logId>1525</logId>
>> <projectId>127</projectId>
>> <biosourceName>MUTANTS 07</biosourceName>
>> <sowingDate>1970-01-01T00:00:00+01:00</sowingDate>
>> <remark>N.R. </remark>
>> <isPrivate>false</isPrivate>
>> </biosource>
>> <biosource>
>> <dbId>354</dbId>
>> <logId>5424</logId>
>> <projectId>127</projectId>
>> <biosourceName>MUTANTS 03</biosourceName>
>> <sowingDate>1970-01-01T00:00:00+01:00</sowingDate>
>> <remark>N.R. </remark>
>> <isPrivate>false</isPrivate>
>> </biosource>
>> //...
>> </biosources>
>> =====================
>>
>> I have tried to put more classes in
>> JAXBContext.newInstance(classes...) for JAXB knows what to unmarshal
>> with, but no way, I still get the error.
>>
>> Any help would be greatly appreciated.
>>
>> Thanks, Raphael.
>>
>>
>>
>>
>>
>> Raphaël F. wrote:
>>> Oh sure !
>>>
>>> I didn't notice this problem. Now, I use the subclass with Jaxb by
>>> allowing Jaxb to match subclass with Project.class.
>>>
>>> Thanks a lot Wolfang.
>>>
>>>
>>> Wolfgang Laun a écrit :
>>>>
>>>>
>>>> <quote>
>>>>
>>>>
>>>> java.lang
>>>> Class InstantiationException
>>>>
>>>> public class *InstantiationException*
>>>> extends Exception
>>>> <file:////usr/local/java/jdk1.6.0_03/docs/api/java/lang/Exception.html>
>>>>
>>>>
>>>>
>>>> Thrown when an application tries to create an instance of a class
>>>> using the |newInstance| method in class |Class|, but the specified
>>>> class object cannot be instantiated. The instantiation can fail for
>>>> a variety of reasons including but not limited to:
>>>>
>>>> * the class object represents an abstract class,...
>>>>
>>>> </quote>
>>>>
>>>> Get rid of abstract in main.java.***.Project.
>>>> -W
>>>>
>>>>
>>>> 2009/9/8 Raphaël Flores <rflores_at_moulon.inra.fr
>>>> <mailto:rflores_at_moulon.inra.fr>>
>>>>
>>>> Hello all, when I execute my app, I get an exception thrown at
>>>> unmarshalling step.
>>>>
>>>> I don't understand why, and did not find solution via google.
>>>> That's why I post here.
>>>>
>>>> Here is the exception:
>>>>
>>>> ---------------------------------------------------------------------
>>>> Exception in thread "main" javax.xml.bind.UnmarshalException:
>>>> Unable to create an instance of main.java.***.Project
>>>> - with linked exception:
>>>> [java.lang.InstantiationException]
>>>> at
>>>>
>>>> com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallingContext.handleEvent(Unknown
>>>>
>>>> Source)
>>>> at
>>>>
>>>> com.sun.xml.internal.bind.v2.runtime.unmarshaller.Loader.reportError(Unknown
>>>>
>>>> Source)
>>>> at
>>>>
>>>> com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallingContext.createInstance(Unknown
>>>>
>>>> Source)
>>>> at
>>>>
>>>> com.sun.xml.internal.bind.v2.runtime.unmarshaller.StructureLoader.startElement(Unknown
>>>>
>>>> Source)
>>>> at
>>>>
>>>> com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallingContext._startElement(Unknown
>>>>
>>>> Source)
>>>> at
>>>>
>>>> com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallingContext.startElement(Unknown
>>>>
>>>> Source)
>>>> at
>>>>
>>>> com.sun.xml.internal.bind.v2.runtime.unmarshaller.SAXConnector.startElement(Unknown
>>>>
>>>> Source)
>>>> at
>>>>
>>>> com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.startElement(Unknown
>>>>
>>>> Source)
>>>> at
>>>>
>>>> com.sun.org.apache.xerces.internal.impl.XMLNSDocumentScannerImpl.scanStartElement(Unknown
>>>>
>>>> Source)
>>>> at
>>>>
>>>> com.sun.org.apache.xerces.internal.impl.XMLNSDocumentScannerImpl$NSContentDriver.scanRootElementHook(Unknown
>>>>
>>>> Source)
>>>> at
>>>>
>>>> com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl$FragmentContentDriver.next(Unknown
>>>>
>>>> Source)
>>>> at
>>>>
>>>> com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl$PrologDriver.next(Unknown
>>>>
>>>> Source)
>>>> at
>>>>
>>>> com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl.next(Unknown
>>>>
>>>> Source)
>>>> at
>>>>
>>>> com.sun.org.apache.xerces.internal.impl.XMLNSDocumentScannerImpl.next(Unknown
>>>>
>>>> Source)
>>>> at
>>>>
>>>> com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl.scanDocument(Unknown
>>>>
>>>> Source)
>>>> at
>>>>
>>>> com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(Unknown
>>>>
>>>> Source)
>>>> at
>>>>
>>>> com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(Unknown
>>>>
>>>> Source)
>>>> at
>>>> com.sun.org.apache.xerces.internal.parsers.XMLParser.parse(Unknown
>>>> Source)
>>>> at
>>>>
>>>> com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.parse(Unknown
>>>>
>>>> Source)
>>>> at
>>>>
>>>> com.sun.org.apache.xerces.internal.jaxp.SAXParserImpl$JAXPSAXParser.parse(Unknown
>>>>
>>>> Source)
>>>> at
>>>>
>>>> com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallerImpl.unmarshal0(Unknown
>>>>
>>>> Source)
>>>> at
>>>>
>>>> com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallerImpl.unmarshal(Unknown
>>>>
>>>> Source)
>>>> at
>>>> javax.xml.bind.helpers.AbstractUnmarshallerImpl.unmarshal(Unknown
>>>> Source)
>>>> at
>>>> javax.xml.bind.helpers.AbstractUnmarshallerImpl.unmarshal(Unknown
>>>> Source)
>>>> at
>>>> main.java.***.Client.unmarshalNonGeneric(Client.java:401)
>>>> at main.java.***.Client.doSomething(Client.java:349)
>>>> at main.java.***.Client.main(Client.java:66)
>>>> Caused by: java.lang.InstantiationException
>>>> at
>>>>
>>>> sun.reflect.InstantiationExceptionConstructorAccessorImpl.newInstance(InstantiationExceptionConstructorAccessorImpl.java:48)
>>>>
>>>> at
>>>> java.lang.reflect.Constructor.newInstance(Constructor.java:532)
>>>> at
>>>> com.sun.xml.internal.bind.v2.ClassFactory.create0(Unknown Source)
>>>> at
>>>>
>>>> com.sun.xml.internal.bind.v2.runtime.ClassBeanInfoImpl.createInstance(Unknown
>>>>
>>>> Source)
>>>> ... 25 more
>>>>
>>>> ---------------------------------------------------------------------
>>>>
>>>>
>>>> Here is my test code:
>>>> =================================================
>>>> import java.io.IOException;
>>>> import java.io.InputStream;
>>>> import java.net.ConnectException;
>>>>
>>>> import javax.xml.bind.JAXBContext;
>>>> import javax.xml.bind.JAXBException;
>>>> import javax.xml.bind.Unmarshaller;
>>>>
>>>> import main.java.***.Project;
>>>>
>>>> import org.apache.commons.httpclient.HttpClient;
>>>> import org.apache.commons.httpclient.HttpException;
>>>> import org.apache.commons.httpclient.methods.GetMethod;
>>>> import org.apache.cxf.common.util.Base64Utility;
>>>>
>>>> public class Client {
>>>> public static void main(String[] args) throws
>>>> Exception {
>>>>
>>>> String url = "http://localhost:8080/projects/127"
>>>> <http://localhost:8080/projects/127>;
>>>> String login = "toto";
>>>> String password = "tata";
>>>>
>>>> doSomething(url, login, password);
>>>> }
>>>>
>>>> public static void doSomething(String url, String login,
>>>> String password ) throws InterruptedException, HttpException,
>>>> IOException, JAXBException{
>>>> GetMethod get = new GetMethod(url);
>>>> get.addRequestHeader("Accept", "application/xml");
>>>> get.addRequestHeader("ContentType", "application/xml");
>>>> get.addRequestHeader("Authorization",
>>>> getHeaderAuthorization(login, password));
>>>> HttpClient httpclient = new HttpClient();
>>>> try {
>>>> int result = httpclient.executeMethod(get);
>>>>
>>>> System.out.println("\nResponse status code:\n" +
>>>> result);
>>>> InputStream stream = get.getResponseBodyAsStream();
>>>> Project project =
>>>> (Project)unmarshal(Project.class,
>>>> stream);
>>>> System.out.println("Project is:" +
>>>> project.toString());
>>>> }
>>>> catch (ConnectException e) {
>>>> System.out.println("\nConnection to service refused
>>>> !\n"
>>>> + "Please, check that server is running and
>>>> URL and port are right.");
>>>> }
>>>> finally {
>>>> get.releaseConnection();
>>>> }
>>>> }
>>>> public String getHeaderAuthorization(String login,
>>>> String
>>>> password) {
>>>> String loginPassword = login + ":" + password;
>>>> String encodedLoginPassword =
>>>> Base64Utility.encode(loginPassword.getBytes());
>>>> String encodedHeader = "Basic " + encodedLoginPassword;
>>>> return encodedHeader;
>>>> }
>>>> public static <T> T unmarshal(Class<T> docClass,
>>>> InputStream
>>>> inputStream) throws JAXBException {
>>>> System.out.println("Class is: " + docClass);
>>>> JAXBContext jc = JAXBContext.newInstance(docClass);
>>>> Unmarshaller u = jc.createUnmarshaller();
>>>> T object = (T) u.unmarshal(inputStream);
>>>> return (T) object;
>>>> }
>>>> =================================================
>>>>
>>>>
>>>> And here is Project class which is binding:
>>>>
>>>> ---------------------------------------------------------------------
>>>> import javax.xml.bind.annotation.XmlRootElement;
>>>>
>>>> import main.java.***.ProticObject;
>>>>
>>>> @XmlRootElement(name = "project")
>>>> public abstract class Project extends ProticObject {
>>>> protected String projectName;
>>>> protected String projectDescription;
>>>> protected String remark;
>>>> protected boolean isPrivate;
>>>> public Project() {
>>>> }
>>>> public int getProjectId() {
>>>> return projectId;
>>>> }
>>>> public void setProjectId(int projectId) {
>>>> this.projectId = projectId;
>>>> }
>>>> [ other getters/setters ... ]
>>>> }
>>>>
>>>> ---------------------------------------------------------------------
>>>>
>>>>
>>>> Here is the XML what is returned by server, for exemple:
>>>> =================================================
>>>> <project>
>>>> <dbId>127</dbId>
>>>> <logId>0</logId>
>>>> <projectId>127</projectId>
>>>> <private>false</private>
>>>> <projectDescription>
>>>> Here is the description of the project...
>>>> </projectDescription>
>>>> <projectName>ARABIDOPSIS</projectName>
>>>> <remark>
>>>> Abstract:
>>>> Here is the abstract...
>>>> </remark>
>>>> </project>[/CODE]
>>>> =================================================
>>>>
>>>> Would someone have an idea on how resolve this problem please?
>>>>
>>>> Thanks a lot for your help.
>>>>
>>>>
>>
>> --
>> Raphaël F.