java - NoClassDefFoundError when making a query in spring-data-solr within a play framework application -
i keep running issue when making spring-data-solr query within play framework v2.3.8 application. query seems succeed class loader spring using can't find class files data model classes , throws noclassdeffounderror. here relevant code.
first data model in package '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, , setters omitted brevity } here repository:
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); } the application class in play framework:
package controllers; import java.util.arraylist; import java.util.list; import model.theatre; import model.theatrerepository; import play.*; import plugins.solr.solrplugin; import views.html.*; public class application extends controller { public static result index() { theatrerepository repository = play.application().plugin( solrplugin.class ).gettheatrerepository(); if( repository != null ) { list<theatre> alltheatres = null; try { alltheatres = repository.findbydoctype("theatre"); logger.info( "list of theatres found: " + alltheatres.tostring() ); for(theatre theatre: alltheatres) { logger.info( "this theatre is: " + theatre.tostring() ); } } catch( noclassdeffounderror | classnotfoundexception e ) { logger.error( "classpath: " + system.getproperty( "java.class.path" ) ); } } else { logger.error( "theatrerepository null!" ); } return ok(index.render("your new application ready.")); } } and applicationcontext spring:
package plugins.solr; import play.plugin; import model.theatrerepository; import org.springframework.context.applicationcontext; import org.springframework.context.annotation.annotationconfigapplicationcontext; import play.logger; import play.play; import play.api.application; public class solrplugin extends plugin { private theatrerepository theatrerepository; applicationcontext ctx; public solrplugin(application app) { } public theatrerepository gettheatrerepository() { return theatrerepository; } @override public void onstart() { super.onstart(); logger.info( "solr plugin started" ); ctx = new annotationconfigapplicationcontext(solrconfig.class); theatrerepository = ctx.getbean( theatrerepository.class ); } } here javaconfig based spring configuration:
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() ); } } so @ run time application.index() gets called when reloading browser window , result call theatrerepository.findbydoctype("theatre"); gets executed. stack trace call:
java.lang.noclassdeffounderror: model/theatre @ model.theatre_instantiator_982rn.newinstance(unknown source) ~[na:na] @ org.springframework.data.convert.bytecodegeneratingentityinstantiator$entityinstantiatoradapter.createinstance(bytecodegeneratingentityinstantiator.java:193) ~[spring-data-commons-1.10.0.release.jar:na] @ org.springframework.data.convert.bytecodegeneratingentityinstantiator.createinstance(bytecodegeneratingentityinstantiator.java:76) ~[spring-data-commons-1.10.0.release.jar:na] @ org.springframework.data.solr.core.convert.mappingsolrconverter.read(mappingsolrconverter.java:127) ~[spring-data-solr-1.4.0.release.jar:na] @ 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 @ java.lang.classloader.findclass(classloader.java:531) ~[na:1.7.0_80] @ java.lang.classloader.loadclass(classloader.java:425) ~[na:1.7.0_80] @ java.lang.classloader.loadclass(classloader.java:358) ~[na:1.7.0_80] @ model.theatre_instantiator_982rn.newinstance(unknown source) ~[na:na] @ org.springframework.data.convert.bytecodegeneratingentityinstantiator$entityinstantiatoradapter.createinstance(bytecodegeneratingentityinstantiator.java:193) ~[spring-data-commons-1.10.0.release.jar:na] what have noticed model.theatre class files in play frameworks class loader not in system class loader. however, doesn't seem should problem because spring able find theatrerespoitory class file when needed instantiate instance of class. figure there must simple i'm doing wrong after trying few things , doing research i'm still @ loss. did find following post doesn't seem relevant since referencing difference between versions of spring-data-mongodb.
also, tried using play frameworks class loader in spring application context doing following in solrplugin.onstart()
ctx = new annotationconfigapplicationcontext(solrconfig.class); ((annotationconfigapplicationcontext)ctx).setclassloader( play.application().classloader() ); this resulted in same noclassdeffounderror , stack trace. tried making query in same function, right after setting class loader, , received same error again.
a workaround force reflectionentityinstantiator in mappingmongoconverter reverts pre 1.7.0.release instantiation strategy based on reflection. example:
mappingconverter.setinstantiators( new entityinstantiators(reflectionentityinstantiator.instance));
Comments
Post a Comment