首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >简单选择的lambdaJ和ClassCastException

简单选择的lambdaJ和ClassCastException
EN

Stack Overflow用户
提问于 2013-01-21 13:35:39
回答 1查看 1K关注 0票数 4

我的想法用完了,谷歌也帮不上忙。用例看起来很简单,但是它在ClassCastException中失败了。我不知道我做错了什么。有一个简单的方法可以返回匹配给定类别的第一个元素,请看一看。

代码语言:javascript
复制
private Category selectElement(List<? extends Category> results, Code code) {
    return selectFirst(results, having(on(Category.class).getCode(), is(code)));
}

执行给出了堆栈的顶部:

代码语言:javascript
复制
java.lang.ClassCastException: name.wilu.logic.report.utils.SheetLoader$Category$$EnhancerByCGLIB$$3a35aefc cannot be cast to net.sf.cglib.proxy.Factory
at ch.lambdaj.proxy.ClassImposterizer.createProxy(ClassImposterizer.java:134)
at ch.lambdaj.proxy.ClassImposterizer.imposterise(ClassImposterizer.java:101)
at ch.lambdaj.proxy.ProxyUtil.createProxy(ProxyUtil.java:52)
at ch.lambdaj.function.argument.ArgumentsFactory.createPlaceholder(ArgumentsFactory.java:68)
at ch.lambdaj.function.argument.ArgumentsFactory.registerNewArgument(ArgumentsFactory.java:58)
at ch.lambdaj.function.argument.ArgumentsFactory.createArgument(ArgumentsFactory.java:50)
at ch.lambdaj.function.argument.ArgumentsFactory.createArgument(ArgumentsFactory.java:39)
at ch.lambdaj.Lambda.on(Lambda.java:63)

在使用lambdaJ对hibernate的持久化集合保持实体进行操作时,我也遇到了同样的问题。我放弃了假设代理对象(集合中的实体)可能存在一些已经是代理的问题。我似乎错了,因为分类和所有继承的类都是作为结果转换器传递给hibernate的pojos。

这种行为的原因可能是什么?你有什么想法吗?

(我使用的是最近的lambdaj2.4)。

添加以满足马里奥的请求,

代码是一个简单的枚举。类别是不同类别的基类,它有代码字段。此外,它是公共静态类,与所有继承类相同(如果重要的话)。

我会尽力提供不及格的测试。

再次编辑以提供更多的信息。我的一个朋友看了一下代码,在这个问题上放了一个新的亮光。

我将从一开始就尝试重现我们的演绎之路。

//给予

有一个应用程序分为两个部分,一个是基本应用程序(保存模型文件),另一个是web应用程序(保存UI连接的文件,比如backing等等)。--我们的类别和代码是模型类,因此位于基本应用程序中。我们有一个后台bean,用于某些web逻辑,特别是bean或其协作者调用我们的select.的

//何时

我们正在将应用程序部署到web服务器上!JBoss在我的案子里。类是由加载程序读取的,一些我不知道会发生的非常复杂的事情,都是为了运行我的应用程序。我做了一些web操作和,支持bean的方法被称为

代码语言:javascript
复制
 selectFirst(results, having(on(Category.class).getCode(), is(code)));

从应用程序的web部分。

魔法来了。我们的Category.class和Code.class是由UnifiedClassLoader在应用程序加载时加载的。我们在on(Category.class)方法中,类别的代理将被构建。一些非常复杂的逻辑被用来做这件事,最重要的是,代理被工具化了

代码语言:javascript
复制
setThreadsCallbacks(Callback[]callbacks) 

方法,但是Callback.class是从该类加载器中提取的。

代码语言:javascript
复制
 aCategory.getClass.getClassLoader()

因此,最初加载该类的是类加载器,即UnifiedClassLoader。这一切干净利落,我们终于打电话给

代码语言:javascript
复制
 getFirstInstance()

使用反射浏览代理类查找: Proxy.getDeclaredMethod("setThreadsCallbacks",新Class[]{ Callback[].class });

我忽略了这个事实,我不明白

代码语言:javascript
复制
 new Class[]{ Callback[].class }

在我们的例子中,重要的是Callback.class不是由UnifiedClassLoader提供的。应用程序是在一个网络轮胎中执行的,所以对Callback.class的调用将通过web应用程序来实现。类加载器和重新定义的Callback.class将从先前作为对提到的setThreadsCallbacks函子的扩展中删除。反射是残酷的失败。

代码语言:javascript
复制
Category.class != Category.class //these two were provided by different classLoaders

这就是为什么我不能提供不及格的测试。(相同的类装入器)。

我怀疑那个案子有什么解决办法。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2013-02-04 12:17:13

我也遇到过类似的问题。(引发的相同异常: java.lang.ClassCastException: XXX$类别$$EnhancerByCGLIB$$XXX不能转换为net.sf.cglib.proxy.Factory)

在我的例子中,结果是重复(甚至三倍)的CGLib库出现了问题。我们的情况如下:

  • cglib.jar in JBoss (4.2.3)库
  • 在我们的应用程序web库(WAR文件)中,cglib-nodep.jar
  • 应用程序web库中的labmdaj-2.4-with-Reliencies.jar。

然后,在使用Lambda.on(SomeClass.class)时,我们在CGLib的Enhancer类中得到了这个方法:

代码语言:javascript
复制
private static Method getCallbacksSetter(Class type, String methodName) throws NoSuchMethodException {
        return type.getDeclaredMethod(methodName, new Class[]{ Callback[].class });
}

其中methodName = "CGLIB$SET_THREAD_CALLBACKS"和type是由Enhancer包装的SomeClass。

"CGLIB$SET_THREAD_CALLBACKS“方法存在于包装类型中,但getDeclaredMethod()返回null。在getDeclaredMethod()内部,似乎存在两个net.sf.cglib.proxy.Callback.class实例的比较。它们是不同的,因为一个是从cglib.jar (JBoss)加载的,另一个是从cglib-nodep.jar (webapp)加载的。

解决方案是删除冗余的cglib-nodep.jar,并将lambda-2.4-替换为-dependencies.jar,将其替换为lambda-2.4.jar。现在,所有的CGLib类都是从公共位置加载的,并且问题已经消失。

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

https://stackoverflow.com/questions/14439864

复制
相关文章

相似问题

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