xp-framework/rfc — Issue #204: Modules
Author: thekid
Created: 2011-10-17 16:05:34+00:00
State: open
Labels: draft, framework

Scope of Change
====
Module support will be added to the XP Framework. Modules are a groups
of types and resources with added metadata: Versions, dependencies, main
class, initialization code.

Rationale
====
Take for example an application that someone has written using the XP
Framework and wants to make it available for the public to use. This
application uses a certain version of the framework (or a range, such
as "5.7-SERIES"), but also depends on a certain library which is not
part of the framework but the app's author himself has written and made
available as a separate download. The following questions arise:
* Where is the software installed to?
* How is the dependency on the library tracked?
* How is the framework version verified?

Functionality
====
At the moment, the procedure would probably be as follows:
* Bundle the library into the application's lib directory
and add that to the class path via path files.
* Zip that all up into a file, posting that for download.
* Tell the users to unzip that to an arbitrary directory.
* Add startup code to the main class verifying the framework version.

Directory layout:

```
~/apps/
^- sloccount-2.0.1
|- lib/lang-parsers-1.0.0.xar
|- src/
| ^- de/
| ^- thekid/
| ^- sloccount/
| ^- SlocCount.class.php
|- app.pth
^- README

```
The app.pth file contains the lines `src` and `lib/lang-parsers-1.0.0.xar`.

To use the application, the following is necessary:

```
$ cd ~/apps/sloccount-2.0.1
$ xpcli de.thekid.sloccount.SlocCount ~/devel/xp/trunk

```

This approach has the following downsides:
* The user has to "cd" to the application's directory to use the app.
* The user has to know the fully qualified (and thus: long) classname
to execute the app.
* The dependency needs to be bundled by the app's author manually.
* The app has to be re-released if the bundled library is updated.
* The version verifications have to be performed manually.

What we would want to do would be something along the lines of:

Usage:

```
# Use a certain version: Long version, -m shorthand
$ xpcli -cp sloccount@2.0.1 de.thekid.sloccount.SlocCount ~/devel/xp/trunk
$ xpcli -m sloccount@2.0.1 ~/devel/xp/trunk

# Use a certain version: Long version, -m shorthand
$ xpcli -cp sloccount@ de.thekid.sloccount.SlocCount ~/devel/xp/trunk
$ xpcli -m sloccount ~/devel/xp/trunk

```

The app would still be installed in a certain place (but this would
have to be known to the xp runners), and would somehow indicate it
required the `lang-parsers` library in a certain version as
well as the XP Framework's 5.7-SERIES to run.

So the directory layout would be something like this:

```
/???/
|- sloccount -> sloccount-2.0.1
^- sloccount-2.0.1
|- src/
| |- ???
| ^- de/
| ^- thekid/
| ^- sloccount/
| ^- SlocCount.class.php
|- app.pth
^- README

```
The app.pth file contains the lines `src` and `lang-parsers@1.0.0`
so that the dependencies are loaded.

module-info.xp
----
Most simple version:

```php

```

An application with a main class:

```php

```

A library:

```php
register('mysqlx', $driver);

// Snap-in replacement if no MySQL support loaded
if (!isset($instance->drivers['mysql'])) {
$instance->register('mysql', $driver);
}
}
}
?>
```

Execution
----
A module with a main class can be executed as follows:

```
$ xp -m dialog.addalbum [arg1 [arg2 [...]]]

```

Inclusion
----
Command line:

```
$ xp -cp mysqlx@0.1.1 [class.Name]

```

Path file:

```
src/ # A directory
lib/utils.xar # An archive
mysqlx@0.1.1 # A module reference

```

Configuration
----
In xp.ini:

```
use=~/.xp/5.9.0
repository=local(~/.xp/modules,/opt/xp/modules/)
repository=ivy(~/.ivy)

```

Bootstrapping
----
Here's a directory listing for an XP release:

```
$ ls 5.9.0/*
5.9.0/boot.pth 5.9.0/bootstrap.xar

5.9.0/tools:
class.php web.php xar.php lang.base.php

```
The bootstrap.xar file contains all the classes in the `lang` package
and its subpackages and the `VERSION` file. The `boot.pth` file
contains the lines `bootstrap.xar` and `xp-rt@5.9.0`.

Module layout
----
A typical module directory consists of a class path and a `module-info.xp`
file as well as the sources, either inside a file system structure or inside
an archive.

```
$ ls xp-rt/*/*
xp-rt/5.9.0/class.pth xp-rt/5.9.0/module-info.xp

xp-rt/5.9.0/lib:
xp-rt-5.9.0.xar xp-tools-5.9.0.xar

```

Reflection
----

```php
getName(); // 'dialog'
$modules[0]->getVersion(); // '2.5.0'

// Requirements
$requirements= $modules[0]->getRequirements();
$requirements[0]->getModule(); // 'parallels'
$requirements[0]->getConstraint(); // '0.1.1'
$requirements[1]->getModule(); // 'xp'
$requirements[1]->getConstraint(); // '5.7+'

// Annotations
$modules[0]->getAnnotations(); // main => 'de.thekid.dialog.cmd.AddAlbum'
$modules[0]->getAnnotation('main'); // 'de.thekid.dialog.cmd.AddAlbum'
$modules[0]->hasAnnotation('main'); // TRUEs
?>
```

Repository
----

```
/opt/xp/modules/
|- parallels-0.1.1.xar
| |- module-info.xp
| ^- de/
| ^- thekid/
| ^- parallels/
| |- package-info.xp
| ^- Process.class.php
|
|- dialog.addalbum -> dialog.addalbum-2.5.0/
|
|- dialog.addalbum-2.5.0/
| |- module-info.xp
| ^- de/
| ^- thekid/
| ^- dialog/
| ^- cmd
| |- AddAlbum.class.php
| ^- ...
|
|- dialog-2.5.0.xar
| |- module-info.xp
| ^- de/
| ^- thekid/
| ^- dialog/
| |- Album.class.php
| |- IEntry.class.php
| ^- ...
|
^- dialog-2.4.2.xar
|- module-info.xp
^- ...

```

Security considerations
====

Speed impact
====

Dependencies
====

Related documents
====
* http://xp-framework.net/rfc/contrib/rfc0204-modules.diff
Alternative implementation
* http://openjdk.java.net/projects/modules/
Java Modules @ OpenJDK
* http://openjdk.java.net/projects/modules/samplerepo/
Online repository
* http://www.javabeat.net/articles/print.php?article_id=101
Introduction to Java Module System in Java 7.0
* http://mediacast.sun.com/users/sundelabassee/media/J1Ag_Modularity.pdf
Modularity in Java OSGi and/or JSR 277
* http://blogs.sun.com/abuckley/resource/Devoxx2008-ModularityInJava.pdf
Modularity in Java - Devoxx 2008