我目前正在维护一个未记录的代码,并在Spring Boot中运行一个类时偶然发现了一个奇怪的错误。该代码在执行时引发非法访问错误,但编译正确。
似乎原始团队尝试访问 Kafka Streams 私有方法的方式是"MacGyver 方式",但我不确定它的行为,因为 IntelliJ 正确导入代码并按应有的方式处理继承(如果我将类声明为本地包,它会突出显示说 AbstractStream 和 KTableImpl 类不存在)。
该项目由 Gradle 管理,它是一个微服务。执行是通过 Spring 引导进行的,启动时会引发错误。
一种可能的解决方案是使用Java的反射库,但它似乎不是解决此错误的正确方法。也许启动设置错误?
package org.apache.kafka.streams.kstream.internals;
import org.apache.kafka.streams.kstream.KTable;
public class KTableSpy {
public static <K> String getName(AbstractStream<K> stream) {
return stream.name;
}
public static <K, V> void enableSendingOldValues(KTable<K, V> table) {
((KTableImpl<K, ?, V>) table).enableSendingOldValues();
}
}
此类应该正常工作,并且不会干扰服务启动。相反,我们有以下错误
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'AVCompanyStateProjector': Invocation of init method failed; nested exception is java.lang.IllegalAccessError: tried to access method org.apache.kafka.streams.kstream.internals.KTableImpl.enableSendingOldValues()V from class org.apache.kafka.streams.kstream.internals.KTableSpy
不确定您要完成什么,但AbstractStream
和KTableImpl
来自包org.apache.kafka.streams.kstream.internals
,而不是公共 API 的一部分(顾名思义)。这意味着可以在不通知的情况下添加/删除方法(甚至整个类)。
也许enableSendingOldValues()
的可见性是从public
更改为包私有破坏了您的代码。