2017-01-10 2 views
0

Когда я пытаюсь подключить мой класс модели с помощью defineClass (findClass URLClassLoader или самореализации ClassLoader), возникает исключение.defineClass for ActiveJdbc Исключение для исключения модели

Любые другие методы загружают мою модель, но не позволяют динамически перегружать классы.

@Table("accounts") 
@BelongsToParents({ 
    @BelongsTo(parent = Customer.class, foreignKeyName = "Customer"), 
    @BelongsTo(parent = Currency.class, foreignKeyName = "Currency") 
}) 
public class Account extends Document{ 
    public static DocFields prepareDocument(...){ 

    ... fields = new ...(getTableName()); 
    ... 
    } 
... 
} 

public abstract class Document extends Model{ 
    public static DocFields prepareDocument(Session session){ 
    return null; 
    } 
    ... 
} 

public class DynCLoader extends ClassLoader { 

    public DynCLoader(ClassLoader parentClass) { 
    super(parentClass); 
    } 
    @Override 
    public Class<?> loadClass(String className) throws ClassNotFoundException { 
    if(StrFuncs.isEmpty(className)){ 
     throw new ClassNotFoundException("Ошибка в модуле DynCLoader, в функцие loadClass. Детали: className is empty"); 
    } 
    try { 
     ... 
     if(...){ // Загрузка нового, неопределенного класса 
     Class<?> clazz; 
     try{ 
      String url = "file:"+...+".class"; 
      URL myUrl = new URL(url); 
      URLConnection connection = myUrl.openConnection(); 
      InputStream input = connection.getInputStream(); 
      ByteArrayOutputStream buffer = new ByteArrayOutputStream(); 
      int data = input.read(); 
      while(data != -1){ 
       buffer.write(data); 
       data = input.read(); 
      } 
      input.close(); 
      byte[] classData = buffer.toByteArray(); 
      clazz = defineClass(className, classData, 0, classData.length); 
      ... 
      return clazz; 
     } 
     catch (FileNotFoundException ex) { 
      clazz = Class.forName(className); 
      ... 
      return clazz; 
     } 
     catch (MalformedURLException ex) { 
      ... 
      return null; 
     } 
     catch (Throwable ex) { 
      try{ 
      clazz = Class.forName(className, true, this); 
      return clazz; 
      } 
      catch(ClassNotFoundException oErr){ 
      ... 
      } 
      ... 
      return null; 
     } 
     } 
     else if(...) // Загрузка системного класса 
     return Class.forName(className); 
     else{ 
     return Class.forName(className, true, this); 
     } 
    } 
    catch (ClassNotFoundException ex) { 
     throw ex; 
    } 
    } 
} 

Вход:

[main] INFO org.javalite.activejdbc.DB - Opened connection: [email protected] 
[main] INFO org.javalite.activejdbc.ConnectionsAccess - Attached connection named: default: to current thread: [email protected] Extra info: jdbc:mysql://127.0.0.1:3306/*** 
[main] INFO org.javalite.activejdbc.Configuration - Load models from: file:/***/Product/***/Server/target/classes/activejdbc_models.properties 
[main] INFO org.javalite.activejdbc.Configuration - Load models from: file:/***/Kernel/Server/target/classes/activejdbc_models.properties 
[main] INFO org.javalite.activejdbc.Registry - Registered model: class kz.mwb.qupris.server.data.model.Account 
*** 
[main] INFO org.javalite.activejdbc.Registry - Registered model: class kz.mwb.qupris.server.data.model.User 
*** 
[main] INFO org.javalite.activejdbc.Registry - Fetched metadata for table: accounts 
*** 
[main] INFO org.javalite.activejdbc.Registry - Fetched metadata for table: usertable 
*** 
[main] INFO org.javalite.activejdbc.MetaModel - Association found: Customer ----------< Account, type: has-many 
[main] INFO org.javalite.activejdbc.MetaModel - Association found: Account >---------- Customer, type: belongs-to 
*** 
[main] INFO org.javalite.activejdbc.cache.QueryCache - MISS, "SELECT * FROM *** WHERE *** 
*** 
[Thread-20] INFO org.javalite.activejdbc.DB - Opened connection: [email protected] 
[Thread-20] INFO org.javalite.activejdbc.ConnectionsAccess - Attached connection named: default: to current thread: [email protected] Extra info: jdbc:mysql://127.0.0.1:3306/*** 
[Thread-20] INFO org.javalite.activejdbc.LazyList - Query: "SELECT * FROM *** WHERE ***, took: 5 milliseconds 
*** 
00:42:52 > 34 > UserLib > ERROR > java.lang.reflect.InvocationTargetException 
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
    at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) 
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) 
    at java.lang.reflect.Method.invoke(Unknown Source) 
    at kz.mwb.qupris.server.tool.loader.Include.processMethod(Include.java:111) 
    at kz.mwb.qupris.server.userlib.doDoc.initMod(doDoc.java:59) 
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
    at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) 
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) 
    at java.lang.reflect.Method.invoke(Unknown Source) 
    at kz.mwb.qupris.server.tool.loader.Include.processMethod(Include.java:111) 
    at kz.mwb.qupris.server.tool.loader.Include.EvalFunction(Include.java:31) 
    at kz.mwb.qupris.server.engine.ModEngine.MProcess(ModEngine.java:133) 
    at kz.mwb.qupris.server.engine.ModEngine.IProcess(ModEngine.java:85) 
    at kz.mwb.qupris.server.engine.ModEngine.XProcess(ModEngine.java:203) 
    at kz.mwb.qupris.server.engine.Task.ProcessRequest(Task.java:396) 
    at kz.mwb.qupris.server.engine.Task.GateWayLine(Task.java:162) 
    at kz.mwb.qupris.server.engine.Task.ConnectToGateWay(Task.java:326) 
    at kz.mwb.qupris.server.engine.Task.run(Task.java:61) 
    at java.lang.Thread.run(Unknown Source) 
Caused by: org.javalite.activejdbc.DBException: failed to find metamodel for class kz.mwb.qupris.server.data.model.Account. Are you sure that a corresponding table exists in DB? 
    at org.javalite.activejdbc.Registry.getTableName(Registry.java:414) 
    at org.javalite.activejdbc.ModelDelegate.tableNameOf(ModelDelegate.java:326) 
    at kz.mwb.qupris.server.data.model.Account.getTableName(Account.java:2831) 
    at kz.mwb.qupris.server.data.model.Account.prepareDocument(Account.java:23) 
    ... 20 more 
+0

Что вы пытаетесь достичь? – ipolevoy

+0

также вы получаете исключение: «Вы уверены, что соответствующая таблица существует в БД», что самоочевидно, модель не могла быть инициализирована, потому что она не могла вытащить метаданные из таблицы non-existng. Кроме того, вы можете удалить аннотацию '@Table (« accounts »)', потому что она избыточна. – ipolevoy

+0

Этот класс успешно работал, если я использую Class.forName или loadClass из стандартного ClassLoader. Другие мои классы также отлично работали с таблицами базы данных, но не работают! Проблема, вероятно, в инструментах ActiveJdbc, которые не могут извлекать метаданные, если в ядре и модулях есть среда с разными каталогами. В моем случае ядро ​​JAR, модули - файлы классов каталога. –

ответ

1

Я изменил getTableName в MetaModels.java и это сработало!

String getTableName(Class<? extends Model> modelClass) { 
    MetaModel mm = null; 
    for (Map.Entry<Class<? extends Model>, MetaModel> entry : metaModelsByClass.entrySet()){ 
     if(modelClass.getName().equals(entry.getKey().getName())) 
     mm = entry.getValue(); 
    } 
    return mm == null ? null : mm.getTableName(); 
} 

Оригинальная функция:

String getTableName(Class<? extends Model> modelClass) { 
    MetaModel mm = metaModelsByClass.get(modelClass); 
    return mm == null ? null : mm.getTableName(); 
} 

Я предлагаю не использовать класс в качестве ключа или изменить логику выбора.

+0

Сергей, это имеет смысл. Я добавил новую проблему: https://github.com/javalite/activejdbc/issues/570. Он скоро будет исправлен, поэтому вы можете снять снимок – ipolevoy

0

Это была небольшая ошибка в структуре, связанной с моделями, загружаемыми другим загрузчиком классов. Исправление было предоставлено реквестером, вопрос был создан: https://github.com/javalite/activejdbc/issues/570 и уже решена.

Вы можете вытащить последний снимок с исправлением от: http://repo.javalite.io/org/javalite/activejdbc/2.0-SNAPSHOT/

благодарит за вклад!

+0

commit: https://github.com/javalite/activejdbc/commit/4dd6ca09a6879544f6dcba59e3cf68e6f5f97b30 – ipolevoy

Смежные вопросы