OSGI - 如何解决:ClassNotFoundException? (org.eclipse.osgi.internal.loader.BundleLoader.findClass)
Posted
技术标签:
【中文标题】OSGI - 如何解决:ClassNotFoundException? (org.eclipse.osgi.internal.loader.BundleLoader.findClass)【英文标题】:OSGI - How to solve: ClassNotFoundException? (org.eclipse.osgi.internal.loader.BundleLoader.findClass) 【发布时间】:2021-09-01 06:04:00 【问题描述】:当使用三个包时 A = first.bundle B = second.bundle 和 C = third.bundle,其中 A 依赖于 B和C,C调用方法java.lang.Class.forName
时找不到B的类是否在任何 pom.xml 文件中缺少配置或以任何其他方式为 bunlde C 的 ClassLoader 配备 B.SecondClass 类?
org.example.first.bundle.FirstClass
public void topLevelMethod()
ThirdClass thirdObject = new ThirdClass();
thirdObject.resolveTheClassName("org.example.second.bundle.SecondClass")
org.example.third.bundle.ThirdClass
public <T> Class<T> resolveTheClassName(String className) throws ClassNotFoundException
return (Class<T>) Class.forName(className);
java.lang.ClassNotFoundException:在 org.eclipse.osgi.internal.loader.BundleLoader.findClass(BundleLoader.java:516) 上的 third.bundle_1.0.0.SNAPSHOT 找不到 org.example.second.bundle.SecondClass 在 org.eclipse.osgi.internal.loader.ModuleClassLoader.loadClass(ModuleClassLoader.java:171) 在 java.lang.ClassLoader.loadClass(ClassLoader.java:357) 在 java.lang.Class.forName0(本机方法) 在 java.lang.Class.forName(Class.java:264) 在 org.example.third.bundle.ThirdClassA.getContentType(ThirdClassA.java:100) 在 org.example.third.bundle.ThirdClassB$ReceivingTask.run(ThirdClassB.java:135) 在 java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) 在 java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) 在 java.lang.Thread.run(Thread.java:748)
first.bundle/pom.xml
<dependencies>
<groupId>$project.groupId</groupId>
<artifactId>second.package</artifactId>
<version>1.0-SNAPSHOT</version>
<scope>provided</scope>
<groupId>$project.groupId</groupId>
<artifactId>third.package</artifactId>
<version>1.0-SNAPSHOT</version>
<scope>provided</scope>
</dependencies>
second.bundle/pom.xml
<build>
<plugins>
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
<extensions>true</extensions>
<configuration>
<instructions>
<Bundle-SymbolicName>$project.name</Bundle-SymbolicName>
<Embed-Dependency>*;scope=compile|runtime</Embed-Dependency>
<Embed-Directory>OSGI-INF/lib</Embed-Directory>
<Embed-Transitive>true</Embed-Transitive>
<Import-Package>
*;resolution:=optional
</Import-Package>
<Export-Package>
org.example.second.bundle
</Export-Packlage>
</instructions>
</configuration>
</plugin>
</plugins>
</build>
third.bundle/pom.xml
<build>
<plugins>
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
<extensions>true</extensions>
<configuration>
<instructions>
<Bundle-SymbolicName>$project.name</Bundle-SymbolicName>
<Embed-Dependency>*;scope=compile|runtime</Embed-Dependency>
<Embed-Directory>OSGI-INF/lib</Embed-Directory>
<Embed-Transitive>true</Embed-Transitive>
<Import-Package>
*;resolution:=optional
</Import-Package>
<Export-Package>
org.example.third.bundle
</Export-Packlage>
</instructions>
</configuration>
</plugin>
</plugins>
</build>
【问题讨论】:
【参考方案1】:类加载器配置在一个图中,每个导入的包都有边。因此,如果 C 没有 B 中的包的导入边缘,则 C 无法从 B 中的该包中类加载类。
如果 C 有来自 B 的对象,它可以在 Class.forName 调用中使用来自 B 的对象的类的类加载器。但通常不应该在 OSGi 中使用 Class.forName。使用 OSGi 服务会更好。然后 C 可以在 OSGi 服务注册表中找到感兴趣的对象。
【讨论】:
谢谢,我研究了原生 OSGI 方法并找到了解决方案【参考方案2】:找到了解决办法!
public <T> Class<T> resolveTheClassName(String className) throws ClassNotFoundException
BundleContext bundleContext = FrameworkUtil.getBundle(this.getClass()).getBundleContext();
List<Class<?>> foundClasses = findClass(bundleContext, serializedContentType);
if(foundClasses.isEmpty())
return (Class<T>)Class.forName(serializedContentType);
else
return (Class<T>)foundClasses.get(0);
private List<Class<?>> findClass(BundleContext context, String name)
List<Class<?>> result = new ArrayList<Class<?>>();
for (Bundle b : context.getBundles())
try
Class<?> c = b.loadClass(name);
result.add(c);
catch (ClassNotFoundException e)
// No problem, this bundle doesn't have the class
return result;
How to load a class by classname string from OSGi runtime environment?
【讨论】:
以上是关于OSGI - 如何解决:ClassNotFoundException? (org.eclipse.osgi.internal.loader.BundleLoader.findClass)的主要内容,如果未能解决你的问题,请参考以下文章
python中是不是有类似于osgi试图在java中解决的要求?