@@ -78,26 +78,49 @@ def jvm_version() -> tuple[int, ...]:
7878 )
7979
8080 p = Path (jvm_path )
81+ java = None
82+
8183 if not p .exists ():
82- raise RuntimeError (f"Invalid default JVM path: { p } " )
84+ # Try Java 8 macOS dylib path (jre/lib/jli/libjli.dylib vs lib/libjli.dylib).
85+ p8 = Path (
86+ default_jvm_path .replace (
87+ "/Contents/MacOS/libjli.dylib" ,
88+ "/Contents/Home/jre/lib/jli/libjli.dylib" ,
89+ )
90+ )
91+ if p8 .exists ():
92+ p = p8
8393
84- java = None
85- for _ in range (3 ): # The bin folder is always <=3 levels up from libjvm.
86- p = p .parent
87- if p .name == "lib" :
88- java = p .parent / "bin" / "java"
89- elif p .name == "bin" :
90- java = p / "java"
91-
92- if java is not None :
94+ if not p .exists ():
95+ # Fall back to JAVA_HOME if the dylib path resolution failed.
96+ java_home = os .environ .get ("JAVA_HOME" )
97+ if java_home :
98+ candidate = Path (java_home ) / "bin" / "java"
9399 if os .name == "nt" :
94- # Good ol' Windows! Nothing beats Windows.
95- java = java .with_suffix (".exe" )
96- if not java .is_file ():
97- raise RuntimeError (f"No ../bin/java found at: { p } " )
98- break
100+ candidate = candidate .with_suffix (".exe" )
101+ if candidate .is_file ():
102+ java = candidate
103+
104+ if java is None :
105+ raise RuntimeError (f"Invalid default JVM path: { p } " )
106+
99107 if java is None :
100- raise RuntimeError (f"No java executable found inside: { p } " )
108+ for _ in range (3 ): # The bin folder is always <=3 levels up from libjvm.
109+ p = p .parent
110+ if p .name == "lib" :
111+ java = p .parent / "bin" / "java"
112+ elif p .name == "bin" :
113+ java = p / "java"
114+
115+ if java is not None :
116+ if os .name == "nt" :
117+ # Good ol' Windows! Nothing beats Windows.
118+ java = java .with_suffix (".exe" )
119+ if not java .is_file ():
120+ raise RuntimeError (f"No ../bin/java found at: { p } " )
121+ break
122+ if java is None :
123+ raise RuntimeError (f"No java executable found inside: { p } " )
101124
102125 _logger .debug (f"Invoking `{ java } -version`..." )
103126 try :
@@ -154,6 +177,19 @@ def start_jvm(options: Sequence[str] = None) -> None:
154177 # download Java as appropriate
155178 ensure_jvm_available ()
156179
180+ # Fail fast if Java version is too old. JPype 1.6+ dropped Java 8 support.
181+ try :
182+ ver = jvm_version ()
183+ if ver < (11 ,):
184+ raise RuntimeError (
185+ f"Java { '.' .join (str (v ) for v in ver )} is not supported. "
186+ "scyjava requires Java 11 or later."
187+ )
188+ except RuntimeError as e :
189+ if "not supported" in str (e ):
190+ raise
191+ _logger .debug (f"Could not determine JVM version before start: { e } " )
192+
157193 # get endpoints and add to JPype class path
158194 if len (endpoints ) > 0 :
159195 # sort endpoints list, except for the first one
0 commit comments