Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/345.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java CacheException-反序列化对象时出错-MyBatis和Play_Java_Playframework_Ibatis_Mybatis - Fatal编程技术网

Java CacheException-反序列化对象时出错-MyBatis和Play

Java CacheException-反序列化对象时出错-MyBatis和Play,java,playframework,ibatis,mybatis,Java,Playframework,Ibatis,Mybatis,我将MyBatis与playframework结合使用,除了: 当我试图在xml映射器文件中使用默认的内置MyBatis标记的缓存时,在检索缓存的select语句时,我得到了这个stacktrace 如果我在单元测试或其他应用程序中运行相同的语句,而不使用playframework,则一切正常 因此,我猜这与playframework加载/编译类的方式有关,这是类加载器的问题 我的项目的目录布局如下所示: app controllers data // xml mapping files

我将MyBatis与playframework结合使用,除了:

当我试图在xml映射器文件中使用默认的内置MyBatis标记的缓存时,在检索缓存的select语句时,我得到了这个stacktrace

如果我在单元测试或其他应用程序中运行相同的语句,而不使用playframework,则一切正常

因此,我猜这与playframework加载/编译类的方式有关,这是类加载器的问题

我的项目的目录布局如下所示:

app
  controllers
  data // xml mapping files and java interfaces for ibatis
       // & a class that returns a SqlSessionFactory
    domain // Pojos for SQL results (e.g. User.java)
  models
  views
lib // here is myibatis jar file
(...) // the rest of the standard play framework project
引发异常的模型方法如下:

  public static UserAuthentication findAuthenticatonIdentity(UserId userId){
    SqlSessionFactory sessionFactory = IbatisSessionFactory.getSqlMapper();
    SqlSession session = sessionFactory.openSession();
    AuthMapper authMapper = session.getMapper(AuthMapper.class);

    UserAuthentication ua = authMapper.selectByUserId(userId); // line 162
    session.close();
    return ua;
  }
用户身份验证实现了可序列化

这是stacktrace:

Execution exception (In /app/models/UserModel.java around line 162)
PersistenceException occured : 
 ### Error querying database.  Cause: org.apache.ibatis.cache.CacheException: Error deserializing object.  Cause: java.lang.ClassNotFoundException: data.domain.UserAuthentication
 ### Cause: org.apache.ibatis.cache.CacheException: Error deserializing object.  Cause: java.lang.ClassNotFoundException: data.domain.UserAuthentication

play.exceptions.JavaExecutionException: 
### Error querying database.  Cause: org.apache.ibatis.cache.CacheException: Error deserializing object.  Cause: java.lang.ClassNotFoundException: data.domain.UserAuthentication
### Cause: org.apache.ibatis.cache.CacheException: Error deserializing object.  Cause: java.lang.ClassNotFoundException: data.domain.UserAuthentication
    at play.mvc.ActionInvoker.invoke(ActionInvoker.java:231)
    at Invocation.HTTP Request(Play!)
Caused by: org.apache.ibatis.exceptions.PersistenceException: 
### Error querying database.  Cause: org.apache.ibatis.cache.CacheException: Error deserializing object.  Cause: java.lang.ClassNotFoundException: data.domain.UserAuthentication
### Cause: org.apache.ibatis.cache.CacheException: Error deserializing object.  Cause: java.lang.ClassNotFoundException: data.domain.UserAuthentication
    at org.apache.ibatis.exceptions.ExceptionFactory.wrapException(ExceptionFactory.java:23)
    at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:102)
    at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:94)
    at org.apache.ibatis.session.defaults.DefaultSqlSession.selectOne(DefaultSqlSession.java:58)
    at org.apache.ibatis.binding.MapperMethod.execute(MapperMethod.java:90)
    at org.apache.ibatis.binding.MapperProxy.invoke(MapperProxy.java:40)
    at $Proxy8.selectByUserId(Unknown Source)
    at models.UserModel.findAuthenticatonIdentity(UserModel.java:162)
    at controllers.securesocial.MySecureSocial.checkAccess(MySecureSocial.java:97)
    at play.mvc.ActionInvoker.invoke(ActionInvoker.java:504)
    at play.mvc.ActionInvoker.invokeControllerMethod(ActionInvoker.java:478)
    at play.mvc.ActionInvoker.invokeControllerMethod(ActionInvoker.java:473)
    at play.mvc.ActionInvoker.handleBefores(ActionInvoker.java:322)
    at play.mvc.ActionInvoker.invoke(ActionInvoker.java:142)
    ... 1 more
Caused by: org.apache.ibatis.cache.CacheException: Error deserializing object.  Cause: java.lang.ClassNotFoundException: data.domain.UserAuthentication
    at org.apache.ibatis.cache.decorators.SerializedCache.deserialize(SerializedCache.java:94)
    at org.apache.ibatis.cache.decorators.SerializedCache.getObject(SerializedCache.java:50)
    at org.apache.ibatis.cache.decorators.LoggingCache.getObject(LoggingCache.java:50)
    at org.apache.ibatis.cache.decorators.SynchronizedCache.getObject(SynchronizedCache.java:55)
    at org.apache.ibatis.executor.CachingExecutor.query(CachingExecutor.java:72)
    at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:100)
    ... 13 more
Caused by: java.lang.ClassNotFoundException: data.domain.UserAuthentication
    at java.net.URLClassLoader$1.run(URLClassLoader.java:202)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.net.URLClassLoader.findClass(URLClassLoader.java:190)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:306)
    at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:301)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:247)
    at java.lang.Class.forName0(Native Method)
    at java.lang.Class.forName(Class.java:247)
    at java.io.ObjectInputStream.resolveClass(ObjectInputStream.java:603)
    at java.io.ObjectInputStream.readNonProxyDesc(ObjectInputStream.java:1574)
    at java.io.ObjectInputStream.readClassDesc(ObjectInputStream.java:1495)
    at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1731)
    at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1328)
    at java.io.ObjectInputStream.readObject(ObjectInputStream.java:350)
    at java.util.ArrayList.readObject(ArrayList.java:593)
    at java.io.ObjectStreamClass.invokeReadObject(ObjectStreamClass.java:974)
    at java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:1848)
    at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1752)
    at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1328)
    at java.io.ObjectInputStream.readObject(ObjectInputStream.java:350)
    at org.apache.ibatis.cache.decorators.SerializedCache.deserialize(SerializedCache.java:91)
    ... 18 more
UserAuthentication.java

public class UserAuthentication implements Serializable {

  private int id;
  private String authId;
  private String secret;
  private String token; // Oauth1 token
  private String accessToken; // Oauth2 request token
  private String displayName;
  private String authMethod;
  private String provider;
  private String email;
  private String avatarUrl;
  private Date lastAccess;
  private String password;
  private boolean emailVerified;
  private int userId;
  private String activationUuid;
  private Date activationExpiry;

  // + getters & setters
}
UserId.java

public class UserId implements java.io.Serializable {
    /**
     * The id the user has in a external service.
     */
    public String id;

    /**
     * The provider this user belongs to.
     */
    public ProviderType provider; // simple enum
}

抱歉,我想我错了-这不是名称冲突,而是类加载器问题

Play使用动态类加载机制检测源代码的更改,并通过字节码注入增强方法

我认为问题可能在于MyBatis使用的是常规类加载器,因此无法找到通过Play机制加载的类。当您将源代码放入Play目录时,MyBatis将使用Play类加载器

以下是一些选项:

1将域对象编译成JAR文件。在项目中包括该jar:

2强制MyBatis使用Play类加载器-在MyBatis调用之前的某个地方

Thread.currentThread().setContextClassLoader(Play.classloader); 
看起来仍然像是一种黑客行为,但它可能会降低应用程序源代码的大小

3确保在调用MyBatis之前加载您的类。所以,在这种情况下

Class.forName("data.domain.UserAuthentication");
Class.forName("data.domain.UserId");
这似乎是更糟糕的黑客行为

我希望这些选项中有一个适合您。

更新:当前版本中包含了修补程序530,一切正常

Play1.x用户可能对我正在维护的模块感兴趣。这在开发中非常有用,因为当java源文件或xml映射器配置发生更改时,它将重置会话工厂,从而避免重新启动web应用程序

原职: 我找到了一个解决办法:

如果我在app目录下复制MyBatis的源文件,我会让play框架像往常一样编译它们,并从lib目录中删除ibatis预编译的jar,它会按预期工作。 然而,我正在寻找一个听起来不像黑客的更好的解决方案:


谢谢

为了记录在案,MyBatis 3.1.1中修复了此问题


我已经添加了您需要的额外信息。根据您的修复,听起来可能是类名冲突。通过在项目中编译它们,您可以更改顺序。如果您在eclipse中使用Open Type ctrl+shift+T,您会看到多少可序列化类假定您正在使用eclipse。共有2个类:java.io.Serializable&sunw.io.Serializable很抱歉之前没有跟进此问题,但我没有收到您最近编辑的任何通知。我使用解决方案1使其工作。另外两个似乎不起作用——或者我做错了什么。非常感谢@DiegoLopez抱歉,我应该在这里更新这些信息。实际上,我是为第530期提交补丁的人。所以,是的,它现在工作正常:。谢谢