When i try to use #Inject to inject my DAO class, in a manager to make it able to give a gson file to a current address i get this exception when i go to the specific web address.Can someone explain me what is the problem. I thought that the problem come maybe from the #Inject and it does not work correctly, but i am not sure.
java.lang.RuntimeException: org.apache.cxf.interceptor.Fault: Cannot obtain a free instance.; nested exception is:
javax.enterprise.inject.UnsatisfiedResolutionException: Api type [cinema.dao.ProjectionDAO] is not found with the qualifiers
Qualifiers: [#javax.enterprise.inject.Default()]
for injection into Field Injection Point, field name : projectionDAO, Bean Owner : [ProjectionManager, Name:null, WebBeans Type:DEPENDENT, API Types:[cinema.services.ProjectionManager,java.lang.Object], Qualifiers:[javax.enterprise.inject.Any,javax.enterprise.inject.Default]] while invoking public java.util.Collection cinema.services.ProjectionManager.getAllProjections() with params [].
org.apache.cxf.interceptor.AbstractFaultChainInitiatorObserver.onMessage(AbstractFaultChainInitiatorObserver.java:116)
org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:324)
org.apache.cxf.transport.ChainInitiationObserver.onMessage(ChainInitiationObserver.java:121)
org.apache.cxf.transport.http.AbstractHTTPDestination.invoke(AbstractHTTPDestination.java:240)
org.apache.openejb.server.cxf.rs.CxfRsHttpListener.onMessage(CxfRsHttpListener.java:187)
org.apache.openejb.server.rest.RsServlet.service(RsServlet.java:53)
javax.servlet.http.HttpServlet.service(HttpServlet.java:727)
org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
Code for the manager:
package cinema.services;
import java.util.Collection;
import javax.ejb.Stateless;
import javax.inject.Inject;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import cinema.dao.ProjectionDAO;
import cinema.model.Projection;
#Stateless
#Path("projection")
public class ProjectionManager {
#Inject
private ProjectionDAO projectionDAO;
#GET
#Produces("application/json")
public Collection<Projection> getAllProjections(){
return projectionDAO.getAllProjections();
}
}
Here is the ProjectionDAO:
package cinema.dao;
import java.util.Collection;
import javax.inject.Singleton;
import javax.persistence.EntityManager;
import javax.persistence.NoResultException;
import javax.persistence.PersistenceContext;
import cinema.model.Projection;
import cinema.model.User;
#Singleton
public class ProjectionDAO {
#PersistenceContext
private EntityManager em;
public Collection<Projection> getAllProjections(){
return em.createNamedQuery("getAllProjections", Projection.class).getResultList();
}
public void addProjection(Projection projection){
em.persist(projection);
}
public Projection findProjectionByMovieTitle(String movieTitle){
try {
return em.createNamedQuery("getProjectionByMovieTitle", Projection.class)
.setParameter("movieTitle", movieTitle).getSingleResult();
} catch (NoResultException e){
return null;
}
}
public void buyTicket(Projection projection, User user){
Projection foundProjection = findProjectionByMovieTitle(projection.getMovieTitle());
if(foundProjection != null){
user.getCurrentProjections().add(projection);
int newFreeSpaces = foundProjection.getFreeSpaces() - 1;
foundProjection.setFreeSpaces(newFreeSpaces);
}
}
}
Projection is a simple model which give the movieTitle and start time of different projections in a cinema.
Your question doesn't state important information such as versions in use or how you're deploying, so I'm going to take a wild stab.
You're not including a beans.xml file in your deployment. I'm not sure though if you're deploying a WAR or a JAR file.
Assuming you have a properly placed beans.xml file, try swapping the #Singleton with an #ApplicationScope. This should more correctly discover your class.
Related
I'm checking out some of Spring Integration with GCP pub sub and I've cloned their sample project. I'm getting a warning / error in my IDE which I'm struggling to understand.
Basically in this class https://github.com/spring-cloud/spring-cloud-gcp/blob/6c95a16f7e6ad95404b4f992b5f46340e831e5cb/spring-cloud-gcp-samples/spring-cloud-gcp-integration-pubsub-json-sample/src/main/java/com/example/WebController.java#L47
package com.example;
import java.util.ArrayList;
import java.util.List;
import com.example.SenderConfiguration.PubSubPersonGateway;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.servlet.view.RedirectView;
/**
* Provides REST endpoint allowing you to send JSON payloads to a sample Pub/Sub topic for
* demo.
*
* #author Daniel Zou
*/
#RestController
public class WebController {
private final PubSubPersonGateway pubSubPersonGateway;
#Autowired
#Qualifier("ProcessedPersonsList")
private ArrayList<Person> processedPersonsList;
public WebController(PubSubPersonGateway pubSubPersonGateway, SenderConfiguration.PubSubProjectGateway pubSubProjectGateway ) {
this.pubSubPersonGateway = pubSubPersonGateway;
}
#PostMapping("/createPerson")
public RedirectView createUser(#RequestParam("name") String name, #RequestParam("age") int age) {
Person person = new Person(name, age);
this.pubSubPersonGateway.sendPersonToPubSub(person);
return new RedirectView("/");
}
#GetMapping("/listPersons")
public List<Person> listPersons() {
return this.processedPersonsList;
}
}
I have the following error
Could not autowire. No beans of 'PubSubPersonGateway' type found.
Could someone please explain why I'm getting this error / warning and if its something I need to be concerned with? FYIW, The project will compile and run correctly
This is just an IDE inspection issue, nothing more. That PubSubPersonGateway is a special #MessagingGateway bean which is not understood by IDE. Probably better to raise an improvement ticket against that IDE to let them know that Spring Integration inspection should be improved.
i'm trying to inject services in Web service Class like this
package com.mobinets.web.nep.backend.soapControllers;
import javax.jws.WebMethod;
import javax.jws.WebParam;
import javax.jws.WebService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.context.support.SpringBeanAutowiringSupport;
import com.mobinets.web.nep.backend.data.entity.Router;
import com.mobinets.web.nep.backend.data.entity.Version;
import com.mobinets.web.nep.backend.services.RouterService;
import com.mobinets.web.nep.backend.services.VersionService;
#Service
#WebService
public class RouterSoapService extends SpringBeanAutowiringSupport{
#Autowired
private RouterService routerService;
#Autowired
private VersionService versionService;
#WebMethod
public String getRouter(#WebParam int objectId, #WebParam String versionName) {
Version version = versionService.findByName(versionName);
Router router = routerService.findByObjectIdAndVersion(objectId, version.getId());
return router.getName();
}
}
I extended the class from SpringBeanAutowiringSupport and add #Service annotation,
it keeps giving me null on versionService and routerService,
am I missing something ?
Only reason I can think of would be if either of the services
are missing one of the #Component stereotypes (you say they both have #Service
so this should be fine) or
if they rely on any other components which aren't autowired for example if
either has a repository which has been instantiated with the new keyword
they would be excluded from autowiring
I have a plain POJO being autowired in Spring whose properties appear to persist.
I find that the happy path is OK - Set bean properties and return then, however when I'm not on the happy path and I no longer wish to set a property (in this case responseCode), I find it is still set to the previous value (when a call was successful).
I would like this value to not be set and be equal to what I have currently specified in the model.
I have the following POJO Prototype bean
package com.uk.jacob.model;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
#Component
#Scope("prototype")
public class Website {
public String url;
public boolean response;
public int responseCode = 0;
}
I am setting it's information within a service class
package com.uk.jacob.service;
import java.net.HttpURLConnection;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import com.uk.jacob.adapter.HttpAdapter;
import com.uk.jacob.model.Website;
#Component
public class PingerService {
#Autowired
HttpAdapter httpAdapter;
#Autowired
Website website;
public Website ping(String urlToPing) {
website.url = urlToPing;
try {
HttpURLConnection connection = httpAdapter.createHttpURLConnection(urlToPing);
website.response = true;
website.responseCode = connection.getResponseCode();
} catch (Exception e) {
website.response = false;
}
return website;
}
}
Which is called from a RestController
package com.uk.jacob.controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import com.uk.jacob.model.Website;
import com.uk.jacob.service.PingerService;
#RestController
#RequestMapping("api/v1/")
public class PingController {
#Autowired
PingerService pingerService;
#RequestMapping(value = "ping", method = RequestMethod.GET)
public Website getPing(#RequestParam String url){
return pingerService.ping(url);
}
}
The fact that your Website bean is #Scope("prototype") means that every time that it gets injected as a dependency in another bean upon this bean's creation, a new instance gets created and injected. In this case PingerService gets a new instance of Website. If say Website is also injected on another bean called Website2 then a different (new) instance gets injected.
If your anticipation is Website to be new upon each invocation within Website then this cannot be done simply with the prototype annotation. You'll need to expose the context and invoke ApplicationContext#getBean("website").
For your use case, I understand that you need a fresh instance of Website bean for every request.
Use #Scope("request").
Prototype scope on the other hand means it will be creating a separate instance for every Autowiring of Website it sees everywhere. For example, PingerService will have its own Website bean and won't be shared on other classes with the same Autowiring but its values will persist across http requests on PingerService.
I read a lot about this kind of problem here, but it seems my code is good but the autowire is not working :
Error creating bean with name 'optionController': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private service.InteractionBanque controllers.OptionController.interactionBanque; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [service.InteractionBanque] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {#org.springframework.beans.factory.annotation.Autowired(required=true)}
Here is the code of my Controller :
package controllers;
package controllers;
import javax.annotation.Resource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import model.Banque;
import model.Client;
import service.InteractionBanque;
import serviceimpl.InteractionBanqueImpl;
#Controller
public class OptionController {
#Autowired
private InteractionBanque interactionBanque;
#RequestMapping(value="/virement",method=RequestMethod.GET)
public String index(Model model, #ModelAttribute Client client) {
model.addAttribute("virement", new Virement());
return "virement";
}
#RequestMapping(value="/virement",method=RequestMethod.POST)
public String index(#ModelAttribute Virement virement, Model model) {
return "options";
}
}
And the Code of my Service :
package serviceimpl;
import java.util.HashMap;
import org.json.simple.JSONArray;
import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser;
import org.json.simple.parser.ParseException;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;
import com.fasterxml.jackson.databind.annotation.JsonPOJOBuilder;
import dao.BanqueDAO;
import daoimpl.BanqueDaoImpl;
import model.Banque;
import model.Client;
import service.InteractionBanque;
import utils.SendRequest;
#Service
public class InteractionBanqueImpl implements InteractionBanque {
public static final int END_ID_BANQUE = 5;
public static final String LOGIN_URL = "/account";
public boolean connecter(Client client) {
some code
}
}
And The code of the interface :
package service;
public interface InteractionBanque {
boolean connecter(Client client);
}
And my Application class define the #SpringBootApplication which should be use to wire everything :
package controllers;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.ComponentScan;
#SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
SO I don't get it, for me this should do the work but the autowired is not working.
Help would be appreciated :)
#SpringBootApplication scans only package (recursively) within a class that uses it. InteractionBanqueImpl is in another package.
Create a package 'app' with Application class, and then move to it controllers and and other packages. Should be fine.
As #Mati said, you have a problem with packages.
Create a root package for your application and move everything under it, so you have it something like this:
+ myapp
Application.java
+ controller
+ service
+ serviceimpl
The answers you have about putting your Application class in a parent package of the rest of your code will work, but an alternative, if you don't want to change your package structure, would be to use the #ComponentScan annotation, specifying the packages that contain components you want to autowire, for example:
#ComponentScan(basePackages = {"serviceimpl", ...}
i'm absolutely baffled. I have a standard, old school EJB-CDI-JSF-Hibernate JavaEE Application, running on a JBoss AS 7.1. Furthermore my structure is an absolut standard structure. I have JSF-Sites, which access my CDI Beans. The CDI Beans are holding a reference to one of my entities, the EJBs are used as DAOs. One of my beans is this CommissionController. It works absolutely fine. Only one instance is created for one user.
package controller;
import java.io.Serializable;
import java.util.Date;
import javax.annotation.PostConstruct;
import javax.enterprise.context.SessionScoped;
import javax.inject.Inject;
import javax.inject.Named;
import lombok.Data;
import lombok.extern.java.Log;
import entities.Commission;
#SessionScoped
#Data
#Log
#Named
public class CommissionController implements Serializable {
private static final long serialVersionUID = -8452887234021054225L;
#Inject
private UserController userController;
#Inject
private CartController cartController;
private Commission commission;
#PostConstruct
public void init() {
commission = new Commission();
log.info("new CommissionController instance");
}
public void makeNewCommission() {
commission.setCart(cartController.getCart());
commission.setOrderDate(new Date());
commission.setOrderer(userController.getUser());
cartController.clearCart();
log.info(commission.toString());
}
}
Now i have a different bean, but it think it's the excact same structure:
package controller;
import java.io.Serializable;
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import javax.enterprise.context.SessionScoped;
import javax.inject.Inject;
import javax.inject.Named;
import lombok.Data;
import lombok.extern.java.Log;
import entities.Article;
import entities.Cart;
#SessionScoped
#Data
#Log
#Named
public class CartController implements Serializable {
private static final long serialVersionUID = 649140288918816488L;
#Inject
private UserController userController;
#Inject
private ArticleController articleController;
private Cart cart;
public void addToCart(Article article) {
cart.getArticleList().add(article);
cart.setSum(cart.getSum() + article.getPrice());
}
public void clearCart() {
cart.getArticleList().clear();
cart.setSum(0.0);
}
#PreDestroy
public void destroy() {
log.info("bean destroyed");
}
#PostConstruct
public void init() {
cart = new Cart();
log.info("new CartController instance");
}
public void removeFromCart(Article article) {
cart.getArticleList().remove(article);
cart.setSum(cart.getSum() - article.getPrice());
}
}
I can't explain it to myself, but the second bean is instanciated again and again and I can't store anything in it, because it get always a reference to another bean.
Please, help me to bring light in this mystery. If you need additional information, I would love to give it to you. Maybe, I have a big lack of understanding but for now, I can't help myself.
Gimby gave me the answer to this question. In fact, JBoss AS 7.1.0 Community Edition is outdated. With WildFly 8.0.0 Final, everything worked perfectly fine. So, if you're working with the fantastic possibilities of CDI, try WildFly instead of JBoss AS 7.1.0 Final Community.