I have a Java webapp in eclipse. I have auto-deploy enabled, so whenever I make a change, eclipse automatically redeploys the webapp to my local Tomcat server, and all I have to do is refresh the page. This has worked fine and dandy up until now.
However, I recently added this dependency:
<dependency>
<groupId>com.eclipsesource.j2v8</groupId>
<artifactId>j2v8_win32_x86_64</artifactId>
<version>3.1.6</version>
</dependency>
This dependency includes some native libraries (.dll
files on my Windows machine). When I manually deploy (by right-clicking the project, clicking "run as" and then "run on server"), this works fine. I can use the library exactly like I'd expect.
If I then make a change (any change, even adding a comment), eclipse does its automatic redeploy. But when I try to use that library (by simply refreshing the page and running the exact same code again), I get this error:
java.lang.UnsatisfiedLinkError: Could not load J2V8 library. Reasons:
no j2v8_win32_x86_64 in java.library.path
So it appears that eclipse is failing to load the native libraries upon auto-deploy, even though it works fine when I deploy manually.
The value of java.library.path
is the same in both cases though:
C:\Program Files\Java\jdk1.8.0_65\bin;
C:\WINDOWS\Sun\Java\bin;
C:\WINDOWS\system32;
C:\WINDOWS;
C:\ProgramData\Oracle\Java\javapath;
C:\Program Files\ImageMagick-6.9.0-Q16;
C:\Program Files (x86)\NVIDIA Corporation\PhysX\Common;
C:\Program Files\ImageMagick-6.8.9-Q16;
C:\Program Files\Java\jdk1.8.0_65;
c:\Program Files (x86)\Intel\iCLS Client\;
c:\Program Files\Intel\iCLS Client\;
C:\WINDOWS\system32;
C:\WINDOWS;
C:\WINDOWS\System32\Wbem;
C:\WINDOWS\System32\WindowsPowerShell\v1.0\;
C:\Program Files\Intel\Intel(R) Management Engine Components\DAL;
C:\Program Files\Intel\Intel(R) Management Engine Components\IPT;
C:\Program Files (x86)\Intel\Intel(R) Management Engine Components\DAL;
C:\Program Files (x86)\Intel\Intel(R) Management Engine Components\IPT;
C:\Program Files\WIDCOMM\Bluetooth Software\;
C:\Program Files\WIDCOMM\Bluetooth Software\syswow64;
C:\Program Files\TortoiseSVN\bin;
C:\Program Files (x86)\IVI Foundation\VISA\WinNT\Bin;
C:\Program Files (x86)\leJOS NXJ\bin;
C:\Program Files (x86)\Windows Live\Shared;
C:\Program Files\OpenVPN\bin;
C:\Program Files\Java\jdk1.8.0_65\bin;
C:\Program Files\apache-ant-1.9.3\bin;
C:\Program Files\apache-maven-3.2.1\bin;
C:\Users\Kevin\Desktop\gradle-2.2.1\bin;
;
C:\Program Files (x86)\SSH Communications Security\SSH Secure Shell;
.
In both cases, the location of .
is C:\Users\Kevin\Desktop\eclipse\.
, and in both cases it contains the same files:
#log.txt#save#
.eclipseproduct
artifacts.xml
configuration
crawl.log
derby.log
dropins
eclipse.exe
eclipse.ini
eclipsec.exe
epl-v10.html
features
notice.html
p2
plugins
Queue.zip
readme
server
StaticVoidGames.log
StaticVoidGames_SystemErr.txt
StaticVoidGames_SystemOut.txt
The line of code that throws the exception is:
V8 runtime = V8.createV8Runtime();
That code works fine when I deploy manually, but it fails upon subsequent auto-deploys.
My googling got me to this forum post which only says "there may be problems upon reload" but doesn't offer any solutions. So, my questions are:
Why isn't eclipse including native libraries upon automatic redeploy?
Can I tell eclipse to include native libraries upon automatic redeploy? Is there some setting I'm not seeing?
If automatic redeploy simply doesn't support native libraries, is there some official source saying that?
DLL's are tied to a specific classloader. When we redeploy, that means that the classloader used for our application is destroyed. Unfortunately the Java Virtual Machine does not allow a second classloader to reload a DLL again.
I think its possible to create a Jar file that loads the DLL and add it to the classpath of Tomcat itself, instead of adding it to our application. Normally Tomcat have a "shared" directory where such jar files can be added that will be shared by all applications.
Demo:
1.Change the jar scope to provided so it can be used only in compile time.
<dependency>
<groupId>com.eclipsesource.j2v8</groupId>
<artifactId>j2v8_win32_x86_64</artifactId>
<version>3.1.6</version>
<scope>provided</scope>
</dependency>
Create a 'shared' folder inside tomcat folder
Paste j2v8_win32_x86_64-3.1.6.jar to shared folder
Append ${catalina.home}/shared/*.jar to shared.loader property in catalina.properties
Reference :
http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4225434 http://grokbase.com/t/tomcat/users/06acn8f491/jni-native-libraries-and-tomcat-reloading-web-apps
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With