Skip to content
This repository was archived by the owner on Aug 5, 2021. It is now read-only.

Commit 2f35354

Browse files
authored
Merge pull request #97 from voutilad/issue-83
Issue 83 - Refactoring to support direct pip install from GitHub or source
2 parents e6b297b + ac634b6 commit 2f35354

File tree

4 files changed

+252
-268
lines changed

4 files changed

+252
-268
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,3 +17,4 @@ jpy.egg-info
1717
lib/
1818
.vagrant
1919
Vagrantfile
20+
*.so

MANIFEST.in

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,6 @@ recursive-include doc *.rst
88
recursive-include src/main/c *.h
99
recursive-include src/main/c *.c
1010
recursive-include src/main/java *.java
11-
recursive-include src/main/python *.py
1211
recursive-include src/test/java *.java
1312
recursive-include src/test/python *.py
13+

jpyutil.py

Lines changed: 36 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
import ctypes
3030
import ctypes.util
3131
import logging
32+
import subprocess
3233

3334

3435
__author__ = "Norman Fomferra, Brockmann Consult GmbH"
@@ -80,7 +81,8 @@ def _add_paths_if_exists(path_list, *paths):
8081
return path_list
8182

8283

83-
def _get_module_path(name, fail=False):
84+
def _get_module_path(name, fail=False, install_path=None):
85+
""" Find the path to the jpy jni modules. """
8486
import imp
8587

8688
module = imp.find_module(name)
@@ -89,6 +91,10 @@ def _get_module_path(name, fail=False):
8991
path = module[1]
9092
if not path and fail:
9193
raise RuntimeError("module '" + name + "' is missing a file path")
94+
95+
if install_path:
96+
return os.path.join(install_path, os.path.split(path)[1])
97+
9298
return path
9399

94100

@@ -103,10 +109,10 @@ def _find_file(search_dirs, *filenames):
103109
return None
104110

105111

106-
def _get_java_api_properties(fail=False):
112+
def _get_java_api_properties(fail=False, path=None):
107113
jpy_config = Properties()
108-
jpy_config.set_property('jpy.jpyLib', _get_module_path('jpy', fail=fail))
109-
jpy_config.set_property('jpy.jdlLib', _get_module_path('jdl', fail=fail))
114+
jpy_config.set_property('jpy.jpyLib', _get_module_path('jpy', fail=fail, install_path=path))
115+
jpy_config.set_property('jpy.jdlLib', _get_module_path('jdl', fail=fail, install_path=path))
110116
jpy_config.set_property('jpy.pythonLib', _find_python_dll_file(fail=fail))
111117
jpy_config.set_property('jpy.pythonPrefix', sys.prefix)
112118
jpy_config.set_property('jpy.pythonExecutable', sys.executable)
@@ -115,7 +121,8 @@ def _get_java_api_properties(fail=False):
115121

116122
def find_jdk_home_dir():
117123
"""
118-
Try to detect the JDK home directory from dedicated environment variables.
124+
Try to detect the JDK home directory from Maven, if available, or use
125+
dedicated environment variables.
119126
:return: pathname if found, else None
120127
"""
121128
for name in JDK_HOME_VARS:
@@ -124,6 +131,22 @@ def find_jdk_home_dir():
124131
and os.path.exists(os.path.join(jdk_home_dir, 'include')) \
125132
and os.path.exists(os.path.join(jdk_home_dir, 'lib')):
126133
return jdk_home_dir
134+
logging.debug('Checking Maven for JAVA_HOME...')
135+
try:
136+
output = subprocess.check_output(['mvn', '-v'])
137+
if isinstance(output, bytes) and not isinstance(output, str):
138+
#PY3 related
139+
output = output.decode('utf-8')
140+
for part in output.split('\n'):
141+
if part.startswith('Java home:'):
142+
path = part.split(':')[1].strip()
143+
if path.endswith('jre'):
144+
return path[0:-3]
145+
146+
except Exception:
147+
# maven probably isn't installed or not on PATH
148+
logging.debug('Maven not found on PATH. No JAVA_HOME found.')
149+
127150
return None
128151

129152

@@ -480,12 +503,12 @@ def load(self, path):
480503
raise ValueError('illegal Java properties format ' + line)
481504

482505

483-
def _execute_python_scripts(scripts):
506+
def _execute_python_scripts(scripts, **kwargs):
484507
import subprocess
485508

486509
failures = 0
487510
for script in scripts:
488-
exit_code = subprocess.call([sys.executable, script])
511+
exit_code = subprocess.call([sys.executable, script], **kwargs)
489512
if exit_code:
490513
failures += 1
491514
return failures
@@ -494,6 +517,7 @@ def _execute_python_scripts(scripts):
494517
def write_config_files(out_dir='.',
495518
java_home_dir=None,
496519
jvm_dll_file=None,
520+
install_dir=None,
497521
req_java_api_conf=True,
498522
req_py_api_conf=True):
499523
"""
@@ -502,6 +526,7 @@ def write_config_files(out_dir='.',
502526
:param out_dir: output directory, must exist
503527
:param java_home_dir: optional home directory of the Java JRE or JDK installation
504528
:param jvm_dll_file: optional file to JVM shared library file
529+
:param install_dir: optional path to where to searfh for modules
505530
:param req_java_api_conf: whether to write the jpy configuration file 'jpyconfig.properties' for Java
506531
:param req_py_api_conf: whether to write the jpy configuration file 'jpyconfig.py' for Python
507532
:return: zero on success, otherwise an error code
@@ -543,7 +568,7 @@ def write_config_files(out_dir='.',
543568

544569
try:
545570
java_api_config_file = os.path.join(out_dir, java_api_config_basename)
546-
java_api_properties = _get_java_api_properties(fail=req_java_api_conf)
571+
java_api_properties = _get_java_api_properties(fail=req_java_api_conf, path=install_dir)
547572
java_api_properties.store(java_api_config_file, comments=[
548573
"Created by '%s' tool on %s" % (tool_name, str(datetime.datetime.now())),
549574
"This file is read by the jpy Java API (org.jpy.PyLib class) in order to find shared libraries"])
@@ -578,6 +603,7 @@ def _main():
578603
help="Require that Java API configuration succeeds.")
579604
parser.add_argument("-p", "--req_py", action='store_true', default=False,
580605
help="Require that Python API configuration succeeds.")
606+
parser.add_argument("--install_dir", action='store', default=None, help="Optional. Used during pip install of JPY")
581607
args = parser.parse_args()
582608

583609
log_level = getattr(logging, args.log_level.upper(), None)
@@ -596,7 +622,8 @@ def _main():
596622
java_home_dir=args.java_home,
597623
jvm_dll_file=args.jvm_dll,
598624
req_java_api_conf=args.req_java,
599-
req_py_api_conf=args.req_py)
625+
req_py_api_conf=args.req_py,
626+
install_dir=args.install_dir)
600627
except:
601628
logging.exception("Configuration failed")
602629
retcode = 100

0 commit comments

Comments
 (0)