java - Bean discovery problems when using weld-se with Gradle application plugin -
i building gradle-based java se application built on top of hibernate orm of choice. plan use weld-se
able use cdi annotations injections of entitymanagers
throughout application.
based on common hibernateutil
helper class found in hibernate documentation, moved towards jpa interfaces , added @produces
annotations provide producer methods (i have added empty meta-inf/beans.xml
well):
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(); } } }
when try use @inject
annotation on field, however, weld fails resolve correct producer method , produces exception instead:
exception in thread "main" org.jboss.weld.exceptions.unsatisfiedresolutionexception: weld-001308: unable resolve beans type: class app.demoapplication; qualifiers: [@javax.enterprise.inject.any()] @ org.jboss.weld.bean.builtin.instanceimpl.get(instanceimpl.java:101) @ app.main.main(main.java:14)
the offending code instantiated through weld container cdi support , incredibly basic:
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(); } { em.gettransaction().rollback(); em.close(); } } }
am missing obvious point here? how can weld discover producer method injecting dependencies?
i have put minimal project reproducing problem on github. helpful suggestions! :)
update 2015-05-18:
seems misunderstood error message. in fact, weld not resolve demoapplication
bean, leads me believe, something's wrong bean discovery process. after updating weld-se dependency freshly released 3.0.0.alpha8 version (see linked github repo), able application work manually telling weld beans in main.java
:
final weld weld = new weld() .enablediscovery() .addpackage(false, hibernateutil.class) .addpackage(false, demoapplication.class);
still, suggestions why beans not automatically discovered despite having empty meta-inf/beans.xml
in place highly appreciated!
update 2015-05-19:
the mystery unraveled, see own answer below. changed question title, in order reflect actual nature of issue.
having spent more time seems sane on problem this, able hunt down origin of issue. has neither weld nor jandex, rather way gradle structures output directories:
the :build
task creates 2 separate output folders actual compilation results , and additional resources (build/classes
, build/resources
). when create jar archive these 2 folders merged. :run
task starts application directly compilation output folders 2 separate classpath entries classes , resources.
weld's bean discovery mechanism apparently attempts discover beans same classpath entry meta-inf/beans.xml
file, in case build/resources/main
folder. in turn, no beans ever discovered , never eligible injection anywhere.
my workaround (see git repository) create additional gradle task copy resources appropriate folder, bean discovery happens on correct classpath entry:
task copyresources(type: copy) { "${projectdir}/src/main/resources" "${builddir}/classes/main" } processresources.dependson copyresources
the same issue similar has been described in gradle forums: 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
thanks hints!
Comments
Post a Comment