1.14.4 error serialization

Discussion in 'Spigot Plugin Development' started by eralysium, Jan 27, 2020.

  1. It's to make a system of "kinematics". I launch the "record" with the stick, I add all my locations in my list. I save all this (is there a better way to save than serialization ?) and then I get back what I saved to teleport the player to the different positions.

    precision (I'm a beginner x) )

    Code (Text):
    if ((event.getItem().getType() == Material.STICK) && ((event.getAction() == Action.RIGHT_CLICK_BLOCK) || (event.getAction() == Action.RIGHT_CLICK_AIR))) {
                    ArrayList<Location> list=new ArrayList<Location>();
                    clicks.put(player, true);
                    player.sendMessage("start");
                    new BukkitRunnable() {
                        public void run() {
                            if (clicks.get(player) == null ||  clicks.get(player) == true) {
                                float pitch = player.getEyeLocation().getPitch();
                                float yaw = player.getEyeLocation().getYaw();
                                World world = player.getLocation().getWorld();
                                double x = (double) player.getLocation().getX();
                                double y = (double) player.getLocation().getY();
                                double z = (double) player.getLocation().getZ();
                                Location location = new Location(world, x+4, y, z, yaw, pitch);
                                list.add(location);
                            }
                            else {
                                 try {
                                     FileOutputStream f = new FileOutputStream(new File("loc"));
                                     ObjectOutputStream o = new ObjectOutputStream(f);
                                     o.writeObject(list);
                                     o.close();
                                     f.close();
                                 } catch (IOException e) {
                                     System.out.println("Error initializing stream");
                                 }
                                 cancel();
                            }
                        }
                    }.runTaskTimer(main, 0L, 1L);
            }
    that return "Error initializing stream"
    My list contains all my locations. This is the o.writeObject(list) line; which blocks execution (I sent messages to the console between each line of the try, and it blocks on that line).
     
  2. If I remember correctly, creating a new file using the constructor with a single string will use the absolute file path. I suppose loc is not in that path; so you'll need to get the relative filePath. If that file is inside your plugin-folder, you can use the File-constructor like so:
    Code (Text):
    File file = new File(<? extends JavaPlugin>.getDataFolder(), "loc");
    You'll need to replace <? extends JavaPlugin> with an instance of your main class and make sure the file exists, before you use it:
    Code (Java):
    File dataFolder = <? extends JavaPlugin>.getDataFolder();
    if (!dataFolder.exists()) {
        dataFolder.mkdir();
    }
     
  3. give the error. theres more to an error than just the text reason
     
  4. there's no error there x) it just sends me back the message that the try didn't work

    and the file will be created each time (with my code, so I don't think the problem is that it doesn't "find" the file or write (I think :) )


    And I did it on eclipse, and it really brings out the two "people" in me when I do it.

    Code (Text):
    public class WriterReader {

        public static void main(String[]args) {
            ArrayList<Personne> List= new ArrayList<Personne>();
            Personne p1 = new Personne("John", "Male", 30);
            Personne p2 = new Personne("Rachel", "Female", 25);
            List.add(p1);
            List.add(p2);

            try {
                FileOutputStream f = new FileOutputStream(new File("lalala"));
                ObjectOutputStream o = new ObjectOutputStream(f);

               //Write
                o.writeObject(List);

                o.close();
                f.close();

                FileInputStream fi = new FileInputStream(new File("lalala"));
                ObjectInputStream oi = new ObjectInputStream(fi);

               //Read
                @SuppressWarnings("unchecked")
                final ArrayList<Personne> listfinal = (ArrayList<Personne>) oi.readObject();

                System.out.println(listfinal + " " + List.size());

                oi.close();
                fi.close();

            } catch (FileNotFoundException e) {
                System.out.println("File not found");
            } catch (IOException e) {
                System.out.println("Error initializing stream");
            } catch (ClassNotFoundException e) {
                e.printStackTrace();
            }

        }

    }
     
    #4 eralysium, Jan 27, 2020
    Last edited: Jan 27, 2020
  5. oh. youre not printing the error. youre just ignoring it. e.printStackTrace().
     
  6. Code (Text):
    [19:58:58] [Server thread/INFO]: Error initializing stream
    [19:58:58] [Server thread/WARN]: java.io.NotSerializableException: org.bukkit.Location
    [19:58:58] [Server thread/WARN]:     at java.io.ObjectOutputStream.writeObject0(Unknown Source)
    [19:58:58] [Server thread/WARN]:     at java.io.ObjectOutputStream.writeObject(Unknown Source)
    [19:58:58] [Server thread/WARN]:     at java.util.ArrayList.writeObject(Unknown Source)
    [19:58:58] [Server thread/WARN]:     at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    [19:58:58] [Server thread/WARN]:     at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
    [19:58:58] [Server thread/WARN]:     at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    [19:58:58] [Server thread/WARN]:     at java.lang.reflect.Method.invoke(Unknown Source)
    [19:58:58] [Server thread/WARN]:     at java.io.ObjectStreamClass.invokeWriteObject(Unknown Source)
    [19:58:58] [Server thread/WARN]:     at java.io.ObjectOutputStream.writeSerialData(Unknown Source)
    [19:58:58] [Server thread/WARN]:     at java.io.ObjectOutputStream.writeOrdinaryObject(Unknown Source)
    [19:58:58] [Server thread/WARN]:     at java.io.ObjectOutputStream.writeObject0(Unknown Source)
    [19:58:58] [Server thread/WARN]:     at java.io.ObjectOutputStream.writeObject(Unknown Source)
    [19:58:58] [Server thread/WARN]:     at fr.bobinho.cite.join.Join$1.run(Join.java:104)
    [19:58:58] [Server thread/WARN]:     at org.bukkit.craftbukkit.v1_14_R1.scheduler.CraftTask.run(CraftTask.java:81)
    [19:58:58] [Server thread/WARN]:     at org.bukkit.craftbukkit.v1_14_R1.scheduler.CraftScheduler.mainThreadHeartbeat(CraftScheduler.java:394)
    [19:58:58] [Server thread/WARN]:     at net.minecraft.server.v1_14_R1.MinecraftServer.b(MinecraftServer.java:1022)
    [19:58:58] [Server thread/WARN]:     at net.minecraft.server.v1_14_R1.DedicatedServer.b(DedicatedServer.java:393)
    [19:58:58] [Server thread/WARN]:     at net.minecraft.server.v1_14_R1.MinecraftServer.a(MinecraftServer.java:970)
    [19:58:58] [Server thread/WARN]:     at net.minecraft.server.v1_14_R1.MinecraftServer.run(MinecraftServer.java:815)
    [19:58:58] [Server thread/WARN]:     at java.lang.Thread.run(Unknown Source)
     
  7. Ah, you can't serialize a location. My solution to this problem is to make a SerializableLocation and then swap from one form to another in that class:
    Code (Java):
    public class SerializableLocation {

        private double x, y, z;
        private float pitch, yaw;
        private UUID worldUId;

        public SerializableLocation(...) {
            // init everything
        }

        public static SerializableLocation fromLocation(Location location) {
            return new SerializableLocation(location.getWorld.getUniqueId()...);
        }

        public Location toLocation() {
            return new Location(World.fromUUID()....);
        }
    }
     
    • Friendly Friendly x 1
  8. I don't really know what to put in SerializableLocation(...).
    I understand what it's for, and generally how it works, but I'm not sure what to put in it (because it has to be "static").

    Code (Text):
    public class SerializableLocation {

        private double x, y, z;
        private float pitch, yaw;
        private World world;

        public SerializableLocation(World world, double x, double y, double z, float yaw, float pitch) {
            this.world = world;
            this.x = x;
            this.y = y;
            this.z = z;
            this.yaw = pitch;
            this.pitch = pitch;
        }

        public static SerializableLocation fromLocation(Location location) {
            return new SerializableLocation(location.getWorld.getUniqueId()...);
        }

        public Location toLocation() {
            return new Location(world, x, y, z, yaw, pitch);
        }
    }
     
  9. That's just a convenience method. Instead of having to call
    Code (Java):
    SerializableLocation serLoc = new SerializableLocation(location.getWorld(), location.getX(),...)
    you can call it like this:
    Code (Java):
    SerializableLocation serLoc = SerializableLocation.fromLocation(location);
    The method is defined like this:
    Code (Java):
    public static SerializableLocation fromLocation(Location loc) {
            return new SerializableLocation(loc.getWorld.getUniqueId(), loc.getX(), loc.getY(), loc.getZ(), loc.getYaw(), loc.getPitch());
        }
    Also, 2 things:
    1) Don't use the World-object. This is the reason why you can't serialize Location; you would have to save the entire world to a file. You have to use the UUID (World#getUID()) or the name of the world (preferably the UUID thou).
    2) You saved both yaw and pitch as pitch
     
    • Friendly Friendly x 1
  10. ok, I have no more mistakes x) I'll test tomorrow. I also corrected the 2nd return, because World.fromUUID() doesn't work. (error) I use Bukkit.getWorld(world) (world being uuid).

    Sorry if the question seemed obvious (x), but I'm a total beginner... I never learned to dev in java, I just use my notions of algorithmic and doc x).
    So in my head I know what to do, but putting it in java form is a bit of a hassle x)