mojira.dev
MCL-1443

Windows Launcher mangles directory names if path to .minecraft contains symlink to network share, causing the game to freeze

If %AppData%\.minecraft is a symlink to a network share, the Launcher sometimes changes subdir names to uppercase. For me, this caused the game to freeze when I clicked a button in the menu, because the click sound could not be loaded. The debug log said:

Client> Error in class 'CodecJOrbis'
Client> Unable to acquire inputstream in method 'initialize'.
Client> ERROR MESSAGE:
Client> minecraft:sound/random/click.ogg

Which subdirs end up with uppercase names seems random, for example, multiple tries with a fresh .minecraft lead to the following combinations:

.minecraft/assets/SOUND/MOB
.minecraft/assets/sound/MOB
.minecraft/assets/sound/mob
.minecraft/ASSETS/SOUND/mob

This was already reported twice, as MCL-1001 and MC-28302. Because it happens only with a symlink to a network share, it was assumed it must be the Windows symlink or the network server which happen to mangle the names.

However, I analyzed Windows API calls of the Launcher using ProcessMonitor (1), and found evidence that the name mangling happens in the Launcher. The Launcher doesn't let the OS follow symlinks, but handles them by itself, and this handling sometimes introduces uppercase names.

I used ProcessMonitor to watch javaw.exe when starting the Launcher with an empty .minecraft directory, and I compared what happens when .minecraft is a symlink and when not. Windows has an API CreateFile() (2), which is used to open and/or create files and directories. This function would by default follow a symlink, returning a handle to the target of the link. That would make the link transparent to the application. But this function can also be called with the flag OPEN_REPARSE_POINT, which causes it not to follow a symlink, but to open a handle to the symlink itself, making it possible to modify symlinks, check where they point, etc.

The Launcher calls CreateFile() with the OPEN_REPARSE_POINT flag, and if it hits a symlink, CreateFile() is called again with a translated path. Sometimes, this translations introduces uppercase names.

I attached log files of my monitoring sessions, they can be viewed with ProcessMonitor, and I made a screenshot, pointing to some log entries showing where a bad name translation happens. I've also attached a Launcher debug log, but this doesn't reveal whether a symlink is involved or not.

(1) http://technet.microsoft.com/sysinternals/bb896645.aspx
(2) http://msdn.microsoft.com/en-us/library/windows/desktop/aa363858%28v=vs.85%29.aspx

Linked issues

Attachments

Comments 6

Making duplicates of bugs to describe them better is not going to have them being picked up any differently.

There is absolutely nothing we can do about this.

The Launcher calls CreateFile() with the OPEN_REPARSE_POINT flag, and if it hits a symlink, CreateFile() is called again with a translated path. Sometimes, this translations introduces uppercase names.

I'm not really sure where this understanding goes wrong. We're not using 'CreateFile()', the JVM might, we're not. So unless you have a solution to be found within java (please keep in mind that even your logs provide proof we're creating lowercase paths, and we are) the cause will be: "Something wrong in your setup with your combination of java, linux-reverse-engineered-samba-protocol, windows 'symlinks'."

The only reason I can think this is actually going wrong is because of a JVM bug. Feel free to report this to Oracle (http://bugreport.sun.com/bugreport/)

You could use "--workDir symlinktarget" as argument to the launcher as workaround.

This is not something Mojang can fix.

I know that your Java code doesn't call CreateFile() directly, this is trivial, please 🙂

But your code calls some higher level Java functions, which, in the long end, lead to calls to CreateFile(). So still, whatever your code does will influence in some way how it gets translated to API calls by the JVM. The old Launcher didn't mangle any names, which is a strong indication that something changed on your side. Even if it is a bug in the JVM, you are triggering that bug now while you haven't in the old Launcher. (I traced the old Launcher too, it also uses OPEN_REPARSE_POINT, but translates the names always correct.)

From the perspective of a user, I'm not in a good position to report such a bug to Oracle. They will ask for demonstration, and you are owner of the code which demonstrates the problem. So from the perspective of a customer, I would expect that Mojang continues to investigate such a bug and take it to Oracle if needed. At least that is what professional software companies usually do. I already invested hours to nail down the issue to the point where your previous assumptions who is to blame where proven wrong... 😉

I don't understand the "--workDir symlinktarget" bit, couldn't find any documentation mentioning that flag. Can you explain further please?

You can do:

Minecraft.exe --workDir F:\

That will point the launcher at that folder and use it 'for all the things' (unless you change the gamedir from your profile manually).

I am not in a position to report the bug because I have no means to replicate it. If they suggest a workaround, ask me to look up some information or ask me to try something, what will I say? "Oh yeah erm I can't because I actually didn't have the problem?"

We're not doing anything special in any way.

BTW Did you already try this using a windows<->windows smb setup?

Understood --workDir, thanks very much.

I tried it right now with a symlink to a share hosted by the same Windows machine which runs Minecraft, no real networking involved at all. Same result, i got ASSETS and SOUND. You should be able to replicate the issue easily by sharing a local folder and then replacing %AppData%/.minecraft with a symlink to that share.

In a cmd shell with Admin Privileges, do the following:

cd %AppData%
mklink /d .minecraft \\computer\sharename

arranjem minecraft

Kolja Nowak

(Unassigned)

Unconfirmed

freeze, network, windows

Retrieved