private void scan() throws InvalidPluginException {
    Enumeration<JarEntry> e = jarFile.entries();
    while (e.hasMoreElements()) {
      JarEntry entry = e.nextElement();
      if (skip(entry)) {
        continue;
      }

      ClassData def = new ClassData();
      try {
        new ClassReader(read(entry)).accept(def, SKIP_ALL);
      } catch (IOException err) {
        throw new InvalidPluginException("Cannot auto-register", err);
      } catch (RuntimeException err) {
        PluginLoader.log.warn(
            String.format(
                "Plugin %s has invaild class file %s inside of %s",
                pluginName, entry.getName(), jarFile.getName()),
            err);
        continue;
      }

      if (def.exportedAsName != null) {
        if (def.isConcrete()) {
          export(def);
        } else {
          PluginLoader.log.warn(
              String.format(
                  "Plugin %s tries to @Export(\"%s\") abstract class %s",
                  pluginName, def.exportedAsName, def.className));
        }
      } else if (def.listen) {
        if (def.isConcrete()) {
          listen(def);
        } else {
          PluginLoader.log.warn(
              String.format(
                  "Plugin %s tries to @Listen abstract class %s", pluginName, def.className));
        }
      }
    }
  }