[SOLVED] AssetNotFoundException: Asset name doesn't match requirements

Hi all,

I’m developing in this environment:

Product Version: jMonkeyEngine SDK v3.3.2-stable
Updates: jMonkeyEngine SDK is updated to version NetBeans 8.2 Patch 2
Java: 11.0.6; OpenJDK 64-Bit Server VM 11.0.6+10
Runtime: OpenJDK Runtime Environment 11.0.6+10
System: Linux version 5.4.0-90-generic running on amd64; UTF-8; en_US (jmonkeyplatform)

And everything works fine.

When I try to run the project under Windows I got this exception:

Uncaught exception thrown in Thread[jME3 Main,5,main]
AssetNotFoundException: Asset name doesn't match requirements.
"Z:/home/phx/Documents/VMsShared/jMonkey_PrjFolder/Plane-Inferno_WinX64_20211113_2335/Models/persistentData.j3o" doesn't match "Models\persistentData.j3o"

Searching around I found old issues similar to this one but I have not been able to figure it out by myself :frowning:

Seems the problem is related to:

DEFAULT_INT_PATH =System.getProperty("user.dir"); 
// Tested and fail Paths.get(".").toAbsolutePath().normalize().toString();
// Tested and fail new File(".").getCanonicalPath()
am.registerLocator(DEFAULT_INT_PATH, FileLocator.class);

When I LOG on a file the path (before get the exception) are correct for the OS but in the exception seems the first one have unix slash and the second one have the Windows backslash…I don’t understand why.

What I’m doing wrong?

Thank you in advance for any clues you have for me!

If the asset path contains a backslash (\), try changing it to a forward slash (/). For instance, change “Models\persistentData.j3o” to “Models/persistentData.j3o”.

1 Like

You haven’t shown us the code that loads the asset so we are left to guess. But as sgold suggests, I suspect your loadModel() or whatever has back slashes in the path. They should be OS-independent forward slashes.

But if that’s not the issue then you will have to post code.


Thank you very much for yours suggestions!!

I’m going to provide a clean example to test it, sorry I didn’t share the code from the beginning.

btw I had understood that the method “registerLocator” (where the exception rised ) have an internal check…something like:

if (!canonical.endsWith(absolute)){
throw new AssetNotFoundException(“Asset name doesn’t match requirements.n”+
+ canonical + “ doesn’t match ” + absolute);

From the following link you can download the .zip of the test project:

From this link a standalone version for Windows (done with packr) using the .jar build in Linux that rise the exception

1 Like

Really, all you have to do is paste the line that loads the asset to get us started.


Ok sorry,

here is the main:

private DataSet myDS;
    public void simpleInitApp() {
        myDS = PersistentData.loadData(assetManager);


Here the PersistentData Class:

public static final String DEFAULT_DATA_FILE_NAME = "persistentData.j3o";
public static String fileName = DEFAULT_DATA_FILE_NAME;
public static DataSet dataNode = new DataSet();
public static String DEFAULT_INT_PATH = System.getProperty("user.dir");;            
public static String DEFAULT_EXT_PATH = System.getProperty("user.home");

public static DataSet loadData(AssetManager am) {       
        String userHome = DEFAULT_INT_PATH;               
        File f = new File(userHome + File.separator + "Models" + File.separator + fileName);
        if (!f.exists()) {
            saveData(new DataSet());
        am.registerLocator(userHome, FileLocator.class);
        dataNode.setData((Node) am.loadModel("Models" + File.separator + fileName));
        return dataNode;

public static void saveData(DataSet dataSetToBeSaved) {
        try {
            String userHome = DEFAULT_INT_PATH;
            BinaryExporter exporter = BinaryExporter.getInstance();
            File file = new File(userHome + File.separator + "Models" + File.separator + fileName);
            exporter.save(dataSetToBeSaved.getData(), file);
            // Create a copy with the default name if a different one has been set
               file = new File(userHome + File.separator + "Models" + File.separator + DEFAULT_DATA_FILE_NAME);
                exporter.save(dataSetToBeSaved.getData(), file); 
        } catch (IOException ex) {
            Logger.getLogger(PersistentData.class.getName()).log(Level.SEVERE, null, ex);

This is the DataSet class:

public class DataSet {
    private Node data = new Node();
    public static final String NODE_NAME = "dataSet";
    public static final String LAST_LVL = "lastLvl"; // Last level Played = StatesGame.PLAY_LVL
    public static final String LAST_SCORE = "lastScore"; // Last Score getted = StatesGame.SCORE_LAST_LVL
    public static final String MAX_LVL = "maxLvl";
    public static final String MAX_SCORE = "maxScore";
    public static final String PLAYER_NAME = "playerName";
    public static final String LANGUAGE = "language";
    public static final String COUNTRY = "country";
    public static final String EFFECT_ON = "effectOn"; // Audio effect
    public static final String MUSIC_ON = "musicOn";
    public static final String PATH_EXP_IMP = "pathExpImp";
    public static final String RESET_ALL_AT_START = "resetAllAtStart";
    public static final String DATA_FILE_NAME = "dataFileName";
    public DataSet(){
        data = new Node();
        int lastLvl = 0;
        int maxLvl = 0;
        int lastScore = 0;
        int maxScore = lastScore;
        String playerName = "ND";
        int audioOn = 5;
        int musicOn = 5;
        String pathExpImp = PersistentData.DEFAULT_EXT_PATH;
        int resetAllAtStart = 0;
        String dataFileName = PersistentData.getFileName();
        data.setUserData(LAST_LVL, lastLvl); // Last lvl played by user
        data.setUserData(LAST_SCORE, lastScore); // Last score getted by user
        data.setUserData(MAX_LVL, maxLvl); // Max lvl reached and completed by user
        data.setUserData(MAX_SCORE, maxScore); // Max score getted by user
        data.setUserData(PLAYER_NAME, playerName); 
        data.setUserData(EFFECT_ON, audioOn);                
        data.setUserData(MUSIC_ON, musicOn);

I tried to avoid all unnecessary code :slight_smile:

1 Like

Asset names are different from file paths. For the sake of platform independence, JME expects asset names to use forward slashes instead of backslashes. On Windows systems, File.separator is a backslash.

1 Like

Yeah, but as said a few times already we could diagnose the issue from one line of code.

But we finally have it:

Change to:

am.loadModel("Models/" + fileName));

As already stated in the first response:


Thank you both!!!
it is working, I was looking to the asset path when I used the registerLocator() method but was in the load as you suggested :sweat_smile:
I keep it mind for future requests :wink: