This discussion is archived
14 Replies Latest reply: Oct 26, 2012 6:28 AM by 970173 RSS

How to Provide Native Methods in an Executable?

970173 Newbie
Currently Being Moderated
Hey there,

I'm writing a native Java launcher as a replacement for java.exe (or eclipse.exe). So far I'm only on Windows NT x64. Things work pretty well: My native executable launches the JVM using the Invocation API and calls a static `main' method.

Now I thought it was a good idea if my executable could provide the implementations of a few native methods so the `jvm.dll' can communicate with the executable that it was loaded by. This would free me from having to locate and load a shared library at runtime. I expected this to "just work," but alas, it didn't. Providing a simple native method such as

-----
JNIEXPORT jboolean JNICALL
Java_com_phrood_kourou_Kourou_available0(JNIEnv* env, jclass cls) {
return JNI_TRUE;
}
-----

in the executable and calling it from Java through JNI, I get an `UnsatisfiedLinkError'. Why is that so? Both the executable and the DLL live in the same process, so shouldn't the C function be found without further concern?

Then I came up with the somewhat experimental idea and just loaded the EXE file from Java by `System.load(pathToExe)'. I never expected this to work, but---it did!

That's good news, of course. Only I'm afraid that's a lot more memory-consuming than it needs to be. My EXE file has some 200 KB and counting, and I only need I a handful of small native-method implementations. I could write a DLL, of course, but I'd like to do without an extra file and an extra project to set up and maintain.

So, my question is: Why do I have to load the EXE into the same process a second time? Is there a more elegant solution?

Regards,
-- Phil
  • 1. Re: How to Provide Native Methods in an Executable?
    gimbal2 Guru
    Currently Being Moderated
    Yes, put your shared functionality into a shared library.

    Adding your own native logic into your application framework is the thing that is making your life difficult, not the fact that you have to work with DLLs. Java works best when you have pure Java solutions and just use the runtime as it was designed and intended.
  • 2. Re: How to Provide Native Methods in an Executable?
    970173 Newbie
    Currently Being Moderated
    If the whole point of my project is to provide a native launcher to fire off the JVM, then how would a pure Java solution help?

    As I wrote, I would know how to do it with a DLL. But why write a DLL if I already have a native executable that is part of the process?

    I would like to hear why a DLL doesn't see the functionality provided by the executable that loaded it. Or, should it do so, what I did wrong.

    What happens if I pass an EXE file to `System.load' anyway? Is the whole file read and kept in memory, or only the portions that it exports via `__declspec(dllexport)'?

    Edited by: 967170 on 23.10.2012 09:03
  • 3. Re: How to Provide Native Methods in an Executable?
    DrClap Expert
    Currently Being Moderated
    Other people who write Windows executables seem to write supporting DLLs and distribute them as a matter of course. That's a perfectly normal thing to do in the Windows world. You write your executable, you write your DLLs, you create an MSI installer to install them all, and you're done.

    So it seems to me you have a non-problem which is only becoming a problem because you want to do things in a nonstandard way.
  • 4. Re: How to Provide Native Methods in an Executable?
    970173 Newbie
    Currently Being Moderated
    It doesn't work anyway. Although I can load my EXE as a DLL, the newly-loaded image has its own address space, so I cannot use that to call back the EXE.

    I think I can acomplish what I need without a DLL altogether. Hopefully.

    I want the usage of my executable to be as simple as using `java.exe'. Clients should just write a configuration file, rename and start or double-click the EXE and that's it. An MSI would be pointless here, since the usage of the launcher is completely generic.

    More importantly, maintaining cross-platforms C++ projects with Eclipse CDT is possible but a bit of a hassle. I already have two projects: one for the EXE and one for the Java companion Jar. Creating a new DLL project would require me to maintain 3 Eclipse build configurations for Windows, Linux, and Mac; and even another three should I support the x86 architecture. I'd be happy if I could do without.

    What strikes me is that you folks try to teach me what I should do or not do, even call my problem a "nonproblem," rather than just help me out and try to answer my questions. None of the answers here were helpful to me, but I think I figured it out.

    Nonetheless, thanks for taking the time to read and answer.
  • 5. Re: How to Provide Native Methods in an Executable?
    970173 Newbie
    Currently Being Moderated
    Thinking about it again, I'm not sure whether a DLL would really solve my problem.

    Let's say I have a native class in a DLL that I want to access both from the EXE and from Java through JNI, using the same address space. How would I do that?

    My EXE would load `my.dll' and use `MyClass'. Okay.

    My EXE would then load `jvm.dll', fire off the JVM, have it use a Java class of mine with a native method that needs access to `MyClass'.

    Now what would happen? Would the Java DLL see `my.dll'? My guess is it would not unless I load it a second time via `System.loadLibrary', meaning there would be two instances of the DLL, which is obviously not what I want.

    It all boils down to my original question which hasn't been answered yet: Can a DLL call functions provided by the EXE it was loaded by? I don't see why that is a "nonproblem" or an esoteric question. And what about Linux?

    I'd have to make an experiment. But, as I sad, it looks like I don't need native methods anyway.
  • 6. Re: How to Provide Native Methods in an Executable?
    EJP Guru
    Currently Being Moderated
    A DLL is only loaded once into any process. Subsequent loads only increment a usage counter, so that the same number of unloads is required to really unload it.

    This is all documented stuff.
  • 7. Re: How to Provide Native Methods in an Executable?
    jschellSomeoneStoleMyAlias Expert
    Currently Being Moderated
    Philip Köster wrote:
    That's good news, of course. Only I'm afraid that's a lot more memory-consuming than it needs to be. My EXE file has some 200 KB and counting, and I only need I a handful of small native-method implementations. I could write a DLL, of course, but I'd like to do without an extra file and an extra project to set up and maintain.

    So, my question is: Why do I have to load the EXE into the same process a second time? Is there a more elegant solution?
    Your assumptions about how modern operating systems work is wrong.

    As noted in another response the shared library is not loaded twice. Not on windows. Not on linux.

    And your exe wasn't loaded twice either. (Although I am presuming that you think it was in fact loaded twice versus that you think it gets unloaded somehow after the VM starts - it doesn't.)
  • 8. Re: How to Provide Native Methods in an Executable?
    970173 Newbie
    Currently Being Moderated
    Okay, I didn't know that. So the code isn't duplicated, but the static data is?

    Anyway I don't want to load the EXE again because it was already loaded.

    And sorry for asking a question about something that is documented somewhere. And, again, thanks for not answering my question.
  • 9. Re: How to Provide Native Methods in an Executable?
    EJP Guru
    Currently Being Moderated
    Okay, I didn't know that. So the code isn't duplicated, but the static data is?
    When a DLL/.so is re-loaded into the same process, nothing is duplicated. A usage counter is incremented. That's it.

    Nothing to do with Java either.
  • 10. Re: How to Provide Native Methods in an Executable?
    970173 Newbie
    Currently Being Moderated
    Thanks for the info. You're perfectly right.

    Don't know what I did wrong the first time, but now I got it working.

    My EXE loads `jvm.dll', which in turn, in a Java class of mine, calls `System.load' on the executable again. Now native methods implemented in the EXE are reachable through JNI. Global/static data is the same everywhere. All is well.

    So there is really no need to write an extra DLL if you provide a native launcher executable. At least on Windows, you don't. I will look into Linux soon and possibly into Mac OS some day.

    What discouraged me was that `eclipse.exe' always ships with an `eclipse_XXXX.dll', and I thought, if the best programmers in the world do so, they will have a reason. At least until now I haven't found one. ;)

    Thanks for your help.

    -- Ph.
  • 11. Re: How to Provide Native Methods in an Executable?
    DrClap Expert
    Currently Being Moderated
    Philip Köster wrote:
    What strikes me is that you folks try to teach me what I should do or not do, even call my problem a "nonproblem," rather than just help me out and try to answer my questions. None of the answers here were helpful to me, but I think I figured it out.
    You're welcome for the help.
  • 12. Re: How to Provide Native Methods in an Executable?
    EJP Guru
    Currently Being Moderated
    DrClap wrote:
    Philip Köster wrote:
    What strikes me is that you folks try to teach me what I should do or not do, even call my problem a "nonproblem," rather than just help me out and try to answer my questions. None of the answers here were helpful to me, but I think I figured it out.
    You're welcome for the help.
    What strikes me is that what he had been told up to that point was 100% correct and to the point.
  • 13. Re: How to Provide Native Methods in an Executable?
    970173 Newbie
    Currently Being Moderated
    No hard feelings here; in the end, we figured it out. Yes, it was correct what you told me, I just had to find it out myself the hard way. I guess the answer I needed was "It should work, just try again," and not something along the lines "Write a DLL, dude."

    Sorry for being impatient, you all did help me. Thanks.

    -- Ph.
  • 14. Re: How to Provide Native Methods in an Executable?
    970173 Newbie
    Currently Being Moderated
    It is, by the way, never polite to talk about somebody that is present and listening in third person. That makes me feel like I had wet leprosy.

    The reason why I reacted so angrily, maybe overreacted, was that my experiences with C++ questions on the Internet haven't been overly positive throughout all these years. At best, you would not receive an answer but only a vague hint from somebody that doesn't know the whole story either. You could say the discussions are long poisoned by too much testosterone. This is why my answer was unfriendly. And if I scroll back this discussion, none of your answers were more friendly than it is wonderful. In German we say "Ich mußte euch jedes Wort einzeln aus der Nase ziehen," I don't know a good translation for that, literally it would mean "I had to draw each and every word right out of your nose."

    ---Ph.

Legend

  • Correct Answers - 10 points
  • Helpful Answers - 5 points