Jump to content

Trying to launch Java VM through JNI_CreateJavaVM

Recommended Posts


I am writing a EXE launcher for a Java application using AutoIt. It works fine when starting Java through ShellExecute, but for several reasons I would like to call it through the DLL (so that I don't create a separate process)

But I can't figure out how to provided the needed DLL struct for the call. The problem is, that it's a nested struct, where the nested element is an array of char* pointers.

The JDK documentation contains an example: https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/invocation.html#JNI_CreateJavaV

JavaVMInitArgs vm_args;
JavaVMOption options[4];

// Defining the array and filling the elements is the part I don't know how to do with AutoIt
// (Don't mind the content here)
options[0].optionString = "-Djava.compiler=NONE";           /* disable JIT */
options[1].optionString = "-Djava.class.path=c:\myclasses"; /* user classes */
options[2].optionString = "-Djava.library.path=c:\mylibs";  /* set native library path */
options[3].optionString = "-verbose:jni";                   /* print JNI-related messages */

vm_args.version = JNI_VERSION_1_2;
vm_args.options = options;
vm_args.nOptions = 4;
vm_args.ignoreUnrecognized = TRUE;

res = JNI_CreateJavaVM(&vm, (void **)&env, &vm_args);

The two structs are defined this way:

typedef struct JavaVMOption {
    char *optionString;
    void *extraInfo;
} JavaVMOption;

typedef struct JavaVMInitArgs {
    jint version;

    jint nOptions;
    JavaVMOption *options;
    jboolean ignoreUnrecognized;
} JavaVMInitArgs;

This is what I came up with so far:

Local $optionArray[2]
  $optionArray[0] = "-cp MyApp.jar"
  $optionArray[1] = "MyMain"
  $env = 0
  $option = DllStructCreate("struct;char* optionString;ptr extraInfo;endstruct")
  $vmInitArgs = DllStructCreate("struct;LONG version;LONG nOptions;ptr options;BOOLEAN ignoreUnrecognized;endstruct")

  ; Not sure if this is correct
  DllStructSetData($option, "optionString", $optionArray)

  DllStructSetData($vmInitArgs, "version", 0x00010008)
  DllStructSetData($vmInitArgs, "nOptions", 2)
  DllStructSetData($vmInitArgs, "options", DllStructGetPtr($option))
  DllStructSetData($vmInitArgs, "ignoreUnrecognized", 1)
  Local $handle = DllOpen($dllPath)
  $res = DllCall($handle, "INT", "JNI_CreateJavaVM", "ptr*", $env, "ptr", DllStructGetPtr($vmInitArgs))
  ConsoleWrite("*** Error: " & @error & @CRLF)
  ConsoleWrite("*** Result: " & $res[0] & @CRLF)

I also tried calling DllStructSetData with an index number rather than the "member name". I also tried calling DllStructCreate without the "struct/endstruct" markers and without the member names.

The @error code is always 0, but $res[0] contains an error code (-3) which in theory indicates that the JNI version is incorrect, but most answers I found indicate that this can also mean the JavaVMInitArgs struct was not populated correctly.

I have no experience with C/C++ programming so I am at a loss with mapping the information from the Java docs to AutoIt

Any ideas?

Thanks in advance


Link to comment
Share on other sites

  • 2 months later...

Because Java can't create native Windows .exe files. And I want a custom launcher to run my Java application that can download a Java VM if none was found. It was quite easy to do that using AutoIt and starting Java through ShellExecuteWait(). But that creates two processes and for several reasons I would like to only have a single process.

Link to comment
Share on other sites

I know those alternatives, but none of them let me e.g. customize the download. That's why I decided to write my own - and it was really easy using AutoIt, but I had to use ShellExecuteWait() and I would rather only have a single process.

But it seems that I need to ditch AutoIt anyway as the generated .exe is being reported by multiple anti-virus programs and my users start complaining.


Link to comment
Share on other sites

  • 1 month later...

I am aware that it's a false positive, but my tool has about 20.000 downloads per month, and I can't tell everybody to manually upload the files. What's even worse, that some browsers refuse to download the ZIP archive with the generated EXE completely, so those users don't even have the chance to report it as a false positive.

So I decided to abandon AutoIt completely. I will check back if this is fixed in a future release.

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

  • Recently Browsing   0 members

    • No registered users viewing this page.
  • Create New...