Tom Tom - 1 month ago 12
Java Question

CDI @Inject won't work, object stays null | CDI/JavaEE - payara server - Netbeans

I am trying to use CDI, using

@Inject
for dependency injection but my object stays
null
and won't initialze... more precisely:
I have a webapplication with
WeatherController
wich use a java application with all my modules. In the Java application I have a
ForecastService
where I try to initialize my repositories with CDI without succes ...
I tried/searched alot .. Hopefully somebody can help me here ?

I have a web application wich use this controller:

@Path("/weather")
public class WeatherController {

private ForecastService forecastService;
//private ForecastRepository forecastRepository = new ForecastFakeDB();
//private ObservationRepository observationRepository = new ObservationFakeDB();

public WeatherController() {
//this.forecastService.setForecastRepository(forecastRepository);
//forecastService.setObservationRepository(observationRepository);
forecastService = new ForecastService();
}

//localhost:8080/DA_project_weatherPredictions/api/weather/observation/Leuven
@GET
@Produces({"application/json"})
@Path("/observation/{location}")
public Response getObservation(@PathParam("location") String location) {
try {
ObjectMapper mapper = new ObjectMapper();
Observation observation = forecastService.getCurrentObservation(location);
//Object to JSON in String
String jsonInString = mapper.writeValueAsString(observation);
return Response.status(200).entity(jsonInString).build();
} catch (Exception ex) {
System.out.println("error");
System.out.println(ex.getMessage());
ex.printStackTrace();
return null;
}
}


This works perfectly. This is my forecastService:

public class ForecastService implements Service {

@Inject
ForecastRepository forecastRepository;

@Inject
ObservationRepository observationRepository;

private Client client;
private WebTarget webTargetObservation, webTargetForecast;

public ForecastService() {
// WeatherRepositoryFactory weatherRepositoryFactory = new WeatherRepositoryFactory();
// forecastRepository = weatherRepositoryFactory.getForecastRepository(repository);
// observationRepository = weatherRepositoryFactory.getObservationRepository(repository);
loadWeather();
}

public void setForecastRepository(ForecastRepository forecastRepository) {
this.forecastRepository = forecastRepository;
}

public void setObservationRepository(ObservationRepository observationRepository) {
this.observationRepository = observationRepository;
}

public void loadWeather() {
//http://api.openweathermap.org/data/2.5/weather?units=metric&appid=12fa8f41738b72d954b6758d48e129aa&q=BE,Leuven
//http://api.openweathermap.org/data/2.5/forecast?units=metric&appid=12fa8f41738b72d954b6758d48e129aa&q=BE,Leuven
client = ClientBuilder.newClient();
webTargetObservation = client.target("http://api.openweathermap.org/data/2.5/weather")
.queryParam("mode", "json")
.queryParam("units", "metric")
.queryParam("appid", "12fa8f41738b72d954b6758d48e129aa");
webTargetForecast = client.target("http://api.openweathermap.org/data/2.5/forecast")
.queryParam("mode", "json")
.queryParam("units", "metric")
.queryParam("appid", "12fa8f41738b72d954b6758d48e129aa");
}

public Observation getCurrentObservation(String location) throws Exception {
Observation observation;
observation = observationRepository.getObservation(location);
if (observation == null) {
try {
//observation = webTargetObservation.queryParam("q", location).request(MediaType.APPLICATION_JSON).get(Observation.class);
Response response = webTargetObservation.queryParam("q", location).request(MediaType.APPLICATION_JSON).get();
String json = response.readEntity(String.class);
//System.out.println(json);
response.close();
observation = new ObjectMapper().readValue(json, Observation.class);
//System.out.println(observation.getWeather().getDescription());
}
catch (Exception e){
StringBuilder sb = new StringBuilder(e.toString());
for (StackTraceElement ste : e.getStackTrace()) {
sb.append("\n\tat ");
sb.append(ste);
}
String trace = sb.toString();
throw new Exception (trace);
//throw new Exception("Location not found");
}
this.observationRepository.addObservation(observation, location);
}
return observation;
}


So the problem is that my repositories stay
null


@Alternative
public class ObservationDB implements ObservationRepository{

//as ID we can use the ASCI value of the String key .. example uklondon to ASCII

public ObservationDB(String name) {

}

@Override
public Observation getObservation(String location) {
throw new UnsupportedOperationException("Not supported yet.");
}

@Override
public void addObservation(Observation observation, String location) {
throw new UnsupportedOperationException("Not supported yet.");
}

}


Mermory DB:

@Default
public class ObservationFakeDB implements ObservationRepository {

//example String key : beleuven, uklondon
private static Map<String, Observation> observations;

public ObservationFakeDB() {
observations = new HashMap<>();
}

@Override
public Observation getObservation(String location) {
return observations.get(location);
}

@Override
public void addObservation(Observation observation, String location) {
observations.put(location, observation);
}
}


I have a beans.xml, I thought beans.xml,
@Inject
,
@Default
en
@Alternative
would make this work ... I tried
@Dependent
,
@Applicationscoped
, ..

Here my map structure:

EDIT:
I also often get this warning on Netbeans ..
enter image description here

My 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"
bean-discovery-mode="all">

</beans>

Answer

You need to let your CDI container manages the lifecycle of all your beans to allow it to resolve and inject properly their dependencies.

So, in your case you should not create yourself the instance of ForecastService, you should rather delegate it to the CDI container by simply annotating the field forecastService with @Inject this way its dependencies will be automatically resolved and set by the container.

public class WeatherController {

    @Inject
    private ForecastService forecastService;

    ...
Comments