Skip to content
Permalink
Browse files

A collection of provisional hacks at running under openjdk-11

Working under openjdk-11; Currently testing for openjdk-8.
Afterwards, openjdk-6, openjdk-7, and whatever additional
implementations we wish to support.

Even though it emits Java 5 bytecode (version 49.0), the result can be
run on openjdk-11, the compiler seems to work fine.

This patch reworks ABCL-CONTRIB strategy to introspect the value of
the the Java system property "java.class.path".  This may not be
sufficient to find the contribs under all possible ways that the
implementation may be hosted.

Currently, JSS does not work.  The first stumbling block is
enumerating all available loadable classfiles using the new
java.lang.module.ModuleView abstraction.

JSS certainly does not work but the ABCL-CONTRIB works for
implementations with access to a filesystem on which CL:DIRECTORY can
work.

To provide some background to the issues here, ABCL-CONTRIB is
deliberately packaged separately from the contents of `abcl.jar` in
order to:

1. Keep the base ANSI implementation plus the included ASDF version in
   a single artifact with no other dependencies.

2. Push the decision to potentially infringe on licenses explicitly to
   the user.

The knowledgable User may use the build-time option for the inclusion
of code in system.lisp and the AIO packaging mechanism to create an
unified "All-in-one" artifact.

Since ASDF is always included as part of the base `abcl.jar`, we may
rely on its presence to find additional artifacts to add as additional
code to abcl, aka. "the abcl contribs".  Currently, this is achieved
by the following strategies, tried sequentially until one is found to
be successful:

1.  Introspecting for an implementation of "org.abcl-contrib" as
    declared in the system jar manifest.

2.  Attempting to locate a jar file named `abcl-contrib{MUMBLE}.jar`,
    on the filesystem by searching directories referenced on the class
    path.

3.  Replacing the occurance of 'abcl' with 'abcl-contrib' in the the
    name of the system jar pathname, and then introspecting the
    contents.

It would probably be helpful to add the following strategies to find
members of ABCL-CONTRIB:


4.  Locating an `abcl-contrib.asd` artifact via the usual ASDF
    conventions.

5.  Retrieving the contents of ABCL-CONTRIB from the network via a
    "cool URI".

6.  (Java 11) Appropiate use of Java modules to describe graphs of
    loadable ABCL artifacts.
  • Loading branch information
mevenson@1c010e3e-69d0-11dd-93a8-456734b0d56f
mevenson@1c010e3e-69d0-11dd-93a8-456734b0d56f committed Nov 1, 2019
1 parent 312d275 commit a628e961a1dc33e1f225191a19494701d7770e55
Showing with 101 additions and 31 deletions.
  1. +8 −4 abcl.properties.in
  2. +5 −2 contrib/jss/invoke.lisp
  3. +88 −25 src/org/armedbear/lisp/abcl-contrib.lisp
@@ -1,7 +1,5 @@
# $Id$

# XXX should be called 'build.properties' but this collides with its
# usage by the Eclipe IDE
# usage by the Eclipse IDE

# Template for Ant based build process settings.

@@ -15,8 +13,14 @@ abcl.build.incremental=true

## java.options sets the Java options in the abcl wrapper scripts

# Base JVM settings that work on all supported platforms
java.options=-XshowSettings:vm -Dfile.encoding=UTF-8

# Java 11
#java.options=

# Maximum safe performance on JDK8
java.options=-d64 -XX:+UseG1GC -XshowSettings:vm -Dfile.encoding=UTF-8 -XX:+AggressiveOpts -XX:CompileThreshold=10
#java.options=-d64 -XX:+UseG1GC -XshowSettings:vm -Dfile.encoding=UTF-8 -XX:+AggressiveOpts -XX:CompileThreshold=10

# Reasonable defaults for Java 8
#java.options=-d64 -XshowSettings:vm -XX:+UseG1GC
@@ -464,8 +464,11 @@ associated is used to look up the static FIELD."
'cons))
(do-imports (cp)
(import-classpath (expand-paths (split-classpath cp)))))
(do-imports (jcall "getClassPath" (jstatic "getRuntimeMXBean" '|java.lang.management.ManagementFactory|)))
(do-imports (jcall "getBootClassPath" (jstatic "getRuntimeMXBean" '|java.lang.management.ManagementFactory|)))))

(let ((mx-bean (jstatic "getRuntimeMXBean"
'|java.lang.management.ManagementFactory|)))
(do-imports (jcall "getClassPath" mx-bean))
(do-imports (jcall "getBootClassPath" mx-bean)))))

(eval-when (:load-toplevel :execute)
(when *do-auto-imports*
@@ -1,13 +1,18 @@
(in-package :system)

;;;; Mechanisms for finding loadable artifacts from the environment,
;;;; which are then used to locate the Common Lisp systems included as
;;;; `abcl-contrib`.
(require :asdf)

(defconstant +get-classloader+
(java:jmethod "java.lang.Class" "getClassLoader"))
(in-package :system)

(defun boot-classloader ()
(let ((boot-class (java:jclass "org.armedbear.lisp.Main")))
(java:jcall +get-classloader+ boot-class)))
(let ((boot-class (java:jclass "org.armedbear.lisp.Main"))
(get-classloader (java:jmethod "java.lang.Class" "getClassLoader")))
(java:jcall get-classloader boot-class)))

;;; java1.[678] packages the JVM system artifacts as jar files
(defun system-artifacts-are-jars-p ()
(java:jinstance-of-p (boot-classloader) "java.net.URLClassLoader"))

(defun system-jar-p (p)
(or (named-jar-p "abcl" p)
@@ -40,20 +45,77 @@ Used to determine relative pathname to find 'abcl-contrib.jar'."
(ignore-errors
(find-system-jar))
(ignore-errors
(some
(lambda (u)
(probe-file (make-pathname
:defaults (java:jcall "toString" u)
:name "abcl")))
(java:jcall "getURLs" (boot-classloader))))
(when (system-artifacts-are-jars-p)
(some
(lambda (u)
(probe-file (make-pathname
:defaults (java:jcall "toString" u)
:name "abcl")))
(java:jcall "getURLs" (boot-classloader)))))
#+(or)
;; Need to test locating the system boot jar over the network, and
;; it would minimally need to check version information.
(ignore-errors
#p"http://abcl.org/releases/current/abcl.jar")))

(defun flatten (list)
(labels ((rflatten (list accumluator)
(dolist (element list)
(if (listp element)
(setf accumluator (rflatten element accumluator))
(push element accumluator)))
accumluator))
(let (result)
(reverse (rflatten list result)))))

(defun java.class.path ()
(let* ((separator (java:jstatic "getProperty" "java.lang.System" "path.separator"))
(path (java:jcall "split"
(java:jstatic "getProperty" "java.lang.System"
"java.class.path")
separator)))
(setf path (coerce path 'list))
(values
(mapcar (lambda (jar)
(make-pathname :defaults jar
:name nil
:type nil))
path)
path)))

(defun enumerate-resource-directories ()
(flet ((directory-of (p)
(make-pathname :defaults p
:name nil
:type nil)))
(let ((result (java.class.path)))
(dolist (entry (flatten (java:dump-classpath)))
(cond
((java:jinstance-of-p entry "java.net.URLClassLoader") ;; java1.[678]
(dolist (url (coerce (java:jcall "getURLs" entry)
'list))
(let ((p (directory-of (pathname (java:jcall "toString" url)))))
(when (probe-file p)
(pushnew p result :test 'equal)))))
((pathnamep entry)
(pushnew (directory-of entry) result :test 'equal))
((and (stringp entry)
(probe-file (pathname (directory-of entry))))
(pushnew (pathname (directory-of entry)) result :test 'equal))
(t
(format *standard-output*
"Skipping enumeration of resource ~a with type ~a"
entry (type-of entry)))))
result)))

(defun find-jar (predicate)
(dolist (loader (java:dump-classpath))
(let ((jar (some predicate loader)))
(when jar
(return jar)))))
(dolist (d (enumerate-resource-directories))
(let ((entries (directory (make-pathname :defaults d
:name "*"
:type "jar"))))
(let ((jar (some predicate entries)))
(when jar
(return-from find-jar jar))))))

(defun find-system-jar ()
"Return the pathname of the system jar, one of `abcl.jar` or
@@ -83,18 +145,18 @@ Initialized via SYSTEM:FIND-CONTRIB.")
(let ((asdf-directory (make-pathname :defaults asdf-file :name nil :type nil)))
(unless (find asdf-directory asdf:*central-registry* :test #'equal)
(push asdf-directory asdf:*central-registry*)
(format verbose "~&; abcl-contrib; Added ~A to ASDF.~&" asdf-directory))))))
(format verbose "~&; Added ~A to ASDF.~%" asdf-directory))))))

(defun find-and-add-contrib (&key (verbose cl:*load-verbose*))
"Attempt to find the ABCL contrib jar and add its contents to ASDF.
returns the pathname of the contrib if it can be found."
(if *abcl-contrib*
(format verbose "~&; abcl-contrib; Using already initialized value of SYS:*ABCL-CONTRIB* '~A'.~%"
(format verbose "~&; Using already initialized value of SYS:*ABCL-CONTRIB* '~A'.~%"
*abcl-contrib*)
(progn
(let ((contrib (find-contrib)))
(when contrib
(format verbose "~&; abcl-contrib; Using probed value of SYS:*ABCL-CONTRIB* '~A'.~%"
(format verbose "~&; Using probed value of SYS:*ABCL-CONTRIB* '~A'.~%"
contrib)
(setf *abcl-contrib* contrib)))))
(when *abcl-contrib* ;; For bootstrap compile there will be no contrib
@@ -158,12 +220,13 @@ returns the pathname of the contrib if it can be found."
:name (concatenate 'string
"abcl-contrib"
(subseq (pathname-name system-jar) 4)))))))
(some
(lambda (u)
(probe-file (make-pathname
:defaults (java:jcall "toString" u)
:name "abcl-contrib")))
(java:jcall "getURLs" (boot-classloader)))))
(when (java:jinstance-of-p (boot-classloader) "java.net.URLClassLoader")
(some
(lambda (u)
(probe-file (make-pathname
:defaults (java:jcall "toString" u)
:name "abcl-contrib")))
(java:jcall "getURLs" (boot-classloader))))))

(export '(find-system
find-contrib

0 comments on commit a628e96

Please sign in to comment.
You can’t perform that action at this time.