i am new to java and i am learning deserialization and while doing so i am getting classcastexception
I did serialization at one class and deserialization at another
serialization
zipfile f = new zipfile(30,"kavin");
ArrayList<zipfile> a = new ArrayList<zipfile>(101);
a.add(f);
String file = "def.txt";
try {
FileOutputStream fi = new FileOutputStream(file);
ObjectOutputStream s = new ObjectOutputStream(fi);
s.writeObject(f);
System.out.println(f.age);
s.close();
fi.close();
} catch (FileNotFoundException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
catch (IOException e)
{
e.printStackTrace();
}
deserialization
String file = "def.txt";
try {
FileInputStream fi = new FileInputStream(file);
ObjectInputStream s = new ObjectInputStream(fi);
f=(deserialization)s.readObject();
System.out.println(f.age);
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
catch (IOException e)
{
e.printStackTrace();
}
catch (ClassNotFoundException e)
{
e.printStackTrace();
}
}
output
Exception in thread "main" java.lang.ClassCastException: demo2.zipfile cannot be cast to demo2.deserialization
at demo2.deserialization.main(deserialization.java:69)
The following must be kept in mind when dealing with Serialization:
If a parent class has implemented Serializable interface then child class doesn’t need to implement it but vice-versa is not true.
Only non-static data members are saved via Serialization process.
Static data members and transient data members are not saved via Serialization process. So, if you don’t want to save the value of a non-static data member then make it transient.
The constructor of the object is never called when an object is deserialized.
Associated objects must be implementing the Serializable interface.
Try to look thru your code and find if one of the above-mentioned cases is the problem.
For more help, refer to the source at - Serialization in Java
Related
I am creating java files from json Objects using a library called jsonschema2pojo-core.jar. It successfully creates the required files for me. Now I need to access the newly(dynamically) created file and creates its instance to use it further.
But as the newly created class is still not in the classpath I am unable to do this. Tried to do my part of research and figured out that Eclipse jars allows such refresh only in plugin projects. Can anyone suggest some thing for this?
public static void main(String[] args){
String fileName = "MyJavaFile";
POJOBuilder pojo = new POJOBuilder();
pojo.buildPOJO("file:///C:/mypath/myJSON.json", fileName); //generates the java file MyJavaFile.java
Object obj = null;
try {
obj = Class.forName("com.mypackage."+fileName).newInstance(); // Java file not available yet
} catch (InstantiationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
Can this be done through threads? I mean wait until the creation of the POJO is done and then start with the rest after that?
I'm trying to read a file. so in my class 'Skanner' i have a field that looks like this:
private Reader reader, readerX;
Now I initialized these fields in the contructor:
public Skanner()
{
try
{
Reader readerX = new FileReader("aliceinwonderland.txt");
Reader reader = new BufferedReader(readerX);
}
catch (FileNotFoundException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
}
but when I try to use the fields in methods of class Skanner, I get a null-pointer exception. If I instead use reader.read() in the try block of the constructor that doesn't give any problems. Why can't I call reader.read() outside the scope where I initiated it?
You're hiding the instance members by redeclaring them in the method. Remove the Reader type declarations from the code you posted.
the problem is the Reader object is only available in your contructor which is
public Skanner()
{
try
{
Reader readerX = new FileReader("aliceinwonderland.txt");
Reader reader = new BufferedReader(readerX);
}
catch (FileNotFoundException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
}
if you would like to access them outside the constructor you need to declare them outside the constructor
Reader readerX;
Reader reader;
public Skanner()
{
try
{
readerX= new FileReader("aliceinwonderland.txt");
reader = new BufferedReader(readerX);
}
catch (FileNotFoundException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public void someMethod(){
//is now available
// make sure you use new Skanner() first before calling this method or it will result to NPE(null pointer exception) because the initialization of reader is in the constructor
reader.read();
}
and if you want to access them outside the class use the public access modifier.
Is it possible to save a loaded class to a file?
Class cc = Class.forName("projects.implementation.JBean");
Or, maybe to get the physical location of that class?
Yes you can as Class.class implements Serializable interface you can serialize it into file and as well deserialize again.
Example -
Class Test{
public static void main(String[] args) throws ClassNotFoundException {
try {
OutputStream file = new FileOutputStream("test.ser");
OutputStream buffer = new BufferedOutputStream(file);
ObjectOutput output = new ObjectOutputStream(buffer);
try {
Class cc = Class.forName("com.test.Test");
System.out.println(cc);
output.writeObject(cc);
} finally {
output.close();
}
} catch (IOException ex) {
ex.printStackTrace();
}
try {
// use buffering
InputStream file = new FileInputStream("test.ser");
InputStream buffer = new BufferedInputStream(file);
ObjectInput input = new ObjectInputStream(buffer);
try {
// deserialize the class
Class cc = (Class) input
.readObject();
// display
System.out.println("Recovered Class: " + cc);
} finally {
input.close();
}
} catch (ClassNotFoundException ex) {
ex.printStackTrace();
} catch (IOException ex) {
ex.printStackTrace();
}
}
}
Serializing a Class object in Java serializes little more than the qualified name of the class. When deserializing the class is looked up by name.
In the general case, I don't think it's possible to get the bytes corresponding to a class definition (the bytecode) once it has been loaded. Java permits classes to be defined at runtime and, so far as I'm aware, doesn't expose the bytes after the class has been loaded.
However, depending on the ClassLoader in use, you may find that
cc.getResourceAsStream("JBean.class")
is all you need, loading the class stream as a resource using its own ClassLoader.
Another option could be to intercept the loading of the class. The ClassLoader will get to see the bytes in "defineClass", so a custom ClassLoader could store them somewhere.
I know we can load a Object from .class file and my question is how to do it reversely.
I use Class.forName("classname") to get a Class object and how can I write this back to the .class file?
Serialization class is not the point for this issue because the loaded file may not be implement Serializable interface.
The reason why I ask this is I need convert Class object to java source text string. If anyone knows how to convert Object class to source directly, it might be great helpful.
If you want to add functions etc to a class you can use.
http://www.jboss.org/javassist
example:
clazz = fullclass name, method = "public void doxxx(){ int x =0;x++}"
private static void createMethod(String clazz,String method){
ClassPool pool = ClassPool.getDefault();
try {
Class<?> class1 = Class.forName(clazz);
class1.getProtectionDomain().getCodeSource().getLocation();
pool.insertClassPath(new ClassClassPath(class1));
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
CtClass pt;
try {
pt = pool.get(clazz);
CtMethod m = CtNewMethod.make(method, pt);
pt.addMethod(m);
pt.writeFile();
pt.toClass();
} catch (NotFoundException e) {
e.printStackTrace();
} catch (CannotCompileException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
I'm wondering if and how one can load dex or class files dynamically
in dalvik, some quick'n'dirty test function I wrote was this:
public void testLoader() {
InputStream in;
int len;
byte[] data = new byte[2048];
try {
in = context.getAssets().open("f.dex");
len = in.read(data);
in.close();
DexFile d;
Class c = defineClass("net.webvm.FooImpl", data, 0, len);
Foo foo = (Foo)c.newInstance();
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InstantiationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
whereas the Foo interface is this
public interface Foo {
int get42();
}
and f.dex contains some dx'ed implementation of that interface:
public class FooImpl implements Foo {
public int get42() {
return 42;
}
}
The above test driver throws at defineClass() and it doesn't
work and I investigated the dalvik code and found this:
http://www.google.com/codesearch/p?hl=en#atE6BTe41-M/vm/Jni.c&q=Jni.c...
So I'm wondering if anyone can enlighten me if this is possible in
some other way or not supposed to be possible. If it is not possible,
can anyone provide reasons why this is not possible?
There's an example of DexClassLoader in the Dalvik test suite. It accesses the classloader reflectively, but if you're building against the Android SDK you can just do this:
String jarFile = "path/to/jarfile.jar";
DexClassLoader classLoader = new DexClassLoader(
jarFile, "/tmp", null, getClass().getClassLoader());
Class<?> myClass = classLoader.loadClass("MyClass");
For this to work, the jar file should contain an entry named classes.dex. You can create such a jar with the dx tool that ships with your SDK.