Osgi EclipseRCP:编织时如何添加内部类

Osgi EclipseRCP:编织时如何添加内部类,osgi,eclipse-rcp,classloader,equinox,load-time-weaving,Osgi,Eclipse Rcp,Classloader,Equinox,Load Time Weaving,在我的RCP应用程序中,我使用WeavingHook服务在加载时修改第三方类。我无法对第三方代码进行任何更改,因此我的编织实现必须按原样使用它 除了一个问题外,我的工作。对于我制作的一个mod,我实例化了一个内部类。它必须是一个内部类,因为它依赖于一个超类中定义的内部类 现在,当第三方代码加载修改后的类时,它的类路径上没有内部类的文件,这只在我实现编织的插件中可用。如果第三方插件声明了一个伙伴策略registered,我可以向清单中添加一个eclipseregisterbuddy指令,但事实并非

在我的RCP应用程序中,我使用WeavingHook服务在加载时修改第三方类。我无法对第三方代码进行任何更改,因此我的编织实现必须按原样使用它

除了一个问题外,我的工作。对于我制作的一个mod,我实例化了一个内部类。它必须是一个内部类,因为它依赖于一个超类中定义的内部类

现在,当第三方代码加载修改后的类时,它的类路径上没有内部类的文件,这只在我实现编织的插件中可用。如果第三方插件声明了一个伙伴策略
registered
,我可以向清单中添加一个
eclipseregisterbuddy
指令,但事实并非如此

编织是否有某种方式使修改后的类能够访问通过二进制编织添加的内部匿名类


我能想到的唯一解决方案是,在发生二进制编织时,将内部类文件复制到第三方代码的bin/目录中。看起来像是一个黑客,所以我希望有更好的方法。

当使用
getdynamicmports()
方法通过编织钩子编织类时,可以动态添加导入包:

wovenClass.getDynamicImports().add("my.package.to.import");

这个包显然应该由另一个包导出。

这里有一个有效的解决方案,将内部类的类文件复制到包含weave目标的第三方插件的bin/目录。如果有人知道一种不太老套的方法来做这件事,请发布一个单独的答案

编辑:使原始解决方案更通用,发现正在编织的类的所有内部类文件,如果缺少或大小不同,则将它们复制到编织目标插件

公共类激活器扩展插件{
...
公共静态最终字符串类_FILE_ROOT=“bin/”;
/**
*类文件的二进制编织可能会导致添加或修改
*此插件中需要放置在类路径上的内部类文件
*包含weave目标的插件的。此方法比较内部类
*此插件中给定类的文件以及插件中的内部类文件
*包含weave目标的。weave中缺少任何内部类文件
*目标或与此插件中的相应文件大小不同
*复制到weave目标插件中相应的包目录。
* 
*@param bundle正在编织的类的bundle
*@param className正在编织的类的完全限定名
*@如果复制内部类文件时未遇到错误,则返回true
*/
私有布尔checkInnerClassFileSync(捆绑包,字符串类名称){
className=className.replaceAll(“\\”,“/”);
String classDir=CLASS\u FILE\u ROOT+className.substring(
0,FilenameUtils.indexoflastsseparator(className));
for(字符串innerClass:getInnerClassNames(classDir,FilenameUtils.getName(className))){
试一试{
URL srcUrl=getBundle().getEntry(classDir+“/”+innerClass);
File srcFile=新文件(FileLocator.resolve(srcUrl.toURI());
URL destUrl=bundle.getEntry(classDir);
File destDir=新文件(FileLocator.resolve(destUrl.toURI());
File destFile=FileUtils.getFile(destDir,innerClass);
if(srcFile.isFile()&&(!destFile.exists()| | destFile.length()!=srcFile.length()){
copyFile(srcFile,destFile);
}
}捕获(IOException | URISyntaxException e){
logger.log(Level.ERROR,“试图将内部类文件复制到weave目标捆绑包时出错”,e);
返回false;
}
}
返回true;
}
/**
*获取表示在指定类中定义的内部类的类文件,并
*在指定目录中找到。
* 
*@param dir包含
className
*可能还有一个或多个类文件,表示中定义的内部类 *
className
*@param className类文件位于
dir
*@return class文件表示在中定义的每个内部类的名称 *
className
并可在
dir
中找到。 */ 私有字符串[]GetInnerClassName(字符串目录,字符串类名){ List classNames=new ArrayList(); 试一试{ File classDir=新文件(FileLocator.resolve(getBundle().getEntry(dir)).toURI()); for(字符串fName:classDir.list()){ Pattern p=Pattern.compile(“^”+className+“\\$。+$”); 匹配器m=p.Matcher(fName); 如果(m.matches()){ 添加(fName); } } 返回classNames.toArray(新字符串[0]); }捕获(URISyntaxException | IOException e){ logger.log(Level.ERROR,“扫描内部类文件时发生错误”,e); 返回classNames.toArray(新字符串[0]); } } .... }
谢谢,我看了一下,但我的问题是如何将表示新内部类的类文件放到包含weave目标的第三方代码的类路径上,即在单个匿名类的情况下,MyClass$1.class。它只存在于我编织的插件中,因为我制作的mod涉及添加一个匿名内部类。我想知道WeavingHook或其他服务是否提供了在weave目标的同一目录中注入新类文件的方法。可能不会。我将在单独的答案中发布一个工作文件副本解决方案。