Processing can find the data folder in Windows 11 but not in Linux or Mac

Hello! I am working on a project for a class in Processing and Java.

It is a game, and for this game I need to load multiple images, a video, and a font. It works correctly in Windows 11. The problem arises when I try to move this project to another computer with a different operating system.

The folder structure is as recommended: Main.pde is located at the same level as the data folder within Main.

I will try to describe the behavior of each one:

Computer with Windows 10: I download the project, run it, and it works correctly.

Computer with Linux Mint (latest version) and Processing downloaded from flatpak: It does not point correctly to the data folder.

Computer with MacOS (I don’t know the version, it belongs to my classmate): It does not point correctly to the data folder.

From Linux, I tried to create a project from scratch and save it in my preferred folder. Then I created a data folder inside that folder, at the same level as Main, and transferred all the necessary files there, but it doesn’t work either.

I also checked to see if, for example, there was an image like ā€œimage.png.png,ā€ but that’s not the case.

I’ll leave the code where I load the images below. It’s in Spanish, so I apologize:

Main.pde loads the images, videos, and fonts. Then the other classes query Main for these files.

public class Main extends PApplet {

    // --- ASSETS ---
    public static PFont fuenteMenu;
    public static Movie videoFondoJugando;
    
    public static PImage fondoMenu;
    public static PImage fondoGameOver;
    public static PImage spriteLeila;
    public static PImage spriteFantasma;
    public static PImage proyectilLeila;
    public static PImage proyectilFantasma;
    public static PImage botonRetorno;
    public static PImage barraVida4;
    public static PImage barraVida3;
    public static PImage barraVida2;
    public static PImage barraVida1;
    public static PImage barraVida0;
private void cargarAssets(PApplet sketch) {
        System.out.println("=== ASSET LOADING ===");
        File sketchPath = new File(sketch.sketchPath(""));
        System.out.println("Sketch route: " + sketchPath.getAbsolutePath());
        File dataPath = sketch.dataFile("");
        System.out.println("Searching data in: " + dataPath.getAbsolutePath());
        System.out.println();

        try {
            // Cargar imagenes
            fondoMenu = validarImagen(sketch.loadImage("fondoMenu.png"), "fondoMenu.png");
            fondoGameOver = validarImagen(sketch.loadImage("fondoGameOver.png"), "fondoGameOver.png");
            spriteLeila = validarImagen(sketch.loadImage("spriteLeila.png"), "spriteLeila.png");
            spriteFantasma = validarImagen(sketch.loadImage("spriteFantasma.png"), "spriteFantasma.png");
            proyectilLeila = validarImagen(sketch.loadImage("proyectilLeila.png"), "proyectilLeila.png");
            proyectilFantasma = validarImagen(sketch.loadImage("proyectilFantasma.png"), "proyectilFantasma.png");
            botonRetorno = validarImagen(sketch.loadImage("botonRetorno.png"), "botonRetorno.png");
            barraVida4 = validarImagen(sketch.loadImage("barraVida4.png"), "barraVida4.png");
            barraVida3 = validarImagen(sketch.loadImage("barraVida3.png"), "barraVida3.png");
            barraVida2 = validarImagen(sketch.loadImage("barraVida2.png"), "barraVida2.png");
            barraVida1 = validarImagen(sketch.loadImage("barraVida1.png"), "barraVida1.png");
            barraVida0 = validarImagen(sketch.loadImage("barraVida0.png"), "barraVida0.png");

            // Cargar fuente
            fuenteMenu = sketch.createFont("upheavtt.ttf", 30);
            if (fuenteMenu == null) {
                throw new RuntimeException("ERROR: Fuente 'upheavtt.ttf' no encontrada");
            } else {
                System.out.println("OK: Fuente 'upheavtt.ttf' cargada");
            }

            // Cargar video
            videoFondoJugando = new Movie(sketch, "fondo_jugando.mp4");
            if (videoFondoJugando == null) {
                throw new RuntimeException("ERROR: Video 'fondo_jugando.mp4' no encontrado");
            } else {
                videoFondoJugando.loop();
                System.out.println("OK: Video 'fondo_jugando.mp4' cargado y en loop");
            }

            System.out.println("\nAssets cargados correctamente.\n");

        } catch (Exception e) {
            System.err.println("Error crĆ­tico cargando assets:");
            e.printStackTrace();
            sketch.exit();
        }
    }

AssetLoader is a previous class that I used for this task, but I have commented it out thinking that it might be the problem.

The other classes do not load any files, they only query Main using the declared images (for example calling Main.fondoMenu).

I really don’t know what I’m doing wrong. If anyone here has MacOS or Linux and would be kind enough to run my project and let me know if it works for them, that would be amazing. The Video library needs to be installed for it to load one of the files in data.

This is my Project (file size when uncompressed: 203 mb) . Thank you.

Hello @ffernandaffranco ,

Welcome to the forum!

Please read:

Do you have permission to post your academic work publicly?
https://discourse.processing.org/faq#homework

Please try and reduce your code to a small runnable example.
It may help to isolate the issue.
This will also focus on the one issue without the need to post the entire code.

What is the output from this?

:)

Hello! Thank you very much for responding. My professor has no problem with me asking about this issue, and I wrote the code myself, so we’re good in that regard.

I’ll simplify the code and send it to you in a few minutes. The output is as follows:

=== ASSET LOADING ===
Sketch route: C:\Users\mffra\OneDrive\Desktop\Main
Searching data in: C:\Users\mffra\OneDrive\Desktop\Main\data

But I’m on the computer that had no problems running it. At least it helps me see that it’s pointing to the correct folder. However, in Linux, when it gives an error, it shows:

Sketch route: /app/share/processing
Searching data in: /app/share/processing/data

The reason I clarified that I installed Processing on Linux as a flatpak is because that way it is installed in an encapsulated environment, so the paths are not the real ones.

On the other hand, my colleague on MacOS had the problem that her data route did not point to the same place as her sketch route. I don’t remember the exact path because I’m not familiar with the Mac structure, but I remember that it pointed somewhere else. We tried saving the project somewhere else and creating the data folder again, but we couldn’t get it to look for the data in the right place. The sketch path would change location, but it would always point to search for data in the default processing folder. In Linux, it’s not obvious because it can’t show me the real folder it’s looking in, but I assume the problem is similar.

So I guess the real question is: How can I make Processing search the data folder inside my sketch folder and not somewhere else?

EDIT: When I open my project and select Sketch > Open sketch folder, it loads the correct folder. The data folder is located in that folder. So Processing knows where my sketch is, but for some reason it does not point to the data folder inside it.

This works on my Mac:

println(dataPath(""));

Is it showing you the correct path? Great. Could I ask what you did? I know it’s a stupid question, but it may have something to do with how my colleagues saved the project.

  1. Create a sketch in Processing.
  2. It will work without it, but you should place a folder entitled ā€˜dataā€˜ inside of your sketch folder.
  3. In setup() place the line of code that I posted.

Output:

/Users/xxxx/Documents/Processing/dataPath_demo/data

Ah, sorry, I misunderstood. I thought you had run the game. Yes, my colleagues can do personal projects in Processing and they work. The problem is that when they download mine, for some reason it doesn’t recognize where the data is, even if they save it on their own computer in a folder with the structure you mentioned.

Cross platform work is challenging and Windows uses a different file system than the other two. Windows also use back slashes (as opposed to forward slashes) as I recall. Your friends will need to convert your data path to code for their systems.

The problem is that I’m not using any literal data paths in the code. I’m just trying to do loadImage(ā€œimage.pngā€), which I understand should work if the folder structure is correct regardless of the OS.

1 Like

I assume that you have already seen this:

Alternatively, the file maybe be loaded from anywhere on the local computer using an absolute path (something that starts with / on Unix and Linux, or a drive letter on Windows), or the filename parameter can be a URL for a file found on a network.

loadImage(ā€œimg.pngā€œ) works as advertised on my mac for whatever it’s worth. Haven’t tried it on the other two platforms. Wish I could be more help.

It’s okay. Thank you!

Hello again!

This is where the Processing helper functions reside:

ChatGPT was helpful * in navigating this and providing a Cheat Sheet for documents and undocumented functions!
* With correct prompting and corrections along the way.

This topic may be related (used OneDrive):

:)

I also notice that you are using a PApplet and in my tests loadImage() will not work in a PApplet on a mac without using the path to the image, ie loadImage(ā€œ/Users/xxxx/Documents/Processing/myApp/data/myImg.pngā€œ)

When I tried just loadImage(ā€œmyImg.pngā€œ) I got a null pointer and this error message:

The file ā€œquads.pngā€ is missing or inaccessible, make sure the URL is valid or that the file has been added to your sketch and is readable.

Source code:

PImage img;

class TestWindow extends PApplet {
TestWindow () {
PApplet.runSketch(new String
 {this.getClass().getSimpleName()}, this);
}

void settings() {
size(600, 600);
}

void setup() {
// This works
img = loadImage(ā€œ/Users/xxxx/Documents/Processing/myApp/data/quads.pngā€);
// This fails
//  img = loadImage(ā€œquads.pngā€);
}

void draw() {
image(img, 0, 0);
}
}

TestWindow testWindow;

void setup() {
surface.setVisible(false);
testWindow = new TestWindow();
}

Output:

Hi! My desktop is inside the OneDrive folder, but it’s just the folder structure because I’ve uninstalled OneDrive. So I don’t think that’s the problem, but either way, I’ll take a look. Thank you!

1 Like

I see! I think it must be something along those lines. I’ll try to look into how MacOS (and maybe potentially Linux?) work with PApplet to see if I can find an alternative. Thank you very much.

I did a bit of experimenting!

The sketchPath() and dataPath() functions only return valid paths when called within the main sketch; they do not work correctly when used in a PApplet subclass, as the path resolution depends on the main sketch’s environment and directory structure.

Let me know how the code below works in your environment.
Clearly state the environment for the benefit of posterity and to uphold forum integrity. :)

This worked on Windows 10 with Processing 4.4.10:

// Global variables that can be shared:

PImage img;
String testDataPath;

// Main sketch

void setup() {
  //surface.setVisible(false);
  size(200, 200);
  
  // Make an image to save to the data and sketch folder:   
  background(255, 0, 0);
  circle(width/2, height/2, 50);

  saveFrame("circle0.png");        // Saves to sketch folder  
  
// Use / to keep it simple and OS compatible
  testDataPath = dataPath("");
  saveFrame(testDataPath + "/" + "circle1.png");  // Creates data folder and saves to it
  
saveFrame("circle2.png");        // Saves to sketch folder
      
  // This must be before launching PApplet:
  println("Main sketch:");
  
  println(sketchPath(""));
  println(sketchFile(""));
  
  println(dataPath(""));    // There is no data folder yet!
  println(dataFile(""));
  println();
    
  testWindow = new TestWindow();
}

// PApplet

class TestWindow extends PApplet {
  TestWindow () {
    PApplet.runSketch(new String[]{this.getClass().getSimpleName()}, this);
  }

  void settings() {
    size(400, 400);
  }

  void setup() {    
    background(128);
    
    println("PApplet:");
    println(sketchPath(""));
    println(dataPath(""));    // There is no data folder yet!
    println(sketchFile(""));
    println(dataFile(""));   
        
    //This works:
    img = loadImage(testDataPath + "/" + "circle1.png");
  }

  void draw() 
    {
    background(0);
    image(img, 10, 10);
  }
}

TestWindow testWindow;

I ran it with sketch folder open to see how it worked!
Be sure to refresh folders when experimenting.

That was fun!

:)

Try this:

PApplet.runSketch(new String {this.getClass().getSimpleName()}, this);

This works in PApplet (demo above) on my Windows11 system:

img = loadImage(ā€œ\\Users\\s\\Documents\\Processing\\loadImage_demo\\data\\icon3.jpgā€);

Notice the double back slashes. Watch for curly quotes if you copy/paste.

And this works on Linux(popOS):

img = loadImage(ā€œ/home/s/sketchbook/loadImageDemo/data/myImg.pngā€);

The problem has been solved!

I’m still trying to understand exactly what happened. Apparently, it’s something like this:

My original project was a standard Java project. My main file was Main.pde, while all the others had the .java extension. However, I was treating my Main file as if it were a .java file and defining the class as shown here in Main.pde:

import processing.core.PApplet;

public class Main extends PApplet { // <-- this is the problem

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

    @Override
    public void settings() {
        //...
    }
}

There was then a conflict between the Processing IDE and my code. Processing was trying to take care of certain functions (such as setup() or draw()) and wrap them in a class that extends PApplet. But I had already done that work by declaring the class myself.

Apparently, this caused a problem whereby it couldn’t correctly point to the data folder, even though it was in the right place. Processing knows how to do this on its own, but it’s as if I wasn’t letting Processing do its job by creating my own Main class that extended PApplet. There is no point in doing that with a .pde file, because it already knows how to do those things on its own.

I still don’t understand what difference switching between operating systems makes and why it would run on Windows computers but not Linux or Mac, but maybe the problem isn’t even related to that.

I would like to thank @svan and @glv for paying attention to my problem. It was simpler than it seemed, but I really had no idea why the code worked for me but not for my colleagues. Thank you!!!

1 Like

Great to see this has been identified and resolved! If I can ask, could you also make an issue on the Processing repo? Then we could possibly fix it in a future release!

1 Like

When copy/pasting into the forum it apparently leaves out the double brackets:

The brackets were in the code on my system.