title: Struts2 and PI4J
body: <p>I tryied to use a Struts2 web framework with PI4J to change relays status on Rapsberry 3B+ device on Tomcat 9 web container. </p>
  
  <p>My Action class. </p>
  
  <pre><code>    package com.action;
  
      import org.apache.log4j.Logger;
  
      import com.opensymphony.xwork2.ActionSupport;
      import com.pi4j.io.gpio.GpioController;
      import com.pi4j.io.gpio.GpioFactory;
      import com.pi4j.io.gpio.GpioPinDigitalOutput;
      import com.pi4j.io.gpio.PinState;
      import com.pi4j.io.gpio.RaspiPin;
  
  
      public class RelayAction extends ActionSupport  {
          /**
           * 
           */
          private static final long serialVersionUID = 1L;
          final static Logger logger = Logger.getLogger(RelayAction.class);
  
          // create gpio controller
         final GpioController gpio = GpioFactory.getInstance();
  
  
          // provision gpio pin as an output pin and turn on
         final GpioPinDigitalOutput output = gpio.provisionDigitalOutputPin(RaspiPin.GPIO_23, "My Output", PinState.HIGH);
  
         public String on() {
  
              logger.error("Start execute : ");
  
  
              output.setState(PinState.HIGH); // or ... output.high();
  
  
              return SUCCESS;
          }
  
          public String off() {
  
              logger.error("Start execute : ");
  
  
             output.setState(PinState.LOW); // or ... output.high();
  
  
              return SUCCESS;
          }
  
      }
  </code></pre>
  
  <p>My JSP </p>
  
  <pre><code>    &lt;%@ taglib prefix="s" uri="/struts-tags"%&gt;
      &lt;%@ page language="java" contentType="text/html; charset=UTF-8"
          pageEncoding="UTF-8"%&gt;
      &lt;html&gt;
      &lt;head&gt;
      &lt;meta name="viewport" content="width=device-width, initial-scale=1.0"&gt;
      &lt;meta http-equiv="Cache-Control" content="no-cache, no-store, must-revalidate" /&gt;
      &lt;meta http-equiv="Pragma" content="no-cache" /&gt;
      &lt;meta http-equiv="Expires" content="0" /&gt;
      &lt;title&gt;Pokaż temperaturę&lt;/title&gt;
      &lt;style&gt;
      @media only screen and (max-device-width: 400px) {
          html {
              -webkit-text-size-adjust : none;
              text-size-adjust         : none;
          }
          /* adapt the rest of the mobile interface here */
      }
      &lt;/style&gt;
      &lt;/head&gt;
      &lt;body&gt;
          &lt;h2&gt;Przekaznik&lt;/h2&gt;
          &lt;s:form action="relayAction" method="post"&gt;
  
  
  
          &lt;s:submit value="ON" align="center" method="on" /&gt;
          &lt;s:submit value="OFF" align="center" method="off"/&gt;
          &lt;/s:form&gt;
  
      &lt;/body&gt;
      &lt;/html&gt;
  </code></pre>
  
  <p>When execute I get error type
  Exception report</p>
  
  <p>message Filter execution threw an exception</p>
  
  <pre><code>description The server encountered an internal error that prevented it from fulfilling this request.
  
  exception
  
  javax.servlet.ServletException: Filter execution threw an exception
  root cause
  
  java.lang.UnsatisfiedLinkError: com.pi4j.wiringpi.Gpio.wiringPiSetup()I
      com.pi4j.wiringpi.Gpio.wiringPiSetup(Native Method)
      com.pi4j.io.gpio.RaspiGpioProvider.&lt;init&gt;(RaspiGpioProvider.java:69)
      com.pi4j.io.gpio.RaspiGpioProvider.&lt;init&gt;(RaspiGpioProvider.java:51)
      com.pi4j.platform.Platform.getGpioProvider(Platform.java:125)
      com.pi4j.platform.Platform.getGpioProvider(Platform.java:118)
      com.pi4j.io.gpio.GpioFactory.getDefaultProvider(GpioFactory.java:109)
      com.pi4j.io.gpio.impl.GpioControllerImpl.&lt;init&gt;(GpioControllerImpl.java:53)
      com.pi4j.io.gpio.GpioFactory.getInstance(GpioFactory.java:91)
      com.action.RelayAction.&lt;init&gt;(RelayAction.java:21)
      sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
      sun.reflect.NativeConstructorAccessorImpl.newInstance(Unknown Source)
      sun.reflect.DelegatingConstructorAccessorImpl.newInstance(Unknown Source)
      java.lang.reflect.Constructor.newInstance(Unknown Source)
      java.lang.Class.newInstance(Unknown Source)
      com.opensymphony.xwork2.ObjectFactory.buildBean(ObjectFactory.java:131)
      com.opensymphony.xwork2.ObjectFactory.buildBean(ObjectFactory.java:162)
      com.opensymphony.xwork2.ObjectFactory.buildBean(ObjectFactory.java:151)
      com.opensymphony.xwork2.ObjectFactory.buildAction(ObjectFactory.java:121)
      com.opensymphony.xwork2.DefaultActionInvocation.createAction(DefaultActionInvocation.java:293)
      com.opensymphony.xwork2.DefaultActionInvocation.init(DefaultActionInvocation.java:393)
      com.opensymphony.xwork2.DefaultActionProxy.prepare(DefaultActionProxy.java:194)
      org.apache.struts2.impl.StrutsActionProxy.prepare(StrutsActionProxy.java:63)
      org.apache.struts2.impl.StrutsActionProxyFactory.createActionProxy(StrutsActionProxyFactory.java:39)
      com.opensymphony.xwork2.DefaultActionProxyFactory.createActionProxy(DefaultActionProxyFactory.java:58)
      org.apache.struts2.dispatcher.Dispatcher.serviceAction(Dispatcher.java:534)
      org.apache.struts2.dispatcher.ng.ExecuteOperations.executeAction(ExecuteOperations.java:77)
      org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter.doFilter(StrutsPrepareAndExecuteFilter.java:91)
  </code></pre>
  
  <p>Aditionally I created Java swing application with code and I can change a status of replays with buttons in application.Output when run on Windows.</p>
  
  <pre><code>cze 11, 2020 9:19:28 PM com.pi4j.util.NativeLibraryLoader load
  SEVERE: Unable to load [libpi4j.so] using path: [/lib/raspberrypi/dynamic/libpi4j.so]
  java.lang.IllegalArgumentException: The path has to be absolute, but found: \lib\raspberrypi\dynamic\libpi4j.so
      at com.pi4j.util.NativeLibraryLoader.loadLibraryFromClasspath(NativeLibraryLoader.java:136)
      at com.pi4j.util.NativeLibraryLoader.load(NativeLibraryLoader.java:105)
      at com.pi4j.wiringpi.Gpio.&lt;clinit&gt;(Gpio.java:189)
      at com.pi4j.io.gpio.RaspiGpioProvider.&lt;init&gt;(RaspiGpioProvider.java:69)
      at com.pi4j.io.gpio.RaspiGpioProvider.&lt;init&gt;(RaspiGpioProvider.java:51)
      at com.pi4j.platform.Platform.getGpioProvider(Platform.java:125)
      at com.pi4j.platform.Platform.getGpioProvider(Platform.java:118)
      at com.pi4j.io.gpio.GpioFactory.getDefaultProvider(GpioFactory.java:109)
      at com.pi4j.io.gpio.impl.GpioControllerImpl.&lt;init&gt;(GpioControllerImpl.java:53)
      at com.pi4j.io.gpio.GpioFactory.getInstance(GpioFactory.java:91)
      at main.Main$2.actionPerformed(Main.java:62)
  </code></pre>
  
  <p>Have sombebody use Struts2 with PI4J to change a relays status? </p>
  
  <p>UPDATE: 
  I found this in logs </p>
  
  <p>[2020-06-11 19:08:54] [info] Deploying web application archive [/var/lib/tomcat8/webapps/Relay.war]
  [2020-06-11 19:09:14] [info] At least one JAR was scanned for TLDs yet contained no TLDs. Enable debug logging for this logger for a complete list of JARs that were sc$
  [2020-06-11 19:09:15] [info] Deployment of web application archive [/var/lib/tomcat8/webapps/Relay.war] has finished in [21,194] ms
  [2020-06-11 19:09:24] [info] WARNING: An illegal reflective access operation has occurred
  [2020-06-11 19:09:24] [info] WARNING: Illegal reflective access by ognl.OgnlRuntime (file:/var/lib/tomcat8/webapps/Relay/WEB-INF/lib/ognl-3.0.6.jar) to method java.uti$
  [2020-06-11 19:09:24] [info] WARNING: Please consider reporting this to the maintainers of ognl.OgnlRuntime
  [2020-06-11 19:09:24] [info] WARNING: Use --illegal-access=warn to enable warnings of further illegal reflective access operations
  [2020-06-11 19:09:24] [info] WARNING: All illegal access operations will be denied in a future release
  [2020-06-11 19:09:28] [info] wiringPiSetup: Unable to open /dev/mem or /dev/gpiomem: Brak dostępu.
  [2020-06-11 19:09:28] [info]   Aborting your program because if it can not access the GPIO
  [2020-06-11 19:09:28] [info]   hardware then it most certianly won't work
  [2020-06-11 19:09:28] [info]   Try running with sudo?</p>
  
  <p>Most important is 
  <strong>Unable to open /dev/mem or /dev/gpiomem: No access. Let me check it abd back to you.</strong> </p>
  
  <p>UPDATE: 
  It starst to work by adding user tomcat8 to gpio group</p>
  
  <p>sudo adduser tomcat8 gpio</p>
  
  <p>Thanks for all viewers of my post! </p>
  
  <p>Please let me know. 
  Sławek, </p>