Table of Contents
Intro
Java Native Interface is a standard programming interface for writing Java native methods. Most JNI developers utilize C/C++ but most of the JNI header files ported to Delphi.
In a simple word: Java Native Interface (JNI) is the Java interface to non-Java code. And when you work with data types you should always convert data between Delphi and Java.
JavaBridge library WINSOFT offers you to interoperate with Java using JNI. This is a commercial library and if you wish to utilize the JavaBridge, you must register a license.
Overview
Why use Java Native Interface?
- Legacy code wrapper
- Low-level specifics not provided by Java
- Performance
- Reuse: Allow access to use native code
Through JNI interface pointer, native code can:
- Access field
- Operate on Classes
- Catch and Throw exceptions
- Call methods
- Manipulate strings and arrays
Installation/Configuration
After downloading the library you should add the library path. Here you can watch a short tutorial on how to configure them
Development
The next step is to open the Examples folder, then Delphi, and you can select either Java4Delphi or Delphi4Java folder there you can execute build32.bat file which creates Test.exe or Test.dll file for you.
Let’s try to convert Java into Delphi.
Start build32.bat file. This batch file creates an executable file using Test.dpr file and connects Test.java source code.
Here is how we are calling the Java code and using the JavaBridge library in Delphi:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 |
program Test; {$APPTYPE CONSOLE} uses SysUtils, JNI, JavaBridge; var Jvm, Env: Pointer; type TTest = class private FCls: JClass; FObj: JObject; FInit: JMethodID; FHello: JMethodID; FValue: JFieldID; function GetValue: Integer; procedure SetValue(Value: Integer); public constructor Create; procedure Hello(const Text: string); property Value: Integer read GetValue write SetValue; end; constructor TTest.Create; begin inherited Create; FCls := JNIEnv(Env).FindClass('test/Test'); FInit := JNIEnv(Env).GetMethodID(FCls, '<init>', '()V'); FHello := JNIEnv(Env).GetMethodID(FCls, 'hello', '(Ljava/lang/String;)V'); FValue := JNIEnv(Env).GetFieldID(FCls, 'value', 'I'); FObj := JNIEnv(Env).NewObjectA(FCls, FInit, nil); end; function TTest.GetValue: Integer; begin Result := JNIEnv(Env).GetIntField(FObj, FValue); end; procedure TTest.SetValue(Value: Integer); begin JNIEnv(Env).SetIntField(FObj, FValue, Value); end; procedure TTest.Hello(const Text: string); begin JNIEnv(Env).CallNonvirtualVoidMethodA(FObj, FCls, FHello, PJValue(Args(Env, [CreateJString(Env, Text)]))); end; var InitArgs: JavaVMInitArgs; MyTest: TTest; begin JavaBridge.LoadLibrary; FillChar(InitArgs, SizeOf(InitArgs), 0); InitArgs.version := JNI_VERSION_1_6; if JNI_CreateJavaVM(Jvm, Env, InitArgs) <> 0 then raise Exception.Create('Cannot initialize JavaVM'); MyTest := TTest.Create; WriteLn('Value = ' + IntToStr(MyTest.Value)); MyTest.Value := 10; WriteLn('Value = ' + IntToStr(MyTest.Value)); MyTest.Hello('Hello, world!'); end. |
And Test.java source code:
1 2 3 4 5 6 7 |
package test; class Test { public void hello(String text) { System.out.println(text); } public int value = 1; } |
- As you can see we are using JClass, JObject, JMethodID to play with Test.java source code.
- Before creating an instance you should create Java VM.
- And here is how you can call a method
1 2 3 4 |
procedure TTest.Hello(const Text: string); begin JNIEnv(Env).CallNonvirtualVoidMethodA(FObj, FCls, FHello, PJValue(Args(Env, [CreateJString(Env, Text)]))); End; |
Delphi for Java demo is a bit different, it generates you to a dynamic link library. Then you can call native (DLL) code from Java using JNI.
You can check how it is creating an executable file and dynamic link library by opening the build32.bat batch file.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
if "%PROCESSOR_ARCHITECTURE%" == "AMD64" GOTO Win64 if "%PROCESSOR_ARCHITEW6432%" == "AMD64" GOTO Win64 :Win32 set JDK=%ProgramFiles%\Java\jdk1.8.0_261\bin set DELPHI=%ProgramFiles%\Embarcadero\Studio\21.0\bin goto Next :Win64 set JDK=%ProgramFiles(x86)%\Java\jdk1.8.0_261\bin set DELPHI=%ProgramFiles(x86)%\Embarcadero\Studio\21.0\bin :Next call clean.bat "%JDK%\javac" -g:vars test\Test.java "%DELPHI%\dcc32" -NSSystem;Vcl;Winapi;System.Win -U..\..\..\Delphi104 Test.dpr "%JDK%\java" test.Test |
Head over and check out the full WINSOFT JavaBridge library.
Like what you see? You can get the JavaBridge Library and over 100 other fantastic WinSoft components with our Enterprise Component Pack. For a limited time, when you purchase RAD Studio Enterprise or Architect Edition at special Upgrade Pricing, you will also get this package of third-party software worth over $13,000, including the full WinSoft Component Library, at NO EXTRA COST! Step up to RAD Studio 10.4.1 today!
Design. Code. Compile. Deploy.
Start Free Trial Upgrade Today
Free Delphi Community Edition Free C++Builder Community Edition
Mixing efficient compiled software with sluggish unsafe pseudo-compiled Java…
Why in hell would someone want to do such a thing?
Either you’re a developper and compile your apps (C/C++/Pascal…) and produce professional apps, or you are a webmaster (PHP,JAVA, etc…) and pretend to release “web apps”, but you don’t do both. They’re not aimed at the same thing.