Calling an external Java function from Haxe

I’m trying to call an “external” Java function from Haxe. The function is defined like so:

// Test.java
package com.example.myapp;

public class Test {
    public static String hello() {
        return "Hello from Java.";
    }
}

// Test.hx
package;

extern class Test {
    public static function hello():String;
}

Both Test.java and Test.hx are located in “/myproject/source” with Project.xml in “/myproject”. I have tried adding the following java node to Project.xml with a few different path variations without success:

<java path="source" />

When I type “lime test android” at the command prompt, I get the following error:

Error: ./src/PlayState.cpp: In member function ‘virtual Void PlayState_obj::create()’:
./src/PlayState.cpp:90:5: error: ‘::Test_obj’ has not been declared
::Test_obj::hello();
^

I’m running Windows 10 with an Android tablet connected through adb and USB, and I’m trying to code this test on top of Haxeflixel.

I suspect the path in my java node in Project.xml is wrong. What should it look like, and where should I put my Java sources in the project directory structure? Do I need to compile the Java class separately beforehand?

It shouldn’t matter where the Java sources are, as long as it is found by the compiler once it passes through Haxe.

Because your Test class is an extern, Haxe will try to resolve it by finding the default path when translating to Java. But in your Java code, your package is com.example.myapp.

Haxe will be translating that code to:

Test.hello();

Instead of:

com.example.myapp.Test.hello();

I haven’t used Java before, so I can’t be 100% sure on that, but maybe use the @:native meta tag to tell Haxe what to generate when the function is called, something like:

package;

extern class Test {
    @:native("com.example.myapp.Test.hello")
    public static function hello():String;
}

You can use extern to access Java methods using Haxe/Java builds, but the OpenFL Android target uses Haxe/C++ to build. As a result, you need to use lime.utils.JNI (or a similar class) in order to interface with custom Java. In the future, it might be sensible to support a Java-based Android target, just an idea, but in the meantime it will require a little more wiring to access your custom method.

Try lime create extension SampleExtension and see, it should have some JNI example code for Android :slight_smile:

Thanks! I was able to get something similar to work by modifying the JNI sample extension :slight_smile:

1 Like

Use this library to make it easier on yourself.