Across in a nutshell

Across is a Java framework that aims to facilitate module based development for Java (web) applications. It builds heavily on Spring framework and allows defining a module consisting of a number of classes and configuration files. Every module defines its own Spring application context and can share one or more beans with other modules.

Across modules can contain any set of functionality: low-level add-ons like facilities to activate caching or end user functionality including web controllers and their views. Across provides the basic infrastructure to define modules and make them depend on each other. A module will most often be a separate jar, but this is in no way a requirement.

The general principle is that every Across module can depend on others, but is responsible for its own installation and start-up procedures. To this end, a module can define its own installers.

Before you begin

To understand what Across is and how it works you should have good knowledge of Java web development as well as Spring framework and Spring Web MVC. At the very least you should be familiar with the concepts of dependency injection (auto-wiring), the ApplicationContext and JavaConfig configuration style.

1. About Across

1.1. Modular development

Across framework aims to facilitate module based development of your Java applications. An application would simply consist of a collection of modules, where each module brings a set of functionality to the table. Modules are somewhat knowledgeable, they know about the application/set-up they are running in and can make decisions based on that knowledge. They know about other modules and the services they provide, and they are able to talk to those other modules to provide automatic integration.

Well defined modules can offload work from the developer. The development team does not need to make the same decisions over and over again for every new application. With a well defined module it needs to be made only once, and in new applications the same module will make the same reliable decision.

For modules to be able to do this they have to speak a common language. In software development terms this means they need to implement a same contract (usually in the form of interfaces or base classes). Providing that common language is what Across framework is about.

Across framework gives developers an easy way to create, configure and reuse smart modules.

1.2. The difference between libraries and modules

The terms libraries and modules are sometimes used interchangeably in the software development landscape. The exact meaning depends on the context. When talking about Across we identify the following difference between the two:

A library

Provides a set of low-level building blocks, infrastructure that can be used to build application logic. Libraries are dumb, they only do exactly as they have been told by a developer.

In a car analogy libraries could be wheels and frames. Someone - a developer - would still need to decide how to assemble the different components to achieve an actual car.

In this context Apache Commons is a library, but so is Spring framework as well as the Across core itself.

A module

Provides more high-level building blocks in the form of complete functionality requiring little or even no configuration. Even with just a few modules present you could get a fully functional application. Modules are smart, they can make decisions based on their knowledge of the environment they are running in.

In the car analogy a module could in fact be an entire car. The car knows how to drive, it knows it has four wheels and knows the state of every one of them. Configuration of the module could be the decision of the engine you’d want.

As to deciding whether you want a module or a library, think of it this way: are you required to build a car, or is your mission to travel from A to B and you simply need a car to be able to do so?

In all Across documentation we refer to a module as an implementation of an AcrossModule that provides a set of functionality out of the box.

1.3. Across standard modules

Apart from the Across framework itself, a different project maintains a set of Across standard modules. These modules aim to be productivity enhancers by providing you with a common set of functionality that can be used as the foundation for your applications or even for an entire web cms.

There are standard modules that provide you with the set-up for an administrative web interface, secured with Spring security and built on top of an entire roles and permissions management domain layer. Other modules generate web forms at runtime for persistent entities you have declared in your application.

Across framework provides only a ground layer, the real win is in re-using well-defined modules that have already been built. The standard modules projects aims to do exactly that: bring some best of breed modules to the open source Across landscape.

1.4. Across and Spring framework

Spring framework is a de facto industry standard for building Java (web) applications. It was a logical choice to use it as the foundation for Across. Across extends or even customizes some aspects of Spring, but still supports most if not all common Spring functions out of the box. To use Across optimally, a good knowledge of Spring is required.

Across core and Across web build on top of the common Spring framework, while other standard modules integrate different Spring libraries like Spring Data, Spring Batch or Spring security.

1.5. Across and OSGi

While Across talks about modules just like OSGi does and some similarity between the basic concepts can be found, there is currently no relation between the two. Across modules are not OSGi and the current development does not involve developing and testing for OSGi containers.

The focus of Across is more on providing a way to group end-user functionality than it is on a dynamic runtime environment. Integrating Across applications in the OSGi landscape is on the long-term roadmap.

2. Core concepts

At the heart of Across are a couple of concepts you should understand. The terms related tot these concepts are used throughout all Across documentation, consider them part of the Across DSL.

2.1. context

2.2. modules

2.3. dependencies

2.4. bootstrap

2.5. installers

2.6. exposing

2.7. events

2.8. refreshing

3. Across framework artifacts

3.1. Overview

Across framework itself consists of 3 artifacts: across-core, across-web and across-test.

across-core

Supports the configuration of an Across context and provides all necessary infrastructure to define and execute modules.

across-web

Provides an AcrossModule that supports configuration of a web application using Across with the Spring DispatcherServlet as the most common scenario.

across-test

Supports integration testing of your Across modules, both web and non-web related. Builds on top of spring-test.

3.2. Common dependencies

Across is directly tied to Spring framework and all artifacts come with a set of curated dependencies. Applications built on top of Across should either manage the dependencies manually by fixing the versions or let the modules pull in the required dependencies transitively. A platform BOM is also provided to aid in managing dependencies.

Table 1. Most common dependency versions that almost all modules rely on

Java

1.7

Java Servlet API (if applicable)

3.0.1

Spring framework

4.1.4.RELEASE

3.3. Repository

All Across related artifacts - both release and snapshot versions - can be fetched from the Foreach Nexus repository. This also includes the set of Across standard modules.

<repositories>
    <repository>
        <id>foreach-nexus</id>
        <name>Foreach nexus</name>
        <url>http://repository.foreach.be/nexus/content/groups/public/</url>
    </repository>
</repositories>

4. Across platform BOM

Across also provides a so called bill of material POM that provides the curated list of Across related dependencies, including all standard modules. Using this BOM pom is advised as it helps you to avoid dependency conflicts and gives you the confidence that the dependency versions work together correctly.

Using the BOM can be done by including it in the dependencyManagement section of your Maven build file. Dependencies known in the platform BOM do not need a version element to be specified. If a version is omitted, the version from the BOM will be used.

<!-- Include the platform BOM with scope import -->
<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>across</groupId>
            <artifactId>platform-bom</artifactId>
            <version>1.1.0</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>

<!-- Specific dependencies do not need a version -->
<dependencies>
    <dependency>
        <groupId>across</groupId>
        <artifactId>across-web</artifactId>
    </dependency>
    <dependency>
        <groupId>across-standard-modules</groupId>
        <artifactId>debug-web</artifactId>
    </dependency>
</dependencies>

4.1. Dependency versions

The Across platform BOM extends the Spring platform BOM, the base list of dependencies can be found in the Spring platform documentation. Additionally Across platform BOM defines and overrides the following dependencies:

Group

Artifact

Version

org.liquibase

liquibase.core

3.1.0

com.mattbertolini

liquibase-slf4j

1.2.1

org.apache.commons

commons-collections4

4.0

net.engio

mbassador

1.2.0

com.mysema.querydsl

querydsl-core

3.5.1

com.mysema.querydsl

querydsl-apt

3.5.1

com.mysema.querydsl

querydsl-jpa

3.5.1

org.hibernate

hibernate-core

4.2.14.Final

org.hibernate

hibernate-entitymanager

4.2.14.Final

org.hibernate

hibernate-validator

4.3.2.Final

org.jboss.logging

jboss-logging

3.1.3.GA

javax.validator

validation-api

1.0.0.GA

cglib

cglib

3.1

mysql

mysql-connector-java

5.1.31

com.oracle

ojdbc6

11.2.0

net.sourceforge.jtds

jtds

1.2.8

com.foreach.libs

common-concurrent

0.11

com.foreach.libs

common-spring

0.11

com.foreach.libs

common-web

0.11

com.foreach.libs

common-test

0.11

across

across-core

1.1.0

across

across-web

1.1.0

across

across-test

1.1.0

across-standard-modules

across-hibernate

1.1.0

across-standard-modules

across-ehcache

1.1.0

across-standard-modules

debug-web

1.1.0

across-standard-modules

admin-web

1.1.0

across-standard-modules

spring-security

1.1.0

across-standard-modules

spring-security-acl

1.1.0

across-standard-modules

oauth2-module

1.1.0

across-standard-modules

properties-module

1.1.0

across-standard-modules

entity-module

1.1.0

across-standard-modules

user-module

1.1.0

across-standard-modules

application-info

1.1.0

across-standard-modules

logging-module

1.1.0

across-standard-modules

filemanager

1.1.0

across-standard-modules

spring-batch

1.1.0

5. Across core

Artifact

<dependencies>
    <dependency>
        <groupId>across</groupId>
        <artifactId>across-core</artifactId>
        <version>1.1.0</version>
    </dependency>
</dependencies>

5.1. Dependencies

5.2. Creating an AcrossContext

5.2.1. Manual creation of an AcrossContext

An AcrossContext can be configured manually and is started using the bootstrap() method, and stopped using shutdown(). These methods take care of the Spring ApplicationContext lifecycle of all modules configured in the context.

AcrossContext context = new AcrossContext();
context.setParentApplicationContext( optionalParentContext );
context.setDataSource( someDataSource );
context.addModule( new SomeModule() );

// Start the context
context.bootstrap();

// Stop the context
context.shutdown();

5.2.2. Using @EnableAcrossContext and AcrossContextConfigurer

Usually your application will consist of a single AcrossContext that is configured in the main Spring ApplicationContext. You can enable the automatic creation of an AcrossContext by putting the @EnableAcrossContext on any @Configuration class. This will initialize a new AcrossContext with the main ApplicationContext as parent, look for a default datasource bean named acrossDataSource and then delegate context configuration to all AcrossContextConfigurer beans it can find in the ApplicationContext before bootstrapping.

The AcrossContext will be configured with sensible defaults but all settings can be overridden in any AcrossContextConfigurer.

@Configuration
@EnableAcrossContext
public class WebConfiguration implements AcrossContextConfigurer
{
	@Bean
	public DataSource acrossDataSource() {
		BasicDataSource dataSource = new BasicDataSource();
		dataSource.setDriverClassName( "org.hsqldb.jdbc.JDBCDriver" );
		dataSource.setUrl( "jdbc:hsqldb:mem:/hsql/testDataSource" );
		dataSource.setUsername( "sa" );
		dataSource.setPassword( "" );

		return dataSource;
	}

	@Override
	public void configure( AcrossContext context ) {
		context.setDevelopmentMode( true );

		context.addModule( new SomeModule() );
	}
}

5.3. Datasources and installers

An AcrossContext requires at least one datasource if modules need to run installers. Certain core features like the DistributedLockRepository also require the core schema to be installed and will require a valid datasource to be configured.

The main datasource is available for all modules as a bean named acrossDataSource. Optionally a separate installer datasource can be configured that will be available as acrossInstallerDataSource. If no separate installer datasource is specified, the default across datasource will be used.

Important
A valid default datasource is always required for installers to run. It is not possible to configure only an installer datasource as the distributed locking mechanism uses the default datasource.

The installer datasource can be wired anywhere, but will be the default datasource used for all `AcrossLiquibaseInstaller instances. Its purpose is to provide a separate datasource with augmented permissions to perform schema changes and installer tracking in the database.

For security purposes the installer datasource could be closed after the context has bootstrapped. This is the responsibilty of the application configuration and be aware that some functionality related to querying the installer repository will not be available if the installer datasource goes offline.

6. Across web

artifact

link builders: prefixing path context special characters: - ! = suppress prefix - {adminWeb}/boe/test/

7. Across test

artifact