0

I am trying to inject a service in GeofenceMonitoring class using

@Autowired
private IDeviceService deviceService;

but I am getting a NullPointerException This is the interface of the service and below it's implementation :

IDeviceService

package com.sifast.gpstracking.service;

import java.util.List;

import org.springframework.transaction.annotation.Transactional;

import com.sifast.gpstracking.model.Device;
import com.sifast.gpstracking.service.util.IGenericService;

@Transactional
public interface IDeviceService extends IGenericService<Device, Integer> {
    Device findDeviceByUniqueId(String uniqueId);

    List<Device> findAllDevice();

}

DeviceService

package com.sifast.gpstracking.service.impl;

import java.io.Serializable;
import java.util.List;

import org.hibernate.Query;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.sifast.gpstracking.dao.impl.DeviceDao;
import com.sifast.gpstracking.model.Device;
import com.sifast.gpstracking.service.IDeviceService;
import com.sifast.gpstracking.service.util.GenericService;

@Service("deviceService")
public class DeviceService extends GenericService<Device, Integer> implements IDeviceService, Serializable {
    private static final long serialVersionUID = 1L;
    @Autowired
    private DeviceDao deviceDao;

    @Override
    public Device findDeviceByUniqueId(String uniqueId) {
        Query query = deviceDao.getSession().getNamedQuery("findDeviceByUniqueId").setString("uniqueId", uniqueId);
        return deviceDao.findOne(query);
    }

    @Override
    public List<Device> findAllDevice() {

        return deviceDao.findAll(Device.class);
    }
}

And here when I try to inject the service : GeofenceMonitoring

package com.sifast.gpstracking.webServiceRest;

import java.util.ArrayList;
import java.util.List;

import org.primefaces.model.map.LatLng;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.ComponentScan;

import com.sifast.gpastracking.monitoring.IMonitor;
import com.sifast.gpstracking.model.Device;
import com.sifast.gpstracking.model.Geofence;
import com.sifast.gpstracking.model.GeofenceDevice;
import com.sifast.gpstracking.model.Point;
import com.sifast.gpstracking.push.DevicePositionData;
import com.sifast.gpstracking.service.IDeviceService;
import com.sifast.gpstracking.service.util.IntersectionGeofence;

@ComponentScan("com.sifast.gpstracking")
public class GeofenceMonitor implements IMonitor {
    ArrayList<Geofence> geofences = new ArrayList<Geofence>();
    GeofenceDevice geofenceDevice;
    Boolean geofenced=false;

    public static final Logger logger = LoggerFactory.getLogger(GeofenceMonitor.class);

    @Autowired
    private IDeviceService serviceDevice;

    public GeofenceMonitor() {
    }

    @Override
    public void updateMonitor(DevicePositionData devicePositionData) {


        //logger.debug("DEVICE ID = " + devicePositionData.getUniqueId());
        Device device = serviceDevice.findDeviceByUniqueId(devicePositionData.getUniqueId());
        LatLng currentPosition = new LatLng(devicePositionData.getLatitude(), devicePositionData.getLongitude());

        for (GeofenceDevice geofenceDevice : device.getListGeofenceDevice()) {
           List<LatLng> listPoint = convertListPointToListLatLng(geofenceDevice.getGeofence().getListPoint());
           logger.debug("SIZE =====> "+listPoint.size());
           if (IntersectionGeofence.isPointInsidePolygon(currentPosition, listPoint))
           {
               geofenced = true;
               logger.debug("Le device " + devicePositionData.getDeviceName() + " a dépassé la zone limitée");
               break;
           }
        } 

    }

    private List<LatLng> convertListPointToListLatLng(List<Point> listPoint)
    {
        List<LatLng> listLatLng = new ArrayList<LatLng>();
        for (Point point : listPoint){
            listLatLng.add(new LatLng(point.getLatitude(),point.getLongitude()));
        }
        return listLatLng;
    }

}

And finally ApplicationContext.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop"
    xmlns:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:mvc="http://www.springframework.org/schema/mvc"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.2.xsd
          http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.2.xsd
          http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.2.xsd
          http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd
          http://www.springframework.org/schema/mvc
          http://www.springframework.org/schema/mvc/spring-mvc.xsd">

    <mvc:annotation-driven />

    <!-- Activates scanning of annotations -->
    <context:component-scan base-package="com.sifast.gpstracking" />
    <context:annotation-config/>
    <context:spring-configured/>

    <!-- Database Configuration -->
    <import resource="/database/dataSource.xml" />
    <import resource="/database/hibernate.xml" />

    <!-- Transaction Manager is defined -->
    <bean id="txManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager">
        <property name="sessionFactory" ref="sessionFactory" />
    </bean>

    <!-- Enable the configuration of transactional behavior based on annotations -->
    <tx:annotation-driven transaction-manager="txManager" />
    <mvc:annotation-driven></mvc:annotation-driven>
    <!-- Pour avoir accès au resources comme les fichiers /js et /css lorsqu'on utilise un mapping / avec le servletDispatcher dans le web.xml -->
    <mvc:resources mapping="/css/**" location="/resources/css/" /> 
    <mvc:resources mapping="/images/**" location="/resources/images/" /> 

    <!-- Init DataBase -->
    <bean id="dbInit"
        class="org.springframework.jdbc.datasource.init.ResourceDatabasePopulator">
        <property name="scripts">
            <list>
                <value>classpath:sql/1.0.0/CreateData.sql</value>
            </list>
        </property>
        <property name="continueOnError" value="true" />
    </bean>

    <bean id="startupScripts"
        class="org.springframework.jdbc.datasource.init.DataSourceInitializer">
        <property name="dataSource">
            <ref bean="dataSource" />
        </property>
        <property name="databasePopulator">
            <ref bean="dbInit" />
        </property>
    </bean>

</beans>
  • Can you provide the stack trace please? Is the npe occurring on startup (I expect) or invocation? – RobP Apr 07 '16 at 10:19
  • @RobP it's happening on invocation, this is a link for the stack trace because it's too long : http://pasted.co/51914f25 – Ghassen Khalil ATI Apr 07 '16 at 10:27
  • Thanks. What's line 42 of GeofenceMonitor.java? Is it: 'Device device = serviceDevice.findDeviceByUniqueId(devicePositionData.getUniqueId());'? And, just to confirm, is it serviceDevice here that's null? – RobP Apr 07 '16 at 10:33
  • Line 42 is : `LatLng currentPosition = new LatLng(devicePositionData.getLatitude(), devicePositionData.getLongitude());` Yes `serviceDevice` is null – Ghassen Khalil ATI Apr 07 '16 at 10:39

3 Answers3

0

It's because that IDeviceService is an interface. Spring won't know which instance you want to autowire, since the default way to autowire is byType, if I'm not wrong.

Try this

@Autowired
@Qualifier("deviceService")
private IDeviceService deviceService;

try double stars first

<context:component-scan base-package="com.sifast.gpstracking.**" />

An simple example to get bean via applicationContext.getBean()

http://www.mkyong.com/spring/quick-start-maven-spring-example/

And you want to get it in web environment, you can inject it.

How to inject ApplicationContext itself

Community
  • 1
  • 1
Duncan
  • 696
  • 1
  • 5
  • 15
  • It's only necessary to add a qualifier if there is more than one implementation of the interface available via component scan. – RobP Apr 07 '16 at 10:17
  • I still get `NullPointerException` even with that. – Ghassen Khalil ATI Apr 07 '16 at 10:20
  • @RobP there is only one implementation of that interface – Ghassen Khalil ATI Apr 07 '16 at 10:20
  • have you tried to get it via applicationContext.getBean() ? – Duncan Apr 07 '16 at 10:22
  • @BlitheHuang I changed the base-package but it's the same problem, I didn't tried via applicationContext.getBean() could you please tell me how to implement it ? (I am new to Spring) – Ghassen Khalil ATI Apr 07 '16 at 10:33
  • @BlitheHuang I think I should use applicationContext.getBean() only when creating manually my beans in the xml file right ? In my case I am using annotations ! (double stars didn't worked too) – Ghassen Khalil ATI Apr 07 '16 at 11:13
  • I know, I told you to use applicationContext.getBean() is just for testing. – Duncan Apr 07 '16 at 14:27
  • If you can't even get beans via applicationContext.getBean(), that means 1. you applicationContext may not be set up. or 2. you didn't create the "deviceService" bean at all. Try declare "deviceService" in xml as. – Duncan Apr 07 '16 at 14:31
  • Well I think that "beanService" bean is already created because I am using it in an other class annotated by @Service and the injection works fine ! That's why I am wondering – Ghassen Khalil ATI Apr 08 '16 at 08:25
  • I found out that the problem is with an Instance of GeofenceMonitor that I am creating with : `private static ArrayList monitors; static { monitors = new ArrayList(); monitors.add(new SpeedMonitor()); monitors.add(new GeofenceMonitor()); }` – Ghassen Khalil ATI Apr 08 '16 at 09:08
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/108607/discussion-between-ghassen-khalil-ati-and-blithe-huang). – Ghassen Khalil ATI Apr 08 '16 at 09:09
0

Is your GeofenceMonitor bean registered in the application context ? From your code snippets its missing streotype annotations (@Component / @Service etc) So it wont be auto detected and any specified dependencies wont be injected. Change @ComponentScan("com.sifast.gpstracking") public class GeofenceMonitor implements IMonitor to @Component public class GeofenceMonitor implements IMonitor

ekem chitsiga
  • 5,523
  • 2
  • 17
  • 18
0

the problem was that I am creating a new instance of GeofenceMonitor with new GeofenceMonitor() in a service class that's meant to handle the web service invokation. So I modified it to @Scope("singleton") and added @PostConstruct private void init(). Below is my code:

PositionNotification (web service class)

@Service("positionNotification")
@Path("/positionNotification")
@Scope("singleton")
public class PositionNotification implements Serializable, IMonitorable {
    private static final long serialVersionUID = 1L;

    @Autowired
    private GeofenceMonitor geofence;



    private static ArrayList<IMonitor> monitors;
    /*static {
        monitors = new ArrayList<IMonitor>();
        monitors.add(new SpeedMonitor());
        monitors.add(geofence);
    }*/


    @Autowired
    private IDeviceService deviceService;
    @Autowired
    private IPositionService positionService;
    private final static String CHANNEL = "/notify";
    public static final Logger logger = LoggerFactory.getLogger(PositionNotification.class);
    private static final int STATUS_OK = 200;



    @PostConstruct
    private void init(){
        monitors = new ArrayList<IMonitor>();
        monitors.add(new SpeedMonitor());
        monitors.add(geofence);
    }


    @POST
    @Path("/getGeoLocFromDevice")
    public Response test(@FormParam("LATITUDE") String latitude, @FormParam("LONGITUDE") String longitude, @FormParam("DEVICE_ID") String uniqueId,
            @FormParam("SPEED") String speed, @FormParam("Horodateur") String date) {

        logger.debug("X long: " + latitude + " __ Y lat: " + longitude + " uniqueId  " + uniqueId + " " + date);
        Device device = deviceService.findDeviceByUniqueId(uniqueId);
        if (device != null) {
            if (speed == null) {
                speed = "0";
            }

            String address = AddressResolver.AddressReseolve(latitude, longitude);
            DevicePositionData devicePositionData = new DevicePositionData();

            devicePositionData.setLatitude(Double.valueOf(latitude));
            devicePositionData.setLongitude(Double.valueOf(longitude));
            devicePositionData.setUniqueId(uniqueId);
            devicePositionData.setAddress(address);
            devicePositionData.setDeviceName(device.getName());

            devicePositionData.setSpeed(Double.parseDouble(speed));
            devicePositionData.setIcon(device.getType().getIconActive());

            Position position = new Position();
            position.setAddress(address);
            position.setLatitude(Double.valueOf(latitude));
            position.setLongitude(Double.valueOf(longitude));
            if (date != null) {
                try {
                    position.setDatePosition(new SimpleDateFormat("dd-MM-yyyy HH:mm:ss").parse(date));
                    devicePositionData.setDatePosition(date);
                    device.setLastUpdate(new SimpleDateFormat("dd-MM-yyyy HH:mm:ss").parse(date));
                } catch (ParseException e) {
                    e.printStackTrace();
                }
            } else {
                position.setDatePosition(new Date());
                devicePositionData.setDatePosition(new SimpleDateFormat("dd-MM-yyyy HH:mm:ss").format(new Date()));
                device.setLastUpdate(new Date());
            }

            position.setSpeed(Double.parseDouble(speed));
            position.setDevice(device);
            positionService.saveOrUpdateService(position);

            deviceService.saveOrUpdateService(device);

            if (EventBusFactory.getDefault() != null) {
                EventBus eventBus = EventBusFactory.getDefault().eventBus();
                eventBus.publish(CHANNEL, devicePositionData);
            }
            notifyMonitors(devicePositionData);
        }

        return Response.status(STATUS_OK).build();
    }

    @Override
    public void notifyMonitors(DevicePositionData devicePositionData) {
        for (IMonitor monitor : monitors) {
            monitor.updateMonitor(devicePositionData);
        }

    }

    @Override
    public void addMonitor(IMonitor monitor) {
        monitors.add(monitor);
    }

    @Override
    public void deleteMonitor(IMonitor monitor) {
        monitors.remove(monitor);

    }

    @Override
    public void clearMonitors() {
        monitors.clear();
    }
}
sunleo
  • 10,589
  • 35
  • 116
  • 196