FunctionPackage: net.jlinkerToCDocOverviewCGDocRelNotesFAQIndexPermutedIndex
Allegro CL version 9.0
New since 9.0 release.

scan-java-api

Arguments: &key jar init-args classpath keep classes mode out package names exclude rename

This operator was added in a patch release in April, 2014.

This function analyzes a collection of Java libraries and classes to generate Lisp functions that call Java methods and constructors through a Jlinker connection.

Each Java instance method name is mapped to a Lisp function with a corresponding Lisp name. Overloading is handled by dynamic dispatch in Lisp. More details on this later.

Each Java static method name is mapped to a Lisp name composed from the class name and method name.

Java constructors are mapped to a Lisp name derived from the class name.

Each static final field is mapped to a Lisp name derived from the class name and field name. The Lisp function caches the value in Lisp so that repeated uses of the field do not require round-trips to Java.

The scan and analysis is done by calling Java reflection API methods. Therefore, Java and the required jar files must be available during the scan and code generation.

The generated code is sensitive to the case-mode of both the generating and running Lisp. In most cases code generated in :break mode in mlisp will run equally well in alisp or mlisp. Code generated in :keep mode in mlisp is most likely to cause problems when run in alisp. (mlisp is the case-sensitive modern Common Lisp version. alisp is the case-insensitive Common Lisp. See case.htm for details of case sensitivity in Allegro Common Lisp.

Arguments:

jar: A jar file entry or a list of jar file entries:

 	 jar-file-entry -> path-string | (path-string filter... )
	 filter -> :include reg-exp-string
	        -> :exclude reg-exp-string

Each filter is applied in turn to each name in the jar file manifest.

Very often, a jar file contains many entries above and beyond the documented public api in a library. There is little benefit in generating Lisp names for all the internal names of the library.

init-args: A list of initial arguments to jlinker-init.

classpath: A list of additional classpath components.

If Jlinker is already running when scan-java-api is called, then both init-args and classpath are ignored.

If Jlinker is not running, jlinker-init is called with the specified arguments. A classpath argument is added to this list by combining the classpath argument with the list of jar files.

The remaining keyword arguments are:

Here is a table of consequences of the various values for the names argument:

:names argument ACL general ACL compile ACL run Notes
:break ANSI ANSI ANSI only
:break Modern Modern ANSI and Modern
:keep ANSI ANSI ANSI only
:keep Modern Modern Modern
:keep Modern Modern ANSI Conflicts likely
:keep ANSI ANSI ANSI
:keep Modern Modern Modern

All other case-mode combinations are likely to produce conflicts and errors at code generation, compile or load time, and likely garbled results at run time.

Name conflicts in Lisp:

Lisp name conflicts occur when two or more Java names map to the same generated Lisp name. When a conflict is detected, a message is printed to the console; the first definition detected for this name is emitted, but any subsequent code is suppressed for that Lisp name. A summary of all the conflicts is inserted at the end of the generated code file.

When Java names cause conflicts in Lisp, there are several actions possible:

Dynamic Dispatch of Java methods:

The generated Lisp functions attempt to dispatch overloaded Java methods by analyzing the Java classes of the instance and other arguments. An available method is a potential match if the instance and argument classes are subclasses of the declaring method and declared signature parts. If this results in more than one match, then declaring classes are compared and any methods declared on a superclass are discarded. If there are still more than one method remaining, and error is signaled. No attempt is made to order the methods by their signatures.

This strategy is similar to but not identical to the way methods are dispatched by the Java compiler. In some cases, the Lisp code identifies more than one method; in some cases it may be unable to match the Lisp arguments to the declared method signatures; in these case an error is signaled.

Example:

     Java classes       Fine extends Narrow;   Narrow extends Broad
     Java methods on class Foo       convert(Narrow x)   convert(Broad x)
     Lisp call          (convert instance-of-Foo, instance-of-Fine)
                 Dispatcher will find two convert methods.

It is also possible to call the wrong method when the intent is to call a method more general than the most specific. In Java the situation is handled by casting the argument, but there is no way to cast the argument in Lisp. These situations must be recognized by the programmer.

In some of these cases, the solution is to call the desired method explicitly with jcall, jstatic, or jnew. In some, there is no way to call the method with jlinker:

See jlinker.htm for more information on the jLinker facility.


Copyright (c) 1998-2019, Franz Inc. Oakland, CA., USA. All rights reserved.
This page is new in the 9.0 release.
Created 2019.8.20.

ToCDocOverviewCGDocRelNotesFAQIndexPermutedIndex
Allegro CL version 9.0
New since 9.0 release.