【问题标题】:Replacing a class with another using Eclipse Transforms: can't fix ClassFormatError使用 Eclipse 转换将一个类替换为另一个类:无法修复 ClassFormatError
【发布时间】:2016-06-01 12:10:13
【问题描述】:

我正在使用Equinox Transforms 在类路径上用它的自定义版本替换一个类。转换机制似乎工作正常,我从转换器类的 public InputStream getInputStream(InputStream inputStream, URL transformerUrl) 返回自定义类的 InputStream

但是加载该类会导致ClassFormatError 带有消息Truncated class file。我能想象到的唯一原因是 Java 版本之间的不匹配,但我已经尽我所能消除它作为问题的根源,但无济于事。

我在已安装的 JRE 首选项中从 Eclipse 中删除了除一个 JDK 之外的所有 JDK。我确保所涉及的所有插件的执行环境都具有相同的 Java 版本,并且构建路径上的 JRE 使用相同的执行环境指定。目标和产品执行环境的定义也相同。我在工作区中做了一个clean all 并多次使用-clean 重新启动了eclipse 和我的运行时工作台。毕竟这一切,我仍然得到错误。

如果不是 Java 版本导致此错误,还有什么可能? Equinox Transforms 页面说它可以用来转换类资源。真的有人这样做过吗?

【问题讨论】:

  • 这个项目的最新提交是 2013 年,似乎被放弃了..
  • 是的,我注意到了。但它被记录为工作。可能有一些关于加载类的事情我不明白,因为 Equinox 代码似乎正在做它应该做的事情。
  • 你应该尝试一下在 osgi 中覆盖类的“标准”方式:weavinghook osgi.org/javadoc/r6/core/org/osgi/framework/hooks/weaving/…
  • 嗯,这似乎容易多了,但我也不能让它工作。我在 wovenClass 上调用 setBytes,我在调试器中看到我正在从修改后的类文件中获取字节。但是该类没有表现出任何修改后的行为。就好像编织没有发生一样。我在构造函数和我覆盖的方法之一中有一个调试语句,但我从来没有看到我的调试输出。还有什么我应该让框架使用修改后的类吗?
  • 我从加载的字节数中注意到,我实际上是在获取原始类的字节,并用相同的字节“替换”原始类中的字节。我通过更改为类定义 InputStream 的方式来修复它。如果您想发布有关使用编织的答案,我会接受它,并提供类加载问题的详细信息。

标签: java osgi eclipse-rcp classloader equinox


【解决方案1】:

通过WeavingHook 替换osgi 中的类有一种更标准化的方法。这个钩子应该注册为服务,并且有可能动态增强一个类。

参见the WeavingHook JavadocAries Proxy 的具体示例,它在asm (WovenProxyGenerator) 的帮助下动态创建代理。

【讨论】:

  • 谢谢,这比使用通用挂钩扩展创建我自己的转换要容易得多。我最初遇到了一个问题,因为我获取替换类的字节的方式。我最初尝试在进行编织的插件中: InputStream is = Activator.class.getClassLoader().getResourceAsStream("/" + "qualified.class.name".replaceAll("\\.", "/") + ".class");本以为会解析当前项目中的替换类,结果居然解析了第三方插件中的原类。
  • 这行得通: InputStream is = new URL("platform:/plugin/my.plugin.name/bin/path/to/replacement/class.").openConnection().getInputStream();
猜你喜欢
  • 2011-04-10
  • 2022-08-18
  • 1970-01-01
  • 2017-12-25
  • 1970-01-01
  • 2022-12-21
  • 2023-01-20
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多