🖼️

Processing 4.3をJavaから使用する

2024/10/13に公開

はじめに

Processing はJavaをベースにした独自の言語とのIDE (統合開発環境) を持っており、ユーザーは基本的にこの環境で開発を行います。しかし、Javaで書かれたProcessingのコアライブラリをJavaのコードから読み込んで使うこともできます。JavaのコードからProcessingを使うことで、エディタ、JDKのバージョン、パッケージマネージャ等々を好きに選ぶことができます。

この記事では、Processing 4.3をJavaから使う方法について説明します。記事を書くにあたり次の記事を参考にしました。
https://tkitao.hatenablog.com/entry/2015/09/22/154430

環境

  • 端末: MacBook Air M2 2022
  • OS: macOS Sonoma 14.4.1
  • JDKのバージョン: 21.0.4
  • Processingのバージョン: 4.3

まとめ

% javac -cp '/Applications/Processing.app/Contents/Java/core/library/*' ./App.java
% java -cp '/Applications/Processing.app/Contents/Java/core/library/*:.' -Djava.library.path='/Applications/Processing.app/Contents/Java/core/library/macos-aarch64' App

基本的なコードを動かす

まずは次のコードを動かしてみます。

App.java
import processing.core.*;

public class App  extends PApplet{
  public void settings(){
    size(400, 400);
  }

  public void setup() {
    background(0);
  }

  public void draw() {
    ellipse(200, 200, 300, 300);
  }

  public static void main(String[] args) {
    PApplet.main("App");
  }
}

素朴にコンパイルすると、コンパイラがライブラリを認識できないのでエラーが出ます。

% javac ./App.java                                                                                
./App.java:3: エラー: シンボルを見つけられません
public class App  extends PApplet{
                          ^
  シンボル: クラス PApplet

エラーを解消するには、コンパイル時と実行時にProcessingのコアライブラリの場所をクラスパスに加える必要があります。コアライブラリの場所は環境によって変わりますが、Macで /Applications にProcessingをインストールした場合は /Applications/Processing.app/Contents/Java/core/library/core.jar です。次のコマンドで正しく実行できます。

% javac -cp '/Applications/Processing.app/Contents/Java/core/library/core.jar' ./App.java
% java -cp '/Applications/Processing.app/Contents/Java/core/library/core.jar:.' App

OpenGLを使う場合

ウインドウサイズを設定する部分のコードを次のように変更すると、実行時に例外が発生するようになります。

public void settings(){
    size(400, 400, P2D); // 3番目の引数としてP2Dを追加した
}
% javac -cp '/Applications/Processing.app/Contents/Java/core/library/core.jar' ./App.java
% java -cp '/Applications/Processing.app/Contents/Java/core/library/core.jar:.' App
java.lang.NoClassDefFoundError: com/jogamp/opengl/GLException

描画モードが P2DP3D のとき、Processingは内部でOpenGL関連のライブラリを使います。そのライブラリの場所を指定していないので、クラスが見つからないという例外が発生しています。必要なライブラリのJARファイルは /Applications/Processing.app/Contents/Java/core/library に入ってるので、これらをまとめてクラスパスに追加します。

% ls /Applications/Processing.app/Contents/Java/core/library 
core.jar        gluegen-rt.jar  jogl-all.jar    linux-aarch64   linux-amd64     linux-arm       macos-aarch64   macos-x86_64    windows-amd64
% javac -cp '/Applications/Processing.app/Contents/Java/core/library/*' ./App.java
% java -cp '/Applications/Processing.app/Contents/Java/core/library/*:.' App             
java.lang.UnsatisfiedLinkError: Can't load library: ${javaファイルのディレクトリ}/natives/macosx-universal/gluegen_rt

Processing 3.0ではここまでの内容で実行できるのですが、4.3ではさらに別の例外が発生します。最近のバージョンのProcessingでは、OpenGL関連のネイティブライブラリをプラットフォームごとのディレクトリに分けて配置するようになったため、これも読み込めるようにする必要があるようです。
https://github.com/processing/processing/issues/4783#
https://github.com/benfry/processing4/commit/be38429ef53b6108dff70855efaaadcab47fdd90

AppleシリコンのMacでは /Applications/Processing.app/Contents/Java/core/library/macos-aarch64/ にあるファイルを使います。 中身は次のようになっています。

% ls /Applications/Processing.app/Contents/Java/core/library/macos-aarch64   
libgluegen_rt.dylib             libjogl_desktop.dylib           libjogl_mobile.dylib            libnativewindow_awt.dylib       libnativewindow_macosx.dylib    libnewt_head.dylib

最終的な実行コマンドは次の形になります。

% java -cp '/Applications/Processing.app/Contents/Java/core/library/*:.' -Djava.library.path='/Applications/Processing.app/Contents/Java/core/library/macos-aarch64' App

Mavenで依存性管理

Processing以外のライブラリを使う場合は java コマンドを直接使うよりはなんらかのビルドツールを使った方が便利です。ここではMavenを使います。

プロジェクトの pom.xml にProcessingへの依存性を追加します。依存性以外の部分は省略してあります。

pom.xml
<dependencies>
        <dependency>
            <groupId>com.processing</groupId>
            <artifactId>core</artifactId>
            <version>4.3</version>
        </dependency>
</dependencies>

Processingは公式にMaven Repositoryに公開されてはいないので、JARファイルからローカルレポジトリに登録します。その際、

  • コアライブラリだけでなく、コアライブラリが依存する jogl-all , gluegen-rt もローカルレポジトリに登録すること
  • コアライブラリのJARファイルには pom.xml が含まれていないので、コアライブラリからjogl-all , gluegen-rt への依存性を手動で設定すること

に注意します。

% mvn install:install-file \
  -Dfile=/Applications/Processing.app/Contents/Java/core/library/jogl-all.jar \
  -DgroupId=org.jogamp.jogl \
  -DartifactId=jogl-all \
  -Dversion=2.4.0 \
  -Dpackaging=jar
% mvn install:install-file \
  -Dfile=/Applications/Processing.app/Contents/Java/core/library/gluegen-rt.jar \
  -DgroupId=org.jogamp.gluegen \
  -DartifactId=gluegen-rt \
  -Dversion=2.4.0 \
  -Dpackaging=jar
% mvn install:install-file \
  -Dfile=/Applications/Processing.app/Contents/Java/core/library/core.jar \
  -DgroupId=com.processing \
  -DartifactId=core \
  -Dversion=4.3 \
  -DpomFile=processing-core-pom.xml \
  -Dpackaging=jar

processing-core-pom.xml
<?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>

    <groupId>com.processing</groupId>
    <artifactId>core</artifactId>
    <version>4.3</version>

    <dependencies>
        <dependency>
            <groupId>org.jogamp.jogl</groupId>
            <artifactId>jogl-all</artifactId>
            <version>2.4.0</version>
        </dependency>
        <dependency>
            <groupId>org.jogamp.gluegen</groupId>
            <artifactId>gluegen-rt</artifactId>
            <version>2.4.0</version>
        </dependency> 
    </dependencies>
</project>

Processingに同梱されている jogl-allgluegen-rt のバージョンは、JARファイルをunzip して MANIFEST.MF を読むことで調べました。

さらに、ネイティブライブラリの読み込みのためにメイン関数を次のように書き換えます。

public static void main(String[] args) {
        System.setProperty("java.library.path", System.getProperty("java.library.path") + ":" + "/Applications/Processing.app/Contents/Java/core/library/macos-aarch64");
        PApplet.main("com.example.App");
    }

この状態で次のコマンドを使うことで実行できます。

% mvn compile
% mvn exec:java

Discussion