发布
社区首页 >问答首页 >defineClass用于ActiveJdbc模型抛出异常

defineClass用于ActiveJdbc模型抛出异常
EN

Stack Overflow用户
提问于 2017-01-10 11:53:36
回答 2查看 423关注 0票数 0

当我试图使用defineClass (findClass URLClassLoader或自实现ClassLoader)连接我的模型类时,会出现异常。

正在加载任何其他方法,但不允许动态重载类。

代码语言:javascript
代码运行次数:0
复制
@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;
    }
  }
}

日志:

代码语言:javascript
代码运行次数:0
复制
[main] INFO org.javalite.activejdbc.DB - Opened connection: com.mysql.jdbc.JDBC4Connection@49fd9b
[main] INFO org.javalite.activejdbc.ConnectionsAccess - Attached connection named: default: to current thread: com.mysql.jdbc.JDBC4Connection@49fd9b. 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: com.mysql.jdbc.JDBC4Connection@1db686
[Thread-20] INFO org.javalite.activejdbc.ConnectionsAccess - Attached connection named: default: to current thread: com.mysql.jdbc.JDBC4Connection@1db686. 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
EN

回答 2

Stack Overflow用户

发布于 2017-01-11 16:05:42

我把getTableName换成了MetaModels.java,它成功了!

代码语言:javascript
代码运行次数:0
复制
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();
}

原功能:

代码语言:javascript
代码运行次数:0
复制
String getTableName(Class<? extends Model> modelClass) {
    MetaModel mm = metaModelsByClass.get(modelClass);
    return mm == null ? null : mm.getTableName();
}

我建议不要将类用作键或更改选择逻辑。

票数 1
EN

Stack Overflow用户

发布于 2017-01-11 21:14:42

这是框架中与不同类加载器加载的模型相关的一个小错误。修复是由请求者提供的,创建了问题:https://github.com/javalite/activejdbc/issues/570,并且已经解决了。

您可以使用修补程序从:http://repo.javalite.io/org/javalite/activejdbc/2.0-SNAPSHOT/获取最新的快照。

谢谢你的贡献!

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/41568228

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档