I sorted this out!
I have many libraries installed and they were providing the missing pieces.
This works with the ArtNet library installed but is still underlined in Red as in previous post:
import javax.xml.bind.DatatypeConverter; // Works with ArtNet library installed
//import java.util.*;
final int cameraWidth = 8;
final int cameraHeight = 8;
final int cameraBytesPerPixel = 1;
final int bytesPerFrame = cameraWidth * cameraHeight * cameraBytesPerPixel;
PImage myImage;
byte[] frameBuffer = new byte[bytesPerFrame];
void setup()
{
// Generate a framebuffer for testing
for (int i = 0; i < bytesPerFrame; i++)
{
//frameBuffer[i] = (byte) (choice(0, 256) % 256); // Choice returns 0 to 255 random
frameBuffer[i] = (byte) (i%256); // Generate some data (0, 1, 2, ..., 255)
}
// Works with:
// import javax.xml.bind.DatatypeConverter;
// Arnet Library installed.
String data1 = DatatypeConverter.printBase64Binary(frameBuffer);
printData(data1);
}
void printData(String data)
{
println(data.length());
for(int i=0; i<data.length(); i++)
{
if (i%64 == 0) println();
print(data.charAt(i)); // Too long!
}
println();
}
This is the recommended solution:
//import javax.xml.bind.DatatypeConverter;
import java.util.*;
final int cameraWidth = 8;
final int cameraHeight = 8;
final int cameraBytesPerPixel = 1;
final int bytesPerFrame = cameraWidth * cameraHeight * cameraBytesPerPixel;
PImage myImage;
byte[] frameBuffer = new byte[bytesPerFrame];
void setup()
{
// Generate a framebuffer for testing
for (int i = 0; i < bytesPerFrame; i++)
{
//frameBuffer[i] = (byte) (choice(0, 256) % 256); // Choice returns 0 to 255 random
frameBuffer[i] = (byte) (i%256); // Generate some data (0, 1, 2, ..., 255)
}
// Works with:
// import java.util.*;;
// Arnet Library library not required.
String data2 = Base64.getEncoder().encodeToString(frameBuffer);
println();
printData(data2);
}
void printData(String data)
{
println(data.length());
for(int i=0; i<data.length(); i++)
{
if (i%64 == 0) println();
print(data.charAt(i)); // Too long!
}
println();
}
I asked Google Gemini to summarize for a post:
JAXB is Not Available in Current Processing Versions
The class your code uses, javax.xml.bind.DatatypeConverter
, is not available in recent versions of Processing because it was removed from the standard Java Development Kit (JDK) starting with Java 11.
This occurred because the Java Architecture for XML Binding (JAXB) framework was separated from the core Java SE (Standard Edition) platform that Processing uses, as JAXB was part of the older Java EE (Enterprise Edition) platform.
Accidental Solution: Why the Library Made it Work
Your code worked because the installed, but unused, ArtNet library provided the missing file through an unintended side effect (or transitive dependency).
- Classpath Loading: When you install the ArtNet library, the Processing IDE automatically adds the library’s files and all of its dependencies (the JAR files it needs to run) to your project’s Classpath (the list of locations Java searches for classes).
- The Hidden Dependency: Since the ArtNet library itself relies on XML Binding (JAXB), installing it places the necessary JAXB JAR file (containing
DatatypeConverter
) onto your Classpath.
- Code Execution: The Java Virtual Machine simply finds the missing JAXB class inside the ArtNet dependency JAR and successfully runs your code.
In short, the ArtNet library accidentally solved your problem by adding the correct missing piece of Java’s deprecated technology to your search path.
Recommended Solution
Relying on an unrelated library to fix a dependency issue is unreliable. The proper solution is to use a method for Base64 encoding that is natively supported by modern Java and, therefore, by current versions of Processing: java.util.Base64
.
You were already using the better method in your example code (data2
). Switch your implementation to rely solely on this, and you can remove the problematic DatatypeConverter
import and the installed ArtNet library if you don’t actually need it.
I was able to verify above by examining the artnet4j.jar file:
In the future I will isolate projects into their own sketchbook folder with only the required libraries for testing.
:)