You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Tycho-surefire执行测试抛出java.lang.IllegalAccessException咨询

Tycho Surefire下protected方法访问异常的根因与解决方案

OSGi Fragment类加载机制与IllegalAccessException的关联逻辑

  • 按照OSGi规范,Fragment不是独立Bundle,附着到宿主后应当与宿主共用类加载器、共享类路径。但Tycho Surefire的默认执行逻辑为了实现测试隔离,会为所有测试类单独挂载独立的测试类加载器,并没有完全遵循标准OSGi的Fragment类合并规则。
  • 你配置的Eclipse-ExtensibleAPI: true仅作用于PDE编译期和工具链校验:它的作用是允许Fragment向宿主的导出包列表追加内容,让宿主编译时可以识别到Fragment里定义的类,完全不干预运行时JVM的访问权限校验,也不会修改Tycho Surefire的类加载器隔离策略。
  • Eclipse中普通单元测试模式能跑通,是因为该模式没有启动OSGi环境,测试类和业务类都由同一个应用类加载器加载,只要包名一致,JVM就允许访问protected方法。而Tycho Surefire执行时,业务类由宿主Bundle的OSGi类加载器加载,测试类哪怕属于宿主的Fragment,默认也是由Surefire的独立测试类加载器加载。JVM的运行时包判定规则要求:同包名+同一个类加载器 才属于同一个运行时包,才允许访问protected成员。类加载器不一致时,哪怕包名完全相同,也会直接抛出IllegalAccessException。

可落地的规避方案

方案1:关闭Tycho Surefire的测试类加载器隔离(优先推荐,改动最小)

在承载主测试套件的核心测试插件的pom.xml中,给tycho-surefire-plugin追加如下配置,强制测试类合并到对应宿主Bundle的类加载器中加载,对齐标准OSGi Fragment的原生加载逻辑:

<plugin>
  <groupId>org.eclipse.tycho</groupId>
  <artifactId>tycho-surefire-plugin</artifactId>
  <configuration>
    <!-- 关闭测试类独立类加载器 -->
    <useSeparateTestClassloader>false</useSeparateTestClassloader>
    <!-- 放开boot delegation限制,避免基础类访问冲突 -->
    <framework>
      <bundle>
        <name>org.eclipse.tycho.surefire.osgibooter</name>
        <options>
          <bootDelegation>
            <package>*</package>
          </bootDelegation>
        </options>
      </bundle>
    </framework>
  </configuration>
</plugin>

配置后重新执行构建即可解决访问异常,对现有测试代码、Manifest配置无侵入,Tycho 1.x、2.x、3.x全版本支持该配置。

方案2:标记测试Fragment为补丁片段(适用于Tycho旧版本兼容场景)

如果使用的是Tycho 0.x等不支持useSeparateTestClassloader配置的旧版本,可以在每个测试Fragment的MANIFEST.MF中追加配置,强制OSGi运行时将Fragment的类完全合并到宿主类路径:

Eclipse-PatchFragment: true

配置后需要确认Fragment-Host声明中写全宿主插件的符号名,不要使用模糊的版本范围匹配。注意该配置会赋予Fragment覆盖宿主类的权限,仅可用于测试场景,不要合入生产交付的Feature中。

方案3:反射临时放开访问权限(兜底方案,不推荐)

如果前两种方案受构建环境限制无法落地,可以在调用protected方法前通过反射临时绕过JVM访问校验:

Method targetMethod = bizClass.getDeclaredMethod("protectedMethodName", ParamType.class);
targetMethod.setAccessible(true);
targetMethod.invoke(bizInstance, param);

该方案不需要修改构建配置,但会让测试代码和反射逻辑强绑定,维护成本高,仅建议临时救急使用。


内容的提问来源于stack exchange,提问作者SeHe

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.02 06:57:30