B4J Question Library Error with SLC made Library

peter01

Member
Licensed User
Longtime User
Hi,

I made a simple library (TMath2) from a Java class using B4J SLC. Compilation is ok (I have to compile two times, first time SLC is missing the class folder), but when I use the library with DIM tm1 As TMath2 in B4J the following error shows up:

Compiling generated Java code. Error
B4J line: 29
End Sub
javac 1.8.0_131
src\b4j\example\main.java:55: error: cannot find symbol
TMath2 _tm1 = null;
^
symbol: class TMath2
location: class main
1 error

Here is the Java Code:

B4X:
public class TMath2
{


//Multiplies two doubles (a), (b) and returns result as double
    public double tmultiply(double a, double b)
    {
        return (a * b);
    }

/* Divides two doubles (a), (b) and returns result as double */
    public double tdivide(double a, double b)
    {
        return (a / b);
    }

/* adds two doubles (a), (b) and returns result as double */
    public double tadd(double a, double b)
    {
        return (a + b);
    }

//subtracts two doubles (a), (b) and returns result as double
    public double tsubtract(double a, double b)
    {
        return (a - b);
    }
}

This Code is translated from a C++ Source and the C++ source works with NLG Compiler in B4A.
Another Question is, how to add the shortname feature in the Java Code for XML Output: <shortname>TMath2</shortname>.
 

peter01

Member
Licensed User
Longtime User
Thanks for reply. Now I use the NLG to construct my Java file from the c++ file. Then I copy the src and bin subfolder of the NLG project folder to my b4J SLC workspace. Everything seems to be ok: Dim tm1 as tMath and the subroutines definitions work and comments are shown at the right place. Here is the code:

B4X:
Sub AppStart (Form1 As Form, Args() As String)
    MainForm = Form1
    'MainForm.RootPane.LoadLayout("Layout1") 'Load the layout file.
    MainForm.Show
    Log ("App Started!")
    Dim tm1 As tMath
    Log (tm1.tmultiply(2,5))
    Log (tm1.tadd(2,5))
    Log (tm1.tsubtract(2,5))
    Log (tm1.tdivide(2,5))
End Sub

The test file compiles without problems but then I get:

java.lang.UnsatisfiedLinkError: no tMath in java.library.path

Did I forget an important step?
 
Upvote 0

peter01

Member
Licensed User
Longtime User
This is the full error message in release mode:

App Started!
main._appstart (java line: 64)
java.lang.UnsatisfiedLinkError: no tMath in java.library.path
at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1867)
at java.lang.Runtime.loadLibrary0(Runtime.java:870)
at java.lang.System.loadLibrary(System.java:1122)
at com.peter.tmath.tMath.<clinit>(tMath.java:35)
at b4j.example.main._appstart(main.java:64)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at anywheresoftware.b4a.BA.raiseEvent2(BA.java:90)
at anywheresoftware.b4a.BA.raiseEvent(BA.java:77)
at b4j.example.main.start(main.java:38)
at com.sun.javafx.application.LauncherImpl.lambda$launchApplication1$162(LauncherImpl.java:863)
at com.sun.javafx.application.PlatformImpl.lambda$runAndWait$175(PlatformImpl.java:326)
at com.sun.javafx.application.PlatformImpl.lambda$null$173(PlatformImpl.java:295)
at java.security.AccessController.doPrivileged(Native Method)
at com.sun.javafx.application.PlatformImpl.lambda$runLater$174(PlatformImpl.java:294)
at com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:95)
at com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
at com.sun.glass.ui.win.WinApplication.lambda$null$148(WinApplication.java:191)
at java.lang.Thread.run(Thread.java:748)

I have contacted wonder.
 
Upvote 0

wonder

Expert
Licensed User
Longtime User
Hello!

While I recognize that it would be great if B4J libs could be created 'out-of-the-box' with a single click, we have to remember that NLG was specifically designed to create B4A libraries, as it utilizes Android NDK (gcc-based) to compile the existing C/C++ code (note that C code is compiled as C++).

I'm planning on releasing a new NLG version until the end of this year, which will contain some improved functionality, but it won't, most likely, target B4J lib creation.

The best I can do right now is to start some light investigation into this matter and add this request to the wish-list for future releases.
If only I could dedicate more time to my B4X projects... :(

EDIT: https://trello.com/b/94MF1uLE/native-library-generator
 
Last edited:
Upvote 0

peter01

Member
Licensed User
Longtime User
Hello wonder hello Erel,

As I understand NLG translate the c++ code to Java code and transfer the code the Android NDK, which compiles it into Java Object code and to jar. Then the SLC (for Android) constructs the jar file for B4A.

My idea was, to take the java code from the NLG (not the Android NDK object code) and use the B4J SLC to create the jar file for B4J. I expected the javac.exe, which is used by B4J SLC to do this, including compilation of the object code. But this seems to be wrong ....

Erel, please help me to understand this: what source files does the B4J need, only the .java file or objcet files, or jar files ?

Many thanks for your help!
 
Upvote 0

wonder

Expert
Licensed User
Longtime User
As I understand NLG translate the c++ code to Java code
This is incorrect, NLG does not translate C/C++ code to Java. What is does is, it modifies regular C/C++ into standardized JNI C++ code, so that NDK compilation is possible.

Android NDK, which compiles it into Java Object code
This is incorrect as well, NDK (gcc) compiles the given source files into native machine code (ARM, x86 and/or MIPS), not bytecode.
https://www.quora.com/What-are-the-...achine-code-Is-bytecode-specific-to-Java-only

My idea was, to take the java code from the NLG
The generated Java code is nothing more than a wrapper for the native methods. It has no value without the binary objects (.so files).

upload_2017-10-27_15-57-1.png


https://developer.android.com/ndk/index.html
https://en.wikipedia.org/wiki/Java_Native_Interface

In sum, you only need NLG if you really want/need to create native-based (machine code) B4A libraries.
 
Last edited:
  • Like
Reactions: udg
Upvote 0

peter01

Member
Licensed User
Longtime User
Hi wonder,

here is my b4j file with the necessary informations. Please check the readmefirst.
 

Attachments

  • info_b4j.zip
    53.9 KB · Views: 248
Upvote 0
Top