英文:
Recorder does not fire in native executable
问题
在我们的设置中,我们执行一些静态初始化构建步骤,包括将所有资源路径添加到对象的列表中。我们使用 Recorder 来执行此操作,因为在静态初始化阶段无法访问对象。在 JVM 模式下,我们看到该列表确实包含所有资源路径。然而,在 Native 模式下情况并非如此。列表保持为空,即使构建日志显示我们已遍历资源并将其添加到列表中。
我们的设置如下所示:
首先:在运行时可访问并包含所有资源路径的文件。
@ApplicationScoped
public class ServiceResourcesList {
private List<String> resources;
public ServiceResourcesList() {
resources = new ArrayList<>();
}
public void addResource(String resource) {
this.resources.add(resource);
}
public List<String> getResources() {
return resources;
}
public List<String> getResources(Predicate<String> filter) {
return resources.stream().filter(filter).collect(Collectors.toList());
}
}
Recorder 返回一个 BeanContainerListener 的类:
@Recorder
public class ServiceResourcesListRecorder {
public BeanContainerListener addResourceToList(String resource) {
return beanContainer -> {
ServiceResourcesList producer = beanContainer.instance(ServiceResourcesList.class);
producer.addResource(resource);
};
}
}
最后是(简化的)构建步骤。请注意,我们使用了 BuildProducer<BeanContainerListenerBuildItem>
,这应该确保在应用 Recorder 方法之前已经注册了对象。
@BuildStep
@Record(STATIC_INIT)
void createResourceList(final BuildProducer<BeanContainerListenerBuildItem> containerListenerProducer, ServiceResourcesListRecorder recorder) {
// 获取资源路径的一些代码,但这可以是任何内容
// ...
for (String resourcePath: resourcePaths) {
LOGGER.info(resourcePath + " added to recorder");
containerListenerProducer.produce(new BeanContainerListenerBuildItem(recorder.addResourceToList(resourcePath)));
}
}
我做错了什么吗?Recorder 不能用于本机可执行文件吗?我是否应该在某个地方添加 RegisterForReflection?
谢谢
英文:
In our setup, we perform some STATIC-INIT build steps including adding all resource paths to a list in an object. We use a Recorder for this, because the object cannot be accessed during the static init phase. In JVM mode, we see that the list does indeed contain all resource paths. However, this is not the case in Native mode. The list remains empty, even though the build logs show that we iterated over the resources and added them to the list.
This is what our setup looks like:
First: The file that is accessible at runtime and contains all resource paths.
@ApplicationScoped
public class ServiceResourcesList {
private List<String> resources;
public ServiceResourcesList() {
resources = new ArrayList<>();
}
public void addResource(String resource) {
this.resources.add(resource);
}
public List<String> getResources() {
return resources;
}
public List<String> getResources(Predicate<String> filter) {
return resources.stream().filter(filter).collect(Collectors.toList());
}
}
The recorder, which returns a BeanContainerListener:
@Recorder
public class ServiceResourcesListRecorder {
public BeanContainerListener addResourceToList(String resource) {
return beanContainer -> {
ServiceResourcesList producer = beanContainer.instance(ServiceResourcesList.class);
producer.addResource(resource);
};
}
}
And finally the (simplified) buildstep. Note that we use a BuildProducer<BeanContainerListenerBuildItem> which should make sure that the objects have been registered already before applying the Recorder methods.
@BuildStep
@Record(STATIC_INIT)
void createResourceList(final BuildProducer<BeanContainerListenerBuildItem> containerListenerProducer, ServiceResourcesListRecorder recorder) {
// Some code to get the resource paths, but this could be anything
// ...
for (String resourcePath: resourcePaths) {
LOGGER.info(resourcePath + " added to recorder");
containerListenerProducer.produce(new BeanContainerListenerBuildItem(recorder.addResourceToList(resourcePath)));
}
}
Am I doing something wrong? Are recorders not meant to be used for native executables? Should I add RegisterForReflection somewhere?
Thanks
答案1
得分: 0
我们通过使用RUNTIME-INIT和静态方法来解决了这个问题。
英文:
We solved this problem by using RUNTIME-INIT and static methods instead.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论