Skip to content

Commit

Permalink
#145: initial jni setup (WIP)
Browse files Browse the repository at this point in the history
  • Loading branch information
rladstaetter committed Aug 9, 2023
1 parent c23c270 commit fe1d6f9
Show file tree
Hide file tree
Showing 10 changed files with 225 additions and 2 deletions.
26 changes: 26 additions & 0 deletions dist/dist-osx/native-osx/call-swift-security-bookmarks.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# Manage File access

Since Mac App Store apps are sandboxed, file access is restricted and needs special consideration.

LogoRRR naturally needs access to files, and as such it poses a problem for the whole application.

In order to grant LogoRRR access to files this module has been put into place.

Direct access from Java to the necessary swift code and Mac OsX APIs is only possible via calling it via C code.

Thus as an Java developer, you have to

- call native code via JNI
- from this intermediate layer, call the OsX API

This is far from pretty and quite involved, but at the moment it is the best I can come up with.

Of course, this includes additional complexities in building the code and deployment, more libraries which have to be taken care of and subtle bugs which can easily creep in.

Sadly, it is another road block for JavaFX development; only few developers will bite the bullet and go this path; but since you are reading this you belong to this elitist circle ;-)

## Links

- https://stackoverflow.com/questions/27628385/write-call-swift-code-using-java-s-jni - how to call swift code from Java
- https://developer.apple.com/documentation/security/app_sandbox/accessing_files_from_the_macos_app_sandbox - API to call
- https://schlining.medium.com/a-simple-java-native-interface-jni-example-in-java-and-scala-68fdafe76f5f example on how to use scala & java and JNI
117 changes: 117 additions & 0 deletions dist/dist-osx/native-osx/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>

<parent>
<groupId>app.logorrr.dist.osx</groupId>
<artifactId>dist-osx</artifactId>
<version>${revision}${changelist}</version>
</parent>

<artifactId>native-osx</artifactId>
<name>app.logorrr.dist.osx.native</name>

<dependencies>
<dependency>
<groupId>org.scala-lang</groupId>
<artifactId>scala-library</artifactId>
</dependency>
<dependency>
<groupId>org.scalatest</groupId>
<artifactId>scalatest_${scala.major.version}</artifactId>
</dependency>
<dependency>
<groupId>org.scalacheck</groupId>
<artifactId>scalacheck_${scala.major.version}</artifactId>
</dependency>
<dependency>
<groupId>org.scalatestplus</groupId>
<artifactId>scalacheck-1-15_${scala.major.version}</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<executions>
<!-- generate header file if you change the signature of the native methods -->
<!--
<execution>
<id>generate-header-file</id>
<phase>generate-sources</phase>
<goals>
<goal>exec</goal>
</goals>
<configuration>
<executable>${jdk.javac}</executable>
<workingDirectory>${project.build.directory}</workingDirectory>
<arguments>
<argument>-h</argument>
<argument>${project.basedir}/src/main/c</argument>
<argument>${project.basedir}/src/main/java/app/logorrr/SwiftHelloworld.java</argument>
</arguments>
</configuration>
</execution>
-->
<!-- compile swift code -->
<execution>
<id>compile-swift-code</id>
<phase>compile</phase>
<goals>
<goal>exec</goal>
</goals>
<configuration>
<executable>${osx.swiftc}</executable>
<workingDirectory>${project.basedir}/src/main/c/</workingDirectory>
<arguments>
<!-- SwiftCode.swift -emit-library -o libSwiftCode.dylib -Xlinker -install_name -Xlinker libSwiftCode.dylib -->
<argument>${project.basedir}/src/main/c/SwiftCode.swift</argument>
<argument>-emit-library</argument>
<argument>-o</argument>
<argument>${project.build.directory}/classes/libSwiftCode.dylib</argument>
<argument>-Xlinker</argument>
<argument>-install_name</argument>
<argument>-Xlinker</argument>
<argument>${project.build.directory}/classes/libSwiftCode.dylib</argument>
</arguments>
</configuration>
</execution>
<!-- compile c code -->
<execution>
<id>compile-c-code</id>
<phase>compile</phase>
<goals>
<goal>exec</goal>
</goals>
<configuration>
<executable>${osx.gcc}</executable>
<workingDirectory>${project.build.directory}</workingDirectory>
<arguments>
<!-- -I"$JAVA_HOME/include" -I"$JAVA_HOME/include/darwin/" -o libSwiftHelloWorld.dylib -dynamiclib helloworld_SwiftHelloWorld.c libSwiftCode.dylib -->

<argument>-I${jdk.home}/include</argument>
<argument>-I${jdk.home}/include/darwin/</argument>
<argument>-o</argument>
<argument>${project.build.directory}/classes/libSwiftHelloWorld.dylib</argument>
<argument>-dynamiclib</argument>
<argument>${project.basedir}/src/main/c/SwiftHelloWorld.c</argument>
<argument>${project.build.directory}/classes/libSwiftCode.dylib</argument>
</arguments>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>net.alchim31.maven</groupId>
<artifactId>scala-maven-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.scalatest</groupId>
<artifactId>scalatest-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
8 changes: 8 additions & 0 deletions dist/dist-osx/native-osx/src/main/c/SwiftCode.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import Foundation

// force the function to have a name callable by the c code
@_silgen_name("swiftHelloWorld")
public func swiftHelloWorld(number: Int) -> Int {
print("Hello world from Swift: \(number)")
return 69
}
12 changes: 12 additions & 0 deletions dist/dist-osx/native-osx/src/main/c/SwiftHelloWorld.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
#include <jni.h>
#include <stdio.h>
#include "app_logorrr_SwiftHelloWorld.h"
#include "app_logorrr_SwiftHelloWorld_swift.h"

JNIEXPORT void JNICALL Java_app_logorrr_SwiftHelloWorld_printHelloWorldImpl
(JNIEnv *env, jclass clazz) {

int result = swiftHelloWorld(42);
printf("%s%i%s", "Hello World from JNI! ", result, "\n");

}
21 changes: 21 additions & 0 deletions dist/dist-osx/native-osx/src/main/c/app_logorrr_SwiftHelloWorld.h

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
int swiftHelloWorld(int);
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package app.logorrr;

public class SwiftHelloWorld {

static {
System.loadLibrary("SwiftHelloWorld");
}

public static native void printHelloWorldImpl();

public static void main(final String[] args) {
printHelloWorldImpl();
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package app.logorrr

object OsxBridge {

@native def printHelloWorldImpl() : Unit

def main(args: Array[String]): Unit = {
System.loadLibrary("OsxBridge")
printHelloWorldImpl()
}

}
3 changes: 2 additions & 1 deletion dist/dist-osx/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,8 @@
<modules>
<!-- atm there is no graalvm build active on macosx-->
<!-- <module>binary-osx</module> -->
<module>native-osx</module>
<module>installer-osx</module>
</modules>

</project>
</project>
12 changes: 11 additions & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@
</activation>
<properties>
<jdk.home>${osx.jdk.home.aarch64}</jdk.home>
<jdk.javac>${jdk.home}/bin/javac</jdk.javac>
</properties>
<build>
<plugins>
Expand All @@ -90,7 +91,8 @@
<requireProperty>
<property>mac.signingkey.username</property>
<message>You must set property 'mac.signingkey.username' to create
a signed pkg file. A valid entry has to have the following form: 'John Doe (ABCDEFGHIJ)'
a signed pkg file. A valid entry has to have the following form: 'John
Doe (ABCDEFGHIJ)'
</message>
</requireProperty>
<!--
Expand All @@ -107,6 +109,14 @@
aarch64 jdk.
</message>
</requireProperty>
<requireProperty>
<property>osx.swiftc</property>
<message>You have to set 'osx.swiftc' to the swiftc compiler.</message>
</requireProperty>
<requireProperty>
<property>osx.gcc</property>
<message>You have to set 'osx.gcc' to the gcc compiler.</message>
</requireProperty>
</rules>
<fail>true</fail>
</configuration>
Expand Down

0 comments on commit fe1d6f9

Please sign in to comment.