0

So, I have started writing my plugin for my server. I made a method, that should get values from config and store them inside my storing object. But as the method serialize() tells, the object is except serialVersionUID empty. The output from the serialize() method is at the end.

Here is the main Plugin class (BetterJavaPlugin <- JavaPlugin)

package me.rorak.blazenoidplugin;

import me.rorak.blazenoidplugin.files.ConfigYml;
import me.rorak.blazenoidplugin.files.MessagesYml;
import me.rorak.utils.BetterJavaPlugin;
import me.rorak.utils.YamlFile;
import org.bukkit.Bukkit;

import static me.rorak.utils.Serializer.serialize;

public class Plugin extends BetterJavaPlugin {
    public final Commands commands;
    public final Events events;
    public final TabCompleter tabCompleter;

    public final YamlFile messagesf;

    public ConfigYml config;
    public MessagesYml messages;

    public Plugin() {
        super();
        commands = new Commands(this);
        events = new Events(this);
        tabCompleter = new TabCompleter(this);

        messagesf = new YamlFile(this, "messages.yml"); // YamlFile is OK, not problem here

        config = new ConfigYml();
        messages = new MessagesYml();
    }
    @Override
    public void onEnable() {
        registerCommands(commands);
        registerTabComplete(tabCompleter);
        Bukkit.getPluginManager().registerEvents(events, this);

        // file setup
        saveDefaultConfig();
        messagesf.saveDefault(); // this does the same as saveDefaultConfig, but with
                                 // messages.yml file

        // load files
        config.load(getConfig()); // THIS LOADS THE CONFIG, i think there is the problem
        messages.load(messagesf.get()); // this also doesn't work, but it's the same problem

        debug("config.yml: ");
        debug("\n" + serialize(config)); // here the deserilization - output at the end
        debug("messages.yml: ");
        debug("\n" + serialize(messages));

        getLogger().info("Loaded!");
    }
    @Override
    public void onDisable() {
        getLogger().info("Unloaded!");
    }

    public void debug(String message) {
        Bukkit.getLogger().info("[Debug] " + message);
    }
}

Here is my ConfigYml class

package me.rorak.blazenoidplugin.files;

import me.rorak.blazenoidplugin.files.serializables.*;
import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.configuration.file.FileConfiguration;

import java.io.Serial;
import java.io.Serializable;
import java.util.HashMap;
import java.util.Map;

public class ConfigYml implements Loadable, Serializable { // loadable contains load()
    @Serial
    private static final long serialVersionUID = 10L;

    public Map<String, Permissions> permissions = new HashMap<>();
    public Map<String, Ranks> ranks = new HashMap<>();
    public Map<String, Chats> chats = new HashMap<>();
    public Map<String, Worlds> worlds = new HashMap<>();
    public Famous famous = new Famous();

    @Override
    public void load(FileConfiguration config) {
        final ConfigurationSection __permissions = config.getConfigurationSection("permissions");
        final ConfigurationSection __ranks = config.getConfigurationSection("ranks");
        final ConfigurationSection __chats = config.getConfigurationSection("chats");
        final ConfigurationSection __worlds = config.getConfigurationSection("ranks");

        famous = config.getObject("famous", Famous.class, new Famous());

        // PERMISSIONS
        if (__permissions != null) {
            __permissions.getKeys(false).forEach((u) -> {
                Permissions _permissions = __permissions.getObject(u, Permissions.class, new Permissions());
                permissions.put(u, _permissions);
            });
        }
        // RANKS
        if (__ranks != null) {
            __ranks.getKeys(false).forEach((u) -> {
                Ranks _ranks = __ranks.getObject(u, Ranks.class, new Ranks());
                ranks.put(u, _ranks);
            });
        }
        // CHATS
        if (__chats != null) {
            __chats.getKeys(false).forEach((u) -> {
                Chats _chats = __chats.getObject(u, Chats.class, new Chats());
                chats.put(u, _chats);
            });
        }
        // WORLDS
        if (__worlds != null) {
            __worlds.getKeys(false).forEach((u) -> {
                Worlds _worlds = __worlds.getObject(u, Worlds.class, new Worlds());
                worlds.put(u, _worlds);
            });
        }
    }
}

The MessagesYml is almost the same.

And here is my Serializer code. There might be a problem too

package me.rorak.utils;

import java.lang.reflect.Field;
import java.util.List;
import java.util.Map;

public class Serializer {
    public static String serializeMap(Map<?, ?> toSer, String prefix) throws IllegalAccessException {
        StringBuilder str = new StringBuilder();
        str.append(prefix).append("{\n");
        for (Map.Entry<?, ?> entry : toSer.entrySet()) {
            str.append(prefix).append("[\n");
            str.append(serialize(entry.getKey(), prefix + "[] "));
            str.append(prefix).append("===AND===\n");
            str.append(serialize(entry.getValue(), prefix + "[] "));
            str.append(prefix).append("]\n");
        }
        str.append(prefix).append("}\n");
        return str.toString();
    }
    public static String serializeList(List<?> toSer, String prefix) throws IllegalAccessException {
        StringBuilder str = new StringBuilder();
        str.append(prefix).append("{\n");
        for (Object o : toSer) {
            str.append(prefix).append("[\n");
            str.append(serialize(o, prefix + "[] "));
            str.append(prefix).append("]\n");
        }
        str.append(prefix).append("}\n");
        return str.toString();
    }
    public static String serialize(Object toSer, String prefix) throws IllegalAccessException {
        StringBuilder str = new StringBuilder();
        for (Field f : toSer.getClass().getDeclaredFields()) {
            boolean acc = f.trySetAccessible();
            if (!acc) {
                str.append(prefix).append(f.getName());
                str.append(": not accessible");
                break;
            }
            str.append(prefix).append(f.getName());
            str.append(": ");
            if (f.getType().isPrimitive()) {
                str.append(f.get(toSer).toString());
            }
            else if (f.getType().isInstance(String.class)) {
                str.append((String)f.get(toSer));
            }
            else if (f.getType().isInstance(Map.class)) {
                str.append("\n");
                str.append(serializeMap((Map<?, ?>)f.get(toSer), prefix + ":: "));
            }
            else if (f.getType().isInstance(List.class)) {
                str.append("\n");
                str.append(serializeList((List<?>)f.get(toSer), prefix + ":: "));
            }
            else if (f.getType().isArray()) {
                str.append(serializeList(List.of((Object[])f.get(toSer)), prefix + ":: "));
            }
            else {
                str.append("\n");
                str.append(serialize(f.get(toSer), prefix + ":: "));
            }
            str.append("\n");
        }
        return str.toString();
    }
    public static String serialize(Object toSer) {
        try {
            return serialize(toSer, "");
        }
        catch (Exception e) {
            e.printStackTrace();
            return "null";
        }
    }
}

And here is my output from the serialize() method:

[INFO] [Debug] config.yml:

[INFO] [Debug]

serialVersionUID: 10

permissions:

:: serialVersionUID: not accessible

ranks:

:: serialVersionUID: not accessible

chats:

:: serialVersionUID: not accessible

worlds:

:: serialVersionUID: not accessible

famous:

:: serialVersionUID: 2

:: names:

:: :: serialVersionUID: not accessible

:: password:

:: :: value: not accessible

[INFO] [Debug] messages.yml:

[INFO] [Debug]

serialVersionUID: 11

commands:

:: serialVersionUID: not accessible

serverinfo:

:: serialVersionUID: not accessible

rules:

:: serialVersionUID: not accessible

noSuchPlayer:

:: value: not accessible

noPermissions:

:: value: not accessible

[INFO] [BlazenoidPlugin] Loaded!

(BlazenoidPlugin is my plugin prefix, defined in plugin.yml)

I know, there is a lot of code, but I would appreciate an answer. If you need any of the other classes, comment down.

Thanks!

1 Answers1

0

The serial ID seems not accessible. Try to set as public instead of private or create getter.

Also, be sure that your class Permissions, Ranks... are serializable too.

For me, what you do seems to don't be a good solution. You are re-creating the weel. I suggest you to:

  • Use JSON formattage. Multiple API do it, Jackson do it fine, gson ...
  • Just use the YAML as bukkit use since long time. It's easier because you don't have to do your own formatting. It also contains multiple things to make easier for spigot, such as storing of itemstack.
  • Use toString() method to print different things
Elikill58
  • 4,050
  • 24
  • 23
  • 45
  • that is not a really helpful solution. I think the problem is with the load() method in ConfigYml. Files Permission, Ranks, etc are serializable. Configs in bukkit/spigot use yaml, not JSON. –  Mar 22 '22 at 13:34
  • The issue should be fixed with the first paragraph, after it's mostly suggestions because I don't really understand why you want to make your own serialization system. Also, 3 last items are just different possibilities – Elikill58 Mar 22 '22 at 13:36