我的想法用完了,谷歌也帮不上忙。用例看起来很简单,但是它在ClassCastException中失败了。我不知道我做错了什么。有一个简单的方法可以返回匹配给定类别的第一个元素,请看一看。
private Category selectElement(List<? extends Category> results, Code code) {
return selectFirst(results, having(on(Category.class).getCode(), is(code)));
}执行给出了堆栈的顶部:
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的方法被称为
selectFirst(results, having(on(Category.class).getCode(), is(code)));从应用程序的web部分。
魔法来了。我们的Category.class和Code.class是由UnifiedClassLoader在应用程序加载时加载的。我们在on(Category.class)方法中,类别的代理将被构建。一些非常复杂的逻辑被用来做这件事,最重要的是,代理被工具化了
setThreadsCallbacks(Callback[]callbacks) 方法,但是Callback.class是从该类加载器中提取的。
aCategory.getClass.getClassLoader()因此,最初加载该类的是类加载器,即UnifiedClassLoader。这一切干净利落,我们终于打电话给
getFirstInstance()使用反射浏览代理类查找: Proxy.getDeclaredMethod("setThreadsCallbacks",新Class[]{ Callback[].class });
我忽略了这个事实,我不明白
new Class[]{ Callback[].class }在我们的例子中,重要的是Callback.class不是由UnifiedClassLoader提供的。应用程序是在一个网络轮胎中执行的,所以对Callback.class的调用将通过web应用程序来实现。类加载器和重新定义的Callback.class将从先前作为对提到的setThreadsCallbacks函子的扩展中删除。反射是残酷的失败。
Category.class != Category.class //these two were provided by different classLoaders这就是为什么我不能提供不及格的测试。(相同的类装入器)。
我怀疑那个案子有什么解决办法。
发布于 2013-02-04 12:17:13
我也遇到过类似的问题。(引发的相同异常: java.lang.ClassCastException: XXX$类别$$EnhancerByCGLIB$$XXX不能转换为net.sf.cglib.proxy.Factory)
在我的例子中,结果是重复(甚至三倍)的CGLib库出现了问题。我们的情况如下:
然后,在使用Lambda.on(SomeClass.class)时,我们在CGLib的Enhancer类中得到了这个方法:
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类都是从公共位置加载的,并且问题已经消失。
https://stackoverflow.com/questions/14439864
复制相似问题