
Signature
[ don't email me support questions or followups ]
g o r d o n + n e w s @ b a l d e r 1 3 . s e
Hello,
thank you for your advices! Here is my code and as you have
seen I use JNI in C++ to execute Java code.
...
// here I build my byte array, I read the contents
// of a class file and add them to byte array
...
typedef std::vector<char> BYTE_ARRAY
...
BYTE_ARRAY byteField;
FILE* f = fopen("D:\\Temp\\testClass.class", "r");
if (NULL != f)
{
char line[100];
while (NULL != fgets(line, 100, f))
{
for (int i = 0; i < 100; ++i)
byteField.push_back(line[i]);
}
}
...
// try to define the class
...
BYTE_ARRAY::size_type len = byteField.size();
jbyteArray jByteField = mEnv->NewByteArray(static_cast<jsize>(len));
jbyte* jBytes = mEnv->GetByteArrayElements(jByteField, 0);
for (int i = 0; i < static_cast<int>(len); ++i)
jBytes[i] = static_cast<jbyte>(byteField[i]);
...
jclass jClass = mEnv->DefineClass("testClass", NULL, jBytes, len);
if (mEnv->ExceptionOccurred())
mEnv->ExceptionDescribe();
...
jClass contains here NULL and the following exception
has occured:
Exception in thread "main" java.lang.ClassFormatError:
Unknown constant tag 0 in class file testClass
I hope that you have now sufficient information to
see what is wrong.
Thank you in advance,
Anahita
Andreas Leitgeb - 27 Nov 2006 12:23 GMT
> thank you for your advices! Here is my code and as you have
> seen I use JNI in C++ to execute Java code.
>
> FILE* f = fopen("D:\\Temp\\testClass.class", "r");
If you're on windoze platform, you need "rb", rather than "r"
> char line[100];
> while (NULL != fgets(line, 100, f))
You'd better use fread (rather than fgets), since class files
are not line-oriented, but binary.
Unlike fgets, fread will also tell you the number of
bytes actually read. (this is important at end of file,
so you don't generate trailing garbage)
> I hope that you have now sufficient information to
> see what is wrong.
yes, much better, now :-)
Gordon Beaton - 27 Nov 2006 12:29 GMT
> char line[100];
> while (NULL != fgets(line, 100, f))
> {
> for (int i = 0; i < 100; ++i)
> byteField.push_back(line[i]);
> }
Use fread(), not fgets(), to read your binary data. Also, your code
assumes (probably incorrectly) that exactly 100 characters was read
each time. Probably you have corrupted the class contents here.
I'd suggest that you try writing the resulting array to a file and
comparing it with the original before you attempt DefineClass(). Make
this part work first!
Note too that DefineClass() wants a jbyte* (i.e. native array of
jbyte), not a "java byte array" as you're using in the subsequent
code.
/gordon

Signature
[ don't email me support questions or followups ]
g o r d o n + n e w s @ b a l d e r 1 3 . s e
aa@dsa-ac.de - 27 Nov 2006 13:40 GMT
Hello,
thank you for usful hints! I could solve my problem,
the reason was actually 'fgets(..)' and the corrupt byte
array...
Anahita