Project
In one sentence: tryst helps you to create really reusable components.
Much more reusable then known from other frameworks.
Tryst is framework which tries to ease the development of osgi-application. Using tryst the connection between different bundles (components) is done by using simple annotations in your programm code. so you don't have to care of writing service-listener and such things.
The framework also tries to equip your projects which easy to use bundles such as remote service calling,caching, security, database access and so on
In one sentence: tryst helps you to create really reusable components.
Much more reusable then known from other frameworks.
Source Code
If you want to take a look to the sources please
feel free to find 'em in the "CVS Repository". This webpage also is in a
prealpha state, but try the follow the principle of "release early
and release often".
Documentation
Installation
In the download section of this page you can find the tryst core modules bundled with the equinox osgi bundle. Download the archive and unpack it content to any folder. In the unpacked folder you will find a folder named "bin". Change your current directory to this folder and execute the script startup.sh on linux maschine. In case of windows OS you have to create a similar .bat file to start the framework.
Installation of bundles
In thre tryst bundle folder you can see a folder named "plugins". Simple copy your bundle-jars into this directory. Equinox detects bundles in this folder and install them.#
Equniox
Tryst is bundled with the osgi framework equniox which is the base of the famous eclipse IDE. You can find equinox on the eclipse homepage www.eclipse.org. Equinox is licensed under the terms of the EPL-V1.0.
All downloads are provided under the terms and conditions of the Eclipse Foundation Software User Agreement unless otherwise specified.
How to write a Service
To write a service you have to create OSGI Bundle. As an "Activator" of this bundle you should inherit a class from org.tryst.core.AbstractBundleActivator. This Activator will take care about creation of your service.
Programming by convention
The system follows the concept of "programming by convention" as frameworks like "Ruby on Rails" or "Groovy" which means that you don't have to write boring endless xml-files to configure your system (a way that was modern and was called declarativ programming ;-)). But you have p.e. name your stuff in a special way, so that the system knows what to do with your code.
Exactly this is used to write services. To write a service you just have to write a public class in the same package as the Activator and name it with the symbolic name of the osgi-bundle and appended "Service" to the name. Example:Your bundle is called MyTestBundle which have an activator in the package de.test.myservice, so you simply have to write a class called : de.test.myservice.MyTestBundleService. This will be your service class. This class is automatically registered as a service in the system.
Pojo's as service
The service classes can be normal pojo's (plain old java objects) which means that your service don't have to inherit from some base class or implement a specific interface. The framework will wrap all necessary things around of your service object automatically.
The only thing to care about is that the service classes have to follow the java beans rules, which means it have to implement a default constructor (a constructor without arguments ).
When you want other Services to be able to find and use your service, so you have to write a "Service-Interface" which also is nothing more than a normal interface named something+Service (pe. IMyTestServive). The System will handle every interface which ends with "Service" and is implemented by your class as a service interface. Other servives can use your service by injecting the service with the interface into one of their member-variables.
service factory
If your Service class implements the service factory interface org.osgi.framework.ServiceFactory then your service is handles as a Service Factory which means that the getService method is invoke at injection time, so the bundle can controll different instance to return to the calling bundle p.e. depending on the type of the calling bundle.
How to inject a service into another
One of the main functions of some framework like "Spring" is the dependency injection. Same think can be done with this framework but using the power of osgi. So an injected service can appear and disappear during runtime when you start or stop services.
Service injection is done by using a java-Annotation in the field-declaration.
the @Inject annotation
public class MyTestBundleService {
private @Inject ILoggerService logger;
}
In this example our new service MyTestBundleService needs a LoggingService (=a service which implements the interface ILoggerService). You have not more to do then declaring a variable of the needed type (=service-interface n this case ILoggerService) and annotate it which the inject annotation. as soon as service which implements the required service-interface is getting registered it's getting injected to your object and can be used.
(don't forget to import the interface in your osgi-bundle-manifest !!)
one instance per using bundle
it's also possible to create services which are instantiate one injected serviceObject by bundle which is using the service. This is exactly the same as the org.osgi.framework.ServiceFactory concept found in the osgi reference.
In tryst this can also be done by using annotation.
You simple can annodate your service class with the @Service Annotation. Using the argument "instances" allows you to specify if a service is only instantiated once (SINGLETON which is the default) or one instance us used per using bundle (MULTIPLE).
@Service (instances=Service.INSTANCETYPE.MULTIPLE)
public class MyService {
}
calling a method after registering a service
You can specify one ore more methods to get executed after completly creating and registering a service. The methods were not call when activator start is call but later after the whole initialisation process finished.
The do this simply mark a method (which should not expect any arguments) of your service class with the @ActivationMethod annotation.
public @ActivationMethod void execute() {
log.info("service created and startet");
}
Security
as a basis security concept it is possible to create a service which implements org.tryst.core.serviceinterfaces.ServiceAccessManager.
An implementation of this interface can control every call made to a service-method. Just check in the isCallGranted method if a call of this method on this object is allow.