Reference Documentation

From Acapulco

Jump to: navigation, search
Vektor Software logo 300×300.png


Acapulco Framework Reference Documentation


Vektor Software
http://acapulco.vektorsoft.com
info@vektorsoft.com


Copyright Notice


Copyright © 2009 - 2011 Vektor Software. All rights reserved.


Copies of this document may be made for your own use and for distribution to others, provided that you do not charge any fee for such copies and further provided that each copy contains this Copyright Notice, whether distributed in print or electronically.


6= Introduction = The aim of this project is to create modular Java MVC framework which will enable easy construction of Java Swing application. It is based on OSGI specification, in order to allow creation of modular applications. It is also in some aspects similar to Swing Application Framework.

The primary goal is to eliminate common tasks and boiler-plate code involved in creation of Swing applications, but still be non-intrusive enough to avoid forcing developers to go through steep learning curve. Rather, it is focused on using existing tools and knowledge base.


Contents

Motivation

Swing developers face common problems for most applications they create. Some of them are:

  • event handling – most developers use anonymous inner classes as event handlers, which leads to big and cluttered source files. As application grows, more and more events are added, so eventually source becomes almost unmanageable.
  • Multi threading – Swing applications run in Event Dispatcher thread, so developers must take great care when performing time consuming tasks which use background threads. Most use inner classes also for this task, so it also adds to source cluttering.
  • Internationalization and localization – Swing has built-in support for i18n and l10n, but it also lacks ease of use. For example, it requires some work to implement changing application language at runtime.
  • GUI editors – most developers use visual GUI editors to create user interface. They make creating of GUIs very easy, but they also come with some of their own quirks. On the other hand, some developers prefer to hand-code their GUI. What ever approach is taken, it is good idea to separate application GUI from event handlers and application logic. There are various approaches to this problem, but they all come with some of their own problems.
  • Components reuse – Swing comes with rich set of components, but they are mostly low-level, single components (buttons, combo boxes etc.) Most applications share components that can be reused, but it is difficult to achieve due to different architecture of applications.
  • Application maintenance and upgrading – Since most Swing applications are tightly coupled, change in one module may lead to problems in other modules. OSGI provides great approach to application modularization, and is used as a base for Acapulco platform. However, OSGI represents steep learning curve for new developers, so Acapulco aims to make use of OSGI as easy as possible, while still providing enough flexibility.
  • Deployment – There are many deployment options available, but few of them (if any) provide native deployment strategies across multiple platforms. Thus, most Swing applications have “ugly and unnatural” look and feel.

The goal of Acapulco framework is to address these issues in a way that makes life easier for developers, while still allowing for enough flexibility and freedom. Also, it should allow developers to use their existing skill set and have as flat learning curve as possible.


Acapulco Framework Architecture

Acapulco platform is based on OSGI (http://www.osgi.org). OSGI is chosen because it has became de facto standard for Java application modularization. There are many OSGI implementations available, and Acapulco use Apache Felix (http://felix.apache.org) internally.

In essence, Acapulco is nothing more then set of OSGI bundles with specific functionality. Acapulco bundles provide basic functionality shared by most Swing applications.

In order to create custom applications, developers need to write their own bundles to implement requires functionality. These bundles use features provided by Acapulco bundles in order to make creating application much easier.

Thus, structure of Acapulco based application can be depicted on the following diagram:

[[Image:|thumb|Drawing 1: Structure of application based on Acapulco framework]]


As shown here, both Acapulco bundles and user created bundles run on OSGI runtime (Apache Felix). Depending on their needs, developers can use all Acapulco bundles, or only a required subset.


MVC Framework

MVC pattern is very common design pattern used in application development. It is very well suited for GUI applications, allowing for easy partitioning of application between presentation components, business logic and business objects. Java web application developers have wide range of web MVC frameworks to choose from, like Spring MVC, Struts, JSF, just to name a few.

On the other hand, although Swing components are based on MVC pattern, there's no common approach to development of Swing MVC applications. Most Swing applications use the same classes for all 3 MVC components, with inner classes used for event handling and other tasks.

One of the goals of Acapulco framework is to create real MVC implementation that can be used by developers with very little effort, and reduce code cluttering and writing of boiler-plate code. The image bellow depicts architecture of Acapulco MVC framework.

[[Image:|thumb|Drawing 2: Acapulco MVC framework]]

Model component contains application data, and represents current state of application. Model can have different representations, based on particular needs of the application.

View is the representation component. View uses data from model to render itself. Application can have arbitrary number of views, which can render same or different data. In Swing application, view is actually a GUI container (Jpanel, Jdialog etc.). Components in this container (and container itself) can fire events which are processed by the controller. In order for these events to be processed, view must register listeners for all event-firing components, much as in classic Swing application. The difference is that, in Acapulco framework, registering listeners is handled automatically by the framework.

Controller component contains business logic of the application. It captures all events fired from views, and calls appropriate listener method, based on event type and source of the event.

This whole diagram is basically well-known MVC pattern description, so you might ask where does Acapulco framework fit in? This can all be easily done in plain Swing application. The trick is, Acapulco contains facilities which relieve the developer from most of the grunt work required to implement this pattern. In essence, the following is handled by the framework:

  • automatic creation and updating of model data
  • automatic injection of model data to views, so they can accessible for rendering
  • automatic registration of listeners for desired components, based on annotations
  • uniform handling of events through controller component

Basically, all a developer needs to do is create view forms (using either GUI editor or hand coding), declare model data and required listeners, and the framework takes care of the rest.

The following sections will describe each component in more details.


MVC – Model part

In context of application based on Acapulco framework, model can be described as storage for application data. In addition, this data must be shared between Views and Controllers, so they can operate on them. To facilitate this, Model part of Acapulco framework supports automatic notifications of all interested objects when ever registered data is updated.

Much of the Model implementation in Acapulco framework is hidden from user and used internally within the framework, in order to simplify development process for application developers.


Model implementation

The class com.vektorsoft.acapulco.core.mvc.ApplicationModel is the core of Model implementation. This class handles registering of model data, maintaining their state and sharing it between View and Controller components.

The class com.vektorsoft.acapulco.core.mvc.ModelData represents individual piece of data. All data is encapsulated with this class in order to provide uniform interface for handling various data types. This class also contains observers for encapsulated data. Observers are notified whenever data is changed. In context of Acapulco framework application, observers are Views and Controllers which are interested in particular data.

Diagram in picture 3 illustrates Model implementation. Model contains various data, which are registered by Controllers or Views. This registration is automatic and occurs at application startup.

Let's assume that both Controller and View on the diagram have registered the same piece of data (box containing “Data”). It means that both will track the current state of this data. When Controller updates the data, the model will automatically notify all objects who also registered this data, in this case the View. The View can then render itself to display this data change.

Also, if another Controller has registered this same data, it will also be notified of this change, so it can update it's internal state.


[[Image:|thumb|Drawing 3: Acapulco MVC Model implementation]]

This implementation enables sharing of application-wide data between various components, without the need to track dependencies and current state programatically. All grunt work is handled by the framework. This approach somewhat resembles to Dependency Injection pattern, with addition that it is able to notify interested parties of any change in the data.


Interacting with Model

Client applications do not use Model classes directly. In order to make work more convenient, developers should use @Model annotation to annotate variables that should be kept in Model. It is a field level annotation defined in class com.vektorsoft.acapulco.annotation.Model.

If a class field should be registered with the model, it must be annotated with @Model annotation. This is a signal to framework to perform all necessary operations to register this field with the model. Consider the following code snippet:

    public class Foo{
        @Model(default=true)
        private String bar = “bar;
        
        @Model(dataName=”newName”,defaultValue=true)
        private Date bazz;
        ….........................

In this sample, class Foo contains two variables, bar and bazz, which will be registered with the model.

Variable bar will be registered under it's own name, and it's assigned value will be used as the default. This means that if any other class registers the variable with the same name, it's initial value will not overwrite this one. This is only valid during initialization, so we can assign initial value to a variable.

As for variable bazz, it will be registered under name “newName”, since dataName field of @Model annotation is set. The value of this variable will also be used as default, only in this case, the default value of the type will be used.

For more detailed samples, please refer to “Getting Started” guide.


MVC – View part

Views handle display of application state (Model data) and provide controls for accepting user input. When ever Model data is updated, Views which registered that data are notified, so that they can render itself with new data.

In Swing applications, most of View elements are contained within Swing containers, such as frames, panels and dialogs. Therefore, in context of Acapulco framework, each view is associated with a container which holds Swing components that comprise the view. Depending on the state of Model data, View manipulates these components to render itself correctly to the user.


View implementation

All views in Acapulco Framework application implement ApplicationView interface, which is defined as shown bellow:

    public interface ApplicationView {
        public void renderView();
    }

Interface ApplicationView declares single method renderView(). As the name suggests, this method is used to render the view to reflect current state of the Model. This method is called whenever Model data linked with the View is updated. This call is handled automatically by the framework.

Applications do not use this interface directly. Instead, at application startup, when views are registered, framework declares classes annotated with @View annotation as views, and handles registration accordingly. This is achieved by using Proxy pattern, which allows uniform handling of different view implementations. This process is depicted in the illustration bellow:

[[Image:|thumb|Drawing 4: MVC View implementation]]

View object can be any class, and does not necessarily need to implement ApplicationView interface. Rather then forcing this limitation, framework creates proxy object for the view. Method renderView() of the proxy object is mapped to appropriate method in View object class which does actual rendering of the view.

When Model data is updated by the Controller, registered views are notified and re-rendering is executed. View objects must registered Model data that they are interested in, using @Model annotation.


Interacting with the View

As with the Model, applications based on Acapulco frameworks do not interact with View directly. Instead, annotations are used. There are 3 types of annotations defined for use with the views: @View, @ViewContainer, @ViewConstraints. These are described in more detail in the following sections.


@View annotation

This is class-level annotation that is used to specify that annotated class is to be treated as View in MVC. It has several fields that are used to more closely define characteristics of the view.

  • viewName – this is the string that is used to uniquely identify this view within the application
  • parentName – this is the name of Swing container which will be used as the parent of this view
  • renderer – name of the method within the class which is used to render the view. Method should have no arguments and have return type void.
  • isDialog – specifies whether this view is to be treated as dialog, or as part of main application window. Default value is false.

In order to understand terminology used above, consider the following illustration:

[[Image:|thumb|Drawing 5: Views layout in Acapulco applications]]

Along with unique name, each view has a container which is used to display the view. This is usually Swing container class (JPanel, JFrame, JDialog etc.). These containers also have unique names used to identify them.

In the illustration above, top level view (could be main application window) is named “topView”, and it's container (possibly JFrame) is named “frame”. In order to add view with name “view1” to this top level view, we need to define a point to which this new view will be attached. That point is provided by “parentName” property, which defines the Swing parent component to which view container will be added (using Swing add(Component) method).

Essentially, each view defines a set of Swing controls that comprise a single logical unit of GUI. These controls are contained within Swing container (like JPanel), and this container is attached to some parent component (main window, dialog or another panel).


@ViewContainer annotation

This annotation declares container of the view (described in previous section). This can be either a class, field or method. Here are some examples of it's use:


          @View(viewName=”v1”,parentName=”p1”,renderer=”bazz”)
      public class Foo{
        @ViewContainer
        JPanel container = new JPanel;
         @ViewContainer
         public JPanel getContainer(){
            return new JPanel();
          }
        public void bazz(){
        }
      }
       @ViewContainer
       public class Bar extends JPanel{
     }

Whatever element is annotated, it must evaluate to Swing Container type. This means that annotated fields must be of type Container, annotated methods must return type Container, and annotated classes must be type Container. The code above is only the example, since view will always have only one @ViewContainer annotation.

In our example, class Foo is a View. It's container can be either field container or method getContainer(). In both cases, annotated element evaluates to Container type.


@ViewContraints annotation

This annotation is optional and defines constraints applied when adding the view to it's parent container. Since all views are added to it's parent using Swing method

    add(Component comp,Object constraints)

we can define constraints that will be applied to a view when adding it's container to parent. This is achieved with this annotation.

@ViewConstraints can be used to annotate either types or methods. In both cases, annotated element must evaluate to valid constraint object. Consider the example bellow:

    public class Foo{
          @ViewConstraints
          int side = BorderLayout.North;
         @ViewConstraints
        public int getConstraint(){
        return BorderLayout.SOUTH;
          }
      }

In both cases, annotated element evaluates to valid constraint for border layout. Note that in actual view definition, only one annotation can be used.


MVC – Controller part

Controller part of MVC model is based on Swing listeners model. Developers would write listeners as for any ordinary Swing application, in addition of annotation that defines them as controller component of MVC model. The framework handles registering listeners to specific components and invoking them when appropriate action is performed.

As with the View, all listeners are assigned corresponding proxy object that is used by the framework as a common interface to event listeners. These proxy objects invoke appropriate event listener methods, and are also responsible for notifying views and other controllers of changes to model data. This architecture is depicted on drawing 6.

The core of Acapulco Controller implementation is class com.vektorsoft.acapulco.core.mvc.Controller. It provides methods for registering listeners, and also pre- and post-event methods. These are methods that are executed before and after event is processed. In current implementation pre-event method does nothing, while post-event method is responsible for notifying any interested parties of any change in model data.

The goal of this design is to provide consistent Controller implementation, while not interfering with Swing's own internal event handling mechanism. Writing listeners for Acapulco framework application is basically the same as for any other Swing application, except that it should produce clear separation of concerns between

[[Image:|thumb|Drawing 6: Controller implementation architecture]]

manipulating the data and displaying the changes. Furthermore, it should eliminate the need to initialize data manipulated by the controller, since those would automatically injected by the framework.


Interacting with the Controller

As with previous parts, main tool for interacting with the Controller is annotation, specifically @Listener annotation. This is class-level annotation, which specifies that annotated class is to be registered with the Controller as a listener. The class itself must be valid listener object, eg. implement any of the Swing listener interfaces.

This annotation has single property, componentNames, which is an array of strings. Each string represent a name of one Swing component to which this listener should be added. Component name is the one set by using setName() method. Consider the following example:

     public class MyPanel extends JPanel{
        public MyPanel(){
            JButton button = new Jbutton(“Test”);
            button.setName(“buttonName”);
            …...........................
        }
     }
    @Listener(componentNames={“buttonName”})
    public class MyListener implements ActionListener{
    }

In class MyPanel, we added a button with name “buttonName”. Class MyListener is annotated as a listener, and will be added to component with name “buttonName”. This is in effect the same as calling

button.addActionListener(new MyListener())


only it is handled automatically by the framework.

One important thing to note is that listeners must provide default, no-argument constructor, in order to be instantiated and handled by the framework.


@ComponentBinding

This is a separate annotation type that is not linked only with the controller, but rather with both View and Controller. Basically, this annotation allows to reference another Swing component within a listener or a view. This is usually used when some action needs to be done based on the state of certain Swing control, such as check box or radio button.

Consider the following code fragment:

    public class Foo{
        @ComponentBinding(component=”someComp”)
        private JcheckBox cb;
         public void bar(){
        if(cb.isSelected){
            // do something
          …....................

In this sample, field cb is associated with component with name “someComp”. That means that this field will reflect current state of the referenced component. In this particular case, we are interested in when check box is selected, and perform some action based on that state. Any Swing component can be used as a target for this annotation.


Multitasking

One of the most common features of Swing applications is that all lengthy tasks should be performed in separate thread, in order to maintain responsive GUI. In later Java editions, SwingWorker class is introduced, which makes using threads with Swing components considerably easier. This, in addition to new Java Concurrent API, brings powerful tools to Swing developers.

However, as much as these classes make life easier, they are fairly low-level, and require great amount of coding from scratch for similar tasks. Acapulco Framework attempts to solve this problem in a way that will require minimum amount of coding by the user.


Creating and starting tasks

Main object for multitasking in Acapulco framework is class com.vektorsoft.acapulco.core.task.Task. This is an extension of SwingWorker class, with addition of support for blocking GUI input, if required.

In order to use this class, client needs to subclass it, implement method doInBackground() which contains operation logic, and call method start(). Internally, framework will submit this task to an Executor for execution.

This code sample shows typical use of this class:

    public class Foo extends Task<Void,Void>{
        protected void doInBackground(Void v){
            // do something here
        }
    }
    ….....................
    public class Bar{
        public void bazz(){
        // create and start task here
        Foo foo = new Foo();
        foo.start();
        }
…...................................

Method doInBackground() is inherited from SwingWorker, and should be implemented according to it's specification. Type parameters are also inherited from SwingWorker.


Blocking user input

In some cases, when lengthy operation is performed, it is required to disable user input until operation is complete. For example, application can send query to server and must wait for the response. In order to prevent the user from sending multiple requests, developer may choose to disable user input until response is received.

Blocking input should work for both mouse and keyboard. In addition, there may be different levels of blocking. For example, developer may choose to disable only a single button, a dialog, or entire application window.

To make things easier for developers, class Task has built-in support for disabling user input. In addition, user can choose several levels of blocking. These are defined in enumeration BlockingScope.

  • NONE – no blocking. This is the default
  • SINGLE - only named components are blocked. When this scope is chosen, named components are disabled when task starts. However, children of these components are not affected
  • DIALOG – blocks single Swing container and it's subcomponents. This can be dialog, panel,frame or any type of Swing container.
  • TOP_LEVEL – entire application is disabled

In order to use GUI blocking with tasks, user need only to set blocking scope and define which components should be blocked. Consider the following example:

    Foo task = new Foo();
    task.setBlockingScope(BlockingScope.SINGLE);
    task.setComponentsToBlock(“comp1”,”comp2”);
    ….................................
    task.setBlockingScope(BlockingScope.DIALOG);
    task.setCompoenentsToBlock(“dialog1”);
    …......................................
    task.setBlockingScope(BlockingScope.TOP_LEVEL);

In the first snippet, only single components are blocked. These are determined by their names, comp1 and comp2.

In second snippet, a container with name dialog1 is blocked, along with all it's subcomponents.

In third snippet, entire application is blocked.


Progress monitoring

Often, when task is running for a long time, it is necessary to keep the user informed about the progress. In Swing, this is usually done with progress bars. In order to create a simple progress bar dialog, developers need to set up a lot of boiler plate code before even starting to render progress bar: a separate thread to update the GUI is needed, variable to hold operation state and share this state among the threads, notifications about task progress, completion or failure..

Acapulco Framework provides out-of-the-box support for this type of tasks. It is only neccesary to inherit ProgressAwareTask and create a view to show progress. All needed variables and data are stored into the model and can be shared among threads. Bellow is sample code for progress monitoring task:

public class ProgressTask extends ProgressAwareTask<Object, Object> {

    @Model(defaultValue=true)
    private int progress = 0;
    @Model(defaultValue=true)
    private String status = "";

    @Override
    protected Object doInBackground() throws Exception {
    // do something
    }
}

Here, a few variables are registered which hold current progress (in %) and a status string. These variables are updated when task is running.

In order to display progress, these variables are accessed from the view which displays progress. Bellow is a view code snippet :

@View(....)
@ViewContainer
public class TaskProgressView extends TaskProgressPanel {

    @Model
    private int progress;
    @Model
    private String status;

    public void render(){
        progressBar.setValue(progress);
        statusLabel.setText(status);
    }

As shown in this example, it is quite easy to add progress monitoring to your Swing application. It makes the application appear more professional and robust.

Internationalization and localization

Acapulco Framework provides out-of-the-box support for internationalization and localization of applications. This based on Java resource bundles and locales. The benefit for the developers is that much of the manual coding is automated, and only requirement for the developer is to name the components and resources that need to be internationalized.

This section provides brief description of internationalization and localization subsystem.


Architecture of internationalization system

The central point of the internationalization system is the ResourceManager interface. It provides methods which are common for manipulating resources and locales. Since ResourceManager instances need to be easily obtained by client classes, framework provides the factory class for producing instances of this interface. This is ResourceManagerFactory class.

The diagram below depicts architecture of internationalization subsystem:


[[Image:]]


When framework starts, ResourceManagerFactory is instantiated and default implementation of ResourceManager is registered. This makes internationalization system initialized and ready to be used by client application.

Clients can load resource bundles and manage locales, without worrying about updating GUI. This is done automatically by the framework. Whenever a locale change occurs, GUI is refreshed to reflect the changes, as well as any other components that may be interested in locale change.

Automatic resource injection

For easier resource management, Acapulco Framework provides facilities for automatic management of component resources. That means that developers can simply declare GUI components and their properties that need to be internationalized in resource bundles, and everything else is taken care of by the framework.

Consider the following resource bundle file:

    my.swing.component<text> = Some text
    my.swing.component<toolTipText> = Tooltip text
    my.swing.component<title> = Some title


This represents an excerpt from typical resource bundle file, as defined by Java specification. The only difference is the form of the keys. Here, “my.swing.component” refers to a GUI component with that name, and string between < and > is the name of the component property to be translated. So, in this example, component “my.swing.component” has 3 properties that will be internationalized.

Acapulco Framework assumes that each key that ends with “<text>” represents component property, and will be treated as such. This form is selected since it's not very common for naming of keys. All other key strings are treated as plain keys, and are not processed by i18n subsystem.


Using I18N API

This section briefly describes basic classes and interfaces which clients can use for internationalization and localization.


ResourceManager

This interface is the main piece of code that clients use. It provides basic methods manipulating locales and resource bundles. The listing below shows some of the methods defined by this interface.

    public void setLocale(Locale locale);
    public Locale getCurrentLocale();
    public void setSupportedLocales(Locale[] locales);
    public Locale[] getSupportedLocales();
    public void loadResourceBundle(String name, ClassLoader             classLoader);
    public String getString(String key);

Method names are self-descriptive. There are methods for getting and setting current locale, getting and setting the list of supported locales.

Method loadResourceBundle() takes as arguments path to resource bundles (which should be on the classpath), and a class loader to use. Class loader is required because in OSGI environment, each bundle has it's own class loader, so this is the only way for framework to find the specified resource.

Method getString() gets the value of the string with specified key.


ResourceManagerFactory

This class provides easy access to instances of ResourceManager, since it has to be available to many client classes. Besides this, this class also allows registering custom ResourceManager implementations for client use.


AbstractResourceManager

This abstract class implements most of the functionality required by ResourceManager interface. Clients who wish to make custom ResourceManager implementations should extend this class, instead of implementing the interface directly.

Please check source code and samples for API usage instructions.


Exception handling

Exception handling tends to be one of the most tedious parts of development. In some cases, if the exception condition can be rectified, developers usually display error message to the user. Most times, however, exception condition can not be fixed by user, and in these cases, developers usually just print the stack trace, or declare that their method throws an exception.

Tracking exceptions manually so they can be handled in consistent way can be cumbersome, and even then some of the exceptions can be missed. However, it is very convenient if all exceptions can be handled uniformly, without the developer having to worry about this. Acapulco Framework provides these facilities to developers.


Centralized exception handler

In running Java program, all uncaught exceptions are passed up the stack to the main program thread, where they are handled by default JVM exception handler. This handler just prints out stack trace, which is convenient for most use cases.

Acapulco Framework provides it's own exception handler which replaces JVM default handler. This exception handler can be easily customized and extended, so it can serve various applications. The image bellow depicts overview of this exception handler's architecture:

[[Image:|thumb|Illustration 1: Exception handling architecture]]


Acapulco exception handler is installed at startup as default uncaught exception handler. Users can then register their own strategy implementations for customized exception handling. Acapulco Framework comes with several implementations of this strategy, which should be enough for common use cases.

Using exception handling API

Exception handling API consists of several classses and interfaces, most important of which is ExceptionHandlingStrategy. This interface must be implemented by custom exception handlers. It contains a singe method:

    public interface ExceptionHandlingStrategy{
      public void handleException(Throwable th, Runnable r);
    }

This method contains actual handling code, and implementation should provide desired handling mechanism.

Although users can create and register their own exception handlers, framework comes with a few exception handling strategies that can be used most of the time.


PrintStrategy

This implementation is similar to default Java uncaught exception handler, in that it simply prints out exception stack trace. The difference is that users can add other print streams to which stack trace should be printed, such as file, socket, network share etc.

This is the default exception handling strategy of the framework. It prints all stack traces to standard error stream.


GUIDisplayStrategy

This strategy uses a dialog to display error message to user. Dialog also contains a details pane which can be expanded, and which contains exception details, ie. stack trace.

This class is customizable, in that it allows user to specify custom exception message pattern, and also to provide internationalized strings for different language.


Service injection

Acapulco Framework provides easy access to registered OSGI services in client objects. This is achieved with minimal effort, using annotations. Framework processes these annotations and injects services into corresponding fields. Further, service lifecycle is tracked and fields are updated correspondingly.


Service annotations

Access to OSGI services is achieved by two annotations: @ServiceTracker and @ServiceRef. This is all users need to use. Behind the scenes, Acapulco Framework uses OSGI infrastructures (such as service listeners and service trackers) to achieve this.

@ServiceTracker is a class level annotation, and is used to mark that annotated class is interested in tracking OSGI services. If this annotation is not present, @ServiceRef annotations are ignored.

@ServiceRef is a field-level annotation, and marks that annotated field should be injected with corresponding service object (if one exists). Type of the field must be the type of the service being injected. It is important to note that field type must be an interface, not a class. This is due to the fact that Acapulco uses JDK dynamic proxies behind the scenes, and using interfaces is required. Since OSGI services are mostly registered as interfaces with different implementations, this is not a severe limitation.


Deployment

One of the most tedious tasks with Java applications is deployment. Som e of the most common deployment methods are:

  • simple .zip archives, with a shell script to run the application. This is the simplest deplyoment method for developers, but it makes the user feel like application is weired and unnatiral for their paltform
  • Java Web Start provides more control, but it requires web server and still does not add to natural “look and feel” of the application
  • Windows-style GUI installer wizards give the closest match to native applications installer, but it's downfall is that they are platform specific. Further more, platforms like Linux don't use these installer, but rather package managers. Mac OS uses it's own formats

Acapulco Framework tries to address these issue by providing developers a way to create paltform-specific installers and packages that resemble to native applications. Also, it provides native launcher for different platform, that makes applications even more like a first-class citizens.


Available deployment options

Currently, Acapulco Framework provides the following deployment options:

  • Multi-platform GUI wizard installer, based on IzPack project (http://izpack.org). The installer can be further customized for paltform specific launch options.
  • RPM packages for Linux system based on Red Hat package manager. Versions with both 32-bit and 64-bit native launcher are provided
  • DEB packages for Debian based Linux distros (such as Debian, Ubuntu, Mint etc). Also comes in 32-bit and 64-bit version.

All these options provide highest possible level of desktop integration, such as icons, desktop and menu shortcuts, and discovery of Java runtime environment on user's machine. Installer for each platform is as close as possible for to native application installer.


GUI installer wizard

Acapulco Framework uses IzPack tool to create multi-paltform GUI installation wizards. All resources, such as native launcher, desktop shortcuts, configuration files etc. are provided by the framework. Complete installers with default configuration can be created as part of the build process.

For customized installers, some tweaking of the configuration files is needed, but for most situations, default configuration will do.

Using tools from IzPack distribution, developers can further enhance installers, especially for Windows and Mac OS X platform. IzPack provides tools which create native self-extracting archive which can be used to run the installer.


RPM packages

For RPM based Linux distributions (such as Fedora, Mandriva, OpenSUSE), Acapulco Framework can crate native RPM packages, which can be installed using distribution's package manager, or deployed into distribution software repository.

Packages also provide native launcher, desktop and menu shortcuts etc, to allow for better integration and user experience.

These packages can only be built on Linux systems which have rpm tool installed.

Note: Various Linux distributions have different policies about shortcut file handling, so it might not work as expected in all distribution, and it also depends on whether KDE/GNOME or some other desktop environment is used.


DEB packages

There is also an option to create DEB packages for Debian based disttributions, such as Debian, Ubuntu or Mint. Just as RPM packages, they provide tight integration with paltform they are deployed on.

These packaged can only be built on systems which have dpkg-deb tool installed.


Mac OS X application bundles

For Mac OS X platform, framework has built-in support for creating application bundles from developed applications. Acapulco Framework provides default bundle configuration which is sufficient for most cases, but can be further customized for specific needs.

Mac OS X application bundles are simply directories with specific structure and “.app” extension. These directories appear as ordinary directories on all platforms except Mac OS, where there are handled in different manner. The framework provides complete support to treat these bundles as full-blown native bundles.


Native launcher

Acapulco Framework provides native launcher for a different paltforms, namely for Windows, x86 and x86_64 Linux, and Mac OS X. This launcher is used to search for Java runtime installation on user's machine and to launch the application.

Launcher is configurable through INI style configuration file. It can launch specified .jar archives and accepts different JRE options, globally or for specific paltform.

Personal tools