Java 在play framework应用程序内的spring data solr中进行查询时发生NoClassDefFoundError

Java 在play framework应用程序内的spring data solr中进行查询时发生NoClassDefFoundError,java,spring,solr,playframework,spring-data-solr,Java,Spring,Solr,Playframework,Spring Data Solr,在PlayFrameworkV2.3.8应用程序中进行SpringDataSolr查询时,我一直遇到一个问题。查询似乎成功了,但是spring使用的类加载器找不到我的数据模型类的类文件,并抛出一个NoClassDefFoundError。下面是一些相关代码 首先是包“model”中的数据模型: package model; import org.apache.solr.client.solrj.beans.Field; import org.springframework.data.annot

在PlayFrameworkV2.3.8应用程序中进行SpringDataSolr查询时,我一直遇到一个问题。查询似乎成功了,但是spring使用的类加载器找不到我的数据模型类的类文件,并抛出一个
NoClassDefFoundError
。下面是一些相关代码

首先是包“model”中的数据模型:

package model;

import org.apache.solr.client.solrj.beans.Field;
import org.springframework.data.annotation.Id;

public class Theatre
{
    @Id
    String id;

    @Field
    String docType;

    // other fields, getters, and setters omitted for brevity
}
以下是存储库:

package model;

import java.util.List;

import org.springframework.data.solr.repository.SolrCrudRepository;

public interface TheatreRepository extends SolrCrudRepository<Theatre, String>
{
    List<Theatre> findByDocType(String doc__type);

    void delete(Theatre deleted);

    List<Theatre> findAll();

    Theatre findOne(String id);

    @SuppressWarnings("unchecked")
    Theatre save(Theatre persisted);
}
以下是基于JavaConfig的spring配置:

package plugins.solr;

import org.apache.solr.client.solrj.SolrServer;
import org.apache.solr.client.solrj.impl.HttpSolrServer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.data.solr.core.SolrOperations;
import org.springframework.data.solr.core.SolrTemplate;
import org.springframework.data.solr.repository.config.EnableSolrRepositories;
import org.springframework.data.solr.server.support.HttpSolrServerFactory;

import play.Play;

@ComponentScan
@Configuration
@EnableSolrRepositories(basePackages = { "model" })
public class SolrConfig
{
    public SolrConfig()
    {

    }

    @Bean
    public SolrServer solrServer()
    {
        HttpSolrServerFactory factory = new HttpSolrServerFactory( new HttpSolrServer( Play.application().configuration().getString( "ems.solr.url" ) ) );
        return factory.getSolrServer();
    }

    @Bean
    public SolrOperations solrTemplate()
    {
        return new SolrTemplate( this.solrServer() );
    }

}
因此,在运行时,重新加载浏览器窗口时调用
Application.index()
,从而调用
theaterepository.findByDocType(“theater”)被执行。这是来自该调用的堆栈跟踪:

java.lang.NoClassDefFoundError: model/Theatre
at model.Theatre_Instantiator_982rn.newInstance(Unknown Source) ~[na:na]
at org.springframework.data.convert.BytecodeGeneratingEntityInstantiator$EntityInstantiatorAdapter.createInstance(BytecodeGeneratingEntityInstantiator.java:193) ~[spring-data-commons-1.10.0.RELEASE.jar:na]
at org.springframework.data.convert.BytecodeGeneratingEntityInstantiator.createInstance(BytecodeGeneratingEntityInstantiator.java:76) ~[spring-data-commons-1.10.0.RELEASE.jar:na]
at org.springframework.data.solr.core.convert.MappingSolrConverter.read(MappingSolrConverter.java:127) ~[spring-data-solr-1.4.0.RELEASE.jar:na]
at org.springframework.data.solr.core.convert.MappingSolrConverter.read(MappingSolrConverter.java:119) ~[spring-data-solr-1.4.0.RELEASE.jar:na]
Caused by: java.lang.ClassNotFoundException: model.Theatre
at java.lang.ClassLoader.findClass(ClassLoader.java:531) ~[na:1.7.0_80]
at java.lang.ClassLoader.loadClass(ClassLoader.java:425) ~[na:1.7.0_80]
at java.lang.ClassLoader.loadClass(ClassLoader.java:358) ~[na:1.7.0_80]
at model.Theatre_Instantiator_982rn.newInstance(Unknown Source) ~[na:na]
at org.springframework.data.convert.BytecodeGeneratingEntityInstantiator$EntityInstantiatorAdapter.createInstance(BytecodeGeneratingEntityInstantiator.java:193) ~[spring-data-commons-1.10.0.RELEASE.jar:na]
我注意到,
model.Theatre
类文件在play frameworks类装入器中,但不在系统类装入器中。然而,这似乎不应该是一个问题,因为spring能够在需要实例化类的实例时找到
TheaterEspority
类文件。我想一定有一些简单的事情我做错了,但在尝试了一些事情和做了一些研究之后,我仍然不知所措。 我确实找到了下面的帖子,但似乎并不相关,因为它引用了SpringDataMongoDB版本之间的差异

此外,我还尝试在spring应用程序上下文中使用play Framework类加载器,方法是在
SolrPlugin.onStart()中执行以下操作


这导致相同的
NoClassDefFoundError
和堆栈跟踪。在设置类加载器之后,我还尝试在同一个函数中进行查询,但再次收到相同的错误

一种解决方法是在
MappingMongoConverter
中强制使用
ReflectionTityInstantiator
,它将恢复到1.7.0之前的版本。基于反射的发布实例化策略。例如:

mappingConverter.setInstantiators(
    new EntityInstantiators(ReflectionEntityInstantiator.INSTANCE));

我从未能够使用SpringDataSolr1.4.0解决这个问题。然而,我更新到SpringDataSolr1.4.1,并克服了这个错误!所以我猜这是1.4.0中的一个bug。然而,我在1.4.1中也发现了一个bug。如果solr文档中有任何
多值
字段,那么当spring data solr试图通过
type.getComponentType()
获取组件的类型属性时,它将在
MappingSolrConverter.SolrPropertyValueProvider.readValue()
中失败,并出现空指针异常。我通过删除文档中所有的
多值
字段来解决这个问题(不理想)在
MappingMongoConverter
中设置实例化策略将如何帮助我处理
MappingSolrConverter
中的
mulitValued
字段?这是根据堆栈跟踪解决由
bytecodegeneratingtityinstantiator
引起的
noClassDefoundError
的方法。请注意
剧院实例化器982rn
,它是运行时生成的类。我的解决方案从
bytecodegeneratingtityinstantiator
变为
reflectiontityinstantiator
,速度较慢,但也不太依赖于类加载器的设置。此处的详细信息:。好的。。。但是,正如我在上面的评论中提到的,这个错误在1.4.1中已经修复,因此没有必要绕过
字节码生成TityInstantiator
。但是,我可以尝试您的解决方案,看看1.4.0中是否存在
多值
solr字段错误(我猜是这样的)
java.lang.NoClassDefFoundError: model/Theatre
at model.Theatre_Instantiator_982rn.newInstance(Unknown Source) ~[na:na]
at org.springframework.data.convert.BytecodeGeneratingEntityInstantiator$EntityInstantiatorAdapter.createInstance(BytecodeGeneratingEntityInstantiator.java:193) ~[spring-data-commons-1.10.0.RELEASE.jar:na]
at org.springframework.data.convert.BytecodeGeneratingEntityInstantiator.createInstance(BytecodeGeneratingEntityInstantiator.java:76) ~[spring-data-commons-1.10.0.RELEASE.jar:na]
at org.springframework.data.solr.core.convert.MappingSolrConverter.read(MappingSolrConverter.java:127) ~[spring-data-solr-1.4.0.RELEASE.jar:na]
at org.springframework.data.solr.core.convert.MappingSolrConverter.read(MappingSolrConverter.java:119) ~[spring-data-solr-1.4.0.RELEASE.jar:na]
Caused by: java.lang.ClassNotFoundException: model.Theatre
at java.lang.ClassLoader.findClass(ClassLoader.java:531) ~[na:1.7.0_80]
at java.lang.ClassLoader.loadClass(ClassLoader.java:425) ~[na:1.7.0_80]
at java.lang.ClassLoader.loadClass(ClassLoader.java:358) ~[na:1.7.0_80]
at model.Theatre_Instantiator_982rn.newInstance(Unknown Source) ~[na:na]
at org.springframework.data.convert.BytecodeGeneratingEntityInstantiator$EntityInstantiatorAdapter.createInstance(BytecodeGeneratingEntityInstantiator.java:193) ~[spring-data-commons-1.10.0.RELEASE.jar:na]
ctx = new AnnotationConfigApplicationContext(SolrConfig.class);
((AnnotationConfigApplicationContext)ctx).setClassLoader( Play.application().classloader() );
mappingConverter.setInstantiators(
    new EntityInstantiators(ReflectionEntityInstantiator.INSTANCE));