B4Alpha-Aft3r0mega / javacpp

Automatically exported from code.google.com/p/javacpp
GNU General Public License v2.0
0 stars 0 forks source link

Feature Request: Provide Means to Access jvm #21

Closed GoogleCodeExporter closed 8 years ago

GoogleCodeExporter commented 8 years ago
What steps will reproduce the problem?
1. Attempt to put a Java method call into c++. You can't do it!
2.
3.

What is the expected output? What do you see instead?
Not Relevant.

What version of the product are you using? On what operating system?
Latest on RHEL 5.6

Please provide any additional information below.
I got around this by placing this in my C++ program within the namespace but 
outside of any class:

JavaVM *jvm;

I then purposely placed an error in the C++ to stop javacpp from deleting the 
intermediate c++ file so I could place a line of code to set the jvm. 

Worked like a charm. This would be a killer feature, allowing javacpp to be 
used for new development work that requires bidirectional conversation between 
Java and C++. Not having to fight jni wars and put all that baloney in the  C++ 
code is wonderful, just like jni should have been released from Sun over a 
decade ago...

Original issue reported on code.google.com by wtrib...@gmail.com on 6 Jun 2012 at 12:22

GoogleCodeExporter commented 8 years ago
Isn't that exactly what Jace does? http://code.google.com/p/jace/

Original comment by samuel.a...@gmail.com on 6 Jun 2012 at 1:58

GoogleCodeExporter commented 8 years ago
BTW, if the only thing you need to get is a pointer to the JavaVM, we can do 
that with the @Raw annotation, i.e.: 
    public static native @Raw(withEnv=true) void putEnv();
which maps to
    void putEnv(JavaVM*, jclass*);
Is this all you are looking for?

Original comment by samuel.a...@gmail.com on 6 Jun 2012 at 2:26

GoogleCodeExporter commented 8 years ago
Yes. If that could be implemented it would be wonderful. We would then have
a bidirectional turnkey solution that works easily. If you would like me to
write a quick howto on the Eclipse side (took me a little while to figure
out that I had to associate the shared library with the javacpp jar file, I
also needed to figure out how to arrange the jni scripts and source files)
I would be willing to do that. Most likely when others read it they will be
able to suggest improvements.

Thanks for pointing me to jace. That is actually harder than javacpp, but a
lot more powerful. Our needs are very simple, with javacpp it was really
quick to hook up our c++ code to Java without thinking about the mechanics.
I just got javacpp fully integrated with Eclipse and our java/c++ code
components. It has worked very well up to now, the real development begins
from now but I am confident that it will work well.

Original comment by wtrib...@gmail.com on 6 Jun 2012 at 10:53

GoogleCodeExporter commented 8 years ago
That functionality is already there, as per issue 13, so I guess I'll mark that 
as a duplicate. Oh and I made a mistake. That declaration would actually map to 
    void putEnv(JNIEnv*, jclass*);
from which we can `GetJavaVM()` if desired..

As for Eclipse, not sure what the problem is. The `Builder` puts shared 
libraries along with the compiled class files, so there should not be a need to 
do anything special... What exactly is not working?

Original comment by samuel.a...@gmail.com on 7 Jun 2012 at 1:19

GoogleCodeExporter commented 8 years ago
Or do you mean you had trouble getting Eclipse to call JavaCPP at build time? 
Sure, we could use some documentation. I can give you access to create Wiki 
pages, let me know if you would like to create one, thanks!

Original comment by samuel.a...@gmail.com on 9 Jun 2012 at 1:22

GoogleCodeExporter commented 8 years ago
Samuel,
I would be happy to add Eclipse-related docs to the wiki. Best to do that
once our project is just a little more mature.

Right now I have put in symlinks in a separate directory structure to build
manually. Issue was, we needed to point Eclipse at the manually built
shared library.

To step back, here is what happened:

* Had a Java and C++ requirement, decided to use jni (!!)
* Remembered pain of jni from when I last did it a decade ago...
* Found javacpp, Aped the example and got it to work with plain files.
* Now need to use it for-real. So, I put in some symlinks to expose the
project C++ files and run g++ on the generated jni_name_.cpp file generated
by javacpp using the includes that point to my C++ code.

## Problem Here: Native methods not found at runtime.

So, to solve I had to manually go into Eclipse and under javacpp.jar add
the shared library as the native library reference. This would go away if
we built a jar, that will come later.

Building Note
It turns out that the generated jni_name_.cpp file only changes if the Java
class accessing native methods changes anything to do with native methods.
Other changes to that Java file are ignored. So, we don't have to run
javacpp.jar  again once we have our interface defined, which is the first
thing we do. What we do have to do is run gcc on jni_name_.cpp if we change
our C++ code so that a new .so with all our new stuff in it is generated. A
new wrinkle we have now is that the project has grown bigger than one .h
and .cpp file, right now the command line to generate the library does not
include the other c++ files, so there are missing objects resulting in
missing symbols at runtime...

If there is an easier way

Original comment by wtrib...@gmail.com on 12 Jun 2012 at 3:26

GoogleCodeExporter commented 8 years ago
Added the c++ files for other objects to the build script, no issues there.
I may list all the C++ files needed in the include clause in the Java
class. This would make the whole build seamless, it could be called each
time from within Eclipse.

Have not yet had the chance to test the @ variable for the jvm. I don't
think you can pass JNIEnv * that way, because there is one of these
pointers for every thread, only the jvm is consistent across all threads.

Original comment by wtrib...@gmail.com on 13 Jun 2012 at 1:16

GoogleCodeExporter commented 8 years ago
When you say "native library reference", are you talking about the 
"java.library.path" property? There is a "Native library location" field in 
Eclipse that seems to do that alright. (I see Eclipse continues to not 
dissapoint in making simple things complicated.) Anyway, we don't need that if 
we let the `Builder` put the native libraries in the build directory. The 
`Loader` finds them as Java resources, so there is no need to mess around with 
that.

BTW, we can call "java -jar javacpp.jar" from makefiles or other native build 
tools. I'm not sure what the issue is wrt to JavaCPP here... ?

Original comment by samuel.a...@gmail.com on 13 Jun 2012 at 1:27

GoogleCodeExporter commented 8 years ago
The issue is probably my own ignorance. The example shows all the c++ in a
single include that lives in the same directory as the .java file. When
javacpp.jar is run, the output jni*.cpp generated file is put with the
compiled class and the .so library in a platform-named subdirectory.

If you just put this in the Eclipse source tree, when the project is
cleaned all the files are nuked. Ouch.

I have resorted to doing the build in a jni directory outside Eclipse. We
have 7 c++ source files that make up the system. So, if I am to fully
automate I need to put each of the 7 files in the Java class with a
relative path that will be valid from the place that javacpp does the
compile. I then need to manually set the "Native library location" field
for javacpp. jar within Eclipse to point to this out-of-directory spot.

At any rate, this is all relatively insignificant. A wiki on how to use
Eclipse would be short and would cover all this, it is easy to set up.

Are there options to javacpp.jar such that when it runs the output file
location, as well as extra include directories, etc. (really the command
line for g++) could be customized? Right now what I do is have an invalid
include directive in the java file so that the jni*.cpp file is not deleted
at the end of the compile. I then see from the echo how to set up g++, I
add the flags like -lrt and -lpthreads and put this in a shell script. That
is then run against the c++.

Original comment by wtrib...@gmail.com on 13 Jun 2012 at 1:53

GoogleCodeExporter commented 8 years ago
Like I said, we can call `JNIEnv->GetJavaVM()` to get the JavaVM object.

I'll reply to the rest on the mailing list, let me know if you receive it.

Original comment by samuel.a...@gmail.com on 13 Jun 2012 at 8:09