我编写了一个sqlite数据库库,该库允许我在运行时从数据库加载Java对象。我在Minecraft服务器上使用了这个库,在这里我还添加了一些插件,利用这些插件来存储和检索数据。
服务器和jar的设置方式:服务器(spigot.jar)本身存储在/ spigot /文件夹中,并装有运行Java命令的Shell脚本。此命令在其类路径中使用/ spigot / lib /中的数据库库(和其他必需的库)。然后,spigot.jar从/ spigot / plugins /加载所有插件(也为.jar格式)。
我正在使用的shell命令是:
java -verbose:class -server -Xms4G -Xmx4G -XX:+UseConcMarkSweepGC -XX:ParallelGCThreads=2 -XX:+AggressiveOpts -cp "spigot.jar:./lib/*" org.bukkit.craftbukkit.Main nogui | tee output.txt
数据库的工作方式如下:我已经将完整的类名和程序包(例如“ com.mywebsite.Foo”)一起存储为数据库的字符串。加载Foo的实例时,此字符串用于加载类。使用Class.forName(classname);
将字符串作为参数加载该类。
该设置曾经可以工作几个星期,但是现在我最近对代码进行了很多内部更改,但没有足够的小心,我做了很多事情。我清除了我犯的大多数错误,但是我仍然有信心在Class.forName(classname);
行上得到ClassNotFoundException,尽管我非常相信它以前曾经可以工作。我在shell命令中添加了-verbose:class参数以加载服务器,以确保包含了它尝试加载的类,并且它们确实包含在内。
Sidenote(有关代码的其他信息,但不直接 与该问题有关):
数据库存储两种类型的对象,这些对象实现了 接口DatabaseObject和实现该接口的对象 可序列化。
DatabaseObjects适用于存储到 数据库(例如User类),因此将其所有值存储在 单独的列,以便可以轻松地对其进行编辑。
可序列化对象旨在用于DatabaseObject的字段,该字段 比基本值复杂(例如,变量Location in inside 用户),他们充当该字段的包装器,因此它也可以 被存储和检索。但是,整个对象存储为 单个字符串,因此在此替换单个值不是最佳选择 存储方法。
实现DatabaseObject的对象通常总是由我定义 在我的插件代码中。但是,要求 序列化通常不是由我定义,而是由Spigot API定义, 这是我使用此包装器的另一个原因。
我已经找到了一些解决方案,可以获取 通过存储传递的类来实现数据库对象的类型 到数据库(在数据库初始化时发生,因此它知道 每个类别要存储的值)。所以不要使用
Class.forName()
,我可以将字符串与存储的类进行比较 并从那里得到它。但是此解决方案不涵盖以下任何实现 可序列化的,因为它们最初并未传递给数据库。 为此可以创建解决方法,但是感觉不到 像我的干净代码。鉴于以下事实:
Class.forName()
过去曾 工作之前,该类是根据详细参数加载的, 如果我实际存储它们,我就可以获得DatabaseObject类型 价值观,意味着我应该有一些办法Class.forName()
在此情况下再次工作。