Reputation: 3890
I'm having a rather interesting issue. When attempting to load a model from a Mongo instance, Morphia throws the following error:
[22:17:13 WARN]: Class not found defined in dbObj:
java.lang.ClassNotFoundException: me.mattrick.test.storage.TestStat
at java.net.URLClassLoader.findClass(URLClassLoader.java:381) ~[?:1.8.0_101]
at java.lang.ClassLoader.loadClass(ClassLoader.java:424) ~[?:1.8.0_101]
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:331) ~[?:1.8.0_101]
at java.lang.ClassLoader.loadClass(ClassLoader.java:357) ~[?:1.8.0_101]
at java.lang.Class.forName0(Native Method) ~[?:1.8.0_101]
at java.lang.Class.forName(Class.java:348) ~[?:1.8.0_101]
at org.mongodb.morphia.mapping.DefaultCreator.getClass(DefaultCreator.java:175) [Test-1.5-SNAPSHOT-shaded.jar:?]
at org.mongodb.morphia.mapping.DefaultCreator.createInstance(DefaultCreator.java:97) [Test-1.5-SNAPSHOT-shaded.jar:?]
at org.mongodb.morphia.mapping.EmbeddedMapper.readMapOrCollectionOrEntity(EmbeddedMapper.java:205) [Test-1.5-SNAPSHOT-shaded.jar:?]
at org.mongodb.morphia.mapping.EmbeddedMapper.readCollection(EmbeddedMapper.java:142) [Test-1.5-SNAPSHOT-shaded.jar:?]
at org.mongodb.morphia.mapping.EmbeddedMapper.fromDBObject(EmbeddedMapper.java:45) [Test-1.5-SNAPSHOT-shaded.jar:?]
at org.mongodb.morphia.mapping.Mapper.readMappedField(Mapper.java:772) [Test-1.5-SNAPSHOT-shaded.jar:?]
at org.mongodb.morphia.mapping.Mapper.fromDb(Mapper.java:230) [Test-1.5-SNAPSHOT-shaded.jar:?]
at org.mongodb.morphia.mapping.Mapper.fromDBObject(Mapper.java:191) [Test-1.5-SNAPSHOT-shaded.jar:?]
at org.mongodb.morphia.query.MorphiaIterator.convertItem(MorphiaIterator.java:134) [Test-1.5-SNAPSHOT-shaded.jar:?]
at org.mongodb.morphia.query.MorphiaIterator.processItem(MorphiaIterator.java:146) [Test-1.5-SNAPSHOT-shaded.jar:?]
at org.mongodb.morphia.query.MorphiaIterator.next(MorphiaIterator.java:117) [Test-1.5-SNAPSHOT-shaded.jar:?]
at org.mongodb.morphia.query.QueryImpl.get(QueryImpl.java:220) [Test-1.5-SNAPSHOT-shaded.jar:?]
at org.mongodb.morphia.dao.BasicDAO.findOne(BasicDAO.java:180) [Test-1.5-SNAPSHOT-shaded.jar:?]
at me.mattrick.test.storage.UserRepository.getUserFromPlayer(UserRepository.java:22) [Test-1.5-SNAPSHOT-shaded.jar:?]
at me.mattrick.test.event.JoinEvent.onJoin(JoinEvent.java:37) [Test-1.5-SNAPSHOT-shaded.jar:?]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:1.8.0_101]
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[?:1.8.0_101]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[?:1.8.0_101]
at java.lang.reflect.Method.invoke(Method.java:498) ~[?:1.8.0_101]
at org.bukkit.plugin.java.JavaPluginLoader$1.execute(JavaPluginLoader.java:306) [spigot-1.8.8.jar:git-Spigot-e4d4710-e1ebe52]
at org.bukkit.plugin.RegisteredListener.callEvent(RegisteredListener.java:62) [spigot-1.8.8.jar:git-Spigot-e4d4710-e1ebe52]
at org.bukkit.plugin.SimplePluginManager.fireEvent(SimplePluginManager.java:502) [spigot-1.8.8.jar:git-Spigot-e4d4710-e1ebe52]
at org.bukkit.plugin.SimplePluginManager.callEvent(SimplePluginManager.java:487) [spigot-1.8.8.jar:git-Spigot-e4d4710-e1ebe52]
at net.minecraft.server.v1_8_R3.PlayerList.onPlayerJoin(PlayerList.java:298) [spigot-1.8.8.jar:git-Spigot-e4d4710-e1ebe52]
at net.minecraft.server.v1_8_R3.PlayerList.a(PlayerList.java:157) [spigot-1.8.8.jar:git-Spigot-e4d4710-e1ebe52]
at net.minecraft.server.v1_8_R3.LoginListener.b(LoginListener.java:144) [spigot-1.8.8.jar:git-Spigot-e4d4710-e1ebe52]
at net.minecraft.server.v1_8_R3.LoginListener.c(LoginListener.java:54) [spigot-1.8.8.jar:git-Spigot-e4d4710-e1ebe52]
at net.minecraft.server.v1_8_R3.NetworkManager.a(NetworkManager.java:231) [spigot-1.8.8.jar:git-Spigot-e4d4710-e1ebe52]
at net.minecraft.server.v1_8_R3.ServerConnection.c(ServerConnection.java:148) [spigot-1.8.8.jar:git-Spigot-e4d4710-e1ebe52]
at net.minecraft.server.v1_8_R3.MinecraftServer.B(MinecraftServer.java:814) [spigot-1.8.8.jar:git-Spigot-e4d4710-e1ebe52]
at net.minecraft.server.v1_8_R3.DedicatedServer.B(DedicatedServer.java:374) [spigot-1.8.8.jar:git-Spigot-e4d4710-e1ebe52]
at net.minecraft.server.v1_8_R3.MinecraftServer.A(MinecraftServer.java:654) [spigot-1.8.8.jar:git-Spigot-e4d4710-e1ebe52]
at net.minecraft.server.v1_8_R3.MinecraftServer.run(MinecraftServer.java:557) [spigot-1.8.8.jar:git-Spigot-e4d4710-e1ebe52]
at java.lang.Thread.run(Thread.java:745) [?:1.8.0_101]
[22:17:13 WARN]: Class not found defined in dbObj:
java.lang.ClassNotFoundException: me.mattrick.test.storage.TestStat
at java.net.URLClassLoader.findClass(URLClassLoader.java:381) ~[?:1.8.0_101]
at java.lang.ClassLoader.loadClass(ClassLoader.java:424) ~[?:1.8.0_101]
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:331) ~[?:1.8.0_101]
at java.lang.ClassLoader.loadClass(ClassLoader.java:357) ~[?:1.8.0_101]
at java.lang.Class.forName0(Native Method) ~[?:1.8.0_101]
at java.lang.Class.forName(Class.java:348) ~[?:1.8.0_101]
at org.mongodb.morphia.mapping.DefaultCreator.getClass(DefaultCreator.java:175) [Test-1.5-SNAPSHOT-shaded.jar:?]
at org.mongodb.morphia.mapping.DefaultCreator.createInstance(DefaultCreator.java:87) [Test-1.5-SNAPSHOT-shaded.jar:?]
at org.mongodb.morphia.mapping.DefaultCreator.createInstance(DefaultCreator.java:102) [Test-1.5-SNAPSHOT-shaded.jar:?]
at org.mongodb.morphia.mapping.EmbeddedMapper.readMapOrCollectionOrEntity(EmbeddedMapper.java:205) [Test-1.5-SNAPSHOT-shaded.jar:?]
at org.mongodb.morphia.mapping.EmbeddedMapper.readCollection(EmbeddedMapper.java:142) [Test-1.5-SNAPSHOT-shaded.jar:?]
at org.mongodb.morphia.mapping.EmbeddedMapper.fromDBObject(EmbeddedMapper.java:45) [Test-1.5-SNAPSHOT-shaded.jar:?]
at org.mongodb.morphia.mapping.Mapper.readMappedField(Mapper.java:772) [Test-1.5-SNAPSHOT-shaded.jar:?]
at org.mongodb.morphia.mapping.Mapper.fromDb(Mapper.java:230) [Test-1.5-SNAPSHOT-shaded.jar:?]
at org.mongodb.morphia.mapping.Mapper.fromDBObject(Mapper.java:191) [Test-1.5-SNAPSHOT-shaded.jar:?]
at org.mongodb.morphia.query.MorphiaIterator.convertItem(MorphiaIterator.java:134) [Test-1.5-SNAPSHOT-shaded.jar:?]
at org.mongodb.morphia.query.MorphiaIterator.processItem(MorphiaIterator.java:146) [Test-1.5-SNAPSHOT-shaded.jar:?]
at org.mongodb.morphia.query.MorphiaIterator.next(MorphiaIterator.java:117) [Test-1.5-SNAPSHOT-shaded.jar:?]
at org.mongodb.morphia.query.QueryImpl.get(QueryImpl.java:220) [Test-1.5-SNAPSHOT-shaded.jar:?]
at org.mongodb.morphia.dao.BasicDAO.findOne(BasicDAO.java:180) [Test-1.5-SNAPSHOT-shaded.jar:?]
at me.mattrick.test.storage.UserRepository.getUserFromPlayer(UserRepository.java:22) [Test-1.5-SNAPSHOT-shaded.jar:?]
at me.mattrick.test.event.JoinEvent.onJoin(JoinEvent.java:37) [Test-1.5-SNAPSHOT-shaded.jar:?]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:1.8.0_101]
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[?:1.8.0_101]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[?:1.8.0_101]
at java.lang.reflect.Method.invoke(Method.java:498) ~[?:1.8.0_101]
at org.bukkit.plugin.java.JavaPluginLoader$1.execute(JavaPluginLoader.java:306) [spigot-1.8.8.jar:git-Spigot-e4d4710-e1ebe52]
at org.bukkit.plugin.RegisteredListener.callEvent(RegisteredListener.java:62) [spigot-1.8.8.jar:git-Spigot-e4d4710-e1ebe52]
at org.bukkit.plugin.SimplePluginManager.fireEvent(SimplePluginManager.java:502) [spigot-1.8.8.jar:git-Spigot-e4d4710-e1ebe52]
at org.bukkit.plugin.SimplePluginManager.callEvent(SimplePluginManager.java:487) [spigot-1.8.8.jar:git-Spigot-e4d4710-e1ebe52]
at net.minecraft.server.v1_8_R3.PlayerList.onPlayerJoin(PlayerList.java:298) [spigot-1.8.8.jar:git-Spigot-e4d4710-e1ebe52]
at net.minecraft.server.v1_8_R3.PlayerList.a(PlayerList.java:157) [spigot-1.8.8.jar:git-Spigot-e4d4710-e1ebe52]
at net.minecraft.server.v1_8_R3.LoginListener.b(LoginListener.java:144) [spigot-1.8.8.jar:git-Spigot-e4d4710-e1ebe52]
at net.minecraft.server.v1_8_R3.LoginListener.c(LoginListener.java:54) [spigot-1.8.8.jar:git-Spigot-e4d4710-e1ebe52]
at net.minecraft.server.v1_8_R3.NetworkManager.a(NetworkManager.java:231) [spigot-1.8.8.jar:git-Spigot-e4d4710-e1ebe52]
at net.minecraft.server.v1_8_R3.ServerConnection.c(ServerConnection.java:148) [spigot-1.8.8.jar:git-Spigot-e4d4710-e1ebe52]
at net.minecraft.server.v1_8_R3.MinecraftServer.B(MinecraftServer.java:814) [spigot-1.8.8.jar:git-Spigot-e4d4710-e1ebe52]
at net.minecraft.server.v1_8_R3.DedicatedServer.B(DedicatedServer.java:374) [spigot-1.8.8.jar:git-Spigot-e4d4710-e1ebe52]
at net.minecraft.server.v1_8_R3.MinecraftServer.A(MinecraftServer.java:654) [spigot-1.8.8.jar:git-Spigot-e4d4710-e1ebe52]
at net.minecraft.server.v1_8_R3.MinecraftServer.run(MinecraftServer.java:557) [spigot-1.8.8.jar:git-Spigot-e4d4710-e1ebe52]
at java.lang.Thread.run(Thread.java:745) [?:1.8.0_101]
As you can see, I am running it inside a Spigot server (which is essentially a Minecraft server with a proper API implementation). I'm not sure if this is terribly relevant, but the Spigot server loads plugins in a similar way that Morphia would, so I think it may be possible that this is causing this issue, since there's been previous documented instances of Morphia conflicting with other libraries that use class loaders.
Adding "noClassnameStored = true" to the @Entity annotation seems to prevent this error, however I am storing a list of custom objects inside the database, which also causes this error.
The models I am using can be seen below:
Stat.java:
package me.mattrick.test.storage;
public class Stat {
}
TestStat.java:
package me.mattrick.test.storage;
import lombok.Getter;
import lombok.Setter;
public class TestStat extends Stat {
@Getter @Setter
private int test = 100;
}
User.java:
package me.mattrick.test.storage;
import lombok.Getter;
import lombok.Setter;
import me.mattrick.test.Test;
import me.mattrick.test.api.storage.mongo.MongoEntity;
import me.mattrick.test.cosmetics.particles.EnumParticleEffect;
import me.mattrick.test.player.PlayerRank;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import org.mongodb.morphia.annotations.Entity;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
@Entity(value = "users", noClassnameStored = true)
public class User extends MongoEntity {
@Getter @Setter
private UUID uuid;
@Getter @Setter
private PlayerRank rank = PlayerRank.DEFAULT;
@Getter @Setter
private EnumParticleEffect effect = EnumParticleEffect.NONE;
@Getter @Setter
private int money = 0;
@Getter @Setter
private int level = 0;
@Getter @Setter
private long experience = 0;
@Getter @Setter
private LocalDateTime firstJoined;
@Getter @Setter
private LocalDateTime lastPlayed;
@Getter @Setter
private List<Stat> stats = new ArrayList<>();
public Player getPlayer() {
return Bukkit.getPlayer(uuid);
}
public void save() {
Test.getInstance().getMongoBridge().repositoryBy(User.class).save(this);
}
public <T extends Stat> T getStat(Class<T> statClass) {
for (Stat stat : stats) {
if(stat.getClass() == statClass) {
return statClass.cast(stat);
}
}
return null;
}
public void addStat(Stat stat) {
stats.add(stat);
}
}
MongoEntity.java:
package me.mattrick.test.api.storage.mongo;
import lombok.Getter;
import lombok.Setter;
import org.bson.types.ObjectId;
import org.mongodb.morphia.annotations.Id;
public class MongoEntity {
@Id
@Getter @Setter
private ObjectId id;
}
It should be noted that the User class saves and loads fine as a result of the "noClassnameStored = true" parameter set on the @Entity annotation, but the Stat class does not, since this is not feasible for this.
Would anyone happen to know the solution to this? Its a rather odd error, and I'm not too experienced with Morphia. Thank you for you assistance and apologies for such a long post.
Upvotes: 2
Views: 2961
Reputation: 31
For anyone who's coming across this issue (like I did) in 2020 and uses PaperSpigot, here's what I managed to do after resorting to Morphia's documentation. I am using Morphia v1.6.0 and PaperSpigot 1.16.2.
morphia.getMapper().setOptions(
MapperOptions.legacy().classLoader(<MainClass>.class.getClassLoader())
.build()
);
Here's an explanation:
.setObjectFactory
to achieve this change. In my IDE (IntelliJ), it wasn't only marked as deprecated, but using that along with the DefaultCreator
wasn't doing the job. I don't think it's accepted practice in the new version(s) of Morphia? Anyways, I ended up using the setOptions
method using the legacy builder for setting MapperOptions
. This method wasn't deprecated either.JavaPlugin.getClassLoader()
. That method is protected. Therefore you cannot access it directly. However, if you use your plugin's main class, for instance, you can access the getClassLoader()
method with no issues. You're not going to want to directly access these methods unless you're trying to do some weird/hacky stuff.Upvotes: 2
Reputation: 3890
I've managed to figure it out. You need to override Morphia's ClassLoader with your plugin's own. In case anyone using Spigot or Bukkit are looking for the answer:
morphia.getMapper().getOptions().setObjectFactory(new DefaultCreator() {
@Override
protected ClassLoader getClassLoaderForClass() {
return JavaPlugin.getClassLoader();
}
});
Upvotes: 6
Reputation: 6233
That error usually stems from a broken classpath. It would appear that you spigot server isn't including the jar with your entities on the classpath when it starts up.
Upvotes: 0