Win a copy of Cross-Platform Desktop Applications: Using Node, Electron, and NW.js this week in the JavaScript forum!
  • Post Reply Bookmark Topic Watch Topic
  • New Topic

Class Loading from a file  RSS feed

 
Cheenath Ajay
Ranch Hand
Posts: 32
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi I am trying to read a local class file and load the class object into my custom class loader

Code;
public Class classLoad() throws IOException {
FileInputStream classObjStream = new FileInputStream(new File("D:\\softwares\\parallel\\task-manager\\bin\\com\\tm\\grid\\TaskManager.class"));
int length = classObjStream.read();
byte[] by = new byte[length];
ByteArrayOutputStream byteArray = new ByteArrayOutputStream();
while(classObjStream.read(by) > 0){
byteArray.write(by);
}
Class class1 = defineClass("com.tm.grid.TaskManager",byteArray.toByteArray(), 0, byteArray.toByteArray().length);
System.out.println(">>>>>>>>>>>>"+class1);
return class1;
}
But unfortunately I am getting below error once I tried to execute this
-----------------------
Exception in thread "main" java.lang.ClassFormatError: Incompatible magic value 4273651200 in class file com/tm/grid/TaskManager
at java.lang.ClassLoader.defineClass1(Native Method)
at java.lang.ClassLoader.defineClassCond(Unknown Source)
at java.lang.ClassLoader.defineClass(Unknown Source)
at java.lang.ClassLoader.defineClass(Unknown Source)

Can anyone help me on this?

Thanks in advance,



 
Rob Spoor
Sheriff
Posts: 21048
85
Chrome Eclipse IDE Java Windows
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Cheenath Ajay wrote:

Change that into 0 is a perfectly valid value to read; -1 is the end-of-stream indicator.
 
Cheenath Ajay
Ranch Hand
Posts: 32
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Thanks.

I tried changing it, but still getting the same error.
FileInputStream classObjStream = new FileInputStream(new File("D:\\softwares\\parallel\\task-test\\bin\\com\\tm\\grid\\Test.class"));
int length = classObjStream.read();
byte[] by = new byte[length];
ByteArrayOutputStream byteArray = new ByteArrayOutputStream();
while(classObjStream.read(by) > -1){
byteArray.write(by);
}
Class class1 = defineClass("com.tm.grid.Test",byteArray.toByteArray(), 0, byteArray.toByteArray().length);
System.out.println(">>>>>>>>>>>>"+class1);
return class1;

Any clue??

 
Cheenath Ajay
Ranch Hand
Posts: 32
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Got the ans:
Wasted a day going behind this issue

Used below code to read bytes from a class then problem solved..

byte[] bytes = new byte[(int)length];

// Read in the bytes
int offset = 0;
int numRead = 0;
while (offset < bytes.length
&& (numRead=is.read(bytes, offset, bytes.length-offset)) >= 0) {
offset += numRead;
}

A bit crazy, I was expecting below code will do the same !!!

ByteArrayOutputStream byteArray = new ByteArrayOutputStream();
while(classObjStream.read(by) > -1){
byteArray.write(by);
}

Any way things started working now!!


 
Rob Spoor
Sheriff
Posts: 21048
85
Chrome Eclipse IDE Java Windows
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Now why didn't I see this before...

is.read can read less bytes than fit in the byte array; this size is returned by the read method. However, you still write all the contents of the byte array. That includes old and stale data that was filled by a previous read. Changing the loop like this should work:
Oh, and please UseCodeTags in the future.
 
Cheenath Ajay
Ranch Hand
Posts: 32
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Thanks Rob.

Strange but found one interesting thing.
Whenever you call classObjStream.read() method, that call reads one byte from the stream, hence whenever you try reading from stream using read(byte[]) next time, it will always give you bytes from the stream after the first byte.(one byte missing).

FileInputStream classObjStream = new FileInputStream(new File(fileName));
byte[] classBytes = new byte[1024];
int length = classObjStream.read(); //Here is the issue.........

System.out.println("length - "+length);
ByteArrayOutputStream byteArray = new ByteArrayOutputStream();
int count;
while((count = classObjStream.read(classBytes)) > -1){ // assign, then compare to -1
System.out.println(count);
byteArray.write(classBytes, 0, count); // only write as many bytes as were read
}
System.out.println(new String(byteArray.toByteArray()));
return byteArray.toByteArray();
 
Rob Spoor
Sheriff
Posts: 21048
85
Chrome Eclipse IDE Java Windows
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Ah right, I missed that one. The length of the class file is not stored inside the file; instead, you should use the File object's length() method. But with ByteArrayOutputStream you don't even need it, as the ByteArrayOutputStream allows you to keep adding bytes even if its current capacity is exceeded. Like ArrayList it will simply increase its capacity. You can use it to create the ByteArrayOutputStream for a bit of optimization, but you don't technically need it.
 
Cheenath Ajay
Ranch Hand
Posts: 32
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

I am all set.
Thanks a million for you support
 
Darryl Burke
Bartender
Posts: 5167
11
Java Netbeans IDE Opera
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
May be useful: File Class Loader.
 
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
Boost this thread!