Closed SuperIceCN closed 3 years ago
@kawamuray Is this still working in progress?
Yeah right. Simply it's not implement yet.
@kawamuray I encountered a problem when I tried to implement Config.class, but when I tried to instantiate Config.class, I get a java.lang.UnsatisfiedLinkError. I wonder about that why it happens, could you please offer some suggestions? Any help would be appreciated!
Stacktrace is here:
io.github.kawamuray.wasmtime.ConfigTest > testNewConfig FAILED java.lang.UnsatisfiedLinkError: io.github.kawamuray.wasmtime.Config.newConfig()J at io.github.kawamuray.wasmtime.Config.newConfig(Native Method) at io.github.kawamuray.wasmtime.Config.
(Config.java:9) at io.github.kawamuray.wasmtime.ConfigTest.testNewConfig(ConfigTest.java:8)
Is it a java.library.path issue again?
I tested it by running your patch in my local and it ran successfully without reporting any errors.
If you're not sure about your IDE settings, you may wanna try running gradle directly by gradlew.bat test
to see if it passes the test. gradlew test
runs tests against a built JAR which already contains embedded JNI lib so it should work even without java.library.path
set.
@kawamuray I'm sure that I set the right java.library.path. When I run the test by gradlew.bat test
I encountered the same problem. See https://github.com/Superice666/wasmtime-java/runs/1589558317, the same code works on ubuntu but failed on windows.
Hm.. that's weird indeed. I've just made a commit https://github.com/kawamuray/wasmtime-java/commit/5cb1e982f9a3b4d899fb496f44f1ab914994afcd on master branch to enable logger outputs from unit tests so we can study some situation about your test failures. Can you try:
gradlew clean check
andgrep NativeLibraryLoader build/test-results/test/*.xml
and report the output and.dll
path by the above command, try to dump function symbols in that .dll
please? I don't know how to do that for windows' shared objects but on unix we can do something like:
$ nm -Ug /path/to/libwasmtime_jni_0.2.0_macos.dylib | grep Java_
00000000000270a0 T _Java_io_github_kawamuray_wasmtime_Engine_dispose
00000000000271b0 T _Java_io_github_kawamuray_wasmtime_Engine_newEngine
0000000000030af0 T _Java_io_github_kawamuray_wasmtime_Func_dispose
0000000000030c10 T _Java_io_github_kawamuray_wasmtime_Func_nativeCall
0000000000030ce0 T _Java_io_github_kawamuray_wasmtime_Func_newFunc
@kawamuray I dumped the .dll file with the dumpbin.exe provided in the msvc compiler:
C:\Program Files (x86)\Microsoft Visual Studio\2019\Community>dumpbin /EXPORTS D:\nukkit\wasmtime-java\build\jni-libs\wasmtime_jni_0.1.0_windows.dll Microsoft (R) COFF/PE Dumper Version 14.21.27702.2 Copyright (C) Microsoft Corporation. All rights reserved.
Dump of file D:\nukkit\wasmtime-java\build\jni-libs\wasmtime_jni_0.1.0_windows.dll
File Type: DLL
Section contains the following exports for wasmtime_jni.dll
00000000 characteristics
FFFFFFFF time date stamp
0.00 version
1 ordinal base
98 number of functions
98 number of names
ordinal hint RVA name
1 0 0001C6D0 Java_io_github_kawamuray_wasmtime_Config_cacheConfigLoad = Java_io_github_kawamuray_wasmtime_Config_cacheConfigLoad
2 1 0001C820 Java_io_github_kawamuray_wasmtime_Config_cacheConfigLoadDefault = Java_io_github_kawamuray_wasmtime_Config_cacheConfigLoadDefault
3 2 0001C970 Java_io_github_kawamuray_wasmtime_Config_craneliftDebugVerifier = Java_io_github_kawamuray_wasmtime_Config_craneliftDebugVerifier
4 3 0001CAC0 Java_io_github_kawamuray_wasmtime_Config_craneliftNanCanonicalization = Java_io_github_kawamuray_wasmtime_Config_craneliftNanCanonicalization
5 4 0001CC10 Java_io_github_kawamuray_wasmtime_Config_craneliftOptLevel = Java_io_github_kawamuray_wasmtime_Config_craneliftOptLevel
6 5 0001CD60 Java_io_github_kawamuray_wasmtime_Config_craneliftOtherFlag = Java_io_github_kawamuray_wasmtime_Config_craneliftOtherFlag
7 6 0001CEB0 Java_io_github_kawamuray_wasmtime_Config_debugInfo = Java_io_github_kawamuray_wasmtime_Config_debugInfo
8 7 0001D000 Java_io_github_kawamuray_wasmtime_Config_dynamicMemoryGuardSize = Java_io_github_kawamuray_wasmtime_Config_dynamicMemoryGuardSize
9 8 0001D150 Java_io_github_kawamuray_wasmtime_Config_interruptable = Java_io_github_kawamuray_wasmtime_Config_interruptable
10 9 0001D2A0 Java_io_github_kawamuray_wasmtime_Config_maxWasmStack = Java_io_github_kawamuray_wasmtime_Config_maxWasmStack
11 A 0001D3F0 Java_io_github_kawamuray_wasmtime_Config_newConfig = Java_io_github_kawamuray_wasmtime_Config_newConfig
12 B 0001D530 Java_io_github_kawamuray_wasmtime_Config_profiler = Java_io_github_kawamuray_wasmtime_Config_profiler
13 C 0001D680 Java_io_github_kawamuray_wasmtime_Config_staticMemoryGuardSize = Java_io_github_kawamuray_wasmtime_Config_staticMemoryGuardSize
14 D 0001D7D0 Java_io_github_kawamuray_wasmtime_Config_staticMemoryMaximumSize = Java_io_github_kawamuray_wasmtime_Config_staticMemoryMaximumSize
15 E 0001D920 Java_io_github_kawamuray_wasmtime_Config_strategy = Java_io_github_kawamuray_wasmtime_Config_strategy
16 F 0001DA70 Java_io_github_kawamuray_wasmtime_Config_wasmBulkMemory = Java_io_github_kawamuray_wasmtime_Config_wasmBulkMemory
17 10 0001DBC0 Java_io_github_kawamuray_wasmtime_Config_wasmMultiValue = Java_io_github_kawamuray_wasmtime_Config_wasmMultiValue
18 11 0001DD10 Java_io_github_kawamuray_wasmtime_Config_wasmReferenceTypes = Java_io_github_kawamuray_wasmtime_Config_wasmReferenceTypes
19 12 0001DE60 Java_io_github_kawamuray_wasmtime_Config_wasmSimd = Java_io_github_kawamuray_wasmtime_Config_wasmSimd
20 13 0001DFB0 Java_io_github_kawamuray_wasmtime_Config_wasmThreads = Java_io_github_kawamuray_wasmtime_Config_wasmThreads
21 14 00037BC0 Java_io_github_kawamuray_wasmtime_Engine_dispose = Java_io_github_kawamuray_wasmtime_Engine_dispose
22 15 00037D60 Java_io_github_kawamuray_wasmtime_Engine_newEngine = Java_io_github_kawamuray_wasmtime_Engine_newEngine
23 16 00015440 Java_io_github_kawamuray_wasmtime_Func_dispose = Java_io_github_kawamuray_wasmtime_Func_dispose
24 17 000155E0 Java_io_github_kawamuray_wasmtime_Func_nativeCall = Java_io_github_kawamuray_wasmtime_Func_nativeCall
25 18 00015730 Java_io_github_kawamuray_wasmtime_Func_newFunc = Java_io_github_kawamuray_wasmtime_Func_newFunc
26 19 00031960 Java_io_github_kawamuray_wasmtime_Instance_dispose = Java_io_github_kawamuray_wasmtime_Instance_dispose
27 1A 00031A80 Java_io_github_kawamuray_wasmtime_Instance_nativeGetFunc = Java_io_github_kawamuray_wasmtime_Instance_nativeGetFunc
28 1B 00031BC0 Java_io_github_kawamuray_wasmtime_Instance_nativeGetMemory = Java_io_github_kawamuray_wasmtime_Instance_nativeGetMemory
29 1C 00031D00 Java_io_github_kawamuray_wasmtime_Instance_newInstance = Java_io_github_kawamuray_wasmtime_Instance_newInstance
30 1D 00019F40 Java_io_github_kawamuray_wasmtime_Linker_dispose = Java_io_github_kawamuray_wasmtime_Linker_dispose
31 1E 0001A060 Java_io_github_kawamuray_wasmtime_Linker_nativeDefine = Java_io_github_kawamuray_wasmtime_Linker_nativeDefine
32 1F 0001A1A0 Java_io_github_kawamuray_wasmtime_Linker_nativeGetOneByName = Java_io_github_kawamuray_wasmtime_Linker_nativeGetOneByName
33 20 0001A2F0 Java_io_github_kawamuray_wasmtime_Linker_nativeModule = Java_io_github_kawamuray_wasmtime_Linker_nativeModule
34 21 0001A420 Java_io_github_kawamuray_wasmtime_Linker_newLinker = Java_io_github_kawamuray_wasmtime_Linker_newLinker
35 22 0001FB70 Java_io_github_kawamuray_wasmtime_Memory_buffer = Java_io_github_kawamuray_wasmtime_Memory_buffer
36 23 0001FCC0 Java_io_github_kawamuray_wasmtime_Memory_dataSize = Java_io_github_kawamuray_wasmtime_Memory_dataSize
37 24 0001FED0 Java_io_github_kawamuray_wasmtime_Memory_dispose = Java_io_github_kawamuray_wasmtime_Memory_dispose
38 25 000200A0 Java_io_github_kawamuray_wasmtime_Memory_newMemory = Java_io_github_kawamuray_wasmtime_Memory_newMemory
39 26 000201F0 Java_io_github_kawamuray_wasmtime_Memory_size = Java_io_github_kawamuray_wasmtime_Memory_size
40 27 000203F0 Java_io_github_kawamuray_wasmtime_Module_dispose = Java_io_github_kawamuray_wasmtime_Module_dispose
41 28 00020620 Java_io_github_kawamuray_wasmtime_Module_newFromBinary = Java_io_github_kawamuray_wasmtime_Module_newFromBinary
42 29 00020CB0 Java_io_github_kawamuray_wasmtime_Module_newFromFile = Java_io_github_kawamuray_wasmtime_Module_newFromFile
43 2A 00021470 Java_io_github_kawamuray_wasmtime_Module_newModule = Java_io_github_kawamuray_wasmtime_Module_newModule
44 2B 00017F00 Java_io_github_kawamuray_wasmtime_Store_dispose = Java_io_github_kawamuray_wasmtime_Store_dispose
45 2C 00018090 Java_io_github_kawamuray_wasmtime_Store_enginePtr = Java_io_github_kawamuray_wasmtime_Store_enginePtr
46 2D 000181D0 Java_io_github_kawamuray_wasmtime_Store_newStore = Java_io_github_kawamuray_wasmtime_Store_newStore
47 2E 00018310 Java_io_github_kawamuray_wasmtime_wasi_Wasi_dispose = Java_io_github_kawamuray_wasmtime_wasi_Wasi_dispose
48 2F 00018430 Java_io_github_kawamuray_wasmtime_wasi_Wasi_nativeAddToLinker = Java_io_github_kawamuray_wasmtime_wasi_Wasi_nativeAddToLinker
49 30 00018560 Java_io_github_kawamuray_wasmtime_wasi_Wasi_newWasi = Java_io_github_kawamuray_wasmtime_wasi_Wasi_newWasi
50 31 00701448 __jit_debug_descriptor = __jit_debug_descriptor
51 32 001C14B0 __jit_debug_register_code = __jit_debug_register_code
52 33 004AA020 old_wasi_common_args_get = old_wasi_common_args_get
53 34 004AA0C0 old_wasi_common_args_sizes_get = old_wasi_common_args_sizes_get
54 35 004AA2A0 old_wasi_common_clock_res_get = old_wasi_common_clock_res_get
55 36 004AA340 old_wasi_common_clock_time_get = old_wasi_common_clock_time_get
56 37 004AA160 old_wasi_common_environ_get = old_wasi_common_environ_get
57 38 004AA200 old_wasi_common_environ_sizes_get = old_wasi_common_environ_sizes_get
58 39 004AA3F0 old_wasi_common_fd_advise = old_wasi_common_fd_advise
59 3A 004AA4A0 old_wasi_common_fd_allocate = old_wasi_common_fd_allocate
60 3B 004AA540 old_wasi_common_fd_close = old_wasi_common_fd_close
61 3C 004AA5D0 old_wasi_common_fd_datasync = old_wasi_common_fd_datasync
62 3D 004AA770 old_wasi_common_fd_fdstat_get = old_wasi_common_fd_fdstat_get
63 3E 004AA810 old_wasi_common_fd_fdstat_set_flags = old_wasi_common_fd_fdstat_set_flags
64 3F 004AA970 old_wasi_common_fd_fdstat_set_rights = old_wasi_common_fd_fdstat_set_rights
65 40 004AAB20 old_wasi_common_fd_filestat_get = old_wasi_common_fd_filestat_get
66 41 004AABC0 old_wasi_common_fd_filestat_set_size = old_wasi_common_fd_filestat_set_size
67 42 004AAC60 old_wasi_common_fd_filestat_set_times = old_wasi_common_fd_filestat_set_times
68 43 004AAD20 old_wasi_common_fd_pread = old_wasi_common_fd_pread
69 44 004AAE90 old_wasi_common_fd_prestat_dir_name = old_wasi_common_fd_prestat_dir_name
70 45 004AADF0 old_wasi_common_fd_prestat_get = old_wasi_common_fd_prestat_get
71 46 004AAF40 old_wasi_common_fd_pwrite = old_wasi_common_fd_pwrite
72 47 004AB010 old_wasi_common_fd_read = old_wasi_common_fd_read
73 48 004AB0D0 old_wasi_common_fd_readdir = old_wasi_common_fd_readdir
74 49 004AB1A0 old_wasi_common_fd_renumber = old_wasi_common_fd_renumber
75 4A 004AB240 old_wasi_common_fd_seek = old_wasi_common_fd_seek
76 4B 004AB300 old_wasi_common_fd_sync = old_wasi_common_fd_sync
77 4C 004AB4A0 old_wasi_common_fd_tell = old_wasi_common_fd_tell
78 4D 004AB540 old_wasi_common_fd_write = old_wasi_common_fd_write
79 4E 004AB600 old_wasi_common_path_create_directory = old_wasi_common_path_create_directory
80 4F 004AB6B0 old_wasi_common_path_filestat_get = old_wasi_common_path_filestat_get
81 50 004AB780 old_wasi_common_path_filestat_set_times = old_wasi_common_path_filestat_set_times
82 51 004AB860 old_wasi_common_path_link = old_wasi_common_path_link
83 52 004AB950 old_wasi_common_path_open = old_wasi_common_path_open
84 53 004ABA60 old_wasi_common_path_readlink = old_wasi_common_path_readlink
85 54 004ABB40 old_wasi_common_path_remove_directory = old_wasi_common_path_remove_directory
86 55 004ABBF0 old_wasi_common_path_rename = old_wasi_common_path_rename
87 56 004ABCD0 old_wasi_common_path_symlink = old_wasi_common_path_symlink
88 57 004ABDA0 old_wasi_common_path_unlink_file = old_wasi_common_path_unlink_file
89 58 004ABE50 old_wasi_common_poll_oneoff = old_wasi_common_poll_oneoff
90 59 004ABF10 old_wasi_common_proc_raise = old_wasi_common_proc_raise
91 5A 004ABFE0 old_wasi_common_random_get = old_wasi_common_random_get
92 5B 004ABF20 old_wasi_common_sched_yield = old_wasi_common_sched_yield
93 5C 004AC080 old_wasi_common_sock_recv = old_wasi_common_sock_recv
94 5D 004AC0D0 old_wasi_common_sock_send = old_wasi_common_sock_send
95 5E 004AC110 old_wasi_common_sock_shutdown = old_wasi_common_sock_shutdown
96 5F 001CD140 resolve_vmctx_memory_ptr = resolve_vmctx_memory_ptr
97 60 00502430 rust_eh_personality = _ZN98_$LT$alloc..collections..btree..navigate..replace..PanicGuard$u20$as$u20$core..ops..drop..Drop$GT$4drop17h1da811f28d8a940dE
98 61 001CD240 set_vmctx_memory = set_vmctx_memory
Summary
3000 .data
30000 .pdata
184000 .rdata
B000 .reloc
57C000 .text
and this is the build information with commit 5cb1e98:
D:\nukkit\wasmtime-java>gradlew.bat build
Task :generateJniInterfaces SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder". SLF4J: Defaulting to no-operation (NOP) logger implementation SLF4J: See http://www.slf4j.org/codes.html#StaticLoggerBinder for further details. Applying rustfmt for .\wasmtime-jni\src\io_github_kawamuray_wasmtime_Engine\mod.rs Applying rustfmt for .\wasmtime-jni\src\io_github_kawamuray_wasmtime_Func\mod.rs Applying rustfmt for .\wasmtime-jni\src\io_github_kawamuray_wasmtime_Instance\mod.rs Applying rustfmt for .\wasmtime-jni\src\io_github_kawamuray_wasmtime_Linker\mod.rs Applying rustfmt for .\wasmtime-jni\src\io_github_kawamuray_wasmtime_Memory\mod.rs Applying rustfmt for .\wasmtime-jni\src\io_github_kawamuray_wasmtime_Module\mod.rs Applying rustfmt for .\wasmtime-jni\src\io_github_kawamuray_wasmtime_Store\mod.rs Applying rustfmt for .\wasmtime-jni\src\io_github_kawamuray_wasmtime_wasi_Wasi\mod.rs Applying rustfmt for .\wasmtime-jni\src\io_github_kawamuray_wasmtime_Config\mod.rs
Task :buildJniLib Compiling wasmtime-jni v0.1.0 (D:\nukkit\wasmtime-java\wasmtime-jni) warning: unused variable: env
--> src\io_github_kawamuray_wasmtime_Config\imp.rs:117:19117 fn new_config(env: &JNIEnv, clazz: JClass) -> Result<jlong, Self::Error> { ^^^ help: if this is intentional, prefix it with an underscore: _env
= note:
#[warn(unused_variables)]
on by default
warning: unused variable: clazz
--> src\io_github_kawamuray_wasmtime_Config\imp.rs:117:33
|
117 | fn new_config(env: &JNIEnv, clazz: JClass) -> Result<jlong, Self::Error> {
| ^^^^^ help: if this is intentional, prefix it with an underscore: _clazz
warning: function is never used: from_raw
--> src\interop.rs:26:8 |
26 | pub fn from_raw |
^^^^^^^^ |
---|
= note: #[warn(dead_code)]
on by default
warning: function is never used: set_field
--> src\interop.rs:48:8
|
48 | pub fn set_field<'a, O, S, T>(env: &JNIEnv<'a>, obj: O, field: S, rust_object: T) -> JniResult<()>
| ^^^^^^^^^
warning: function is never used: set_inner
--> src\interop.rs:131:8
|
131 | pub fn set_inner<'a, O, S, T>(env: &JNIEnv<'a>, obj: JObject<'a>, rust_object: T) -> JniResult<()>
| ^^^^^^^^^
warning: 5 warnings emitted
Finished release [optimized] target(s) in 14.41s
Task :test
io.github.kawamuray.wasmtime.ConfigTest > testNewConfig FAILED
java.lang.UnsatisfiedLinkError: io.github.kawamuray.wasmtime.Config.newConfig()J
at io.github.kawamuray.wasmtime.Config.newConfig(Native Method)
at io.github.kawamuray.wasmtime.Config.
io.github.kawamuray.wasmtime.FuncTest > testCall PASSED
io.github.kawamuray.wasmtime.FuncTest > testTrampolineDrop PASSED
io.github.kawamuray.wasmtime.FuncTest > testTrampolineTrap PASSED
io.github.kawamuray.wasmtime.FuncTest > testTrampolineException PASSED
io.github.kawamuray.wasmtime.FuncTest > testTrampoline PASSED
io.github.kawamuray.wasmtime.InstanceTest > testGetFunc PASSED
io.github.kawamuray.wasmtime.InstanceTest > testGetMemory PASSED
io.github.kawamuray.wasmtime.InstanceTest > testCreateDispose PASSED
io.github.kawamuray.wasmtime.MemoryTest > testSize PASSED
io.github.kawamuray.wasmtime.MemoryTest > testExternalRead PASSED
io.github.kawamuray.wasmtime.MemoryTest > testExternalWrite PASSED
io.github.kawamuray.wasmtime.ModuleTest > testCreateDispose PASSED
io.github.kawamuray.wasmtime.StoreTest > testUseAfterFree PASSED
io.github.kawamuray.wasmtime.StoreTest > testCreate PASSED
io.github.kawamuray.wasmtime.StoreTest > testEngine PASSED
io.github.kawamuray.wasmtime.WasmFunctionsTest > testFunc PASSED
io.github.kawamuray.wasmtime.WasmFunctionsTest > testWrapFunction PASSED
18 tests completed, 1 failed
Task :test FAILED
FAILURE: Build failed with an exception.
What went wrong: Execution failed for task ':test'.
There were failing tests. See the report at: file:///D:/nukkit/wasmtime-java/build/reports/tests/test/index.html
Try: Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output. Run with --scan to get full insights.
Get more help at https://help.gradle.org
BUILD FAILED in 32s 15 actionable tasks: 7 executed, 8 up-to-date
and here is the stacktrace of the failed test:
java.lang.UnsatisfiedLinkError: io.github.kawamuray.wasmtime.Config.newConfig()J
at io.github.kawamuray.wasmtime.Config.newConfig(Native Method)
at io.github.kawamuray.wasmtime.Config.
@kawamuray Is there any mistake in the codes?
Thanks for checking :)
Can you also check if you can find a long line like below in files under the build/test-results/test
like below? I think we want to ensure if the loaded jni lib is actually the one that you've checked by dumpbin at first.
$ grep NativeLibraryLoader build/test-results/test/*.xml
build/test-results/test/TEST-io.github.kawamuray.wasmtime.FuncTest.xml: <system-out><![CDATA[01:04:04.952 [Test worker] DEBUG io.github.kawamuray.wasmtime.NativeLibraryLoader - Loading Wasmtime JNI library from /xyz/libwasmtime_jni_0.2.0_macos10447109394333994586.dylib
@kawamuray It seems that adding this can slove the problem:
static {
NativeLibraryLoader.init();
}
Now there is another task: How to pass a Config object to a Store object to build a Enging object with custom configs?
Ah...!
Now I got what has been causing it. To load the JNI library along with class loading, we need to call NativeLibraryLoader.init();
at the point that a class implementing JNI method initializes.
To avoid writing that static block to all possible classes, I've added that to only few, but classes that are typically required to use any of the wasmtime's functionality as an entrypoint such as Engine
. But in your ConfigTest
, it doesn't refer any of those classes (Engine
, Store
) so there is no chance to load JNI library, causing the test to fail.
The reason that it didn't failed in my environment is because there are some other tests ran before ConfigTest
, causing class loading of Store
or Engine
hence JNI lib as well.
In fact, I could reproduce your failure when I limit the test to execute only to ConfigTest
as below:
./gradlew test --tests 'ConfigTest'
So In this case, I think we can add that static block either to Config
class or ConfigTest
to avoid UnsatisfiedLinkError
indeed.
Now there is another task: How to pass a Config object to a Store object to build a Enging object with custom configs?
In wasmtime's Rust API, there's a constructor of Engine
that takes an Config
as an argument. Also, Store
has constructor which takes an Engine
as an argument.
So you need to:
Engine
constructor that takes Config
, both at Java and JNI (rust)Store
constructor that takes Engine
, both at Java and JNI (rust)at least.
@kawamuray could you please check pull request #5 ? Thanks!
@kawamuray hello, could you please release a new version? thx!
Yes! Released as 0.3.0.
Implemented by #5
I failed to found a method to pass a custom config when I call engine() method from a Store object to get a new wasmtime-engine. What's more, I found that there're many native methods in Config.class without rust implementations. Could you please tell me how to custom the configs of wasmtime-engines? Thanks a lot!