Correct way to load jvm.dll in a JNI application?

E

Elena

Hello,

I've developed a native application which loads a Java class at
runtime via JNI. Required JRE is 1.6 or newer.

Since availability of JRE should be optional, I'm looking for jvm.dll
at runtime. I'm not sure about how to properly find its path.
Currently I'm querying the Windows registry like this:
- read value at HKEY_LOCAL_MACHINE\SOFTWARE\JavaSoft\Java Runtime
Environment\CurrentVersion;
- read value HKEY_LOCAL_MACHINE\SOFTWARE\\JavaSoft\\Java Runtime
Environment\<CurrentVersion>\RuntimeLib

Then I put jvm.dll's folder in front of process' PATH environment
variable and then execute:

JavaVM *vm=NULL;
JNIEnv* java_env=NULL;
JavaVMInitArgs vm_args={0};
vm_args.version = JNI_VERSION_1_6;
JNI_GetDefaultJavaVMInitArgs(&vm_args);
// assignment of vm_args.options skipped...
JNI_CreateJavaVM(&vm, (void **)&java_env, &vm_args)) ;

It works, but is it the proper way?

Thanks.
 
R

Roedy Green

Then I put jvm.dll's folder in front of process' PATH environment
variable and then execute:

If you launch with Java Web Start it will install the DLLs for you.

See http://mindprod.com/jgloss/registry.html for more info on how to
do it your way.

You can also look at system properties.

java.ext.dirs = C:\Program
Files\Java\jre6\lib\ext;C:\Windows\Sun\Java\lib\ext

java.library.path = F:\Program Files\Opera 10
Beta;.;C:\Windows\Sun\Java\bin;C:\Windows\system32;C:\Windows;E:\Program
Files\jet6.5-pro\bin;E:\Program
Files\Java\jdk1.6.0_14\bin;E:\env;E:\sys\;F:\Program
Files\jpsoft\tcmd10;F:\Program Files\vslick\win;F:\Program
Files\apache-ant-1.7.1\bin;C:\Windows\system32;C:\Windows;C:\Windows\System32\Wbem;E:\com\mindprod\reorg;F:\Program
Files\TortoiseSVN\bin;F:\program files\asm;F:\Program Files\Microsoft
Visual Studio 9.0\VC\bin;C:\Program
Files\QuickTime\QTSystem\;F:\Program Files\SlikSvn\bin\;F:\Program
Files\Vslick\win

You can also do a getEnv("path");

--
Roedy Green Canadian Mind Products
http://mindprod.com

"The industrial civilisation is based on the consumption of energy resources that are inherently limited in quantity, and that are about to become scarce. When they do, competition for what remains will trigger dramatic economic and geopolitical events; in the end, it may be impossible for even a single nation to sustain industrialism as we have know it in the twentieth century."
~ Richard Heinberg, The Party’s Over: Oil, War, and the Fate of Industrial Societies
 
J

jolz

Currently I'm querying the Windows registry like this:
- read value at HKEY_LOCAL_MACHINE\SOFTWARE\JavaSoft\Java Runtime
Environment\CurrentVersion;
- read value HKEY_LOCAL_MACHINE\SOFTWARE\\JavaSoft\\Java Runtime
Environment\<CurrentVersion>\RuntimeLib

I don't think java is required to put anything in the registry. Also
there may be installed JDK without JRE and the key in registry may be
different (it is different with Sun's JVM). The may be also several
different JVMs in the registry.
Trying to guess correct JVM location is a good idea but you should
consider to let end user configure the location.
Then I put jvm.dll's folder in front of process' PATH environment
variable and then execute:

JavaVM *vm=NULL;
JNIEnv* java_env=NULL;
JavaVMInitArgs vm_args={0};
vm_args.version = JNI_VERSION_1_6;
JNI_GetDefaultJavaVMInitArgs(&vm_args);
// assignment of vm_args.options skipped...
JNI_CreateJavaVM(&vm, (void **)&java_env, &vm_args)) ;

Try loading java library dynamically (on windows start with
LoadLibrary() function) - this way you won't have to link your
application with jvm.lib and in case of any error you can handle it in
the application (default windows behaviour is to show message box and
stop loading application).
 
E

Elena

I don't think java is required to put anything in the registry. Also
there may be installed JDK without JRE and the key in registry may be
different (it is different with Sun's JVM). The may be also several
different JVMs in the registry.

I understand that, but then which is a proper way to locate Java from
a native application? On my system, issuing "java -version" gives:

java version "1.6.0_13"
Java(TM) SE Runtime Environment (build 1.6.0_13-b03)
Java HotSpot(TM) Client VM (build 11.3-b02, mixed mode, sharing)

Whilst, querying for "JAVA_HOME" gives:

JAVA_HOME=C:\Programmi\Java\jdk1.6.0_02

That is: they are not aligned (1.6.0_13 vs 1.6.0_02) and JAVA_HOME is
older. That's why I'm looking into the registry to find more recent
JVM's path.

Moreover, having developed an application which relies on Java 1.6,
should I demand a JRE 1.6 or a JRE 1.6 or higher (that is: 1.7, ecc.)?
Trying to guess correct JVM location is a good idea but you should
consider to let end user configure the location.

That would be a pragmatic solution. Thanks.
Try loading java library dynamically (on windows start with
LoadLibrary() function) - this way you won't have to link your
application with jvm.lib and in case of any error you can handle it in
the application (default windows behaviour is to show message box and
stop loading application).

I'm already doing that (code seems statically linked because I'm
relying ugon the linker to delay loading of jvm.dll).
 
E

Elena

If you launch with Java Web Start it will install the DLLs for you.

Seehttp://mindprod.com/jgloss/registry.htmlfor more info on how to
do it your way.

You can also look at system properties.

java.ext.dirs = C:\Program
Files\Java\jre6\lib\ext;C:\Windows\Sun\Java\lib\ext

java.library.path = F:\Program Files\Opera 10
Beta;.;C:\Windows\Sun\Java\bin;C:\Windows\system32;C:\Windows;E:\Program
Files\jet6.5-pro\bin;E:\Program
Files\Java\jdk1.6.0_14\bin;E:\env;E:\sys\;F:\Program
Files\jpsoft\tcmd10;F:\Program Files\vslick\win;F:\Program
Files\apache-ant-1.7.1\bin;C:\Windows\system32;C:\Windows;C:\Windows\System32\Wbem;E:\com\mindprod\reorg;F:\Program
Files\TortoiseSVN\bin;F:\program files\asm;F:\Program Files\Microsoft
Visual Studio 9.0\VC\bin;C:\Program
Files\QuickTime\QTSystem\;F:\Program Files\SlikSvn\bin\;F:\Program
Files\Vslick\win

You can also do a getEnv("path");

--
Roedy Green Canadian Mind Productshttp://mindprod.com

"The industrial civilisation is based on the consumption of energy resources that are inherently limited in quantity, and that are about to become scarce. When they do, competition for what remains will trigger dramatic economic and geopolitical events; in the end, it may be impossible for even a single nation to sustain industrialism as we have know it in the twentieth century."
~ Richard Heinberg,  The Party’s Over: Oil, War, and the Fate of Industrial Societies

Thank you for your suggestion, but I can't do that, since I'm calling
Java from a native application.
 
R

Roedy Green

JAVA_HOME=C:\Programmi\Java\jdk1.6.0_02

Seems to me, it is up to you to manually maintain JAVA_HOME. The
install modifies the registry.

On the other paw, there are private JVMs not mentioned in the
Registry, and then there is the JET jvm which will not be mentioned in
the registry either.
--
Roedy Green Canadian Mind Products
http://mindprod.com

"The industrial civilisation is based on the consumption of energy resources that are inherently limited in quantity, and that are about to become scarce. When they do, competition for what remains will trigger dramatic economic and geopolitical events; in the end, it may be impossible for even a single nation to sustain industrialism as we have know it in the twentieth century."
~ Richard Heinberg, The Party’s Over: Oil, War, and the Fate of Industrial Societies
 
L

Lew

Elena said:
I understand that, but then which is a proper way to locate Java from
a native application?

If it's not in the PATH or the JAVA_HOME, you have to let the user configure
it or give up. If PATH and JAVA_HOME disagree, just pick one. jolz has
already answered your questions.
That is: they are not aligned (1.6.0_13 vs 1.6.0_02) and JAVA_HOME is
older. That's why I'm looking into the registry to find more recent
JVM's path.

You don't have to find the most recent Java version. You just have to find a
Java version. The user might not want your app to use the most recent version.
Moreover, having developed an application which relies on Java 1.6,
should I demand a JRE 1.6 or a JRE 1.6 or higher (that is: 1.7, ecc.)?

The "version or higher" choice, obviously.
That would be a pragmatic solution. Thanks.

What others have told you: to get the very latest Java on a system, you really
cannot rely on the registry. You cannot rely on JAVA_HOME. You can perhaps
rely on PATH, but not necessarily. In short, there is no programmatic way to
get the latest Java version. Beyond what they told you, if the user has made
some version of Java available through one of those mechanisms, you can use
that one. It need not be the latest if it meets your minimum. If none
suitable are found, you can ask (not demand) the user to provide one, or you
can give up.
 
E

Elena

What others have told you: to get the very latest Java on a system, you really
cannot rely on the registry.  You cannot rely on JAVA_HOME.  You can perhaps
rely on PATH, but not necessarily.  In short, there is no programmatic way to
get the latest Java version.  Beyond what they told you, if the user has made
some version of Java available through one of those mechanisms, you can use
that one.  It need not be the latest if it meets your minimum.  If none
suitable are found, you can ask (not demand) the user to provide one, or you
can give up.

Then the scenario would be like this: if loading jvm.dll at runtime
because of JNI calls fails, then I should let the user decide whether
to fix her environment or tell the application which JRE to use. Do
you agree?

Thanks.
 
J

jolz

Try loading java library dynamically (on windows start with
I'm already doing that (code seems statically linked because I'm
relying ugon the linker to delay loading of jvm.dll).

If you link the application dynamically using jvm.lib it means that
jvm.dll must be present to start the application. However if you use
LoadLibrary()/GetProcAddress() functions you won't have to link with
jvm.dll at all. You will load jvm.dll after the application is loaded
and you will be fully controling JVM loading process. For example you
can show message box asking for JVM location if it isn't configured yet.
And selected dll doesn't even have to be named jvm.dll.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,020
Latest member
GenesisGai

Latest Threads

Top