4

Background
My application has now reached a bottleneck where the slowest part of it is the AES encrypt and decrypt streams through which all data must pass. In order to overcome this I plan to implement this ciphering in native code via JNI and OpenSSL so that I may take advantage of things like AES-NI and direct memory access (my buffers are already direct, so I can already get a pointer to their memory region)

The Issue
It doesn't make sense to recreate the OpenSSL cipher with the key every time I need to cipher or decipher some data. If I were using Java I would simply store the Cipher instance as a field in the class, however since the cipher is a C "object", I can't do this.

The Question
How to tie a C "object" to a Java class instance, so that subsequent invocations can use the stored "object". I imagine this has something to do with storing the "object" pointer as a long into the Java class, and then dereferencing it, however I am not quite sure that this is entirely cross platform.

The Answer
Must be:

  • Simplistic
  • Fast
  • Cross platform

Thanks for your time!

md_5
  • 630
  • 9
  • 26
  • 1
    possible duplicate of [What is the 'correct' way to store a native pointer inside a Java object?](http://stackoverflow.com/questions/337268/what-is-the-correct-way-to-store-a-native-pointer-inside-a-java-object) – Sergey Kalinichenko Aug 22 '13 at 12:20
  • @dasblinkenlight I'd prefer the method I cited here: http://stackoverflow.com/questions/14968547/android-using-jni-without-static-variables/15006577#15006577 over storing pointers as long integers. – junix Aug 24 '13 at 07:05

2 Answers2

1

Since you are passing bulk data, I suggest using a direct ByteBuffer. This is a window into native memory from Java. i.e. once you have written to the ByteBuffer it is already copied to native memory. From C, you can get the address and use it as a pointer to memory which doesn't move.

If you just need cross OSes, but you are using an OpenJDK based JVM, you can use Unsafe to access native memory directly by address (just like a pointer). I suggest you wrap this up in class(es) and test it thoroughly.

Peter Lawrey
  • 525,659
  • 79
  • 751
  • 1,130
  • This isn't anything to do with my question. I've already stated that I'm using native buffers and have direct access to their memory address. What I NEED is a way to create a variable in C land, and store associate it with my Java object. – md_5 Aug 22 '13 at 09:25
  • I suspect this is a bad idea. You can do this, but I suggest you not. This will complicate GCing as you have a reference from C to a Java object. If you discard this reference incorrectly, it will never be cleaned up. – Peter Lawrey Aug 22 '13 at 09:35
  • 1
    I can assure you I am perfectly capable of managing the references. I'm pretty sure I'm on the right track of using a long in the java class to point to my C objects, however confirmation that this is indeed cross platform and that there isn't a better way would be nice. – md_5 Aug 22 '13 at 09:41
1

You can create a variable private int mNativeObj in Java Object, and a method to save native pointer, like public void setNativeObject(int pointer). In C code, call CallVoidMethod() to save the pointer to Java Object. You can refer to Oracle's doc.

yushulx
  • 11,695
  • 8
  • 37
  • 64
  • 2
    Thanks, my main concern here though is shouldn't the pointer be a long (to account for 64 bit servers), would making it long then break 32 bit servers? – md_5 Aug 22 '13 at 09:50
  • you're right. If consider about 64 bit, you should choose long – yushulx Aug 22 '13 at 09:53