0

I have a problem persisting the Class object in the DB.

I tried to convert the object into a byte array using object ObjectArrayOutputStream and ByteArrayOutputStream as shown below and persisted it the byte array:

Class klazz = getClassForClassDef();
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(baos);
oos.writeObject(klazz);
baos.toByteArray();

But I get an error shown below:

java.lang.ClassFormatError: Incompatible magic value 2901213189 in class file

I think that the way byte array was constructed has the problem. But I don't know how to create a correct .class equivalent of the class object.

Kevin Bedell
  • 13,254
  • 10
  • 78
  • 114
promaxdev
  • 455
  • 1
  • 6
  • 19

3 Answers3

2

If you are really trying to store the Class itself:

You can read more about it here: https://stackoverflow.com/a/2390763/1001027

If you are trying to store an Object:

You are using the Class as parameter for the writeObject method. Instead of this you should use the instance you have.


// write the class
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(baos);
oos.writeObject(objectToSerialize);

// this you need to store
byte[] data = baos.toByteArray();

// read it again (just a test)
ByteArrayInputStream bais = new ByteArrayInputStream(data);
Object restored = new ObjectInputStream(bais).readObject();

// write what came from the deserialization
System.out.println(restored);

In the sample, the variable objectToSerialize will hold the object to store.


Are you sure you want really store java serialized objects into your database? There are a few alternatives to that. You could create a formal model using an ORM framework such as Hibernate.

If you think this would be too dynamic, you could use XML serialization such as XStream or even JSON serialization, this would be good because they are readable formats, meaning you can see what is really stored, avoiding the need to deserialize it with a Java application just to check the state.

Community
  • 1
  • 1
Francisco Spaeth
  • 23,493
  • 7
  • 67
  • 106
  • Well. Actually my problem is not to store all java serialized objects. But I need to load classes stored in a DB at runtime. I have created a model to represent the metadata of a simple class. With little coding I managed to create the Class object from the model by using the metadata. But I am not able to store the class object and retrieve to load class at runtime using reflections. – promaxdev Jul 07 '12 at 12:58
  • Ok, meaning you need to perform the two lines of code I posted on the sample below the commente `// read it again (just a test)` where data would be the `byte[]` retrieved from your database field – Francisco Spaeth Jul 07 '12 at 13:01
  • The error is gone now. But I am nowhere near my target. This time I am getting a ClassNotFoundException. When it tries to load the persisted Class object, it is not able to find the .class equivalent of it. Let me try more to get that loaded, may be using some classloader tricks.. – promaxdev Jul 07 '12 at 13:20
1

To serialise an object you have to write into the stream the object itself rather than it's class. Additionally, the object instance must implement the Serializable interface and all its internal fields should be either serializable or transient.

In your code, instead of oos.writeObject(klazz); you should write oos.writeObject(obj);, providing obj is the object instance you want to save.

However, if you are trying to store a Java object into a DB (we are talking about a relational DB, aren't we?) I would map the object to a table, storing each of its attributes as values for the columns. That way you would be able to perform searches and joins using SQL and the values for the columns, you can't index binary fields though.

Alonso Dominguez
  • 7,750
  • 1
  • 27
  • 37
  • Right. But in my case one of the fields is the to store the class and load it at runtime from the field. – promaxdev Jul 07 '12 at 12:52
  • 1
    and why would you want to store the class itself? wouldn't it be better to store the class name and then load the class with `Class.forName(...)`? – Alonso Dominguez Jul 07 '12 at 12:56
1

A .class file is not a serialized Class object. It is something completely different, and you will not be able to produce it with any simple Java code. However, why would you want to? You already have that .class file on disk, that's how your Java program got to know about the class. Why don't you just copy that .class file? It will only be an issue of finding where it comes from (what JAR).

Marko Topolnik
  • 195,646
  • 29
  • 319
  • 436
  • Yes. I used that phrase just to imply that I have to load the class from DB field just as we do from a .class file. – promaxdev Jul 07 '12 at 12:53