I have a utility jar that has a logger producer, and I am working on another project using Arquillian for testing. In the project, I have a class with #Inject Logger logger. When I run tests with Arquillian, I got an error saying that org.jboss.weld.exceptions.DeploymentException: WELD-001408 Unsatisfied dependencies for type Logger with qualifiers #Default
at injection point. I have successfully used producer from current project to produce a logger bean before, but this is the first time I have tried to use a producer from another jar (or a dependency). So, I am wondering if producers have to be in the same project or they can be in other jars. Thank you in advance.
I think see the issue-- This is not wrong with Arquillian.
Explicit jar contain the beans.xml file, that can be an empty, either it contain no version number, or contain the version number 1.1 with the bean-discovery-mode attribute set to all. such as:
For JavaEE7
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
http://xmlns.jcp.org/xml/ns/javaee/beans_1_1.xsd"
version="1.1" bean-discovery-mode="all">
</beans>
CDI will not manage and inject those beans which are annotated with
#Voted
Another one is implicit bean archive,that contains some beans annotated with a scope type, contains no beans.xml files or contains a beans.xml file with the bean-discovery-mode attribute set to annotated.
CDI can only manage and inject beans annotated with a scope type in an
implicit archive.
Refer Java Tutorial
Packaging CDI Applications
Weld-Doc
Related
I have a very simple Spring JPA Repository which is packed into a JAR and stored in the local maven repository.
I can use the JPA Repository in my Unit-Tests and in a little Main-Test-Routine. It gets #Autowired without any problem.
Here is the definition of my JPA-Repository:
public interface TestRepo extends CrudRepository<Seminar , Integer > {
List<Seminar> findAll();
}
And in the applicationContext.xml of the JAR:
<jpa:repositories base-package="de.dmsb.my.core"
entity-manager-factory-ref="entityManagerFactory"
transaction-manager-ref="transactionManager">
</jpa:repositories>
There a also some other Services defined in this JAR too which can be used in the JAR and in the WAR, which includes the JAR as a dependency with maven.
But as soon as a try to #Autowire the the JPA-Repository:
#Autowired
TestRepo testRepo;
I get an runtime error that there is no suitable bean defined. Other beans work - but as soon as it comes to JPA-Repositories it doesn't work.
I mean of course you cannot #Autowire a interface - and in the WAR there is not JPA-Repository bean in the ApplicationContext when I debug it - all the other beans from the JAR are there.
Any idea what the problem might be?
I'm having trouble injecting dao bean declared on a lib jar.
So I have a jar (mine) with a persistence context, entities and daos. Here is a dao example :
#Stateless
public class SomeDao {
#PersistenceContext
private EntityManager em;
...
}
Now I want to use this dao on my main application.
A jax-rs use case :
#Path("rs")
public class WebService{
#Inject
private SomeDao dao;
#POST
public Response doPost(){
//dao is injected but nullpointer thrown on EntityManager
dao.doSomething();
}
...
}
There is a beans.xml in both project (under META-INF/ for lib, WEB-INF/ for the web application). like this one :
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/beans_1_0.xsd">
</beans>
------------- Edit ------------
I've just found out if I remove the #Stateless annotation and the producer it works. So the problem is in fact : how to inject with CDI an EJB declared on an lib jar.
Firstly, if this a jar you create and not a third party just, simply add a beans.xml in the correct location for the jar and you'll have those objects available for injection. That's the easiest way.
If it is a third part jar, your next best idea is to create a portable extension and listen to the BeforeBeanDiscovery in CDI 1.0 or AfterTypeDiscovery in CDI 1.1 and call the addAnnotatedType method to add in those classes you need from the jar. You'd create this extension in your war / ear classpath.
I'm trying to inject a bean located in a different jar file then the bean i'm trying to inject it into. Both beans are just basic #Stateless beans with local and remote interfaces.
If i use the normal injection
#EJB
IBean injectedBean;
or
#EJB
IBeanLocal injectedBean;
i get a NullPointerException when deploying the application.
If i use:
#EJB(mappedName="Bean")
IBean injectedBean;
or
#EJB(mappedName="Bean")
IBeanLocal injectedBean;
everything works and JBoss throws no deployment errors.
I might mention i use JBoss 5.
The bean class i'm injecting is declared as:
#Remote
public interface IBean
#Local
public interface IBeanLocal extends IBean
#Stateless(name = "Bean")
public class Bean implements IBean, IBeanLocal
My problem is that as specified in the documentation the mappedName property is vendor-specific. Is there any other way i could get this to work?
SOLVED:
I managed to solve the problem.
The problem was that i tried to deploy both jars individually which meant that each would get it's own ClassLoader in JBoss so that they couldn't find each other and would return a NullPointerException when trying to inject the bean.
The sollution was to add the jars to an ear and add an META-INF containing an application.xml looking like this:
<application xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee
http://java.sun.com/xml/ns/j2ee/application_1_4.xsd"
version="1.4">
<display-name>Simple example of application</display-name>
<module>
<ejb>ejb1.jar</ejb>
</module>
<module>
<ejb>ejb2.jar</ejb>
</module>
</application>
I also had to change some JNDI lookups i made to match the new structure by adding the ear name before the classes: "ear-name/bean"
After this i just added the jars to the ear and everything deployed nicely.
You need to declare the local interface in order to have JBoss find the bean based on the interface only (assuming you're using EJB 3.0):
#Stateless(name = "Bean")
#Local ( IBeanLocal.class )
#Remote ( IBean.class )
public class Bean implements IBean, IBeanLocal { ... }
Edit: IBean is a remote interface (see comment).
Try injecting your bean with #EJB(beanName = "Bean")
Not sure if it'll work, but we had a similar issue and it was caused by the lack of the beanName attribute.
I am drawing a blank on this for some reason. I have a multi-module Spring/Maven project. In module1 I define a singleton bean called "info" and it works within module1 just fine.
However module2 in this project (which depends on module1) has improvements on property values for the "info" bean. Module2's Spring configuration already includes Module1's configuration. What is the Spring configuration I should use to set properties on the "info" bean defined in this subsequent module?
Since Spring 2.5 there is a PropertyOverrideConfigurer. Maybe that's what you are searching for
http://static.springsource.org/spring/docs/2.5.x/reference/beans.html#beans-factory-overrideconfigurer
There is a small example on this page
http://ondra.zizka.cz/stranky/programovani/java/howto-substitutions_in_spring_configuration-tutorial.texy
Create a new "info" bean in module2, configuring it the way specific to the needs of module 2.
You would do something like this in your module 2 configuration:
<import resource="classpath:/META-INF/module1-config.xml"/>
<bean name="info" class="Module1class"/>
This should inject the right "info" into the dependent beans
I have a new web app that is packaged as a WAR as part of a multi-module Maven project. The applicationContext.xml for this WAR references beans that are imported from the "service" module, which in turn imports beans from the "dao" module. The import statement in applicationContext.xml looks like this:
<import resource="classpath*:service.xml" />
and the one inside the service.xml file looks like this:
<import resource="classpath*:dao.xml" />
Neither Spring STS, nor Eclipse show any warnings or errors in my bean files. I reference the imported beans all over the place. The Maven build works fine and the DAO integration tests all pass (they use the beans). I don't have any service integration tests yet.
But when I start up the WAR in Jetty I get an error:
Error creating bean with name 'securityService'
Cannot resolve reference to bean 'userDAO' while setting constructor argument
All of the imported bean XML files can be found inside their respective JAR files in the WEB-INF/lib directory. Indeed, the service bean that threw the error is itself defined inside the service.xml file inside the service module's JAR file.
Apparently the service module can't find the bean that it imported from the dao module. Obviously I don't understand something...seems like this should this Just Work?
I enabled DEBUG logging for 'org.springframework' in order to see if I could learn anything. What I found were messages to the effect that the DAO beans had been created, but there was also a message about them having no name or id.
I check the file, and they all did have an id. So what was it? I check the XML namespace and saw:
http://www.springframework.org/schema/beans/spring-beans-2.0.xsd"
and noticed it was old (I am using Spring 3.0.2) and changed it to:
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
Once I changed it, Spring instantly threw half a dozen errors regarding beans that were defined incorrectly (but never used apparently). Once I fixed those errors, everything Just Worked. I've since gone through the entire system checking Spring XML file namespace versions.
Thanks to all for the help. Can't believe I wasted a day on this stupidity!!
The difference between the classpath:thingy.xml and classpath*:thingy.xml notation is that the former uses the standard classpath mechanism to resolve one resource (using ClassLoader.getResource(name)), whereas the latter will use ClassLoader.getResources(name) to retrieve all matching resources on the classpath, a distinction that should be irrelevant in your situation as I guess there is only one dao.xml file on the class path.
I think your problem is different, you are missing a leading slash.
Use this for a single resource
<import resource="classpath:/dao.xml" />
and this for multiple resources
<import resource="classpath*:/dao.xml" />
See
Spring Reference: The classpath*
prefix
Sun JavaDocs: ClassLoader
It should be like
<import resource="classpath:service.xml"/>
Are you having multiple applicationContexts and possibly the parent context is referring to a bean defined in the child context?