me and a friend of mine are working on a coding project and we ran into a little issue. We are essentially trying to modify Java Methods/Bytecode during runtime using C++. I am just curious if this is possible or how it is possible. We have already tried using JVMTI and JNI to accomplish this but it seems that you can only modify classes that are currently being loaded into the JVM. We are loading our code in as a DLL while the process is running so we can not do this. We also thought assembly might work by accomplishing this. A little demonstration of what we are trying to do can be seen below.
public boolean Method()
{
boolean value = true;
return value; //<- Value that we want to modify (in java)
}
jclass JVMUtilities::getClass(std::string clazzname) {
jstring name = Wrapper::getJVMHook().getJNI()->NewStringUTF(clazzname.c_str());
jobject classLoader = getclassloader();
jmethodID mid = Wrapper::getJVMHook().getJNI()->GetMethodID(Wrapper::getJVMHook().getJNI()->GetObjectClass(classLoader), "findClass", "(Ljava/lang/String;)Ljava/lang/Class;");
return (jclass)Wrapper::getJVMHook().getJNI()->CallObjectMethod(classLoader, mid, name);
//This is the function we use for geting the class information in c++ including location
}
Basically going by above, we want to change the return value to what we want during run time by manipulating the byte code.
There is a public standard API to do this - JVM TI RedefineClasses and RetransformClasses.
Related
Let's say I create a class 'Car' in cpp.
I want to creat an instance of that class with it's empty constructor in cpp.
Can I do it and use it in java code on android?
For instance:
Java code
Car myCar = new Car();
CPP class
class Car{
std::string model;
int creationYear;
Car(){}
}
thanks for the help
Yes. You can easily have a native object that shadows a Java object - assuming you can call the C++ Car() constructor. You could use a public static method in the C++ Car class to do that.
It's a bit of a hack, but a Java long is guaranteed to be 64 bits, so it's long enough to hold a native pointer value.
In Java:
public class Car
{
// A Java long is 64 bits, so it will
// hold a native pointer
private long nativeCar;
private native long newNativeCar();
private native void deleteNativeCar( long car );
public Car()
{
this.nativeCar = newNativeCar();
}
// allow for explicit native cleanup by caller
public synchronized deleteCar()
{
if ( 0 != this.nativeCar )
{
deleteNativeCar( nativeCar );
nativeCar = 0;
}
}
// handle cases where the native cleanup code
// was not called
#Override
protected void finalize() throws Throwable
{
deleteCar();
super.finalize();
}
}
Compile that, then use javah on the class file to create your C header file. (Note that JNI uses C, not C++. You can write C++ code to implement your logic, but the interface presented to the JVM must be a C interface.)
You'll get a couple of functions in your native header, something like this (I've stripped off the annotation from javah - you will need to keep that...):
jlong some_class_path_newNativeCar( JNIEnv *, jobject );
void some_class_path_deleteNativeCar( JNIEnv *, jobject, jlong );
You can implement your C++ code then:
jlong some_class_path_newNativeCar(
JNIEnv *env, jobject obj )
{
Car *nativeCar = new Car();
// C cast - we're returning a C value
return( ( jlong ) nativeCar );
}
void some_class_path_deleteNativeCar(
JNIEnv *env, jobject obj, jlong jNativeCar )
{
Car *cppNativeCar = ( Car * ) jNativeCar;
delete cppNativeCar;
}
I've deliberately kept the code simple - there's quite a bit I left out. javah can be a bit tricky to figure out how to use properly, for example. But if you can't figure out how to use javah properly you shouldn't be writing JNI code anyway.
Because JNI code is fragile. You can't make any mistakes, or you will wind up getting seemingly random failures or having your JVM crash, and the crash will likely not be easily traced to the bad code that caused the problem. There are lots of rules for making JNI calls using the JNIEnv * pointer supplied to a native call. For example, in general you can't save the values passed to you by the JVM and use them outside of the context you received them in - using them in another thread, or after the function where they were passed to you returns is a great way to cause those JVM crashes I mentioned above.
Nor can you make any JNI calls to Java if there are any exceptions pending from previous calls - again, you risk unpredictable errors and crashes if you do.
So keep your native code simple.
Keep all the logic and processing on only one side of the Java/native interface if you can.
Pass only C or Java strings, primitives or primitive arrays across the Java/native interface if you can.
Interacting with actual complex Java object from native code will take many, many lines of C or C++ code to safely replicate what can be done in Java with one or two lines of code. Even simple one-line get*()/set*() Java calls become 20 or 30 lines or more of C or C++ code if you replicate all the exception and failure checks you need in order to guarantee safe JVM execution after the native call no matter what data gets passed in. If you pass null to a Java method that can't handle a null value it will throw a NullPointerException that you can catch and your JVM runs happily or shuts down cleanly with an uncaught exception. Pass NULL to a JNI function that can't handle it, and if you don't properly check for any failure or any exception and then properly handle it, your JVM will exhibit seemingly unrelated failures or just crash.
I need to call external DLL library function from Java code. I use Netbeans 7.2.
My dll's functions are:
Boolean isValid(string word)
List<String> getWords(String word)
I'm following this example. But I don't know how declare my dll functions.
And I found another link. But it doesn't work for me.
I stumbled upon the same problem of "calling DLL from Java" and first was frustrated about the complexity. Yet, there is an elegant solution (might also be interesting for the people over there in the processing.org habitat..)
Given the rather "general" form of the question (maybe, downrating is not justified for that), I suppose, a rather easy-going solution would be indicated. In other words, a solution that avoids messing aronud with header files, extra conversions, etc., just as the source code is not necessarily available.
My recommendation for that would be JNA (https://github.com/twall/jna), which basically is a simplifying wrapper around JNI. It works great, type mapping is straightforward (e.g. pchar = lpcstr buffer -> string), though I am using it only towards Windows DLLs and my own C-style DLLs created using Delphi-Pascal. The only thing to consider is that return values should be exported through functions rather than "out" flagged reference variables.
The question already points to a linked source that provides an example for that (so, answers around JNI may be misplaced here). Note that the link I provided also contains axamples for the transfer of arrays and pointers.
You will need to use the Java Native Interface (JNI), which is a set of C/C++ functions that allow native code to interface with java code (i.e. receiving parameters from java function calls, returning results, etc). Write a wrapper C library that receive JNI calls and then call your external library.
For instance, the following function invokes a method updateHandlers on a native object (that is stored as long in the Java side).
class MyImpl {
void updateHandlers(JNIEnv *env) {
this->contentHandler = ....;
}
}
JNIEXPORT void JNICALL Java_package_Classname_updateHandlers0
(JNIEnv *env, jobject obj, jlong ptr)
{
((MyImpl*)ptr)->updateHandlers(env);
}
The corresponding declarations in package.ClassName are:
private long ptr; //assigned from JNI
public void updateHandlers() {
if (ptr==0) throw new NullPointerException();
updateHandlers0(ptr);
}
private native void updateHandlers0(long ptr);
static {
try {
/*try preloading the library external.dll*/
System.loadLibrary("external");
} catch (UnsatisfiedLinkError e) {
/*library will be resolved when loading myjni*/
}
System.loadLibrary("myjni"); //load myjni.dll
}
I did write some time ago sample tutorial, maybe it will help.
http://wendro.blogspot.com/2010/03/jni-example-eclipse-dev-cpp.html
You declare your native functions in java (native private ...) with the signature that you need; then run javah (a tool that is provided with the JDK) in order to generate the native headers. A List<String> (actually a List, because of type erasure) is a jobject in native code.
The corresponding C method, would be:
JNIEXPORT jobject JNICALL package_Classname_getWords(JNIEnv *env, jobject jobj, jstring word)
I think it would be easier to return an array of strings jobjectArray, and instantiate the List in java from the returned values. See this example.
I'm working on a Lua wrapper for my Android app, which will allow me to write Lua code to speed up development. I've made a static class called lua with functions like newState and pushString. I manage the Lua state by passing around a long with the pointer to the lua_State. As you can tell, I don't need any fancy stuff that makes interaction easier, like overloads to push variables.
Now, the problem is binding Java functions to Lua variables. I've thought of a few ways to do this, but they're all ugly.
Instead of functions, pass around a table with a reference to the Java function as a userdatum and have a __call metamethod take care of calling the "function".
Alter Lua internals to include a Java reference with Lua C functions.
Is there any better way to go about this? Or should I go with the second method? (I realise the first method is ridiculous, but it manifested itself in my mind as a solution anyways.)
You can have a look at my simple project AndroLua. It contains Lua and LuaJava compiled using the Android NDK.
Because it uses LuaJava, it allows to bind Java functions to Lua, in a similar way like you said, using userdata. Here is an example of how I override the print function to output text into a TextView:
JavaFunction print = new JavaFunction(L) {
#Override
public int execute() throws LuaException {
StringBuilder sb = new StringBuilder();
for (int i = 2; i <= L.getTop(); i++) {
int type = L.type(i);
String val = L.toString(i);
if (val == null)
val = L.typeName(type);
sb.append(val);
sb.append("\t");
}
sb.append("\n");
status.append(sb.toString());
return 0;
}
};
print.register("print");
The downside is that sometimes you cannot pass the print as a function parameter (because it is a userdata, even though it has a __call metamethod). Fortunately, it can be solved in Lua by creating a pure Lua function, like this:
do
local oldprint = print
function print(...) oldprint(...) end
end
I decided to use lua_pushcclosure, as it allows you to 'store' arbitrary values on functions that can be retrieved with the lua_upvalueindex macro.
There is also Kahlua vs LuaJava.
It is mentioned in this book: http://books.google.com/books?id=2v55tfq9rosC&lpg=PA166&ots=9RRVaz5JjP&dq=krka%20kahlua%20blog&pg=PA166#v=onepage&q&f=false
The development blog:
http://krkadev.blogspot.com/2010/05/getting-started-with-kahlua2.html
I am coding up something using the JNI Invocation API. A C program starts up a JVM and makes calls into it. The JNIenv pointer is global to the C file. I have numerous C functions which need to perform the same operation on a given class of jobject. So I wrote helper functions which take a jobject and process it, returning the needed data (a C data type...for example, an int status value). Is it safe to write C helper functions and pass jobjects to them as arguments?
i.e. (a simple example - designed to illustrate the question):
int getStatusValue(jobject jStatus)
{
return (*jenv)->CallIntMethod(jenv,jStatus,statusMethod);
}
int function1()
{
int status;
jobject aObj = (*jenv)->NewObject
(jenv,
aDefinedClass,
aDefinedCtor);
jobject j = (*jenv)->CallObjectMethod
(jenv,
aObj,
aDefinedObjGetMethod)
status = getStatusValue(j);
(*jenv)->DeleteLocalRef(jenv,aObj);
(*jenv)->DeleteLocalRef(jenv,j);
return status;
}
Thanks.
I'm not acquainted with the details of JNI, but once thing I noticed is this:
return (*jenv)->CallIntMethod(jenv,jStatus,statusMethod);
That looks like the official JNI code and it is taking a jobect as a parameter. If it works for JNI, there is no reason it can't work for your code.
All jni objects are valid until the native method returns. As long as you dont store non global jni objects between two jni calls everything should work.
The invocation of a jni function should work like this:
Java function call
create native local references
call native function
do your stuff
exit native function
release existing local references
return to java
The step 4 can contain any code, local references stay valid until step 6 if not release before.
If you want to store jni objects on the c side between two calls to a native java function you have to create global references and release them later. Not releasing a global reference leads to memory leaks as the garbage collector is unable to free the related java objects.
At the moment, i'm trying to create a Java-application which uses CUDA-functionality. The connection between CUDA and Java works fine, but i've got another problem and wanted to ask, if my thoughts about it are correct.
When i call a native function from Java, i pass some data to it, the functions calculates something and returns a result. Is it possible, to let the first function return a reference (pointer) to this result which i can pass to JNI and call another function that does further calculations with the result?
My idea was to reduce the overhead that comes from copying data to and from the GPU by leaving the data in the GPU memory and just passing a reference to it so other functions can use it.
After trying some time, i thought for myself, this shouldn't be possible, because pointers get deleted after the application ends (in this case, when the C-function terminates). Is this correct? Or am i just to bad in C to see the solution?
Edit:
Well, to expand the question a little bit (or make it more clearly): Is memory allocated by JNI native functions deallocated when the function ends? Or may i still access it until either the JNI application ends or when i free it manually?
Thanks for your input :)
I used the following approach:
in your JNI code, create a struct that would hold references to objects you need. When you first create this struct, return its pointer to java as a long. Then, from java you just call any method with this long as a parameter, and in C cast it to a pointer to your struct.
The structure will be in the heap, so it will not be cleared between different JNI calls.
EDIT: I don't think you can use long ptr = (long)&address; since address is a static variable. Use it the way Gunslinger47 suggested, i.e. create new instance of class or a struct (using new or malloc) and pass its pointer.
In C++ you can use any mechanism you want to allocate/free memory: the stack, malloc/free, new/delete or any other custom implementation. The only requirement is that if you allocated a block of memory with one mechanism, you have to free it with the same mechanism, so you can't call free on a stack variable and you can't call delete on malloced memory.
JNI has its own mechanisms for allocating/freeing JVM memory:
NewObject/DeleteLocalRef
NewGlobalRef/DeleteGlobalRef
NewWeakGlobalRef/DeleteWeakGlobalRef
These follow the same rule, the only catch is that local refs can be deleted "en masse" either explicitly, with PopLocalFrame, or implicitly, when the native method exits.
JNI doesn't know how you allocated your memory, so it can't free it when your function exits. Stack variables will obviously be destroyed because you're still writing C++, but your GPU memory will remain valid.
The only problem then is how to access the memory on subsequent invocations, and then you can use Gunslinger47's suggestion:
JNIEXPORT jlong JNICALL Java_MyJavaClass_Function1() {
MyClass* pObject = new MyClass(...);
return (long)pObject;
}
JNIEXPORT void JNICALL Java_MyJavaClass_Function2(jlong lp) {
MyClass* pObject = (MyClass*)lp;
...
}
While the accepted answer from #denis-tulskiy does make sense, I've personnally followed suggestions from here.
So instead of using a pseudo-pointer type such as jlong (or jint if you want to save some space on 32bits arch), use instead a ByteBuffer. For example:
MyNativeStruct* data; // Initialized elsewhere.
jobject bb = (*env)->NewDirectByteBuffer(env, (void*) data, sizeof(MyNativeStruct));
which you can later re-use with:
jobject bb; // Initialized elsewhere.
MyNativeStruct* data = (MyNativeStruct*) (*env)->GetDirectBufferAddress(env, bb);
For very simple cases, this solution is very easy to use. Suppose you have:
struct {
int exampleInt;
short exampleShort;
} MyNativeStruct;
On the Java side, you simply need to do:
public int getExampleInt() {
return bb.getInt(0);
}
public short getExampleShort() {
return bb.getShort(4);
}
Which saves you from writing lots of boilerplate code ! One should however pay attention to byte ordering as explained here.
Java wouldn't know what to do with a pointer, but it should be able to store a pointer from a native function's return value then hand it off to another native function for it to deal with. C pointers are nothing more than numeric values at the core.
Another contibutor would have to tell you whether or not the pointed to graphics memory would be cleared between JNI invocations and if there would be any work-arounds.
I know this question was already officially answered, but I'd like to add my solution:
Instead of trying to pass a pointer, put the pointer in a Java array (at index 0) and pass that to JNI. JNI code can get and set the array element using GetIntArrayRegion/SetIntArrayRegion.
In my code, I need the native layer to manage a file descriptor (an open socket). The Java class holds a int[1] array and passes it to the native function. The native function can do whatever with it (get/set) and put back the result in the array.
If you are allocating memory dynamically (on the heap) inside of the native function, it is not deleted. In other words, you are able to retain state between different calls into native functions, using pointers, static vars, etc.
Think of it a different way: what could you do safely keep in an function call, called from another C++ program? The same things apply here. When a function is exited, anything on the stack for that function call is destroyed; but anything on the heap is retained unless you explicitly delete it.
Short answer: as long as you don't deallocate the result you're returning to the calling function, it will remain valid for re-entrance later. Just make sure to clean it up when you're done.
Its best to do this exactly how Unsafe.allocateMemory does.
Create your object then type it to (uintptr_t) which is a 32/64 bit unsigned integer.
return (uintptr_t) malloc(50);
void * f = (uintptr_t) jlong;
This is the only correct way to do it.
Here is the sanity checking Unsafe.allocateMemory does.
inline jlong addr_to_java(void* p) {
assert(p == (void*)(uintptr_t)p, "must not be odd high bits");
return (uintptr_t)p;
}
UNSAFE_ENTRY(jlong, Unsafe_AllocateMemory(JNIEnv *env, jobject unsafe, jlong size))
UnsafeWrapper("Unsafe_AllocateMemory");
size_t sz = (size_t)size;
if (sz != (julong)size || size < 0) {
THROW_0(vmSymbols::java_lang_IllegalArgumentException());
}
if (sz == 0) {
return 0;
}
sz = round_to(sz, HeapWordSize);
void* x = os::malloc(sz, mtInternal);
if (x == NULL) {
THROW_0(vmSymbols::java_lang_OutOfMemoryError());
}
//Copy::fill_to_words((HeapWord*)x, sz / HeapWordSize);
return addr_to_java(x);
UNSAFE_END