2017-01-10 1 views
0

Wenn ich versuche, meine Modellklasse mit defineClass (findClass URLClassLoader oder Self-Realisation ClassLoader) zu verbinden, tritt die Ausnahme auf.defineClass für ActiveJdbc Modellwurfausnahme

Alle anderen Methoden werden in mein Modell geladen, erlauben aber kein dynamisches Überladen der Klassen.

@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; 
    } 
    } 
} 

Log:

[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

Was versuchen Sie zu erreichen? – ipolevoy

+0

auch, erhalten Sie eine Ausnahme: "Sind Sie sicher, dass eine entsprechende Tabelle in der DB existiert", die selbsterklärend ist, Das Modell konnte nicht initialisieren, weil es Metadaten aus einer nicht existierenden Tabelle nicht ziehen konnte. Zusätzlich können Sie die Annotation '@Table (" accounts ")' entfernen, da diese redundant ist. – ipolevoy

+0

Diese Klasse hat erfolgreich funktioniert, wenn ich Class.forName oder loadClass vom Standard ClassLoader aus verwende. Andere meine Klassen arbeiteten auch mit Datenbanktabellen gut, aber Klassen funktionieren nicht! Das Problem wahrscheinlich in ActiveJdbc Instrumentierung, die Metadaten nicht ziehen kann, wenn der Kernel und die Module unterschiedliche Verzeichnisse Umgebung hat. In meinem Fall ist der Kernel JAR, Module sind Verzeichnisklassendateien. –

Antwort

1

Ich änderte getTableName in einem MetaModels.java und es funktionierte!

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(); 
} 

Original-Funktion:

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

Ich schlage vor, nicht die Klasse als Schlüssel zu verwenden oder die Auswahllogik ändern.

+0

Sergey, das macht Sinn. Ich habe ein neues Problem hinzugefügt: https://github.com/javalite/activejdbc/issues/570. Es wird bald behoben, so dass Sie den Snapshot – ipolevoy

0

Dies war ein kleiner Fehler im Framework in Bezug auf Modelle, die von einem anderen Klassenlader geladen wurden. Das Update wurde vom Anforderer bereitgestellt, das Problem wurde erstellt: https://github.com/javalite/activejdbc/issues/570 und bereits gelöst.

Sie können die neueste Schnappschuss mit dem Update aus dem Pull-: http://repo.javalite.io/org/javalite/activejdbc/2.0-SNAPSHOT/

Dank für den Beitrag!

+0

Commit ziehen können: https://github.com/javalite/activejdbc/commit/4dd6ca09a6879544f6dcba59e3cf68e6f5f97b30 – ipolevoy

Verwandte Themen