Hi, I am using Isis framework with Raspberry PI (RPI) , and use PI4J ( http://pi4j.com ) to read/write GPIO (general input/ouptut pins) and to listen on external events happen on the GPIO pins. E.g. when an button on RPI connected to specific pin is pressed.
The PI4J documentation explains how to do that http://pi4j.com/example/listener.html When my application tries to access Isis persistence layer based on GPIO event, I get next exception: [main] INFO org.eclipse.jetty.server.Server - Started @39099ms Exception in thread "pi4j-gpio-event-executor-0" java.lang.RuntimeException: An error occurred while executing code in a temporary session at org.apache.isis.core.runtime.system.session.IsisSessionFactory.doInSession(IsisSessionFactory.java:356) at org.apache.isis.core.runtime.system.session.IsisSessionFactory.doInSession(IsisSessionFactory.java:319) at org.apache.isis.core.runtime.system.session.IsisSessionFactory.doInSession(IsisSessionFactory.java:306) at domainapp.modules.simple.dom.rpi.RaspberryClient.handleGpioPinDigitalStateChangeEvent(RaspberryClient.java:64) at com.pi4j.io.gpio.tasks.impl.GpioEventDispatchTaskImpl.run(GpioEventDispatchTaskImpl.java:66) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) at java.lang.Thread.run(Thread.java:745) Caused by: java.lang.NullPointerException at org.apache.isis.applib.query.QueryAbstract.getResultType(QueryAbstract.java:70) at org.apache.isis.core.runtime.system.persistence.PersistenceQueryFactory.specFor(PersistenceQueryFactory.java:102) at org.apache.isis.core.runtime.system.persistence.PersistenceQueryFactory.createPersistenceQueryFor(PersistenceQueryFactory.java:59) at org.apache.isis.core.runtime.system.persistence.PersistenceSession.createPersistenceQueryFor(PersistenceSession.java:584) at org.apache.isis.core.runtime.system.persistence.PersistenceSession.findInstancesInTransaction(PersistenceSession.java:556) at org.apache.isis.core.runtime.system.persistence.PersistenceSession.allMatchingQuery(PersistenceSession.java:530) at org.apache.isis.core.runtime.services.persistsession.PersistenceSessionServiceInternalDefault.allMatchingQuery(PersistenceSessionServiceInternalDefault.java:171) at org.apache.isis.core.metamodel.services.repository.RepositoryServiceInternalDefault.submitQuery(RepositoryServiceInternalDefault.java:173) at org.apache.isis.core.metamodel.services.repository.RepositoryServiceInternalDefault.allMatches(RepositoryServiceInternalDefault.java:169) at org.apache.isis.core.metamodel.services.repository.RepositoryServiceInternalDefault.allInstances(RepositoryServiceInternalDefault.java:144) at domainapp.modules.simple.dom.rpi.RaspberryClient.lambda$handleGpioPinDigitalStateChangeEvent$0(RaspberryClient.java:66) at org.apache.isis.core.runtime.system.session.IsisSessionFactory$1.call(IsisSessionFactory.java:322) at org.apache.isis.core.runtime.system.session.IsisSessionFactory$1.call(IsisSessionFactory.java:319) at org.apache.isis.core.runtime.system.session.IsisSessionFactory.doInSession(IsisSessionFactory.java:353) ... 7 more I do basically the same as in other situations where I need to get/attach IsisSession, but here I get exception, as I can't create transaction. I guess it has something with the way how PI4J calls event handler, but not sure how to deal with this. Here the piece of code shows RPI integration and event handling (also available in my Github Isis fork. ) It works only on RPI device, so it can't be reproduced in windows environment. I tried also to declare event handler method handleGpioPinDigitalStateChangeEvent as synchronized, but get the same result. Here the domain service where I get the exception - whole example is on my Github Simpleapp fork https://github.com/niv0/isis/tree/rpi4j-integration/example/application/simpleapp/module-simple/src/main/java/domainapp/modules/simple/dom/rpi DomainService(nature = NatureOfService.DOMAIN) @Slf4j public class RaspberryClient implements GpioPinListenerDigital { private GpioController gpio = null; private GpioPinDigitalInput pinPushKey; @PostConstruct @Programmatic public void initializeRpiGpioDevices() { if (gpio == null) { if (!System.getProperty("os.name").startsWith("Linux")) { log.warn("Recognized operating system: " + System.getProperty("os.name") + ",RPI GPIO deactivated"); return; } gpio = GpioFactory.getInstance(); if (gpio == null) { log.warn("RPI GPIO controller initialization failed!"); return; } log.info("RPI GPIO controller initialized"); } pinPushKey = gpio .provisionDigitalInputPin(RaspiPin.getPinByAddress(16), "GPIO_16_PUSH_KEY", PinPullResistance.PULL_UP); // hornPushedKeyListener = new HornPushKeyListener(this); pinPushKey.addListener(this); } @PreDestroy public void shutdown() { if (gpio == null) { return; } log.info("Shutting down RPI GPIO controller"); gpio.shutdown(); } @Override public void handleGpioPinDigitalStateChangeEvent(final GpioPinDigitalStateChangeEvent gpioPinDigitalStateChangeEvent) { log.debug("Push key on GPIO 16, pressed"); IsisContext.getSessionFactory().doInSession(() -> { // just a test to check if we can access to persistence layer when GPIO event handler fired log.info("Found devices" + repositoryService.allInstances(SimpleObject.class).size()); }); } @Inject RepositoryService repositoryService; } Maybe somebody has an idea how to solve this? Thanks,Vladimir
