8 Replies Latest reply on Aug 22, 2016 10:22 AM by Alexander Lambley

    Proper way to add .so files to project?

    Alexander Lambley Newbie

      I have a few .so files that my project's .war deployments need to function properly. Now I read through the class-loading page as well as done a few Google searches and there doesn't seem to be much consensus. I've tried...

       

      1. Adding the .so files to a module and including them (Log file complains about not being able to unzip the .so files, I'm guessing that modules are only for .jar files?)

      2. Adding the directory with my .so files to java.library.path and then starting my WildFly server in the same console (WildFly classloader ignores it even though "java -XshowSettings:properties" immediately after closing the server still shows the change)

      3. Adding a -Djava.library.path="mypath" to the end of ./standalone.sh as a command line argument.

       

      None of which have worked thus far. Does anyone have some experience in this area? I'm running WildFly 10 on a Linux system.

        • 1. Re: Proper way to add .so files to project?
          jaikiran pai Master

          Alexander Lambley wrote:

           

          I have a few .so files that my project's .war deployments need to function properly. Now I read through the class-loading page as well as done a few Google searches and there doesn't seem to be much consensus. I've tried...

           

          1. Adding the .so files to a module and including them (Log file complains about not being able to unzip the .so files, I'm guessing that modules are only for .jar files?)


           

          Does this help Native Libraries - JBoss Modules - Project Documentation Editor?

          • 2. Re: Proper way to add .so files to project?
            Alexander Lambley Newbie

            Thanks for the reply jaikiran! I added the .so files to the required module in that format without any luck. I did get some more traction by successfully adding the path to my .so files to java.library.path which solved some problems but now I get a few "Native Library already loaded in another classloader" errors during server startup and I continue to see java.lang.UnsatisfiedLinkError's whenever I try to access functions on my client that require native libraries.

            • 3. Re: Proper way to add .so files to project?
              jaikiran pai Master

              Can you paste us the directory listing of the module to show how it looks like when you added the .so files in there? Also with this setup of the module, can you post the relevant code where you load this library and the complete exception stacktrace that you see when you try to do this?

               

              Which OS are you on? What's the output of

               

              uname -a

              • 4. Re: Proper way to add .so files to project?
                Alexander Lambley Newbie

                Absolutely.

                The directory structure for the module is...

                 

                -modules/

                    -mycompany/

                          -communication/

                              -communication.jar

                              -module.xml

                              -lib/

                                    -linux-x86_64/

                                        -libNativeConnectionManager.so

                 

                Where I load the library (within communication.jar, NativeConnection.java)...

                 

                static

                  {

                        LOG.trace("Loading NativeConnectionManager library");

                        try {

                            System.loadLibrary("NativeConnectionManager");

                        } catch (UnsatisfiedLinkError e) {

                            LOG.warn("UnsatisfiedLinkError loading NativeConnectionManager library in static NativeConnection initializer - " + e.getMessage());

                        }

                        LOG.trace("End Loading NativeConnectionManager library");

                  }

                 

                The function that I use...

                 

                private native boolean sendNativeMessage(byte [] messageToSend);

                 

                The full stacktrace when I try to utilize a function that calls a native function...

                 

                2016-08-10 10:50:15,853 WARNING [org.apache.cxf.phase.PhaseInterceptorChain] (default task-230) Interceptor for {http://myservice.mycompany.com/}myservice#{http://myservice.mycompany.com/}updateComment has thrown exception, unwinding now: org.apache.cxf.interceptor.Fault: mycompany.communication.NativeConnection.sendNativeMessage([B)Z

                  at org.apache.cxf.interceptor.ServiceInvokerInterceptor.handleMessage(ServiceInvokerInterceptor.java:144)

                  at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:308)

                  at org.apache.cxf.transport.ChainInitiationObserver.onMessage(ChainInitiationObserver.java:121)

                  at org.apache.cxf.transport.http.AbstractHTTPDestination.invoke(AbstractHTTPDestination.java:251)

                  at org.jboss.wsf.stack.cxf.RequestHandlerImpl.handleHttpRequest(RequestHandlerImpl.java:108)

                  at org.jboss.wsf.stack.cxf.transport.ServletHelper.callRequestHandler(ServletHelper.java:134)

                  at org.jboss.wsf.stack.cxf.CXFServletExt.invoke(CXFServletExt.java:88)

                  at org.apache.cxf.transport.servlet.AbstractHTTPServlet.handleRequest(AbstractHTTPServlet.java:293)

                  at org.apache.cxf.transport.servlet.AbstractHTTPServlet.doPost(AbstractHTTPServlet.java:212)

                  at javax.servlet.http.HttpServlet.service(HttpServlet.java:707)

                  at org.jboss.wsf.stack.cxf.CXFServletExt.service(CXFServletExt.java:136)

                  at org.jboss.wsf.spi.deployment.WSFServlet.service(WSFServlet.java:140)

                  at javax.servlet.http.HttpServlet.service(HttpServlet.java:790)

                  at io.undertow.servlet.handlers.ServletHandler.handleRequest(ServletHandler.java:85)

                  at io.undertow.servlet.handlers.security.ServletSecurityRoleHandler.handleRequest(ServletSecurityRoleHandler.java:62)

                  at io.undertow.servlet.handlers.ServletDispatchingHandler.handleRequest(ServletDispatchingHandler.java:36)

                  at org.wildfly.extension.undertow.security.SecurityContextAssociationHandler.handleRequest(SecurityContextAssociationHandler.java:78)

                  at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)

                  at io.undertow.servlet.handlers.security.SSLInformationAssociationHandler.handleRequest(SSLInformationAssociationHandler.java:131)

                  at io.undertow.servlet.handlers.security.ServletAuthenticationCallHandler.handleRequest(ServletAuthenticationCallHandler.java:57)

                  at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)

                  at io.undertow.security.handlers.AbstractConfidentialityHandler.handleRequest(AbstractConfidentialityHandler.java:46)

                  at io.undertow.servlet.handlers.security.ServletConfidentialityConstraintHandler.handleRequest(ServletConfidentialityConstraintHandler.java:64)

                  at io.undertow.security.handlers.AuthenticationMechanismsHandler.handleRequest(AuthenticationMechanismsHandler.java:60)

                  at io.undertow.servlet.handlers.security.CachedAuthenticatedSessionHandler.handleRequest(CachedAuthenticatedSessionHandler.java:77)

                  at io.undertow.security.handlers.NotificationReceiverHandler.handleRequest(NotificationReceiverHandler.java:50)

                  at io.undertow.security.handlers.AbstractSecurityContextAssociationHandler.handleRequest(AbstractSecurityContextAssociationHandler.java:43)

                  at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)

                  at org.wildfly.extension.undertow.security.jacc.JACCContextIdHandler.handleRequest(JACCContextIdHandler.java:61)

                  at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)

                  at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)

                  at io.undertow.servlet.handlers.ServletInitialHandler.handleFirstRequest(ServletInitialHandler.java:284)

                  at io.undertow.servlet.handlers.ServletInitialHandler.dispatchRequest(ServletInitialHandler.java:263)

                  at io.undertow.servlet.handlers.ServletInitialHandler.access$000(ServletInitialHandler.java:81)

                  at io.undertow.servlet.handlers.ServletInitialHandler$1.handleRequest(ServletInitialHandler.java:174)

                  at io.undertow.server.Connectors.executeRootHandler(Connectors.java:202)

                  at io.undertow.server.HttpServerExchange$1.run(HttpServerExchange.java:793)

                  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.UnsatisfiedLinkError: mycompany.communication.NativeConnection.sendNativeMessage([B)Z

                  at mycompany.communication.NativeConnection.sendNativeMessage(Native Method)

                  at mycompany.communication.NativeConnection.send(Unknown Source)

                  at mycompany.myservice.sendMessage(myclass.java:3597)

                at mycompany.myservice.updateComment(myclass.java:1855)

                  at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)

                  at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)

                  at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)

                  at java.lang.reflect.Method.invoke(Method.java:498)

                  at org.jboss.as.ee.component.ManagedReferenceMethodInterceptor.processInvocation(ManagedReferenceMethodInterceptor.java:52)

                  at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:340)

                  at org.jboss.as.ee.concurrent.ConcurrentContextInterceptor.processInvocation(ConcurrentContextInterceptor.java:45)

                  at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:340)

                  at org.jboss.invocation.InitialInterceptor.processInvocation(InitialInterceptor.java:21)

                  at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:340)

                  at org.jboss.invocation.ChainedInterceptor.processInvocation(ChainedInterceptor.java:61)

                  at org.jboss.as.ee.component.interceptors.ComponentDispatcherInterceptor.processInvocation(ComponentDispatcherInterceptor.java:52)

                  at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:340)

                  at org.jboss.as.webservices.deployers.WSComponentInstanceAssociationInterceptor.processInvocation(WSComponentInstanceAssociationInterceptor.java:56)

                  at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:340)

                  at org.jboss.invocation.InterceptorContext.run(InterceptorContext.java:356)

                  at org.wildfly.security.manager.WildFlySecurityManager.doChecked(WildFlySecurityManager.java:636)

                  at org.jboss.invocation.AccessCheckingInterceptor.processInvocation(AccessCheckingInterceptor.java:61)

                  at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:340)

                  at org.jboss.invocation.InterceptorContext.run(InterceptorContext.java:356)

                  at org.jboss.invocation.PrivilegedWithCombinerInterceptor.processInvocation(PrivilegedWithCombinerInterceptor.java:80)

                  at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:340)

                  at org.jboss.invocation.ChainedInterceptor.processInvocation(ChainedInterceptor.java:61)

                  at org.jboss.as.ee.component.ViewService$View.invoke(ViewService.java:195)

                  at org.jboss.as.webservices.invocation.AbstractInvocationHandler.invoke(AbstractInvocationHandler.java:137)

                  at org.jboss.wsf.stack.cxf.JBossWSInvoker.performInvocation(JBossWSInvoker.java:169)

                  at org.apache.cxf.service.invoker.AbstractInvoker.invoke(AbstractInvoker.java:96)

                  at org.apache.cxf.jaxws.AbstractJAXWSMethodInvoker.invoke(AbstractJAXWSMethodInvoker.java:232)

                  at org.apache.cxf.jaxws.JAXWSMethodInvoker.invoke(JAXWSMethodInvoker.java:85)

                  at org.jboss.wsf.stack.cxf.JBossWSInvoker.invoke(JBossWSInvoker.java:145)

                  at org.apache.cxf.interceptor.ServiceInvokerInterceptor$1.run(ServiceInvokerInterceptor.java:59)

                  at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)

                  at java.util.concurrent.FutureTask.run(FutureTask.java:266)

                  at org.apache.cxf.interceptor.ServiceInvokerInterceptor$2.run(ServiceInvokerInterceptor.java:126)

                  at org.apache.cxf.workqueue.SynchronousExecutor.execute(SynchronousExecutor.java:37)

                  at org.apache.cxf.interceptor.ServiceInvokerInterceptor.handleMessage(ServiceInvokerInterceptor.java:131)

                  ... 39 more

                 

                The end of my uname -a command for the server is...

                x86_64 GNU/Linux

                • 5. Re: Proper way to add .so files to project?
                  jaikiran pai Master

                  Looking at the JBoss Modules code, there might be a bug here. But I am not 100% sure that I am looking at the right code. So can you do this:

                   

                  Pass the following two system properties to the WildFly server:

                   

                  -Djboss.modules.os-name=linux -Djboss.modules.cpu-name=x86_64

                   

                  and restart your server and run your code. See if that works. You can also enable TRACE level logging of org.jboss.modules package to find some log message which might indicate what's going on.

                   

                  By the way, the directory listing you pasted - it contains a copy/paste error I think and probably not a real issue on your setup?

                        -linux-x86_64/

                                          -libNativeConnectionManager.so

                   

                  This ^ should be:

                        -linux-x86_64/

                                          -lib/

                                               - NativeConnectionManager.so

                  • 6. Re: Proper way to add .so files to project?
                    Alexander Lambley Newbie

                    No, that directory listing is accurate. All of my .so files are prepended with "lib" as is linux convention ( java - How to compile dynamic library for a JNI application on linux? - Stack Overflow ). I have tried running the server explicitly setting the os-name and cpu-name variables as you described and got the same error. 

                    • 7. Re: Proper way to add .so files to project?
                      jaikiran pai Master

                      I gave this a try locally and all works fine for me. Can you change your code to just throw any exception it runs into instead of just it? That way we get the complete stacktrace which you can then post here. Something like:

                      static
                        {
                              LOG.trace("Loading NativeConnectionManager library");
                            System.loadLibrary("NativeConnectionManager");
                              LOG.trace("End Loading NativeConnectionManager library");
                        }
                      
                      • 8. Re: Proper way to add .so files to project?
                        Alexander Lambley Newbie

                        I actually found the solution. The "Native Library already loaded in another classloader" errors were being caused because some of my webservices had their lib .jars packaged within their respective .war files, causing the native libraries to be loaded more than once. Pulling these /lib/*.jar out and making them modules fixed the issue. I appreciate your efforts and pointing me in the right direction!