Solved Inconsistent behaviour of my plugin

Discussion in 'Plugin Help/Development/Requests' started by Hitoyu5, Apr 29, 2016.

Thread Status:
Not open for further replies.
  1. Offline

    Hitoyu5

    A while ago, I wrote a translation plugin, using Bukkit, which I've been using on a small Spigot server I've created. The plugin works, as well as can reasonably be expected. It facilitates Google's translation API to provide speedy translations to players of a foreign language. As far as I am aware, it works the same on both Bukkit and Spigot.

    For a long time, I hadn't touched it. The plugin worked, and it did its job well. Very recently I decided to move things around. I had a debug system which wasn't very well organised, with misleading names around the place along with unnecessary debug calls. I decided that it would be worth making a separate "API library" (also using Bukkit), which any future plugins I (or others) make can access and use the methods of without significant issues, at least that was the idea.

    I've done that, and both plugins work as expected LOCALLY (on both Bukkit and Spigot). On my own system, with a small server limited to my own computer, both plugins interact and work with one another perfectly fine. The issue arises when I upload to the Spigot server I have set up online. Both plugins still work, however there is a loss of interaction.

    In the API, I've built in a "debug" method. It's a format in which information specifically for the purpose of debugging the plugin can be displayed which will assist me in fixing any bugs that would occur in the plugins which uses this method. On my computer, this method works as expected when called from another plugin, however on the server it only seems to work when the API calls the debug method itself. Locally (on my own computer using 127.0.0.1), ANT can call the HitoCore's "debugCall" method and it works, but on the server, it does not.

    Local behaviour (open)

    Code:
    [21:46:53] [Server thread/WARN]: [ANT] You have advanced debug mode enabled. This may produce a lot of console spam.
    [21:46:53] [Server thread/WARN]: [ANT] Debug mode is used to help find and fix bugs, if you aren't doing either of those I recommend turning debug off. Disable it by setting 'debug' in the config to 0.
    [21:46:53] [Server thread/WARN]: [ANT] Example debug:
    [21:46:53] [Server thread/INFO]: [HitoCore] Debug from ANT | Class: ant | Method: pluginLoad() | Action: Level 1 | Message: <N/A>
    [21:46:53] [Server thread/INFO]: [HitoCore] AdvDebug from ANT | Class: ant | Method: pluginLoad() | Action: Level 2 | Message: <N/A>


    Server behaviour (open)

    Code:
    [23:02:49] [Server thread/WARN]: [ANT] You have advanced debug mode enabled. This may produce a lot of console spam.
    [23:02:49] [Server thread/WARN]: [ANT] Debug mode is used to help find and fix bugs, if you aren't doing either of those I recommend turning debug off. Disable it by setting 'debug' in the config to 0.
    [23:02:49] [Server thread/WARN]: [ANT] Example debug: 
    


    Another method in the API library is used in the translation plugin, and that method works perfectly fine. The method determines whether players are identified by UUIDs or usernames (primarily for compatibility with servers older than 1.7, which don't support UUIDs). This method works as expected, in both environments.

    The debug method needs to access the config.yml of the plugin which is calling it. For example, if I write this method into a random plugin called Cat12, HitoCore would need to read the config.yml of Cat12 and search for the debug property, which is an integer value of either 0, 1 or 2. If it's not an integer, it's assumed to be 0, and if the number is above or below the three, it's rounded up or down to the closest one in range.

    I consulted a friend of mine, who suggested various different potential solutions, none of which worked. At first, I considered that it was a Java version problem, and tested with server and plugin on Java 7, and then with both of them on Java 8 too, but neither worked. I've considered file permissions too, but it doesn't seem to have been that either (however I confess I don't know how to test this theory properly). I would expect a stacktrace if the plugin couldn't access a necessary file. He suggested a YML error in the plugin.yml too, but I know that an invalid plugin.yml causes the plugin to not load at all, rather than loading in a dysfunctional state in one place and a fully operation state in another.

    In my API plugin, called HitoCore, this is what my debug method looks like. It only prints what it's given, it does nothing else besides that.

    debugCall() (open)

    Code:
        public <T> void debugCall(String pluginName, String className, String method, String action, T message, boolean advanced) {
            FileConfiguration data = YamlConfiguration.loadConfiguration(new File("plugins/" + pluginName, "config.yml"));
            String debug = data.getString("debug");
           
            if(pluginName.equalsIgnoreCase("HitoCore")) {
                debug = "2";
            }
           
            if(debug == null) {
                return;
            }
    
            int debugLevel = Integer.parseInt(debug);
            if (debugLevel < 1 || (advanced == true && debugLevel < 2)) {
                return;
            }
    
            String debugPrefix = "Debug from ";
            if (advanced == true) {
                debugPrefix = "Adv" + debugPrefix;
            }
    
            if (message == null) {
                message = (T) "<N/A>".toString();
            }
    
            getLogger().info(debugPrefix + "ANT" + " | Class: " + className + " | Method: " + method + " | Action: " + action + " | Message: " + message);
        }


    The relevant lines of my translation plugin, which directly relate to the use of the debug method stated above.

    pluginLoad() extract (open)

    Code:
        public static void pluginLoad() { // Also handles reloading
            ant ant = (ant) Bukkit.getServer().getPluginManager().getPlugin("ANT");
            ant.hc = (hitocore) Bukkit.getPluginManager().getPlugin("HitoCore"); // For access by non-static methods
            hcs = ant.hc; // For access by static methods
            ant.getLogger().info("HC: " + ant.hc); // Debug lines, to make sure it's not null.
            ant.getLogger().info("HCS: " + hcs);   // ^^
    
    Code:
           
            // Debug warning
            if (isDebugEnabled() == true) {
                if (isAdvancedDebugEnabled() == true) {
                    ant.getLogger().warning("You have advanced debug mode enabled. This may produce a lot of console spam.");
                } else {
                    ant.getLogger().warning("You have debug mode enabled. This may produce some minor console spam.");
                }
                ant.getLogger().warning("Debug mode is used to help find and fix bugs, if you aren't doing either of those I recommend turning debug off. Disable it by setting 'debug' in the config to 0.");
                ant.getLogger().warning("Example debug: ");
                ant.hc.debugCall(ant.plugin, "ant", "pluginLoad()", "Level 1", null, false);
                ant.hc.debugCall(ant.plugin, "ant", "pluginLoad()", "Level 2", null, true);
            }
        }


    I've been staring at my code, and trying various different things across the plugins to try find out what's causing the problem, but I've had no luck. I'm confused as to why the behaviour is different.

    If you need any more bits of information, I'll be happy to provide them. I want to know what's causing the behaviour differences between environments. If there's any comments that can make the code more efficient, they would be helpful too, but I am more focussed on fixing the inconsistent and puzzling behaviour of the plugin.

    Thank you.
    ~Hitoyu
     
  2. Offline

    WolfMage1

    What are all the differences between the 2 servers?
     
  3. Offline

    Hitoyu5

    The local one is primarily used for testing plugins, so I haven't got all the plugins installed there that I would on the real server. It's had no changes to default bukkit.yml, spigot.yml or other root-level .yml files, same as host.

    Host runs Java 7 (despite having a choice for 8, still uses 7), while local runs using 8. I tested local with Java 7 too, and it still worked fine.

    The local server runs in Windows 7 whereas the real one is using "Linux 3.16.0-0.bpo.4-amd64 (amd64)" according to /wg report.

    Local server has 4GB RAM whereas online can use up to 17GB.
    I don't know what CPU the host has but I run with an AMD FX-4130 at standard clock rate.

    I'm not sure what else I can think of to describe the differences, they're the ones that immediate come up.

    =====
    EDIT:
    I've fixed the problem now.

    The difference between how Windows and Linux handles file paths is the cause. Windows runs as case insensitive, I can write it in caps or in lowercase and it will be the same directory, however Linux handles it as case sensitive. I've wrote in a method to HitoCore which does a case-insensitive search for the directory.

    mapNewDir() and checkForDir() (open)

    Code:
        Map<String, String> dirs = new HashMap<String, String>();
    
        void mapNewDir(String input, String dir) {
            dirs.put(input, dir);
        }
     
        String checkForDir(String input) {
            String output = null;
            if(dirs.containsKey(input)) {
                output = (String)dirs.get(input);
            }
         
            if(output == null) {
                File pluginsDir = new File("plugins/");
                for(File file : pluginsDir.listFiles()) {
                    if(file.isDirectory()) {
                        String dirTest = file.getName();
                        if(dirTest.equalsIgnoreCase(input)) {
                            output = dirTest;
                            mapNewDir(input, output);
                        }
                    }
                }
            }
         
            if(output == null) {
                output = input;
            }
            return output;
        }


    This fixed my issue, and now the plugins interact with one another as expected on both local and server environments. Thank you for looking at this, anyone who did.
     
    Last edited: Apr 30, 2016
Thread Status:
Not open for further replies.

Share This Page