Skip to content

Commit cf6df14

Browse files
committed
Update to jgo v2
1 parent 16fe82b commit cf6df14

File tree

6 files changed

+189
-179
lines changed

6 files changed

+189
-179
lines changed

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
Supercharged Java access from Python.
55

66
Built on [JPype](https://jpype.readthedocs.io/en/latest/)
7-
and [jgo](https://github.com/scijava/jgo).
7+
and [jgo](https://github.com/apposed/jgo).
88

99
## Use Java classes from Python
1010

@@ -83,7 +83,7 @@ u'1.8.0_152-release'
8383
+++oo*OO######OO*oo+++++oo*OO######OO*oo+++++oo*OO######OO*oo+++
8484
```
8585

86-
See the [jgo documentation](https://github.com/scijava/jgo) for more about Maven endpoints.
86+
See the [jgo documentation](https://github.com/apposed/jgo) for more about Maven endpoints.
8787

8888
## Bootstrap a Java installation
8989

pyproject.toml

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,7 @@ classifiers = [
3333
requires-python = ">=3.9"
3434
dependencies = [
3535
"jpype1 >= 1.3.0",
36-
"jgo",
37-
"cjdk",
36+
"jgo>=2.0.0",
3837
]
3938

4039
[dependency-groups]

src/scyjava/_cjdk_fetch.py

Lines changed: 0 additions & 121 deletions
This file was deleted.

src/scyjava/_jdk_fetch.py

Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
"""
2+
Utility functions for fetching JDK/JRE.
3+
"""
4+
5+
from __future__ import annotations
6+
7+
import logging
8+
import os
9+
import subprocess
10+
from typing import TYPE_CHECKING, Union
11+
12+
import jpype
13+
14+
from jgo.exec import JavaLocator, JavaSource
15+
16+
import scyjava.config
17+
18+
if TYPE_CHECKING:
19+
from pathlib import Path
20+
21+
_logger = logging.getLogger(__name__)
22+
23+
24+
def ensure_jvm_available() -> None:
25+
"""
26+
Ensure that the JVM is available.
27+
"""
28+
fetch = scyjava.config.get_fetch_java()
29+
if fetch == "never":
30+
# Not allowed to fetch Java.
31+
return
32+
if fetch == "always" or not is_jvm_available():
33+
fetch_java()
34+
35+
36+
def is_jvm_available() -> bool:
37+
"""Return True if the JVM is available, suppressing stderr on macos."""
38+
from unittest.mock import patch
39+
40+
subprocess_check_output = subprocess.check_output
41+
42+
def _silent_check_output(*args, **kwargs):
43+
# also suppress stderr on calls to subprocess.check_output
44+
kwargs.setdefault("stderr", subprocess.DEVNULL)
45+
return subprocess_check_output(*args, **kwargs)
46+
47+
try:
48+
with patch.object(subprocess, "check_output", new=_silent_check_output):
49+
jpype.getDefaultJVMPath()
50+
# on Darwin, may raise a CalledProcessError when invoking `/usr/libexec/java_home`
51+
except (jpype.JVMNotFoundException, subprocess.CalledProcessError):
52+
return False
53+
return True
54+
55+
56+
def fetch_java(vendor: str | None = None, version: str | None = None) -> None:
57+
"""
58+
Fetch Java and configure PATH/JAVA_HOME.
59+
60+
Supports cjdk version syntax including "11", "17", "11+", "17+", etc.
61+
See https://pypi.org/project/cjdk for more information.
62+
"""
63+
if vendor is None:
64+
vendor = scyjava.config.get_java_vendor()
65+
if version is None:
66+
version = scyjava.config.get_java_version()
67+
68+
_logger.info(f"Fetching {vendor}:{version}...")
69+
70+
locator = JavaLocator(
71+
java_source=JavaSource.AUTO,
72+
java_version=version, # Pass string directly (e.g. "11", "17", "11+", "17+")
73+
java_vendor=vendor,
74+
verbose=True,
75+
)
76+
77+
# Locate returns path to java executable (e.g., /path/to/java/bin/java)
78+
java_exe = locator.locate()
79+
java_home = java_exe.parent.parent # Navigate from bin/java to JAVA_HOME
80+
81+
_logger.debug(f"java_home -> {java_home}")
82+
_add_to_path(str(java_home / "bin"), front=True)
83+
os.environ["JAVA_HOME"] = str(java_home)
84+
85+
86+
def _add_to_path(path: Union[Path, str], front: bool = False) -> None:
87+
"""Add a path to the PATH environment variable.
88+
89+
If front is True, the path is added to the front of the PATH.
90+
By default, the path is added to the end of the PATH.
91+
If the path is already in the PATH, it is not added again.
92+
"""
93+
94+
current_path = os.environ.get("PATH", "")
95+
if (path := str(path)) in current_path:
96+
return
97+
new_path = [path, current_path] if front else [current_path, path]
98+
os.environ["PATH"] = os.pathsep.join(new_path)

src/scyjava/_jvm.py

Lines changed: 18 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,11 @@
1515

1616
import jpype
1717
import jpype.config
18-
from jgo import jgo
18+
import jgo
1919

2020
import scyjava.config
2121
from scyjava.config import Mode, mode
22-
from scyjava._cjdk_fetch import ensure_jvm_available
22+
from scyjava._jdk_fetch import ensure_jvm_available
2323

2424
_logger = logging.getLogger(__name__)
2525

@@ -151,23 +151,31 @@ def start_jvm(options: Sequence[str] = None) -> None:
151151
# use the logger to notify user that endpoints are being added
152152
_logger.debug("Adding jars from endpoints {0}".format(endpoints))
153153

154-
# download JDK/JRE and Maven as appropriate
154+
# download Java as appropriate
155155
ensure_jvm_available()
156156

157157
# get endpoints and add to JPype class path
158158
if len(endpoints) > 0:
159+
# sort endpoints list, except for the first one
159160
endpoints = endpoints[:1] + sorted(endpoints[1:])
160161
_logger.debug("Using endpoints %s", endpoints)
161-
_, workspace = jgo.resolve_dependencies(
162-
"+".join(endpoints),
163-
m2_repo=scyjava.config.get_m2_repo(),
162+
163+
# join endpoints list to single concatenated endpoint
164+
endpoint = "+".join(endpoints)
165+
166+
env = jgo.build(
167+
endpoint=endpoint,
168+
#update=False,
164169
cache_dir=scyjava.config.get_cache_dir(),
165-
manage_dependencies=scyjava.config.get_manage_deps(),
166170
repositories=repositories,
167-
verbose=scyjava.config.get_verbose(),
168-
shortcuts=scyjava.config.get_shortcuts(),
171+
# The following obsolete arguments are from jgo v1:
172+
#m2_repo=scyjava.config.get_m2_repo(),
173+
#manage_dependencies=scyjava.config.get_manage_deps(),
174+
#verbose=scyjava.config.get_verbose(),
175+
#shortcuts=scyjava.config.get_shortcuts(),
169176
)
170-
jpype.addClassPath(os.path.join(workspace, "*"))
177+
jpype.addClassPath(env.modules_dir / "*")
178+
jpype.addClassPath(env.jars_dir / "*")
171179

172180
# HACK: Try to set JAVA_HOME if it isn't already.
173181
if (

0 commit comments

Comments
 (0)