Skip to content

Commit 9bdba53

Browse files
committed
Merge branch 'main' into stubs
2 parents 79524b0 + 89f043a commit 9bdba53

20 files changed

+918
-142
lines changed

README.md

Lines changed: 49 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,24 @@ u'1.8.0_152-release'
8585

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

88+
## Bootstrap a Java installation
89+
90+
```python
91+
>>> from scyjava import config, jimport
92+
>>> config.set_java_constraints(fetch=True, vendor='zulu', version='17')
93+
>>> System = jimport('java.lang.System')
94+
cjdk: Installing JDK zulu:17.0.15 to /home/chuckles/.cache/cjdk
95+
Download 100% of 189.4 MiB |##########| Elapsed Time: 0:00:02 Time: 0:00:02
96+
Extract | | # | 714 Elapsed Time: 0:00:01
97+
cjdk: Installing Maven to /home/chuckles/.cache/cjdk
98+
Download 100% of 8.7 MiB |##########| Elapsed Time: 0:00:00 Time: 0:00:00
99+
Extract | |# | 102 Elapsed Time: 0:00:00
100+
>>> System.getProperty('java.vendor')
101+
'Azul Systems, Inc.'
102+
>>> System.getProperty('java.version')
103+
'17.0.15'
104+
```
105+
88106
## Convert between Python and Java data structures
89107

90108
### Convert Java collections to Python
@@ -135,7 +153,7 @@ AttributeError: 'list' object has no attribute 'stream'
135153
Traceback (most recent call last):
136154
File "<stdin>", line 1, in <module>
137155
TypeError: No matching overloads found for java.util.Set.addAll(set), options are:
138-
public abstract boolean java.util.Set.addAll(java.util.Collection)
156+
public abstract boolean java.util.Set.addAll(java.util.Collection)
139157
>>> from scyjava import to_java as p2j
140158
>>> jset.addAll(p2j(pset))
141159
True
@@ -216,6 +234,22 @@ FUNCTIONS
216234
is_jarray(data: Any) -> bool
217235
Return whether the given data object is a Java array.
218236

237+
is_jboolean(the_type: type) -> bool
238+
239+
is_jbyte(the_type: type) -> bool
240+
241+
is_jcharacter(the_type: type) -> bool
242+
243+
is_jdouble(the_type: type) -> bool
244+
245+
is_jfloat(the_type: type) -> bool
246+
247+
is_jinteger(the_type: type) -> bool
248+
249+
is_jlong(the_type: type) -> bool
250+
251+
is_jshort(the_type: type) -> bool
252+
219253
is_jvm_headless() -> bool
220254
Return true iff Java is running in headless mode.
221255

@@ -267,6 +301,12 @@ FUNCTIONS
267301
You can pass a single integer to make a 1-dimensional array of that length.
268302
:return: The newly allocated array
269303

304+
jsource(data)
305+
Try to find the source code using SciJava's SourceFinder.
306+
:param data:
307+
The object or class or fully qualified class name to check for source code.
308+
:return: The URL of the java class
309+
270310
jclass(data)
271311
Obtain a Java class object.
272312

@@ -303,6 +343,14 @@ FUNCTIONS
303343
:param jtype: The Java type, as either a jimported class or as a string.
304344
:return: True iff the object is an instance of that Java type.
305345

346+
jreflect(data, aspect: str = "all") -> List[Dict[str, Any]]
347+
Use Java reflection to introspect the given Java object,
348+
returning a table of its available methods or fields.
349+
350+
:param data: The object or class or fully qualified class name to inspect.
351+
:param aspect: One of: "all", "constructors", "fields", or "methods".
352+
:return: List of dicts with keys: "name", "mods", "arguments", and "returns".
353+
306354
jstacktrace(exc) -> str
307355
Extract the Java-side stack trace from a Java exception.
308356

dev-environment.yml

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,17 +12,17 @@
1212
#
1313
# In addition to the dependencies needed for using scyjava, it
1414
# includes tools for developer-related actions like running
15-
# automated tests (pytest) and linting the code (black). If you
15+
# automated tests (pytest) and linting the code (ruff). If you
1616
# want an environment without these tools, use environment.yml.
1717
name: scyjava-dev
1818
channels:
1919
- conda-forge
2020
dependencies:
21-
- python >= 3.9
21+
- python = 3.9
2222
# Project dependencies
2323
- jpype1 >= 1.3.0
2424
- jgo
25-
- openjdk >= 8, < 12
25+
- cjdk
2626
# Test dependencies
2727
- numpy
2828
- pandas
@@ -37,6 +37,5 @@ dependencies:
3737
# Project from source
3838
- pip
3939
- pip:
40-
- cjdk
4140
- git+https://github.com/ninia/jep.git@cfca63f8b3398daa6d2685428660dc4b2bfab67d
4241
- -e .

environment.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
#
1313
# It includes the dependencies needed for using scyjava, but not tools
1414
# for developer-related actions like running automated tests (pytest),
15-
# linting the code (black), and generating the API documentation (sphinx).
15+
# linting the code (ruff), and generating the API documentation (sphinx).
1616
# If you want an environment including these tools, use dev-environment.yml.
1717

1818
name: scyjava
@@ -23,7 +23,7 @@ dependencies:
2323
# Project dependencies
2424
- jpype1 >= 1.3.0
2525
- jgo
26-
- openjdk >= 8
26+
- cjdk
2727
# Project from source
2828
- pip
2929
- pip:

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
44

55
[project]
66
name = "scyjava"
7-
version = "1.11.0.dev0"
7+
version = "1.12.1.dev0"
88
description = "Supercharged Java access from Python"
99
license = "Unlicense"
1010
authors = [{name = "SciJava developers", email = "ctrueden@wisc.edu"}]

src/scyjava/__init__.py

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,22 @@
4040
+++oo*OO######O**oo+++++oo*OO######O**oo+++++oo*OO######O**oo+++
4141
+++oo*OO######OO*oo+++++oo*OO######OO*oo+++++oo*OO######OO*oo+++
4242
43+
Bootstrap a Java installation:
44+
45+
>>> from scyjava import config, jimport
46+
>>> config.set_java_constraints(fetch=True, vendor='zulu', version='17')
47+
>>> System = jimport('java.lang.System')
48+
cjdk: Installing JDK zulu:17.0.15 to /home/chuckles/.cache/cjdk
49+
Download 100% of 189.4 MiB |##########| Elapsed Time: 0:00:02 Time: 0:00:02
50+
Extract | | # | 714 Elapsed Time: 0:00:01
51+
cjdk: Installing Maven to /home/chuckles/.cache/cjdk
52+
Download 100% of 8.7 MiB |##########| Elapsed Time: 0:00:00 Time: 0:00:00
53+
Extract | |# | 102 Elapsed Time: 0:00:00
54+
>>> System.getProperty('java.vendor')
55+
'Azul Systems, Inc.'
56+
>>> System.getProperty('java.version')
57+
'17.0.15'
58+
4359
Convert Java collections to Python:
4460
4561
>>> from scyjava import jimport
@@ -71,6 +87,7 @@
7187
from functools import lru_cache
7288
from typing import Any, Callable, Dict
7389

90+
from . import config, inspect
7491
from ._arrays import is_arraylike, is_memoryarraylike, is_xarraylike
7592
from ._convert import (
7693
Converter,
@@ -91,6 +108,10 @@
91108
to_java,
92109
to_python,
93110
)
111+
from ._introspect import (
112+
jreflect,
113+
jsource,
114+
)
94115
from ._jvm import ( # noqa: F401
95116
available_processors,
96117
gc,

src/scyjava/_cjdk_fetch.py

Lines changed: 28 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
"""
2+
Utility functions for fetching JDK/JRE and Maven.
3+
"""
4+
15
from __future__ import annotations
26

37
import logging
@@ -9,21 +13,23 @@
913
import cjdk
1014
import jpype
1115

16+
import scyjava.config
17+
1218
if TYPE_CHECKING:
1319
from pathlib import Path
1420

1521
_logger = logging.getLogger(__name__)
16-
_DEFAULT_MAVEN_URL = "tgz+https://dlcdn.apache.org/maven/maven-3/3.9.9/binaries/apache-maven-3.9.9-bin.tar.gz" # noqa: E501
17-
_DEFAULT_MAVEN_SHA = "a555254d6b53d267965a3404ecb14e53c3827c09c3b94b5678835887ab404556bfaf78dcfe03ba76fa2508649dca8531c74bca4d5846513522404d48e8c4ac8b" # noqa: E501
18-
_DEFAULT_JAVA_VENDOR = "zulu-jre"
19-
_DEFAULT_JAVA_VERSION = "11"
2022

2123

2224
def ensure_jvm_available() -> None:
2325
"""Ensure that the JVM is available and Maven is installed."""
24-
if not is_jvm_available():
26+
fetch = scyjava.config.get_fetch_java()
27+
if fetch == "never":
28+
# Not allowed to use cjdk.
29+
return
30+
if fetch == "always" or not is_jvm_available():
2531
cjdk_fetch_java()
26-
if not shutil.which("mvn"):
32+
if fetch == "always" or not shutil.which("mvn"):
2733
cjdk_fetch_maven()
2834

2935

@@ -47,27 +53,27 @@ def _silent_check_output(*args, **kwargs):
4753
return True
4854

4955

50-
def cjdk_fetch_java(vendor: str = "", version: str = "") -> None:
56+
def cjdk_fetch_java(vendor: str | None = None, version: str | None = None) -> None:
5157
"""Fetch java using cjdk and add it to the PATH."""
52-
if not vendor:
53-
vendor = os.getenv("JAVA_VENDOR", _DEFAULT_JAVA_VENDOR)
54-
version = os.getenv("JAVA_VERSION", _DEFAULT_JAVA_VERSION)
58+
if vendor is None:
59+
vendor = scyjava.config.get_java_vendor()
60+
if version is None:
61+
version = scyjava.config.get_java_version()
5562

56-
_logger.info(f"No JVM found, fetching {vendor}:{version} using cjdk...")
57-
home = cjdk.java_home(vendor=vendor, version=version)
58-
_add_to_path(str(home / "bin"))
59-
os.environ["JAVA_HOME"] = str(home)
63+
_logger.info(f"Fetching {vendor}:{version} using cjdk...")
64+
java_home = cjdk.java_home(vendor=vendor, version=version)
65+
_logger.debug(f"java_home -> {java_home}")
66+
_add_to_path(str(java_home / "bin"), front=True)
67+
os.environ["JAVA_HOME"] = str(java_home)
6068

6169

6270
def cjdk_fetch_maven(url: str = "", sha: str = "") -> None:
6371
"""Fetch Maven using cjdk and add it to the PATH."""
64-
# if url was passed as an argument, or env_var, use it with provided sha
72+
# if url was passed as an argument, use it with provided sha
6573
# otherwise, use default values for both
66-
if url := url or os.getenv("MAVEN_URL", ""):
67-
sha = sha or os.getenv("MAVEN_SHA", "")
68-
else:
69-
url = _DEFAULT_MAVEN_URL
70-
sha = _DEFAULT_MAVEN_SHA
74+
if not url:
75+
url = scyjava.config.get_maven_url()
76+
sha = scyjava.config.get_maven_sha()
7177

7278
# fix urls to have proper prefix for cjdk
7379
if url.startswith("http"):
@@ -88,7 +94,9 @@ def cjdk_fetch_maven(url: str = "", sha: str = "") -> None:
8894
)
8995
kwargs = {sha_lengths[sha_len]: sha}
9096

97+
_logger.info("Fetching Maven using cjdk...")
9198
maven_dir = cjdk.cache_package("Maven", url, **kwargs)
99+
_logger.debug(f"maven_dir -> {maven_dir}")
92100
if maven_bin := next(maven_dir.rglob("apache-maven-*/**/mvn"), None):
93101
_add_to_path(maven_bin.parent, front=True)
94102
else: # pragma: no cover

0 commit comments

Comments
 (0)