sudo is broken
LadyCailinBot opened this issue ยท 17 comments
CMDHELPER-2977 - Reported by kilorat
I'm using Spigot, the newest dev build #1627, and Commandhelper build #2870, and sudo is broken. It's been broken for awhile and on different versions, so this isn't new.
I can reproduce it by making an alias: /sudotest = sudo(/list)
then when I run it, the server prints this stack trace:
Comment by PseudoKnight
Hm, I wonder what's different about your server. I'm on those same builds.
It's getting an NPE on this line:
Class serverClass = ClassDiscovery.getDefaultInstance().forFuzzyName("org.bukkit.craftbukkit.*", "CraftServer").loadClass();
Comment by kilorat
I setup a new test server to figure out what plugin is conflicting, and it is PermissionsEx. If I disable PEX and op myself and run a sudo alias it works, but if I deop then enable PermissionsEx, I get the error.
I'm using the newest version PEX 1.22.3.
Just based on that, any speculation as to what they might be doing that interferes?
I just posted to their forum about it.
http://dev.bukkit.org/bukkit-plugins/permissionsex/forum/70460-commandhelper-breaks-with-pex/
Thanks for the help, I didn't even think it could be a plugin conflict.
Comment by PseudoKnight
There's one other thing you didn't mention here: it works on a 1.7.5 build of spigot.
Have you tried setting an op (doesn't matter who) before using sudo()? There was a bug a while back that caused that to be an issue.
Comment by kilorat
The NPE happens whether I use the op command before or if I don't, I'm not sure what help that is. I never use the op command normally, I only did it for the test since I was running without a permission plugin for the "without PEX" configuration and couldn't give commandhelper.func.use.sudo to myself otherwise.
I have a test server with just Commandhelper and PEX. I just tried Commandhelper and PermissionsBukkit, set myself to not have op, and I gave myself commandhelper.func.use.sudo and everything worked great.
I'm leaning towards it being something with PEX, I'll post again if I find anything else out.
Comment by kilorat
I tried setting an op before using the sudo alias, but it didn't make a difference. If the user running the sudo function is op, there are no problems running that sudo function.
I just setup another test server and this time didn't copy any config files, using spigot build 1627, commandhelper 2780, and instead of PEX I installed PermissionsBukkit 2.3. I removed all the stock CommandHelper aliases, and replaced it with /sudotest = sudo(/list)
and I still get the problem when I run it.
I think I confused things by putting blame on permission systems since I have to set the commandhelper.func.use.sudo node on myself somehow in order to use the sudo function. And I don't know of a way to do that without a permission plugin. And if I have actual ops, the alias runs without a problem, so since tested by opping myself without PEX loaded, I made the bad assumption that it was a PEX problem.
Anything else I can do as far as testing or giving information? I have no programming ability or I would just try to fix it and submit the changes. :)
Comment by PseudoKnight
To avoid needing permissions, use *:/sudotest = sudo('/list')
Comment by kilorat
Alright cool, that rules out any permission plugin then, I get the problem on a fresh install with CommandHelper as the only plugin.
Comment by PseudoKnight
I did a fresh install test myself. This is the full process:
- Add spigot.jar build 1627
- Add basic startup.bat
- Add plugins/commandhelper.jar build 2780
- Start
- Accept eula
- Start
- Edit aliases.msa to only include *:/test = sudo('/help')
- Recompile
- Login and run /test from inside game.
If you didn't do anything differently, perhaps it's something platform related. Like, what Java are you running?
Comment by kilorat
OS: Ubuntu 12.04.4
Java: 1.7.0_55
I'm getting really close to figuring this out, it is related to whatever this does:
[01:45:26 INFO]: Performing one time scan of file:/home/minecraft/test2/spigot.jar, this may take a few moments.
Do you know how I can force it to do that again? Subsequent restarts only do this:
[01:26:00 INFO]: [CommandHelper] Loading CommandHelper v3.3.1-SNAPSHOT.2780-
[01:26:01 INFO]: [CommandHelper] Running initial class discovery, this will probably take a few seconds...
I believe the problem is being triggered by my use of filesystem symlinks. If I ever change where something points, when it gets to "Running initial class discovery" it instantly gets past it (no errors printed), and I get the NPE when I run the test alias.
So it must be saving the fact it did the "one time scan" somewhere, but I can't find that anywhere. I can even wipe out the whole CommandHelper folder and it still won't do that one time scan again. I think if I can just force it to rescan, I can put that in my start script and call this solved.
Comment by PseudoKnight
It stores it in the .cache folder, which is inside the CommandHelper folder.
Comment by kilorat
Thanks. Weird, I can delete the .cache folder, or even the entire CommandHelper folder, and it still doesn't do the one time scan again. But if I make spigot.jar be the real file and not a symlink, it does the one time scan. I really don't know enough about java to know why it is being fooled. Something must have changed that made this work in the past, and only break now.
If it doesn't look like an easy fix, I know I can work around it.
Comment by LadyCailin
As far as I know, java follows symlinks for FileInputStream, which is what the root cache mechanism is following. Backing up some more though, regardless of the symlink, I'm concerned why deleting the .cache folder isn't causing it to rescan. I can only assume that perhaps it's creating the .cache file in another place? If you have weird symlinks, it may be causing it to create the .cache folder in another location, and it's using that, instead of the one in the CH directory. I'm not exactly sure what happens in java if you do new File('/symlink-file').getCanonicalPath() for a symlink, if it returns the path to the actual file, or just the absolute path to the symlink.
Comment by kilorat
I wish I could help, but I don't know programming, I'm just a sysadmin. I can demonstrate how to reproduce it through.
mkdir foo
mv spigot.jar foo
ln -s foo/spigot.jar spigot.jar
the key is the real jar has to be in a different directory. When minecraft starts it will just whizz past the whole process of looking at the cache, normally you can see it hesitate. So my hunch is something about it is making it not even look at that code that even checks for .cache.
Comment by LadyCailin
Check for another .cache folder elsewhere in your file system, perhaps looking in all directories in the folder and down where the real jar exists. If you find the folder elsewhere, try deleting it and seeing if the scan happens again.
Comment by kilorat
There is a $HOME/.cache put there by openbox.
I noticed something I hadn't before, the target of the symlink was named spigot.jar.1627. If I look in the source code I see it is checking to see if the file ends in .jar, so maybe somehow it can see the real filename and is getting confused? I don't know what recent change could have broken that, it wasn't an issue in the older commandhelper.
Why is that *.jar check even there?
Comment by LadyCailin
Hmm, yeah, try renaming the actual file to spigot.1627.jar, and see if that fixes it.
Also, the ".jar" check is to prevent it from trying to read in random files, not to mention the fact that the URI for a file in a jar is different than if it's a raw class file. The ClassDiscovery stuff is supposed to work with both, so that you don't need to assemble a jar just to use it.. which is useful during development, among other advantages. It may be possible to read the file's magic instead of the file extension, which is a generally more robust solution anyways. I'll see if I can't do that, but in the meantime, try ending it with ".jar" and let me know if that fixes it.