You can access the Magik on Java runtime either though the limited Magik on Java console, or by using GNU Emacs with the standard Smallworld extensions.
Run start_magik_console.bat to start the console. This console has limited functionality, but it does:
It is possible to use Magik on Java via the standard Emacs GIS mode. Type F2 Z and then run start_magik_cli.bat in the correct directory:
[<installation directory>] <installation directory>/start_magik_cli.bat
A few things to note for using Emacs are:
You can execute Magik (but there are some limitations).
Command | Description |
---|---|
quit() | close the console |
load_file("filename") | load a file |
smallworld_product.add_product(path to product.def) | add a product |
sw_module_manager.load_module(image_name) | load a module |
You can add products and load modules in the standard Magik way. Here’s how you use Magik on Java to load all code in the base_image module using an existing Core 4.3.0 installation (other modules and TSB versions of Core 4.3.0 may not work):
sw_module_manager.load_module(:base_image)
You will not always be expected to load the base_image module yourself from source: later releases will ship with precompiled versions of all Core code, and provide mechanisms for you to compile your own application code. The functionality in this release is just the first step towards being able to load all Core product and application modules, and also developing support for replacements for closed and open images.
In the meantime, feel free to try loading more modules on top of base, but do expect things to fall over in places. As always, we would appreciate your feedback and bug reports to help us determine the areas that we should work over the next few releases.
Note At this release, we claim to load the source for some modules which aren’t actually loaded. This is needed to work round some outstanding language or low-level library limitations in Magik on Java. See Limitations for a list of these modules.
In case you get an out of memory error while loading more modules, you can work around it for now by increasing the Java permGen memory in the <installation directory>/start_magik_console.bat
when using the console, or
<installation directory>/start_magik_cli.bat
when using Emacs.
You can do it by changing the value of the -XX:MaxPermSize parameter to say something greater than the current 256M.
set ALCHEMY_ARGS=%javaOptions% -Xmx1g -XX:MaxPermSize=256M
-Dmagik.readClasses=true -jar libs/org.eclipse.osgi_3.8.0.v20111025-1330.jar
-configuration libs/magikConsoleConfig %1
Magik on Java provides access to datastore functionality via low-level exemplars such as ds_version_view
or database_view
, and to whole databases via gis_program_manager.open_database()
.
Datastore files can be accessed using the Smallworld Datastore Server, swmfs, or in single-user mode by passing :concurrency_mode, :single_user
to, for example, ds_version_view.add_file()
.
For example, to open the Cambridge Database and access the sector of an object, such as min_road, execute the following in the console:
gis_program_manager.open_database("C:<path_to_cambridge_db>\ds\ds_admin") min_road << gis_program_manager.cached_dataset(:gis).collection(:min_road) centre_line_sector_rope << min_road.an_element().centre_line.sectors
The majority of non-administrative functions are working. This functionality has been extensively tested by in-house automated functionality and stress tests and so is ready for detailed experimentation.
Alternatives and checkpoints are supported.
Magik on Java provides some graphics support. The following example displays a window containing a diagonal line, and the line adjusts when the window is resized (although the drawing canvas will not).
def_slotted_exemplar(:graphics_base, { {:canvas1, _unset }, {:background?, _false }, {:bg_style, _unset }, {:styles, _unset } }, {:model} ) $ graphics_base.define_slot_access(:background?, :writable) $ graphics_base.define_shared_constant(:canvas_width, 600, _false ) $ graphics_base.define_shared_constant(:canvas_height, 450, _false ) $ _private _method graphics_base.activate_in(f) ## create the user interface. Simply creates a canvas on which ## to install the popup menu. a << canvas_agent.new(_unset) .canvas1 << canvas.new(f,_self.canvas_width,_self.canvas_height,a) a.define_redraw(:|redraw()|, _self) _endmethod $ _method graphics_base.redraw(window, _optional bnds) ## This method is the default redraw method, it tests the ## damage area as specified in the BNDS argument. The indicated ## area should match the occluding window. ## endPts << short_integer_vector.new_with(0,0, window.width, window.height) style << line_style.new(colour.called("green"), 4) window.clear() window.draw_rline(style, 10, 10, endPts) _endmethod $ g << graphics_base.new() g.open()
We support mouse events and more and more drawing surface primitives. Please try it and if it doesn’t work let us know.
Magik on Java provides interoperability with Java, although this feature will continue to be fleshed out in future releases. All APIs are subject to change—feedback welcome!
It's simple to create a method in Java and make that available as a procedure in the Magik on Java runtime:
load_jar()
and load_java_class()
.The @MagikProc annotation informs Magik on Java that, when the surrounding Java class is loaded, a Magik procedure is created that calls this method when it is invoked. The annotation’s name parameter is the name the procedure is given in the top-level Magik package.
public class MyProc { @MagikProc(name="my_proc") public static Object javaMethodName( Object proc, Object mandatoryParam, @Optional Object optionalParam, Object optionalParam2) { // do something return null; } }
The first parameter of the Java method must be provided, and will always be populated with the procedure object itself. All parameters after that will be populated with the values supplied when the procedure is invoked in Magik. Any parameters after the @Optional annotation are not mandatory and will default to null if they are not supplied by Magik.
The MagikProc and Optional annotations are both in the Java package com.gesmallworld.magik.commons.runtime.annotations.
This table shows how different types of object in Magik appear in Java.
Magik exemplar | Java type |
---|---|
_unset | null |
integer | java.lang.Integer |
bignum | java.math.BigInteger |
character | java.lang.Character |
float | java.lang.Double |
simple_vector | Object[] |
char16_vector | com.gesmallworld.magik.commons.runtime.objects.Char16Vector
This type is not available to your Java code, but Java can access the contents of the Magik string using the standard Java toString() method. |
symbol | com.gesmallworld.magik.commons.runtime.objects.Symbol
Type not available; use toString() to access the symbol’s value. |
Other Magik exemplars can be passed to Java, but they do not appear as well-known Java types and there is currently no API for interacting with them.
Some examples showing how different Magik calls to the above Java-defined procedure appear on the Java side:
my_proc(1,2)
proc
will be the procedure object mandatoryParam
will be 1, type java.lang.Integer optionalParam
will be 2, type java.lang.Integer optionalParam2
will be null my_proc(“abcdef”)
proc
will be the procedure object mandatoryParam
will be a Char16Vector; call toString() on it to obtain “abcdef” as a java.lang.String optionalParam
will be null optionalParam2
will be null my_proc({1, 1.0}, :hi, %e)
proc
will be the procedure object mandatoryParam
will be an java.lang.Object[] consisting of:
optionalParam
will be a Symbol; call toString() on it to obtain “hi” as a java.lang.String optionalParam2
will be ‘e’, type java.lang.Character my_proc()
too_few_arguments
as the mandatory parameter hasn’t been provided. To use this procedure in Magik, you need to load the class within which the method is defined. The class must appear on the JVM’s classpath.
Two new Magik procedures have been added to help load JARs and classes:
load_jar(“path/to/Java/JAR/file”)
load_java_class(“name.of.JavaClass”)
An Eclipse project has been supplied to demonstrate both Java interoperability and datastore support. The project can be found in the demo folder, along with a copy of the rwo.ds datastore file taken from the Cambridge Database.
The demonstration uses JFreeChart, a free charting library for Java, to draw charts based on information extracted from the rwo.ds datastore. You can open the project to inspect the code.
To run the demonstration, first compile the project into a Jar using Ant.
cd demo\interop.demo ant jar
Then start the console, and try a simple example (this code can be found in demo\interop.demo\src\main\magik\simple_demo.magik).
# load the required jars and classes load_jar("demo/interop.demo/build/magik.interop.jar") load_java_class("com.gesmallworld.magik.interop.ChartProcs") load_jar("demo/interop.demo/lib/jcommon-1.0.17.jar") load_jar("demo/interop.demo/lib/jfreechart-1.0.14.jar") # now draw a pie chart! draw_pie_chart({{"magik", 80}, {"Java", 20}}, "chart", "window")
Now try a more complex example:
load_file("demo/interop.demo/src/main/magik/ds_demo.magik")
This example loads the rwo.ds datastore file (found in the demo folder) and gets some information from the min_roads table. It then displays this information in a pie chart and a bar chart.
Feedback magikonjava.feedback@ge.com
Copyright 1998-2013 General Electric Company. All Rights Reserved. GE and the GE Monogram are trademarks and service marks of General Electric Company.