Stack overflow when using class constructor

Discussion in 'Plugin Development' started by bowlerguy66, Nov 8, 2015.

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

    bowlerguy66

    Ok, so I have multiple classes and I use constructors between them ALOT. This is my first time coming across a stack overflow error. This is what it looks like:
    Console (open)

    Code:
    [21:43:17 ERROR]: Could not load 'plugins/GunsCraft.jar' in folder 'plugins'
    org.bukkit.plugin.InvalidPluginException: java.lang.StackOverflowError
        at org.bukkit.plugin.java.JavaPluginLoader.loadPlugin(JavaPluginLoader.java:135) ~[craftbukkit.jar:git-Spigot-fdc1440-53fac9f]
        at org.bukkit.plugin.SimplePluginManager.loadPlugin(SimplePluginManager.java:329) ~[craftbukkit.jar:git-Spigot-fdc1440-53fac9f]
        at org.bukkit.plugin.SimplePluginManager.loadPlugins(SimplePluginManager.java:251) [craftbukkit.jar:git-Spigot-fdc1440-53fac9f]
        at org.bukkit.craftbukkit.v1_8_R3.CraftServer.loadPlugins(CraftServer.java:292) [craftbukkit.jar:git-Spigot-fdc1440-53fac9f]
        at org.bukkit.craftbukkit.v1_8_R3.CraftServer.reload(CraftServer.java:739) [craftbukkit.jar:git-Spigot-fdc1440-53fac9f]
        at org.bukkit.Bukkit.reload(Bukkit.java:535) [craftbukkit.jar:git-Spigot-fdc1440-53fac9f]
        at org.bukkit.command.defaults.ReloadCommand.execute(ReloadCommand.java:25) [craftbukkit.jar:git-Spigot-fdc1440-53fac9f]
        at org.bukkit.command.SimpleCommandMap.dispatch(SimpleCommandMap.java:141) [craftbukkit.jar:git-Spigot-fdc1440-53fac9f]
        at org.bukkit.craftbukkit.v1_8_R3.CraftServer.dispatchCommand(CraftServer.java:641) [craftbukkit.jar:git-Spigot-fdc1440-53fac9f]
        at org.bukkit.craftbukkit.v1_8_R3.CraftServer.dispatchServerCommand(CraftServer.java:627) [craftbukkit.jar:git-Spigot-fdc1440-53fac9f]
        at net.minecraft.server.v1_8_R3.DedicatedServer.aO(DedicatedServer.java:412) [craftbukkit.jar:git-Spigot-fdc1440-53fac9f]
        at net.minecraft.server.v1_8_R3.DedicatedServer.B(DedicatedServer.java:375) [craftbukkit.jar:git-Spigot-fdc1440-53fac9f]
        at net.minecraft.server.v1_8_R3.MinecraftServer.A(MinecraftServer.java:653) [craftbukkit.jar:git-Spigot-fdc1440-53fac9f]
        at net.minecraft.server.v1_8_R3.MinecraftServer.run(MinecraftServer.java:556) [craftbukkit.jar:git-Spigot-fdc1440-53fac9f]
        at java.lang.Thread.run(Thread.java:745) [?:1.8.0_45]
    Caused by: java.lang.StackOverflowError
        at me.bowlerguy66.gunscraft.GunData.<init>(GunData.java:64) ~[?:?]
        at me.bowlerguy66.gunscraft.Scoping.<init>(Scoping.java:35) ~[?:?]
        at me.bowlerguy66.gunscraft.FireGun.<init>(FireGun.java:32) ~[?:?]
        at me.bowlerguy66.gunscraft.GunScoreboard.<init>(GunScoreboard.java:29) ~[?:?]
        at me.bowlerguy66.gunscraft.GunListener.<init>(GunListener.java:38) ~[?:?]
        at me.bowlerguy66.gunscraft.Scoping.<init>(Scoping.java:36) ~[?:?]
        at me.bowlerguy66.gunscraft.FireGun.<init>(FireGun.java:32) ~[?:?]
        at me.bowlerguy66.gunscraft.GunScoreboard.<init>(GunScoreboard.java:29) ~[?:?]
    ...
    Im not sure what it means, but here are the five classes.
    Classes (open)
    Gun Data:
    Code:
    package me.bowlerguy66.gunscraft;
    
    import java.util.ArrayList;
    import java.util.HashMap;
    import java.util.List;
    import java.util.Random;
    import java.util.UUID;
    
    import org.bukkit.Bukkit;
    import org.bukkit.ChatColor;
    import org.bukkit.Material;
    import org.bukkit.entity.Player;
    import org.bukkit.inventory.Inventory;
    import org.bukkit.inventory.ItemStack;
    import org.bukkit.inventory.meta.ItemMeta;
    
    public class GunData {
      
        @SuppressWarnings("unused")
        private GunListener gl;
      
        public GunData(GunListener gunListener) {
            this.gl = gunListener;
        }
      
        private static GunsCraft plugin;
      
        public GunData(GunsCraft instance) {
            plugin = instance;
        }
      
        @SuppressWarnings("unused")
        private static GunScoreboard gs;
      
        @SuppressWarnings("static-access")
        public GunData(GunScoreboard instance) {
            this.gs = instance;
        }
      
        @SuppressWarnings("unused")
        private FireGun fg;
      
        public GunData(FireGun instance) {
            this.fg = instance;
        }
      
        @SuppressWarnings("unused")
        private BukkitListener bl;
      
        public GunData(BukkitListener instance) {
            this.bl = instance;
        }
      
        @SuppressWarnings("unused")
        private Loading loadclass;
      
        public GunData(Loading instance) {
            this.loadclass = instance;
        }
    
        @SuppressWarnings("unused")
        private Scoping scope;
      
        public GunData(Scoping instance) {
            this.scope = instance;
        }
    
    GunScoreboard:
    Code:
    package me.bowlerguy66.gunscraft;
    
    import org.bukkit.Bukkit;
    import org.bukkit.ChatColor;
    import org.bukkit.entity.Player;
    import org.bukkit.inventory.ItemStack;
    import org.bukkit.scoreboard.DisplaySlot;
    import org.bukkit.scoreboard.Objective;
    import org.bukkit.scoreboard.Score;
    import org.bukkit.scoreboard.Scoreboard;
    import org.bukkit.scoreboard.ScoreboardManager;
    
    public class GunScoreboard {
    
        @SuppressWarnings("unused")
        private GunListener gl;
      
        public GunScoreboard(GunListener instance) {
            this.gl = instance;
        }
      
        private GunsCraft plugin;
      
        public GunScoreboard(GunsCraft instance) {
            this.plugin = instance;
        }
      
        public GunData gdata = new GunData(this);
    
    Gun Listener:
    Code:
    package me.bowlerguy66.gunscraft;
    
    import java.util.ArrayList;
    import java.util.List;
    
    import org.bukkit.Bukkit;
    import org.bukkit.ChatColor;
    import org.bukkit.Location;
    import org.bukkit.Material;
    import org.bukkit.Sound;
    import org.bukkit.entity.EntityType;
    import org.bukkit.entity.Item;
    import org.bukkit.entity.Player;
    import org.bukkit.entity.Projectile;
    import org.bukkit.entity.Skeleton;
    import org.bukkit.entity.Zombie;
    import org.bukkit.event.EventHandler;
    import org.bukkit.event.Listener;
    import org.bukkit.event.block.Action;
    import org.bukkit.event.entity.EntityDamageByEntityEvent;
    import org.bukkit.event.entity.EntityDamageEvent;
    import org.bukkit.event.entity.EntityDamageEvent.DamageCause;
    import org.bukkit.event.entity.ProjectileHitEvent;
    import org.bukkit.event.inventory.InventoryClickEvent;
    import org.bukkit.event.player.PlayerDropItemEvent;
    import org.bukkit.event.player.PlayerInteractEvent;
    import org.bukkit.event.player.PlayerItemHeldEvent;
    import org.bukkit.event.player.PlayerPickupItemEvent;
    import org.bukkit.event.player.PlayerToggleSneakEvent;
    import org.bukkit.inventory.Inventory;
    import org.bukkit.inventory.ItemStack;
    import org.bukkit.inventory.meta.ItemMeta;
    
    public class GunListener implements Listener {
    
        public GunData gdata = new GunData(this);
        public Items items = new Items(this);
        public GunScoreboard gs = new GunScoreboard(this);
    
    Scoping:
    Code:
    package me.bowlerguy66.gunscraft;
    
    import java.util.ArrayList;
    import java.util.HashMap;
    import java.util.List;
    
    import org.bukkit.Bukkit;
    import org.bukkit.ChatColor;
    import org.bukkit.entity.Player;
    import org.bukkit.event.EventHandler;
    import org.bukkit.event.Listener;
    import org.bukkit.event.block.Action;
    import org.bukkit.event.player.PlayerInteractEvent;
    import org.bukkit.event.player.PlayerItemHeldEvent;
    import org.bukkit.event.player.PlayerToggleSneakEvent;
    import org.bukkit.inventory.ItemStack;
    import org.bukkit.potion.PotionEffect;
    import org.bukkit.potion.PotionEffectType;
    
    public class Scoping implements Listener {
    
        private GunsCraft plugin;
      
        public Scoping(GunsCraft instance) {
            this.plugin = instance;
        }
    
        /*@SuppressWarnings("unused")
        private FireGun fg;
      
        public Scoping(FireGun instance) {
            this.fg = instance;
        }*/
      
        public GunData gdata = new GunData(this);
        public GunListener gl = new GunListener(this);
    
    Firegun:
    Code:
    package me.bowlerguy66.gunscraft;
    
    import java.util.HashMap;
    
    import org.bukkit.Bukkit;
    import org.bukkit.Location;
    import org.bukkit.Material;
    import org.bukkit.Sound;
    import org.bukkit.entity.Arrow;
    import org.bukkit.entity.Player;
    import org.bukkit.entity.Projectile;
    import org.bukkit.entity.Snowball;
    import org.bukkit.inventory.ItemStack;
    import org.bukkit.inventory.meta.ItemMeta;
    import org.bukkit.util.Vector;
    
    public class FireGun {
      
        @SuppressWarnings("unused")
        private GunScoreboard gs;
      
        public FireGun(GunScoreboard instance) {
            this.gs = instance;
        }
      
        private GunListener gl;
      
        public FireGun(GunListener instance) {
            this.gl = instance;
        }
      
    //    public Scoping scope = new Scoping(this);
        public GunData gdata = new GunData(this);
    
    Im not sure how they are related. Also, could you please explain to me what a StackOverflow error is and how I can prevent it in the future. Thanks!
     
  2. Offline

    mcdorli

    Java "contains" the tasks in a so called stack. Imagine this as a tower of methods. Everytime you call a method, it an instance of it gets moved to the top of the stack, and only the methods on the top can run (except for multi-threading). Each kf these methods has its own variable lists, and can't reach variables form other methods in the stack. If this tower gets full, and you want to put one more method on top of it, then you get a stackOverflowException.

    Edit: While multi-threading, you have two different stacks, but still, only one can run at a time.
     
  3. Offline

    bowlerguy66

    @mcdorli Ok, so what do I do to stop this from happening?
     
  4. Offline

    teej107

    @bowlerguy66 Don't have code that causes infinite loops.
     
  5. Offline

    bowlerguy66

    Yeah, I kinda figured. But how do I make it so this works without making it loop?
     
  6. Offline

    mcdorli

    Stackoverflows are kind of a hard to debug.
    It can cause by:
    • Methods calling itself
    • A constructor, that stores itself by creating a new instance of itself.
    • By a chain of very short methods.
    • Bad code.
    • Small ram space (This is probably not gonna happen)
    Example:

    Code:
    AwesomeClass instance;
    public AwesomeClass() {
        this.instance = new AwesomeClass(); // This should be replaced with "this"
    }
    
     
    Last edited: Nov 8, 2015
  7. Offline

    Scimiguy

    Check your calls, see where you're making a loop
     
  8. Offline

    teej107

    Look at your stacktrace. You'll notice calls to your class.<init>
    That is the constuctor being ran aka Object being created.
     
  9. Offline

    mcdorli

    I found the error:

    You call the class scoping from the firegun, that calls fireguns construczor, that calls scoping etc. This is a very strange setup of guns. You shouldn't do it like this. Create an abstract class for a basic gun, then create extensions, firegun is a type of gun, flamethrower is a type of firegun, flare gun too, etc. You can create a tree out of this.

    GUN - SNIPER
    |
    FIRE
    GUN - FLAMETHROWER
    |
    FLARE
    GUN
     
Thread Status:
Not open for further replies.

Share This Page