How to make your plugin better.

Discussion in 'Resources' started by Gravity, May 28, 2012.

Thread Status:
Not open for further replies.
  1. Ok I kinda got the part about static fields/variables, but how about static methods ?
  2. Offline


    Do you mean the skeleton?
      public void onDisable() {
        instance = null;
    No, the server takes care of unregistering all instances of Listener from the according HandlerLists.

    There was a very long and emotional discussion about this topic already. I don't want it to happen again.

    In my opinion, most people who tend to overuse static references are either too lazy to write appropriate getters and setters or are too unexperienced to make up a good pattern for their classes. Both are no excuses for the problems static references can cause.

    Based on your question
    I think you are the second type (the better one).

    The final keyword only means that you can not assign a value or reference to the variable again. In case of static variables you have to assign a value when you are designing the class. Static members are class members and therefore the JVM cannot assign a value during runtime to final static fields.

    In your plugins, use final static variables only for primitive types and Strings! Don't use them for structures, like Sets or Maps!

    Read the part about the mobile again and you will understand.

    I hope this helps you to write code of higher quality.

    Static methods are no problem because they don't need to be maintained by the JVM in the heap memory. Use them whenever you think they are appropriate.
  3. Offline


    I still like static variables and quickly wrote a function to unset ALL my static variables in onDisable:
            // unset static fields to prevent memory leaks as Bukkit reloads the classes with a different classloader on reload
            // async to not slow down server reload, delayed to not slow down server shutdown
            new Thread(new Runnable() {
                public void run() {
                    try {
                    } catch (final InterruptedException e) {}
                    try {
                        final Field modifiers = Field.class.getDeclaredField("modifiers");
                        final JarFile jar = new JarFile(getFile());
                        for (final JarEntry e : new EnumerationIterable<JarEntry>(jar.entries())) {
                            if (e.getName().endsWith(".class")) {
                                try {
                                    final Class<?> c = Class.forName(e.getName().replace('/', '.').substring(0, e.getName().length() - ".class".length()), false, getClassLoader());
                                    for (final Field f : c.getDeclaredFields()) {
                                        if (Modifier.isStatic(f.getModifiers()) && !f.getType().isPrimitive()) {
                                            if (Modifier.isFinal(f.getModifiers())) {
                                                modifiers.setInt(f, f.getModifiers() & ~Modifier.FINAL);
                                            f.set(null, null);
                                } catch (final Throwable ex) {
                                    assert ex instanceof NoClassDefFoundError; // soft-dependency not loaded
                    } catch (final Throwable ex) {
                        assert false;
    Nope ;)

    edit: tested & improved the code

    edit2: another improvement
  4. Offline


  5. Offline


    This may be a silly question, but how exactly do you make your commands work from the console. I have never used 'if(cs instanceof Player)' yet my commands never work from console?
  6. Offline


    Very, very outdated
  7. Offline


    ChipDev *points at the date this was posted*
    Skyost and ChipDev like this.
  8. Offline


    Is that like... a record of likes in a minute?
    Oh, i was trolled.
  9. Offline


    ChipDev you weren't trolled... He was pointing out that you are complaining that thisnthread is outdated even though it was started two years ago and thus you should have just left it
  10. Offline


    It is technically possible to "reload" classes through the custom class loader. However, will Bukkit do it? Probably not. The point is that you shouldn't use statics on objects, rather static should only pertain to primitives (String is the exception, maybe a few others like BigDecimal or singleton patterns).
    Final static variables are somewhat also a problem. IIRC, There's a problem when plugins are unloaded where the plugin stays in memory because there is a sync task scheduled that keeps the plugin in memory. I do not recall what the task was supposed to do, however, it keeps a hard reference to the plugin and thus, cannot be garbage collected. I got around this by unloading the plugin myself (also somewhat improved plugin reloading by writing my own implementation/extension of PluginBase) and handling class loaders myself.

    >tfw i realize i just replied to a post from june 2012
    i feel stupid now.
    Skyost and AoH_Ruthless like this.
  11. Offline


    This is great, it should really be pinned!
  12. Offline


    No, some things are very very outdated ....
  13. Offline


    It's from May. How can it be very very outdated? I can see a little outdated, but, come on. It's the concept of having a guide on how to improve your plugins is what should be pinned, because more people should be looking at some of these things.
  14. Offline


    It is from May 2012 ...
  15. Offline


    I only read the May, sorry. But, still, it did not seem all that bad. It obviously needs some touchups, but, most of the information is still good.
Thread Status:
Not open for further replies.

Share This Page