2012-10-18 10 views
1

當我在同一個項目中運行我的playOrm junit測試時,我擁有nosql.Persistence類(以及我的映射實體),它運行良好。 但是,我需要將我的實體打包在一個jar文件中,使用我的DAO和我的find方法。 當我從其他項目使用這個道,我得到了異常的下面。當我的映射類位於單獨的jar文件中時,playorm會啓動異常

毫無頭緒。有關從哪裏開始尋找的想法?

java.lang.RuntimeException: Failure scanning class(see chained exception)=class com.alvazan.orm.api.z8spi.meta.DboTableMeta 
    at com.alvazan.orm.layer0.base.MyClassAnnotationDiscoveryListener.scanClass(MyClassAnnotationDiscoveryListener.java:44) 
    at com.alvazan.orm.layer0.base.MyClassAnnotationDiscoveryListener.discovered(MyClassAnnotationDiscoveryListener.java:34) 
    at com.impetus.annovention.Discoverer.discoverAndIntimateForClassAnnotations(Discoverer.java:197) 
    at com.impetus.annovention.Discoverer.discover(Discoverer.java:155) 
    at com.alvazan.orm.layer0.base.BaseEntityManagerFactoryImpl.rescan(BaseEntityManagerFactoryImpl.java:80) 
    at com.alvazan.orm.layer0.base.BaseEntityManagerFactoryImpl.setup(BaseEntityManagerFactoryImpl.java:131) 
    at com.alvazan.orm.impl.bindings.BootstrapImpl.createInstance(BootstrapImpl.java:51) 
    at com.alvazan.orm.api.base.Bootstrap.create(Bootstrap.java:53) 
    at com.alvazan.orm.api.base.Bootstrap.create(Bootstrap.java:48) 
    at com.alvazan.orm.api.base.Bootstrap.create(Bootstrap.java:45) 
    at com.alvazan.orm.api.base.Bootstrap.create(Bootstrap.java:41) 
    at com.s1mbi0se.dmp.da.dao.PlayOrmConfiguration.init(PlayOrmConfiguration.java:40) 
    at com.s1mbi0se.dmp.da.dao.PlayOrmConfiguration.getEntityManager(PlayOrmConfiguration.java:46) 
    at com.s1mbi0se.dmp.da.dao.AbstractDao.getEm(AbstractDao.java:10) 
    at com.s1mbi0se.dmp.da.dao.UserDao.insertOrUpdateUser(UserDao.java:15) 
    at com.s1mbi0se.dmp.module.UserModule.persistData(UserModule.java:101) 
    at com.s1mbi0se.dmp.processor.mapred.SelectorReducer.reduce(SelectorReducer.java:55) 
    at com.s1mbi0se.dmp.processor.mapred.SelectorReducer.reduce(SelectorReducer.java:1) 
    at org.apache.hadoop.mapreduce.Reducer.run(Reducer.java:176) 
    at org.apache.hadoop.mapred.Task$NewCombinerRunner.combine(Task.java:1502) 
    at org.apache.hadoop.mapred.MapTask$MapOutputBuffer.sortAndSpill(MapTask.java:1436) 
    at org.apache.hadoop.mapred.MapTask$MapOutputBuffer.flush(MapTask.java:1298) 
    at org.apache.hadoop.mapred.MapTask$NewOutputCollector.close(MapTask.java:699) 
    at org.apache.hadoop.mapred.MapTask.runNewMapper(MapTask.java:766) 
    at org.apache.hadoop.mapred.MapTask.run(MapTask.java:370) 
    at org.apache.hadoop.mapred.LocalJobRunner$Job.run(LocalJobRunner.java:212) 
Caused by: com.google.inject.ProvisionException: Guice provision errors: 

1) Error injecting constructor, java.lang.ExceptionInInitializerError 
    at com.alvazan.orm.impl.meta.data.MetaClassSingle.<init>(MetaClassSingle.java:22) 
    while locating com.alvazan.orm.impl.meta.data.MetaClassSingle 

1 error 
    at com.google.inject.internal.InjectorImpl$4.get(InjectorImpl.java:987) 
    at com.alvazan.orm.impl.meta.data.MetaInfo.findOrCreate(MetaInfo.java:60) 
    at com.alvazan.orm.impl.meta.scan.ScannerForClass.addClass(ScannerForClass.java:57) 
    at com.alvazan.orm.layer0.base.MyClassAnnotationDiscoveryListener.scanClass(MyClassAnnotationDiscoveryListener.java:42) 
    ... 25 more 
Caused by: java.lang.ExceptionInInitializerError 
    at com.alvazan.orm.impl.meta.data.MetaAbstractClass.<init>(MetaAbstractClass.java:17) 
    at com.alvazan.orm.impl.meta.data.MetaClassSingle.<init>(MetaClassSingle.java:22) 
    at com.alvazan.orm.impl.meta.data.MetaClassSingle$$FastClassByGuice$$29abb300.newInstance(<generated>) 
    at com.google.inject.internal.cglib.reflect.$FastConstructor.newInstance(FastConstructor.java:40) 
    at com.google.inject.internal.DefaultConstructionProxyFactory$1.newInstance(DefaultConstructionProxyFactory.java:60) 
    at com.google.inject.internal.ConstructorInjector.construct(ConstructorInjector.java:85) 
    at com.google.inject.internal.ConstructorBindingImpl$Factory.get(ConstructorBindingImpl.java:254) 
    at com.google.inject.internal.InjectorImpl$4$1.call(InjectorImpl.java:978) 
    at com.google.inject.internal.InjectorImpl.callInContext(InjectorImpl.java:1024) 
    at com.google.inject.internal.InjectorImpl$4.get(InjectorImpl.java:974) 
    ... 28 more 
Caused by: java.lang.ClassCastException: com.alvazan.orm.api.z8spi.meta.TypedRow_$$_javassist_0 cannot be cast to javassist.util.proxy.Proxy 
    at com.alvazan.orm.api.z8spi.meta.DboTableMeta.testInstanceCreation(DboTableMeta.java:93) 
    at com.alvazan.orm.api.z8spi.meta.DboTableMeta.<clinit>(DboTableMeta.java:84) 
    ... 38 more 

回答

2

您已經遇到某種類加載問題。在創建NoSqlEntityManagerFactory時,您可能需要傳入類加載器。您在這裏處理這個代碼

static { 
    ProxyFactory f = new ProxyFactory(); 
    f.setSuperclass(TypedRow.class); 
    f.setInterfaces(new Class[] {NoSqlTypedRowProxy.class}); 
    f.setFilter(new MethodFilter() { 
     public boolean isHandled(Method m) { 
      // ignore finalize() 
      if(m.getName().equals("finalize")) 
       return false; 
      else if(m.getName().equals("equals")) 
       return false; 
      else if(m.getName().equals("hashCode")) 
       return false; 
      return true; 
     } 
    }); 
    Class clazz = f.createClass(); 
    testInstanceCreation(clazz); 

    typedRowProxyClass = clazz; 

    NAME_PATTERN = Pattern.compile("[a-zA-Z_][a-zA-Z_0-9]*"); 
} 

private static Proxy testInstanceCreation(Class<?> clazz) { 
    try { 
     Proxy inst = (Proxy) clazz.newInstance(); 
     return inst; 
    } catch (InstantiationException e) { 
     throw new RuntimeException("Could not create proxy for type="+clazz, e); 
    } catch (IllegalAccessException e) { 
     throw new RuntimeException("Could not create proxy for type="+clazz, e); 
    } 
} 

注意到它是一個靜態初始化塊,以便將運行一次,該代碼始終工作在正常情況下。例如,如果您有一個在一個ClassLoader中創建的Car類,並且在另一個類加載器中創建了相同的Car類,則實際上可以像這樣(Car)汽車投出並獲取classCastException,因爲在一個汽車中是一個汽車classloader不是另一個類加載器的Car。

好的,第1步是在創建NoSqlEntityManagerFactory時嘗試傳入自己的類加載器,以便知道正在使用哪個類加載器。看看我上面的代碼,我不確定哪個類加載器正在創建代理,所以我需要檢查它以確保它是相同的類加載器。

一個大問題是,hadoop是否已經使用在另一個類加載器中加載的javassist,或者是否發送了一個javassist作爲mapreduce作業的一部分?

編輯:好的,另外,你需要爲javassist設置線程Context Loader以及....我將在PlayOrm中解決這個問題,所以在下一個版本中你將不必......現在做這個

  1. 呼叫Thread.currentThread.setContextClassLoader(yourClassloader)
  2. 呼叫Bootstrap.create傳遞給它相同的類加載器以及
  3. 驗證了Javassist是從相同的類加載器加載

ħ ERE是我找到的信息來源上的classloader了Javassist使用,供大家參考代碼

protected ClassLoader getClassLoader0() { 
591   ClassLoader loader = null; 
592   if (superClass != null && !superClass.getName().equals("java.lang.Object")) 
593    loader = superClass.getClassLoader(); 
594   else if (interfaces != null && interfaces.length > 0) 
595    loader = interfaces[0].getClassLoader(); 
596 
597   if (loader == null) { 
598    loader = getClass().getClassLoader(); 
599    // In case javassist is in the endorsed dir 
600    if (loader == null) { 
601     loader = Thread.currentThread().getContextClassLoader(); 
602     if (loader == null) 
603      loader = ClassLoader.getSystemClassLoader(); 
604    } 
605   } 
606 
607   return loader; 
608  } 

院長

+0

正在由一個罐子衝突產生的類加載器的問題。 javassist版本3.16.1工作正常。 – mvallebr

+0

非常感謝您的回答 – mvallebr

相關問題