[JAVA] What I was addicted to when introducing the JNI library

Introduction

I was addicted to the ClassLoader problem when introducing JNI's external library in the project I am currently participating in, so I would like to leave a solution as a memorandum.

environment

Java8 wildfly-8.1.0.Final

What is JNI

The Java Native Interface (JNI) is a Java platform that combines programs written in Java with code (native code) written in other programming languages (such as C or C ++) that runs on the actual CPU. It is an interface specification for cooperation. (Quoted from Wikipedia: https://ja.wikipedia.org/wiki/Java_Native_Interface)

About the installation library

The main process is an external library implemented in C ++, and I was trying to incorporate it into Java using JNI.

I was addicted to

When I created the build material, I had the following configuration.

service.ear
 ├ lib
 │ └ jni.jar ← Place JNI jar here
 ├ META-INF
 ├ app1.jar
 ├ app2.jar
 └ webapp.war

Deploying this material to WildFly and launching it will work fine the first time. The problem is that the following error occurs when Hot Deploy is performed after the second time.

java.lang.UnsatisfiedLinkError: Native Library xxxx.dll already loaded in another classloader

"It's already loaded in another classloader" ... why ... Restarting WildFly will resolve this issue, but Hot Deploy again will recur.

Survey results

There seems to be a limitation that native libraries can only be loaded into one class loader. Both the first and second times are running on the same JVM, but this phenomenon occurs because different class loaders are used each time it is loaded, and as a result, the same JVM is loaded twice. is. (I interpreted it as, but please point out if it is wrong)

Correspondence part ①

Removed the JNI jar file from the build material.

service.ear
├ lib ← Do not place JNI jar here
 ├ META-INF
 ├ app1.jar
 ├ app2.jar
 └ webapp.war

Correspondence part 2

Place the jar as a static module in WildFly.

wildfly-8.1.0.Final/modules/system/layers/base配下にフォルダを作成します。 (例)wildfly-8.1.0.Final/modules/system/layers/base/xxx/yyy/main

Place the jar file and module.xml in the created folder.

base/xxx/yyy/main
 ├ jni.jar
 └ module.xml ← Create a new file

The contents of module.xml. Match the name of the madule tag with the directory structure created above.

<?xml version="1.0" encoding="UTF-8"?>
<module name="xxx.yyy" xmlns="urn:jboss:module:1.1">
    <resources>
        <resource-root path="jni.jar"/>
    </resources>
</module>

Correspondence ③

Add a dependency to jboss-deployment-structure.xml.

<?xml version="1.0" encoding="UTF-8"?>
<jboss-deployment-structure>
    <deployment>
        <dependencies>
            <module name="xxx.yyy" export="true" />
        </dependencies>
    </deployment>
</jboss-deployment-structure>

Finally

With the above support, the ClassLoader error no longer appears even after HotDeploy. Since there were no other members around the middleware, I desperately investigated it, so I decided to leave it as a reminder. I'm not sure if this response is really correct, but I'm glad that the problem has been resolved for the time being.

reference

WildFly class loading https://qiita.com/tama1/items/f1556886149722b87f78

Recommended Posts

What I was addicted to when introducing the JNI library
Memorandum: What I was addicted to when I hit the accounting freee API
What I fixed when updating to Spring Boot 1.5.12 ・ What I was addicted to
What I was addicted to with the Redmine REST API
The story I was addicted to when setting up STS
I was addicted to the roll method
I was addicted to the Spring-Batch test
What I was addicted to when implementing google authentication with rails
[Rails] I was addicted to the nginx settings when using Action Cable.
A story I was addicted to when testing the API using MockMVC
Problems I was addicted to when building the digdag environment with docker
What I was addicted to when updating the PHP version of the development environment (Docker) from 7.2.11 to 7.4.x
I was addicted to the NoSuchMethodError in Cloud Endpoints
I was addicted to the record of the associated model
I was addicted to starting sbt
What I was addicted to when developing a Spring Boot application with VS Code
What I was addicted to while using rspec on rails
I was addicted to looping the Update statement on MyBatis
What to do when "Fail to load the JNI shared library" is displayed in Eclipse
I was addicted to the setting of laradock + VSCode + xdebug
What I was addicted to when trying to properly openAPI/Swagger documentation with Rails + Grape + Grape Swagger
I tried to summarize what was asked at the site-java edition-
A note when I was addicted to converting Ubuntu on WSL1 to WSL2
About the matter that I was addicted to how to use hashmap
I was addicted to the API version min23 setting of registerTorchCallback
I was addicted to rewriting to @SpringApplicationConfiguration-> @SpringBootTest
Introducing the library
[Rails] How to solve ActiveSupport :: MessageVerifier :: InvalidSignature that I was addicted to when introducing twitter login [ActiveStorage]
What I thought when passing the user input value to the Service class
My.cnf configuration problem that I was addicted to when I was touching MySQL 8.0 like 5.7
I was addicted to a simple test of Jedis (Java-> Redis library)
Recorded because I was addicted to the standard input of the Scanner class
I was addicted to scrollview because I couldn't tap the variable size UIView
[CircleCI] I was addicted to the automatic test of CircleCI (rails + mysql) [Memo]
I was addicted to unit testing with the buffer operator in RxJava
I was addicted to using RXTX on Sierra
I was addicted to installing Ruby/Tk on MacOS
I was addicted to doing onActivityResult () with DialogFragment
What I did when I converted java to Kotlin
What I tried when I wanted to get all the fields of a bean
I was addicted to not being able to connect to AWS-S3 from the Docker container
I was a little addicted to the S3 Checksum comparison, so I made a note.
Introducing what I made when I wanted to add a header and footer to RecyclerView
What I did when I was addicted to the error "Could not find XXX in any of the sources" when I added a Gem and built it
What to do when The SSL certificate has expired
What should I do to reload the updated Dockerfile?
A memo that I was addicted to when making batch processing with Spring Boot
[Summary] What I noticed and did when I was told that the Oracle JDK was paid
The part I was addicted to in "Introduction to Ajax in Java Web Applications" of NetBeans
A memorandum because I was addicted to the setting of the Android project of IntelliJ IDEA
A story I was addicted to when getting a key that was automatically tried on MyBatis
I knew what reflection was
I was addicted to setting default_url_options with Rails devise introduction
When I tried to scroll automatically with JScrollBar, the event handler was drawn only once.
What I did in the version upgrade from Ruby 2.5.2 to 2.7.1
A story I was addicted to in Rails validation settings
I was addicted to using Java's Stream API in Scala
I was addicted to WSl when trying to build an android application development environment with Vue.js
Technical causes and countermeasures for the points I was addicted to with the first Android app & Kotlin
What to do if you get a JNI shared library error when trying to build in Eclipse
[Circle CI] A story I was addicted to at Start Building