所以这里出现了导致问题的问题...

我有使用MongoDB数据库在jBoss上运行的javaEE应用程序。我使用Morphia与mongo进行通信。该应用程序具有以下基本程序组件;

@EntityListeners(RootEntityListener.class)
public class RootEntity {
    @Id
    protected ObjectId id;
    @Indexed
    protected Long uid;
    @Indexed
    protected boolean active;
    ...
}

@Entity
public class User extends RootEntity {
    ...
}

@Entity
public class News extends RootEntity {
    ...
}


然后我的Morphia配置如下所示;

//Morphia Setup
morphia = new Morphia();
morphia.map(User.class).map(News.class);
...


然后,我通过调用下面显示的方法进行查询;

public List<News> findByUID(Long uId){
    Query<News> query = getNewsQuery().field("active").equal(true).field("uid").equal(uId);
    return query.asList();
}


精细!到目前为止...没有错误。但是对于每种模型(用户和新闻),我都会收到一个奇怪的警告。请参阅下面的StackTrace:

WARNING [org.mongodb.morphia.mapping.DefaultCreator] (http-localhost-127.0.0.1-8080-3) Class not found defined in dbObj: :
java.lang.ClassNotFoundException: com.package.models.News from [Module "deployment.Wealth.war:main" from Service Module Loader]
at org.jboss.modules.ModuleClassLoader.findClass(ModuleClassLoader.java:190)
at org.jboss.modules.ConcurrentClassLoader.performLoadClassUnchecked(ConcurrentClassLoader.java:468)
at org.jboss.modules.ConcurrentClassLoader.performLoadClassChecked(ConcurrentClassLoader.java:456)
at org.jboss.modules.ConcurrentClassLoader.performLoadClass(ConcurrentClassLoader.java:398)
at org.jboss.modules.ConcurrentClassLoader.loadClass(ConcurrentClassLoader.java:120)
at java.lang.Class.forName0(Native Method) [rt.jar:1.7.0_45]
at java.lang.Class.forName(Unknown Source) [rt.jar:1.7.0_45]
at org.mongodb.morphia.mapping.DefaultCreator.getClass(DefaultCreator.java:89) [morphia-0.109.jar:]
at org.mongodb.morphia.mapping.DefaultCreator.createInstance(DefaultCreator.java:37) [morphia-0.109.jar:]
at org.mongodb.morphia.mapping.Mapper.fromDBObject(Mapper.java:298) [morphia-0.109.jar:]
at org.mongodb.morphia.query.MorphiaIterator.convertItem(MorphiaIterator.java:79) [morphia-0.109.jar:]
at org.mongodb.morphia.query.MorphiaIterator.processItem(MorphiaIterator.java:65) [morphia-0.109.jar:]
at org.mongodb.morphia.query.MorphiaIterator.next(MorphiaIterator.java:60) [morphia-0.109.jar:]
at org.mongodb.morphia.query.QueryImpl.asList(QueryImpl.java:312) [morphia-0.109.jar:]
at ng.wealth.business.NewsBean.findByActive(NewsBean.java:99) [classes:]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) [rt.jar:1.7.0_45]
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) [rt.jar:1.7.0_45]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) [rt.jar:1.7.0_45]
at java.lang.reflect.Method.invoke(Unknown Source) [rt.jar:1.7.0_45]
...(*the rest omitted for brevity*)...


现在,我发现这可能与Morphia的类映射有关……org.mongodb.morphia.mapping.DefaultCreator不会加载实体类(UserNews)。

因此,经过大量研究……并参考了在https://code.google.com/p/morphia/issues/detail?id=208中找到的解决方案(他们说它可行),我通过将以下内容添加到我的morphia配置中来覆盖org.mongodb.morphia.mapping.DefaultCreator

morphia.getMapper().getOptions().objectFactory = new DefaultCreator() {
    @Override
    protected ClassLoader getClassLoaderForClass() {
        return RootEntity.class.getClassLoader();
    }
};


注意:在原始解决方案中,重写的方法是getClassLoaderForClass(String clazz, DBObject object),但是在我的情况下(由于我的Morphia版本-0.109-我认为这可能是从mongo官方网站获得的最新版本),方法是getClassLoaderForClass() 。因此,我通过返回我的RootEntity类加载器来覆盖它。

但是,警告仍在继续。它不一定会破坏代码,因为实际上是加载了类(UserNews),而我仍然可以正常地从它们中获取值。但是我的日志中充斥着这些警告,也许我不只是知道应用程序的某些部分仍然表现出这些奇怪的警告而感到不适。

因此,我需要的是永久解决此问题的方法……并具体说明了为什么答案实际上可以解决问题。谢谢大家!

最佳答案

我在Play 2.4应用程序中遇到了同样的问题。对我来说,这可行:

// Overwrite objectFactorys ClassLoader Method to use Plays ClassLoader
// This prevents the log from beeing spammed with Warning-Messages about ClassNotFoundExceptions happening in Morphias objectFactory
morphia.getMapper().getOptions().setObjectFactory(new DefaultCreator() {
    @Override
    protected ClassLoader getClassLoaderForClass() {
        if(Play.maybeApplication().isDefined()) {
            return Play.classloader(Play.maybeApplication().get());
        } else {
            return PersistedObject.class.getClassLoader();
        }
    }
});


我不太了解JavaEE,但是它们也有their own class loading paradigms,您需要考虑。希望能帮助到你。

10-07 19:48
查看更多