Recent

Author Topic: Calling JavaVM from Pascal  (Read 23199 times)

molly

  • Hero Member
  • *****
  • Posts: 2330
Re: Calling JavaVM from Pascal
« Reply #15 on: November 03, 2016, 06:12:33 pm »
Code: [Select]
var
  runtimeLib: AnsiString;
  libHandle : THandle;
  CreateVM : TCreateVM;

  PVM : PPJavaVM;
  penv : PPJNIEnv;
  args : Pointer;
begin
  runtimeLib := '/usr/lib/jvm/java-8-oracle/jre/lib/amd64/server/libjvm.so';
  libHandle :=  LoadLibrary(PChar(runtimeLib));
  @CreateVM := getProcAddress(libHandle, 'JNI_CreateJavaVM');
  CreateVM(pvm, penv, args);
end.           

BertVerhees

  • New Member
  • *
  • Posts: 17
Re: Calling JavaVM from Pascal
« Reply #16 on: November 03, 2016, 06:26:30 pm »
It still crashes on my computer, molly, it doesn't on yours?

molly

  • Hero Member
  • *****
  • Posts: 2330
Re: Calling JavaVM from Pascal
« Reply #17 on: November 03, 2016, 06:33:54 pm »
In case you are sure it crashes: make sure the arguments point to something valid ?

BTW: i know it sounds stupid but, check each and every line for the result so that you are able to check what is actually happening. I am assuming the loadproc went ok, but you have no way of telling. The reason i let you changed the pointers is that it is more important to understand what is happening first before applying tricks like that (the link of the wrapper you posted in your first post did some pretty weird stuff like checking if the address of a local variable = nil, which is actually pointless).

Make sure that you provide the right user class directory in case providing that to args.
« Last Edit: November 03, 2016, 06:53:43 pm by molly »

BertVerhees

  • New Member
  • *
  • Posts: 17
Re: Calling JavaVM from Pascal
« Reply #18 on: November 04, 2016, 08:56:36 am »
molly,

I am sure that the loadlibrary works, because it returns a valid handle, although, it returns a non-zero handle, which it does not if it cannot find the library. There is also no reason to doubt it could not load the library. It is a valid library, like many others, and it is well tested (see my C-program I published yesterday in this discussion). I think we can trust that step.

So the problem is in the getProcAddress and the parameters it gets. I used to be quite good in pointers to pointers, and so, but not anymore. For over fifteen or twenty years, I have worked with programming environments which hide these kind of things. So I lost my talent to solve these kinds of things. And I am not sad about that.

That is why I am writing here. I was hoping that this kind of question would be a piece of cake. I was hoping that there were tons of example-programs which load unix-libraries, from which we can learn. But it seems to turn out that I have bad luck.

You say that the code I pointed to was wacky, checking if a pointer is nil? I think the writers are used to OO thinking, where not initialized objects are nil? But their code works on Windows. Maybe Windows is more permissive?

The JNI layer would be very useful to me. It would give me the opportunity to have really fine JVM-libraries available for FPC. This could be very useful, also for the FPC/Lazarus community. Not for using every micro-second., it would be too slow, but for transferring complete jobs/algorithms to the "other" side.

Why would one want to do that?
For Java (and other JVM languages) have lots of academic use, there is so much knowledge available and for free, while FPC has it strong points too. It is fast, and easy to use as a RAD environment and it hides platform dependencies in code. Both are a strong pair, which give lots of opportunities.

The academic knowledge which is available in JVM languages, one can always rewrite that in FPC. But that feels like reinventing the wheel, but then in an uneasy way.

There are other ways too to connect to a Java-environment, for example, a small internal REST mechanism. The boilerplate to do that can be generated, also from the Pascal side. I think that can work too. But I kind of hate that solution a bit. It feels too much as not being connected, and modules living apart on a network connection. But it also has advantages in context of scalability.

So, I still hope, someone is able to solve this problem, which I cannot solve, and if not, I am already preparing plan B. I have to. My product needs it.
« Last Edit: November 04, 2016, 11:50:51 am by BertVerhees »

Thaddy

  • Hero Member
  • *****
  • Posts: 14213
  • Probably until I exterminate Putin.
Re: Calling JavaVM from Pascal
« Reply #19 on: November 04, 2016, 09:14:53 am »
From your example code I deduce that you really mean to call out from java to a Pascal library?
Then simply write that library in FPC and the Pas2JNI utility will create the JNI wrappers for you.
I already pointed to that solution.

If my deduction is right I can post a small example sometime today.

See also http://wiki.freepascal.org/pas2jni that already contains examples.
« Last Edit: November 04, 2016, 09:23:17 am by Thaddy »
Specialize a type, not a var.

BertVerhees

  • New Member
  • *
  • Posts: 17
Re: Calling JavaVM from Pascal
« Reply #20 on: November 04, 2016, 09:25:23 am »
Thanks Thaddy, but no, that is not what I am looking for. That side of JNI is much better documented, I have noticed. I like to use JVM-libraries within a FPC program.

Best regards
Bert

BertVerhees

  • New Member
  • *
  • Posts: 17
Re: Calling JavaVM from Pascal
« Reply #21 on: November 07, 2016, 11:51:57 am »
I wonder how Android programming is handled with FPC?

There must be a lot of Java-interfacing. Or is it a matter of reinventing all available Java libraries on an Android-device?
See this architecture overview: https://www.tutorialspoint.com/android/android_architecture.htm
The second layer (application framework) is full Java, the third layer is partly Java libraries and partly C/C++

But if it is the first choice, then must there be a lot of example code how to load the JVM, and call some function in a class.

What would be a good place to look for some example code?




marcov

  • Administrator
  • Hero Member
  • *
  • Posts: 11383
  • FPC developer.
Re: Calling JavaVM from Pascal
« Reply #22 on: November 07, 2016, 12:06:42 pm »
var
....
  args : Pointer;
begin
  runtimeLib := '/usr/lib/jvm/java-8-oracle/jre/lib/amd64/server/libjvm.so';
  libHandle :=  LoadLibrary(PChar(runtimeLib));
  @CreateVM := getProcAddress(libHandle, 'JNI_CreateJavaVM');
  CreateVM(@pvm, @penv, args);
end.           

As said, I'm a Java non, but it is a bit strange to pass an uninitialized pointer by value. At least initialize it to zero.

Other things I can imagine (since you seem to use 64-bit Linux) is alignment issues in the JNI header translation. That would be tested by printing the sizeof() of structures both in FPC and in a C program and comparing them

BertVerhees

  • New Member
  • *
  • Posts: 17
Re: Calling JavaVM from Pascal
« Reply #23 on: November 07, 2016, 12:14:08 pm »
Thanks very much, I will try it later. I am on another computer for a few days. Looks interesting.

The "args" however, should have content. It is used to pass options to the JVM, for example, which Java-version should the JVM start, the class-path.

    JavaVMInitArgs vm_args; /* JDK/JRE 6 VM initialization arguments */
    JavaVMOption* options = new JavaVMOption[1];
    options[0].optionString = "-Djava.class.path=/usr/lib/java";
    vm_args.version = JNI_VERSION_1_6;
    vm_args.nOptions = 1;
    vm_args.options = options;
    vm_args.ignoreUnrecognized = false;

JNI_CreateJavaVM(&jvm, (void**)&env, &vm_args);

http://docs.oracle.com/javase/7/docs/technotes/guides/jni/spec/invocation.html

Thaddy

  • Hero Member
  • *****
  • Posts: 14213
  • Probably until I exterminate Putin.
Re: Calling JavaVM from Pascal
« Reply #24 on: November 07, 2016, 12:14:23 pm »
The problem is that both the projects that Bert started off with do both have a considerable amount of real bugs.
Atm I don't have the time (At BinckBank I got over 2 whole weeks!) to fix this again, unless BinckBank provides me with the code I wrote back then.
That's performant code (very performant) and safe to use. I will try to get it.
« Last Edit: November 07, 2016, 12:16:27 pm by Thaddy »
Specialize a type, not a var.

BertVerhees

  • New Member
  • *
  • Posts: 17
Re: Calling JavaVM from Pascal
« Reply #25 on: November 07, 2016, 12:16:34 pm »
We'll see, anyway, I keep following this discussion, if you have something new, please notify also here.

Bert

molly

  • Hero Member
  • *****
  • Posts: 2330
Re: Calling JavaVM from Pascal
« Reply #26 on: November 26, 2016, 05:08:36 pm »
It still crashes on my computer, molly, it doesn't on yours?
No, but i'm not using 64 bit.

The reason why it fails (i get a runtime error 216 when using your example code) is that the argument pointer is not allowed to be nil.

If you follow the rules that seem to apply for the JDK, then things start to work. I was lazy, so no interface  :)

My Output:
Code: [Select]
libjvm dynamic loading succeeded
proc JNI_CreateJavaVM() was located
proc JNI_GetDefaultJavaVMInitArgs() was located
Creating initargs succeeded
creating VM succeeded
going to sleep mode for a sec.
closing down
Unloading of library succeeded

Thaddy

  • Hero Member
  • *****
  • Posts: 14213
  • Probably until I exterminate Putin.
Re: Calling JavaVM from Pascal
« Reply #27 on: November 26, 2016, 06:20:21 pm »
It is not difficult. It takes time.... A programmer should be able to know what is wrong and right and how to solve it,
We all got a proper educations fgs. This is a matter of commercial software, written under pressure, with insufficient education.
Or worse: insufficient commitment.
It is also called a recipe for disaster.

A professional would have finished it by now,
Specialize a type, not a var.

BertVerhees

  • New Member
  • *
  • Posts: 17
Re: Calling JavaVM from Pascal
« Reply #28 on: November 26, 2016, 08:05:58 pm »
Thanks Molly,

I will look at it in a few days.

Bert

molly

  • Hero Member
  • *****
  • Posts: 2330
Re: Calling JavaVM from Pascal
« Reply #29 on: December 01, 2016, 04:21:19 pm »
@Thaddy:
I hear you.

Research simply takes time so one should account for that. Especially when it concerns commercial projects. Can't be more obvious then that.

It took me more time to install the whole lot then it took me to produce something workable. Examples are all out in the open (even though mostly oriented at c language)

If you can't do the time then don't do the crime  :)

 

TinyPortal © 2005-2018