Getting "expected at least 1 bean which qualifies as autowire candidate. Dependency annotations" - junit5

I am getting the following error on a autowired field. I have added scan tag in xml file and still does not work.I using spring 5.1.6.RELEASE version
<context:component-scan base-package="com.app.service">
<context:include-filter type="annotation"
expression="org.springframework.stereotype.Service" />
</context:component-scan>
Error:
Unsatisfied dependency expressed through field 'approveTimesheetService'; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'com.app.service.ApproveTimesheetService' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {#org.springframework.beans.factory.annotation.Autowired(required=true)}
24-Apr-2019 15:01:13 at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:596)
24-Apr-2019 15:01:13 at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:90)
24-Apr-2019 15:01:13 at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessProperties(AutowiredAnnotationBeanPostProcessor.java:374)
24-Apr-2019 15:01:13 at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1411)
24-Apr-2019 15:01:13 at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.autowireBeanProperties(AbstractAutowireCapableBeanFactory.java:391)
24-Apr-2019 15:01:13 at org.springframework.test.context.support.DependencyInjectionTestExecutionListener.injectDependencies(DependencyInjectionTestExecutionListener.java:119)
24-Apr-2019 15:01:13 `enter code here`at org.springframework.test.context.support.DependencyInjectionTestExecutionListener.prepareTestInstance(DependencyInjectionTestExecutionListener.java:83)
24-Apr-2019 15:01:13 at org.springframework.test.context.TestContextManager.prepareTestInstance(TestContextManager.java:246)
24-Apr-2019 15:01:13 at org.springframework.test.context.junit.jupiter.SpringExtension.postProcessTestInstance(SpringExtension.
Class that getting an error
#TestMethodOrder(OrderAnnotation.class)
#SpringJUnitWebConfig(locations = { "classpath*: service.xml", "classpath*:data.xml" })
#TestInstance(Lifecycle.PER_CLASS)
#Retention(RetentionPolicy.RUNTIME)
#DirtiesContext(classMode = ClassMode.AFTER_CLASS)
public class TestLeaveHourCal_moes18 {
#Autowired
private ApproveTimesheetService approveTimesheetService; //error on this
#Autowired
private ComparePayUpdates comparePayUpdates;
#Autowired
public TestClassSettings testClassSettings; /* variable access type needs public */;
#Autowired
#RegisterExtension
protected CreateTimesheetBeforeTestExecutionCallback beforeTestExecutionCallback; /* can not be private */
#BeforeAll
public void setup() throws Exception {
/* START SETTINGS */
testClassSettings.setTestIndicator("18");
testClassSettings.setTitleUnitCode("99");
}}
Service annotation is added to ApproveTimesheetService class.
#Service("approveTimesheetService")
public class ApproveTimesheetServiceImpl implements ApproveTimesheetService, Serializable {
protected static final Logger LOG = LoggerFactory.getLogger(ApproveTimesheetServiceImpl.class);
protected final static String TS_QUOTE = "'";
}
Any
suggestions?
My servic.xml and data.xml are in web-inf/config folder. Service.xml has the context scan tag.
My classes are in web-inf/classes folder. I think somehow TestLeaveHourCal_moes18 is unable to find service.xml. May be I am not setting the #SpringJUnitWebConfig tag correctly. I tried "classpath" and that did not work either.

I was able to fix the issue by adding the following in pom.xml for maven sure fire plugin configuration session. Looks like it needs a path for where the xml files (service.xml) are.
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>3.0.0-M3</version>
<configuration>
<skipTests>true</skipTests>
<trimStackTrace>false</trimStackTrace>
<additionalClasspathElements>
<additionalClasspathElement>src/main/webapp/WEB-INF/config</additionalClasspathElement>
</configuration>
</plugin>

Related

CDI doesn't work in a simple adapter

I've added the CDI feature to the server.xml file<feature>cdi-1.2</feature>.
My maven module contains the beans.xml inside the <module_name>/src/main/resources/META-INF folder.
This is the beans.xml content:
<?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>
But when I use the #Inject annotation it doesn't work, my bean is always null.
Code:
package ch.webapp.presentation;
...
#Path("/test/")
public class MyController {
#Inject
private MyService myService;
#GET
#Path("/foo/{count}")
#OAuthSecurity(scope = "login")
#Produces("application/json")
public Response news(#PathParam("count") int count) {
return Response
.ok(myService.getBar(count))
.build();
}
}
EDIT:
That's my bean
package ch.webapp.service;
...
#RequestScoped
public class MyService {
public String getBar(int count) {
return "foo";
}
}
I initialize jax-rs by extended the MFPJAXRSApplication class
package ch.webapp;
...
public class AccountApplication extends MFPJAXRSApplication {
#Override
protected void init() throws Exception {
}
#Override
protected void destroy() throws Exception {
}
#Override
protected String getPackageToScan() {
return getClass().getPackage().getName();
}
}
Environment details:
Launching mfp (WebSphere Application Server 8.5.5.8/wlp-1.0.11.cl50820151201-1942) on Java HotSpot(TM) 64-Bit Server VM, version 1.8.0_172-b11 (en_CH)
Console Product version: 8.0.0.00-20180717-175523
What's wrong?
First it seems that websphere jax-rs implementation does not integrate jax-rs resources automatically unless you annotate them appropriately.
Put the jax-rs in a CDI managed context by annotating it appropriately
#Path("/test/")
#javax.enterprise.context.RequestScoped
public class MyController {
#Inject
private MyService myService;
#GET
#Path("/foo/{count}")
#OAuthSecurity(scope = "login")
#Produces("application/json")
public Response news(#PathParam("count") int count) {
return Response
.ok(myService.getBar(count))
.build();
}
}
Also be sure that the annotation used for your service is
#javax.enterprise.context.RequestScoped
Based on the inputs provided by you please go through the below checklist.
Your services and controllers are in the same module and its packaging type is war, So you must place your beans.xml in this path src/main/resources/WEB-INF/beans.xml. (If this is Java EE 7 application then beans.xml is optional.
In your AccountApplication class try hardcoding the package name to ch.webapp.presentation
#Override
protected String getPackageToScan() {
return "ch.webapp.presentation";
}
This is just to check Behaviour of MFPJAXRSApplication.getPackageToScan() method whether it is scanning the specified package only or its child packages too.
Except these, everything seems fine to me. If this still doesn't work add complete application startup logs so that community can find the root cause of it.
This is classical mistake. CDI works for managed beans (for instance EJB's and servlets). If you want to enable it on your JAXRS bean, you have to make it "managed", that is annotate MyController as (for instance) javax.annotation.ManagedBean or as a javax.ejb.Stateless.
Also beware that in case of webapp (.war), the beans.xml file has to be located in the WEB-INF folder !

Websphere Application Server 9.0.0.1 - EntityManager is null every other request

I'm trying to run a project on WAS 9.0.0.1, that currently works fine on WAS 8.5.5.x. The problem seems to be that entitymanager is not being injected into the DAO, but this only happens every other request. So when doing the em.createNamedQuery in the DAO it is throwing a NullPointerException because the em is null, like I explained above the strange thing is that it is only failing like this every other request. Any ideas?
Persistence.xml:
<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.0" xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd">
<persistence-unit name="OperationsAPI" transaction-type="JTA">
<jta-data-source>jdbc/operations</jta-data-source>
<class>com.i3.operations.entities.Operation</class>
<properties>
<property name="openjpa.Log" value="DefaultLevel=WARN, Runtime=INFO, Tool=INFO, SQL=TRACE"/>
</properties>
</persistence-unit>
</persistence>
Resource class:
#Path("/operations")
#Api("Operations API")
#Stateless
public class OperationsService {
public static Logger logger = Logger.getLogger(OperationsService.class.getName());
#Context
UriInfo uriInfo;
#EJB
private static OperationDAO operationDAO;
public OperationsService() {
operationDAO = new OperationDAO();
}
#GET
#ApiOperation(value = "Gets all operations", response = Operation.class, responseContainer = "List")
#Produces(MediaType.APPLICATION_JSON)
public Response getOperationsAll() {
List<Operation> operations = operationDAO.getOperationsAll();
return Response.ok().entity(operations).build();
}
}
DAO:
#Stateless
public class OperationDAO {
public static Logger logger = Logger.getLogger(OperationDAO.class.getName());
#PersistenceContext(unitName="OperationsAPI")
private EntityManager em;
public List<Operation> getOperationsAll() {
logger.info("EntityManager: " + em);
TypedQuery<Operation> query = em.createNamedQuery("Operation.findAll", Operation.class);
return query.getResultList();
}
}
You typically don't want to mix use of both the new operator and also dependency injection (CDI, etc.) to set the same object references in a given class.
If your dependency graph is mostly using dependency injection then dependency injection (DI) should be instantiating all the objects. Otherwise you end up with the case that you create an object instance that DI doesn't know about, so it doesn't know to inject its dependencies into.
This is probably what's happening in your case. Since these EJB instances are pooled, you may end up with some of your instances having been initialized correctly, and some not.
You probably want to change to just (or remove and default):
public OperationsService() {}
I'll mention I'm not sure injecting into a static field is a good idea, but I'm not really enough of an expert to suggest removing the static modifier from operationDAO.

Unsatisfied dependencies with Weld during integration testing

I am able to deploy a RESTEasy application working well with Weld (meaning my CDI works) but I am having some trouble with my integration tests. I get this error:
org.jboss.weld.exceptions.DeploymentException:
WELD-001408: Unsatisfied dependencies for type SomeService with qualifiers #Default
while testing:
#RunWith(WeldJUnit4Runner.class)
public class SomeServiceIT {
#Inject
private SomeService service;
#Test
public void test() {
System.out.println(service);
}
}
The last message in my logs is
DEBUG::WELD-000100: Weld initialized. Validating beans
Content of src/test/resources/META-INF/beans.xml:
<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>
By the way I tried the cdi-unit library and it works, but I need to use my own WeldJUnit4Runner which is currently:
public class WeldJUnit4Runner extends BlockJUnit4ClassRunner {
private final Weld weld;
private final WeldContainer container;
public WeldJUnit4Runner(Class<?> klass) throws InitializationError {
super(klass);
this.weld = new Weld();
this.container = weld.initialize();
}
#Override
protected Object createTest() throws Exception {
return container.instance().select(getTestClass().getJavaClass()).get();
}
}
I use weld-se 2.4.1.Final for testing.
Thanks.
EDIT:
So it seems like Weld only looks into src/test/java (when I copy SomeService over to src/test/java it woks). This is silly, I am not going to duplicate all my classes to test them... How to tell Weld to retrieve classes from src/main/java?
So I was able to make it work by creating src/main/resources/META-INF/beans.xml in addition to the existing src/main/webapp/WEB-INF/beans.xml and src/test/resources/META-INF/beans.xml meaning now I have 3 times the exact same file in the same project which I find silly but I guess this is how it is in the Weld world...
Thanks all for your time.
EDIT:
Actually I am able to deploy the application with only src/main/resources/META-INF/beans.xml (I removed src/main/webapp/WEB-INF/beans.xml)
Sorry, I have no solution, but only a small clue: if you want to do some customizations of the BlockJUnit4ClassRunner - why don't you try to extend the org.jglue.cdiunit.CdiRunner or org.apache.deltaspike.testcontrol.api.junit.CdiTestRunner? Or at least take a look at their source code.
Ps. I always find Weld's class-path scanning brittle & error prone. And try to avoid it as much as possible.
It should work so I post here what I did.
Firstly, I use :
Eclipse Luna
JDK 7
The tree of my project is the following one :
Here are my pom dependencies :
<dependency>
<groupId>javax</groupId>
<artifactId>javaee-api</artifactId>
<version>7.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.jboss.weld.se</groupId>
<artifactId>weld-se-core</artifactId>
<version>2.4.1.Final</version>
<scope>test</scope>
</dependency>
The SomeService interface :
package org.jvi.cdirunner;
public interface SomeService {
void test();
}
The SomeServiceImpl implementation :
package org.jvi.cdirunner;
public class SomeServiceImpl implements SomeService {
#Override
public void test() {
// TODO Auto-generated method stub
}
}
And the test to run :
package org.jvi.cdirunner.test;
import javax.inject.Inject;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.jvi.cdirunner.SomeService;
#RunWith(WeldJUnit4Runner.class)
public class SomeServiceIT {
#Inject
private SomeService service;
#Test
public void test() {
System.out.println(service);
}
}
And everything works fine if I run the test under Eclipse. I can't figure out why it doesn't work on your side.

How to execute a jar file on jboss7 startup?

I have a simple java class which displays "waiting" text on execution , in "TMSCore" java project.
package com.stock.bo;
public class example {
/**
* #param args
*/
public static void main(String[] args) {
// ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
System.out.println("================================> waiting");
}
}
I have created TMSCore.jar and have set this example.class as entry point ,of my jar file.
Then i have created a module for this project in C:\Jboss\jboss-as-7.1.1\modules\org\tms\main , and pasted the jar in the same path
then i have created module.xml and pasted in the same path
module.xml
<?xml version="1.0" encoding="UTF-8"?>
<module xmlns="urn:jboss:module:1.1" name="org.tms">
<resources>
<resource-root path="TMSCore.jar"/>
</resources>
</module>
then i have created a jboss-deployment-structure.xml in my webproject/web-inf directory
<?xml version="1.0" encoding="UTF-8"?>
<jboss-deployment-structure>
<deployment>
<dependencies>
<module name="org.tms"/>
</dependencies>
</deployment>
</jboss-deployment-structure>
when i start the server with my war containing above jboss-deployment-structure.xml, in my console its showing deployed TMSCore.jar
but my "waiting" text in my jar is not displayed on console
my requirement is i should get "================================> waiting" on my console once jboss is started up
or else can any one can suggest how to make a jar to execute on starting jboss server?
BTW i am using JBOSS7.1
If I am right it's because JBoss doesn't execute a library, it only loads the classes contained in the jar file. So putting a main function and generating an executable jar will not help.
If your goal is to have an global module on the server, I suggest you these modifications:
Create the module (as you have already done)
Declare it as dependency in jboss-deployment-structure.xml (as you have already done)
Declare it as global module on the server, so it will be loaded only once by JBoss. Edit the configuration file standalone.xml and modify the section:
<subsystem xmlns="urn:jboss:domain:ee:1.0">
<global-modules>
<module name="org.tms" />
</global-modules>
</subsystem>
Now you have a module that have classes loaded only once. I you need to have only one instance of your Example class, the I suggest you to use an singleton:
public class Example {
// The only one instance
private static Example instance;
// Private constructor to avoid creation of other instances of this class
private Example()
{
System.out.println("================================> waiting");
}
public static Example getInstance()
{
if(instance == null)
{
instance = new Example();
}
return instance;
}
}
Then to use it in all projects on the server
Example ex = Example.getInstance();
will give you back the existing instance (or create one the first time).
Notice: I can't try, so no guarantee that that will work.
Edit: Maybe a small modification of the Example class can also make it run during the classes loading:
public class Example {
// The only one instance
private static Example instance = new Example();
// Private constructor to avoid creation of other instances of this class
private Example()
{
System.out.println("================================> waiting");
}
public static Example getInstance()
{
return instance;
}
}
Again: not tested.
You can't run a jar, but you can execute a startup method in a singleton.
#Startup
#Singleton
public class FooBean {
#PostConstruct
void atStartup() { ... }
#PreDestroy
void atShutdown() { ... }
}
This will happen at application start up and shutdown. I'd call the function you need from there.
See http://docs.oracle.com/javaee/6/tutorial/doc/gipvi.html

EJB Injection failure on deploy

I've got a problem exxh EJB's.
First of all, my setup: I am using GlassFish & JEE6. I have got a REST-Service packaged as a WAR and a bean packaged as an EJB-Jar. They are not inside an EAR.
The EJB should be used from the REST-WAR via #EJB, but when I try to deploy the WAR, GlassFish shows this error:
Error occurred during deployment:
Exception while deploying the app [exx-upload-1.0] : Cannot resolve reference Local ejb-ref name=com.ex.exx.model.FileUpload/ocr,Local 3.x interface =com.ex.exx.api.IOCRService,ejb-link=null,lookup=,mappedName=,jndi-name=,refType=Session. Please see server.log for more details.
(The EJB was deployed before without any erros).
I have no clue why. Here is the EJB Code:
Interface:
#Local
public interface IOCRService {
public String performOCRonImage(BufferedImage input);
}
and Implementation:
#Stateless
#LocalBean
public class OCRScanner implements IOCRService {
private Logger logger = Logger.getLogger(this.getClass().getName());
private final static String NOT_RECOGNIZED = "Can not regocnize text";
/**
* Default constructor.
*/
public OCRScanner() {
logger.log(Level.INFO, "### OCR SCANNER BUILD" + this);
}
public String performOCRonImage(BufferedImage input) {
logger.log(Level.INFO, "### OCR SCANNER CALLED" + this);
}
...
And here is the important part in the WAR:
public class FileUpload {
private final File PROPERTIES_FILE = new File(
"fileUploadProperties.properties");
private final String PARAMETER_NAME = "file";
private final Logger logger = Logger.getLogger(this.getClass().getName());
#EJB
private IOCRService ocr;
public Response uploadFile(...) {
// do some stuff
logger.log(Level.INFO, "### EJB" + ocr.toString())
}
Anny suggestions? I can not find my failure here.
Solved this, by replaceing #Local with #Remote.
This works, however, I am not satisfied as I do not understand why.
Basically, given the specs (eg. explained in the tutorial), an application can only access other application's EJB, if they are decorated with #Remote.
Thus, you have 3 options:
decorate your EJB with #Remote (what you have done),
package both together inside an ear (as they would reside in the
same application then). But if you intent to deploy them in seperate
applications or even seperate servers, use 1.)
use CDI with #Inject, but this will still only discover the EJB if
either in the same application, or decorated as #Remote if not.
HTH,
Alex
You should not use #EJB if the target is not an EJB. I guess this is your case because you are trying to inject into a class in your WAR.
Instead use:
#Inject
private IOCRService ocr;
Basically, #Inject is better in most cases, because:
it is more typesafe,
it supports #Alternatives
it is aware of the scope of the injected object.
Another solution it's to add #Stateless(name=""), this worked form