Skip to content

Commit 2df1c84

Browse files
author
Mark Kittisopikul
committed
Create new environment test flags, check async fail on windows
1 parent 56abdf6 commit 2df1c84

File tree

5 files changed

+50
-32
lines changed

5 files changed

+50
-32
lines changed

.travis.yml

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,12 +20,14 @@ jobs:
2020
env: JULIA_COPY_STACKS=0
2121
- julia: 1.0
2222
env: JULIA_COPY_STACKS=0
23-
- os: windows
24-
env: JULIA_COPY_STACKS=1
2523
allow_failures:
2624
- julia: nightly
25+
- os: windows
26+
env: JULIA_COPY_STACKS=1
2727
- os: linux
28-
env: JULIA_COPY_STACKS=0
28+
env: JULIA_COPY_STACKS=0 JAVACALL_FORCE_ASYNC_INIT=1
29+
- os: linux
30+
env: JULIA_COPY_STACKS=0 JAVACALL_FORCE_ASYNC_TEST=1
2931

3032
branches:
3133
only:

src/JavaCall.jl

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -31,14 +31,17 @@ include("reflect.jl")
3131

3232
function __init__()
3333
global JULIA_COPY_STACKS = get(ENV, "JULIA_COPY_STACKS", "") ("1", "yes")
34-
if VERSION v"1.1-" && VERSION < v"1.3-"
35-
@warn("JavaCall does not work correctly on Julia v$VERSION. \n" *
36-
"Either use Julia v1.0.x, or v1.3.0 or higher.\n"*
37-
"For 1.3 onwards, please also set the environment variable `JULIA_COPY_STACKS` to be `1` or `yes`")
38-
end
39-
if VERSION v"1.3-" && ! Sys.iswindows() && ! JULIA_COPY_STACKS
40-
@warn("JavaCall needs the environment variable `JULIA_COPY_STACKS` to be `1` or `yes`.\n"*
41-
"Calling the JVM may result in undefined behavior.")
34+
if ! Sys.iswindows()
35+
# On Windows, JULIA_COPY_STACKS is not needed and causes crash
36+
if VERSION v"1.1-" && VERSION < v"1.3-"
37+
@warn("JavaCall does not work correctly on Julia v$VERSION. \n" *
38+
"Either use Julia v1.0.x, or v1.3.0 or higher.\n"*
39+
"For 1.3 onwards, please also set the environment variable `JULIA_COPY_STACKS` to be `1` or `yes`")
40+
end
41+
if VERSION v"1.3-" && ! JULIA_COPY_STACKS
42+
@warn("JavaCall needs the environment variable `JULIA_COPY_STACKS` to be `1` or `yes`.\n"*
43+
"Calling the JVM may result in undefined behavior.")
44+
end
4245
end
4346
findjvm()
4447
global create = Libdl.dlsym(libjvm, :JNI_CreateJavaVM)

src/core.jl

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,7 @@ end
122122

123123

124124
function jnew(T::Symbol, argtypes::Tuple, args...)
125-
assertroottask()
125+
assertroottask_or_goodenv()
126126
sig = method_signature(Nothing, argtypes...)
127127
jmethodId = ccall(jnifunc.GetMethodID, Ptr{Nothing},
128128
(Ptr{JNIEnv}, Ptr{Nothing}, Ptr{UInt8}, Ptr{UInt8}), penv, metaclass(T),
@@ -136,7 +136,7 @@ end
136136
# Call static methods
137137
function jcall(typ::Type{JavaObject{T}}, method::AbstractString, rettype::Type, argtypes::Tuple,
138138
args... ) where T
139-
assertroottask()
139+
assertroottask_or_goodenv()
140140
sig = method_signature(rettype, argtypes...)
141141
jmethodId = ccall(jnifunc.GetStaticMethodID, Ptr{Nothing},
142142
(Ptr{JNIEnv}, Ptr{Nothing}, Ptr{UInt8}, Ptr{UInt8}), penv, metaclass(T),
@@ -147,7 +147,7 @@ end
147147

148148
# Call instance methods
149149
function jcall(obj::JavaObject, method::AbstractString, rettype::Type, argtypes::Tuple, args... )
150-
assertroottask()
150+
assertroottask_or_goodenv()
151151
sig = method_signature(rettype, argtypes...)
152152
jmethodId = ccall(jnifunc.GetMethodID, Ptr{Nothing},
153153
(Ptr{JNIEnv}, Ptr{Nothing}, Ptr{UInt8}, Ptr{UInt8}), penv, metaclass(obj),
@@ -157,7 +157,7 @@ function jcall(obj::JavaObject, method::AbstractString, rettype::Type, argtypes:
157157
end
158158

159159
function jfield(typ::Type{JavaObject{T}}, field::AbstractString, fieldType::Type) where T
160-
assertroottask()
160+
assertroottask_or_goodenv()
161161
jfieldID = ccall(jnifunc.GetStaticFieldID, Ptr{Nothing},
162162
(Ptr{JNIEnv}, Ptr{Nothing}, Ptr{UInt8}, Ptr{UInt8}), penv, metaclass(T),
163163
String(field), signature(fieldType))
@@ -166,7 +166,7 @@ function jfield(typ::Type{JavaObject{T}}, field::AbstractString, fieldType::Type
166166
end
167167

168168
function jfield(obj::JavaObject, field::AbstractString, fieldType::Type)
169-
assertroottask()
169+
assertroottask_or_goodenv()
170170
jfieldID = ccall(jnifunc.GetFieldID, Ptr{Nothing},
171171
(Ptr{JNIEnv}, Ptr{Nothing}, Ptr{UInt8}, Ptr{UInt8}), penv, metaclass(obj),
172172
String(field), signature(fieldType))

src/jvm.jl

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -163,15 +163,20 @@ function init()
163163
end
164164

165165
const ROOT_TASK_ERROR = JavaCallError(
166-
"Either the environmental variable JULIA_COPY_STACKS must be 1 " *
167-
"OR JavaCall must be used on the root Task.")
166+
"Either the environmental variable JULIA_COPY_STACKS must be 1 " *
167+
"OR JavaCall must be used on the root Task.")
168+
169+
const JULIA_COPY_STACKS_ON_WINDOWS_ERROR = JavaCallError(
170+
"JULIA_COPY_STACKS should not be set on Windows.")
168171

169172
# JavaCall must run on the root Task or JULIA_COPY_STACKS is enabled
170-
isroottask() = JULIA_COPY_STACKS || Base.roottask === Base.current_task()
173+
isroottask() = Base.roottask === Base.current_task()
171174
@static if Sys.iswindows()
172-
assertroottask() = nothing
175+
isgoodenv() = ! JULIA_COPY_STACKS
176+
assertroottask_or_goodenv() = isgoodenv() ? nothing : throw(JULIA_COPY_STACKS_ON_WINDOWS_ERROR)
173177
else
174-
assertroottask() = isroottask() ? nothing : throw(ROOT_TASK_ERROR)
178+
isgoodenv() = JULIA_COPY_STACKS || isroottask()
179+
assertroottask_or_goodenv() = isgoodenv() ? nothing : throw(ROOT_TASK_ERROR)
175180
end
176181

177182
isloaded() = isdefined(JavaCall, :jnifunc) && isdefined(JavaCall, :penv) && penv != C_NULL
@@ -182,7 +187,7 @@ assertnotloaded() = isloaded() ? throw(JavaCallError("JVM already initialised"))
182187
# Pointer to pointer to pointer to pointer alert! Hurrah for unsafe load
183188
function init(opts)
184189
assertnotloaded()
185-
assertroottask()
190+
assertroottask_or_goodenv()
186191
opt = [JavaVMOption(pointer(x), C_NULL) for x in opts]
187192
ppjvm = Array{Ptr{JavaVM}}(undef, 1)
188193
ppenv = Array{Ptr{JNIEnv}}(undef, 1)
@@ -259,7 +264,7 @@ function destroy()
259264
if (!isdefined(JavaCall, :penv) || penv == C_NULL)
260265
throw(JavaCallError("Called destroy without initialising Java VM"))
261266
end
262-
assertroottask()
267+
assertroottask_or_goodenv()
263268
res = ccall(jvmfunc.DestroyJavaVM, Cint, (Ptr{Nothing},), pjvm)
264269
res < 0 && throw(JavaCallError("Unable to destroy Java VM"))
265270
global penv=C_NULL; global pjvm=C_NULL;

test/runtests.jl

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,11 @@ macro syncasync(x)
1212
:( (@sync @async eval($x)).result ) |> esc
1313
end
1414

15+
JAVACALL_FORCE_ASYNC_INIT = get(ENV,"JAVACALL_FORCE_ASYNC_INIT","") ("1","yes")
16+
JAVACALL_FORCE_ASYNC_TEST = get(ENV,"JAVACALL_FORCE_ASYNC_TEST","") ("1","yes")
1517

1618
@testset "initialization" begin
17-
if JavaCall.JULIA_COPY_STACKS
19+
if JavaCall.JULIA_COPY_STACKS || JAVACALL_FORCE_ASYNC_INIT
1820
@testasync JavaCall.init(["-Djava.class.path=$(@__DIR__)"])==nothing
1921
else
2022
@test JavaCall.init(["-Djava.class.path=$(@__DIR__)"])==nothing
@@ -63,7 +65,7 @@ end
6365

6466
@testset "static_method_call_async_1" begin
6567
jlm = @jimport "java.lang.Math"
66-
if JavaCall.JULIA_COPY_STACKS || Sys.iswindows()
68+
if JAVACALL_FORCE_ASYNC_TEST || JavaCall.JULIA_COPY_STACKS || Sys.iswindows()
6769
@testasync 1.0 jcall(jlm, "sin", jdouble, (jdouble,), pi/2)
6870
@testasync 1.0 jcall(jlm, "min", jdouble, (jdouble,jdouble), 1,2)
6971
@testasync 1 == jcall(jlm, "abs", jint, (jint,), -1)
@@ -169,8 +171,8 @@ end
169171
# However, since Java and Julia memory are not linked, and manual gc() is required.
170172
gc()
171173
for i in 1:100000
172-
a=JString("A"^10000); #deleteref(a);
173-
if (i%10000 == 0); gc(); end
174+
a=JString("A"^10000); #deleteref(a);
175+
if (i%10000 == 0); gc(); end
174176
end
175177

176178
@testset "sinx_1" begin
@@ -254,12 +256,18 @@ end
254256
@test isa(narrow(o), JString)
255257
end
256258

257-
@testset "isroottask_1" begin
259+
@testset "roottask_and_env_1" begin
258260
@test JavaCall.isroottask()
259-
@testasync JavaCall.JULIA_COPY_STACKS || ! JavaCall.isroottask()
260-
if ! JavaCall.JULIA_COPY_STACKS && ! Sys.iswindows()
261-
@test_throws CompositeException @syncasync JavaCall.assertroottask()
262-
@warn "Ran tests for root Task only. REPL and @async are not expected to work with JavaCall. Set JULIA_COPY_STACKS=1 in the environment to test @async function."
261+
@testasync ! JavaCall.isroottask()
262+
@test JavaCall.isgoodenv()
263+
if JAVACALL_FORCE_ASYNC_TEST || JavaCall.JULIA_COPY_STACKS || Sys.iswindows()
264+
@testasync JavaCall.isgoodenv()
265+
end
266+
if JAVACALL_FORCE_ASYNC_TEST || ! JavaCall.JULIA_COPY_STACKS
267+
@test_throws CompositeException @syncasync JavaCall.assertroottask_or_goodenv()
268+
@warn "Ran tests for root Task only." *
269+
" REPL and @async are not expected to work with JavaCall without JULIA_COPY_STACKS=1." *
270+
" Set JULIA_COPY_STACKS=1 in the environment to test @async function."
263271
end
264272
end
265273

0 commit comments

Comments
 (0)