gpt4 book ai didi

java - 将 weld-se 与 Gradle 应用程序插件一起使用时的 Bean 发现问题

转载 作者:搜寻专家 更新时间:2023-10-30 19:54:59 25 4
gpt4 key购买 nike

我正在构建基于 Hibernate 的基于 Gradle 的 Java SE 应用程序作为我选择的 ORM。我的计划是使用 weld-se 以便能够使用 CDI 注释在整个应用程序中注入(inject) EntityManagers

基于 Hibernate 文档中常见的 HibernateUtil 帮助程序类,我转向 JPA 接口(interface)并添加了 @Produces 注释以提供生产者方法(我添加了一个空的META-INF/beans.xml):

package dao;

import javax.enterprise.inject.Disposes;
import javax.enterprise.inject.Produces;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;

public class HibernateUtil {
private static final EntityManagerFactory emf = buildEntityManagerFactory();

private static EntityManagerFactory buildEntityManagerFactory() {
try {
return Persistence.createEntityManagerFactory("persistenceUnit");
} catch (Throwable ex) {
System.err.println("Initial EntityManagerFactory creation failed." + ex);
throw new ExceptionInInitializerError(ex);
}
}

@Produces
public static EntityManager createEntityManager() {
return emf.createEntityManager();
}

public static void closeEntityManager(@Disposes EntityManager em) {
System.out.println("Closing EM");
try {
em.close();
} catch (Throwable t) {
t.printStackTrace();
}
}
}

但是,当我尝试在字段上使用 @Inject 注释时,Weld 无法解析正确的生产者方法并生成异常:

Exception in thread "main" org.jboss.weld.exceptions.UnsatisfiedResolutionException: WELD-001308: Unable to resolve any beans for Type: class app.DemoApplication; Qualifiers: [@javax.enterprise.inject.Any()] at org.jboss.weld.bean.builtin.InstanceImpl.get(InstanceImpl.java:101) at app.Main.main(Main.java:14)

违规代码通过 Weld 容器实例化以支持 CDI,并且非常基础:

package app;

import javax.inject.Inject;
import javax.persistence.EntityManager;

public class DemoApplication {
@Inject private EntityManager em;

public void run() {
try {
em.getTransaction().begin();
System.out.println("Inside transaction");
} catch (Throwable t) {
t.printStackTrace();
} finally {
em.getTransaction().rollback();
em.close();
}
}
}

我在这里漏掉了一个明显的点吗?我怎样才能让 Weld 发现用于注入(inject)我的依赖项的生产者方法?

我在 Github 上建立了一个最小的项目来重现我的问题.感谢您提供任何有用的建议! :)

2015-05-18 更新:

看来我误解了错误消息。事实上,Weld 甚至没有解析 DemoApplication bean,这让我相信 bean 发现过程出了问题。将我的 weld-se 依赖项更新到新发布的 3.0.0.Alpha8 版本(参见链接的 Github 存储库)后,我能够通过手动告诉 Weld 关于我在 Main.java :

final Weld weld = new Weld()
.enableDiscovery()
.addPackage(false, HibernateUtil.class)
.addPackage(false, DemoApplication.class);

尽管如此,对于为什么尽管有一个空的 META-INF/beans.xml 仍未自动发现 bean 的任何建议,我们都非常感谢!

2015-05-19 更新:

谜底已揭开,请看下面我自己的回答。我更改了问题标题,以反射(reflect)问题的实际性质。

最佳答案

在这样的问题上花费了比看起来更理智的时间,我终于能够找到问题的根源。它与 Weld 或 Jandex 无关,而是与 Gradle 构建其输出目录的方式有关:

:build 任务为实际编译结果和附加资源(build/classesbuild/resources 创建两个单独的输出文件夹).只有当您创建 JAR 存档时,这两个文件夹才会合并。然而,:run 任务直接从编译输出文件夹启动应用程序,其中包含类和资源的两个单独的类路径条目。

Weld 的 bean 发现机制显然只尝试为与 META-INF/beans.xml 文件相同的类路径条目发现 bean,在本例中为 build/resources/main 文件夹。反过来,没有任何 beans 被发现并且永远没有资格在任何地方注入(inject)。

我现在的解决方法(请参阅 Git 存储库)是创建一个额外的 Gradle 任务以将资源复制到适当的文件夹中,以便在正确的类路径条目上进行 bean 发现:

task copyResources(type: Copy) {
from "${projectDir}/src/main/resources"
into "${buildDir}/classes/main"
}

processResources.dependsOn copyResources

Gradle 论坛中描述了类似的相同问题:https://discuss.gradle.org/t/application-plugin-run-task-should-first-consolidate-classes-and-resources-folder-or-depend-on-installapp-or-stuff-like-weld-se-wont-work/1248

感谢大家的提示!

关于java - 将 weld-se 与 Gradle 应用程序插件一起使用时的 Bean 发现问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30255760/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com