I’ve been developing a library for Processing 4 in the Eclipse IDE, using the Processing Library Template. It would be handy to test a PApplet within the library, rather that running it in Processing. However, I can’t get my code to run, even this very basic example:
package net.paulhertz.pixelaudio;
import processing.core.PApplet;
public class TestPixelAudio extends PApplet {
public void setup() {
size(1024, 1024);
}
public void draw() {
}
public static void main(String args[]) {
PApplet.main(new String[] { "--present", "TestPixelAudio" });
}
}
My problem seems to be the following:
java.lang.UnsupportedClassVersionError: processing/core/PApplet has been compiled by a more recent version of the Java Runtime (class file version 61.0), this version of the Java Runtime only recognizes class file versions up to 52.0
I am not running the Ant script to compile a library, just compiling with “Build All” in the Project menu, apparently with success. The library build works just fine.
I’ve compiled with JRE 17, but it would seem that I need a more recent version for the current version of Processing 4.0. What should that be?
I was configuring Eclipse and the build path to use Java 17. I must have missed something.
I think checking Java 1.8 compatibility, even though I was compiling with 17, may have caused problems. With that unchecked, I am not getting the same error – that’s a plus. However, now Eclipse lodges a java.lang.ClassNotFoundException. Odd, considering that I am looking at the .class file in the bin directory where it ought to be. But at least a step in the right direction, I think.
I still get a FileNotFoundException even with a fully qualified path:
java.lang.RuntimeException: java.lang.ClassNotFoundException: /Users/paulhz/Code/Workspace/PixelAudio/bin/net/paulhertz/pixelaudio/TestPixelAudio
at processing.core.PApplet.runSketch(PApplet.java:10074)
at processing.core.PApplet.main(PApplet.java:9845)
at net.paulhertz.pixelaudio.TestPixelAudio.main(TestPixelAudio.java:20)
Caused by: java.lang.ClassNotFoundException: /Users/paulhz/Code/Workspace/PixelAudio/bin/net/paulhertz/pixelaudio/TestPixelAudio
at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:641)
at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:188)
at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:520)
at processing.core.PApplet.runSketch(PApplet.java:10067)
… 2 more
I’m trying to run my code as a Java Application. I think that’s the only choice, since Applets are no longer supported.
You can see from the error message that TestPixelAudio.main is actually being called by PApplet. The Run Configuration points to net.paulhertz.pixelaudio.TestPixelAudio, which seems correct to me.
I tend to use the .main() method signature that takes a .class object, rather than string name. It helps to avoid this kind of problem (and will continue to work if you rename the class).
My fav has always been PApplet.runSketch(), which accepts an array of strings w/ options such as " --sketch-path", and a PApplet instance as its 2nd argument:
I have used Eclipse (since 2009) for developing several Processing libraries and I have found the following strategy works for me.
A minimum of two Eclipse projects Project 1
This contains the source code , resources, ant scripts etc. to build the library.
Project 2.
This project contains all the tests, experiments and demo sketches used while developing the library.
In both projects the library path will be linked to any necessary Processing jars .
In project 2 we don’t link to our library jar rather we link to the actual library project. This makes debug mode and stepping through code so much more useful as it just slips into the library code.
My favourite way of coding main is
public class TestPixelAudio extends PApplet {
public static void main(String[] args) {
PApplet.main(new String[]{TestPixelAudio.class.getName()});
}
This has two benefits
the package name is included in the class name when using getName()
Changing the class name through refactoring will automatically update the main() method