Monday, 21 December 2009

jembedded-0.1.3-Release

Hi all,

I'm very pleased to announce that I've just released the
jEmbedded-0.1.3 version.

It's much more that a collections of fixes from the previous RC
versions as I have included some features that was intended for the
0.2 version (or higher), but it gives a good preview of the future
direction of the project. In fact I though to label this one as 0.2,
but I didn't for consistency.

There are 5 very important features included in this release:

- Annotation inheritance: Now you can extend any of the core
annotations (@AnnotatedService, @AbstractAnnotatedService...) to
create you own annotations. This means that you can set up your
services directly using annotations like if you were writing and xml
bean in Spring:

Until now you were doing this (still you can of course):

@AnnotatedService(id="service", resources={WebClient.class})
public class Service extends AbstractCMTService {

@Compose(ref="webClient")
private WebClient webClient;

@Inject (value=${service.url})
private String url;

}
}

Now you could do this:

public @interface CustomAnnotatedService {

Class inherits() default @AnnotatedService; // the annotation you
want to extend.

//now you override the attributes you'd like to use (this case from
the @AnnotatedService(id, lazy clazz, etc..),
// the ones that are not overriden will be taken from the parent.

String id() default "service";

String clazz() default "org.jsemantic.jembedded.Service";

Class[] resources() default {WebClient.class};

//new attributes
String url();

}

Now the service looks like this:

@CustomAnnotatedService(url="http://code.google.com/p/jembedded")
public class Service extends AbstractCMTService {

@Compose(ref="webClient")
private WebClient webClient;

@Inject (value=${service.url})
private String url;

}

Now you can reuse this new annotation whenever you like.

The inheritance mechanism can be used with the core annotations
(AnnotatedService, AbstractAnnotatedService, AnnotatedBean,
AnnotatedComponent..).

If you have a look at the source code or to the examples you will see
that I have refactored the code to use this feature when it fits.

- @AbstractAnnotatedService

This is a very and a powerful feature that also will give you an idea
of the future direction of the framework. Now you can create a Service
using an abstract class (similar to the @AbstractService) without
needing to extend or implement anything (not even the Service
interface). You can mix regular and abstract classes and injecting or
composing fields.

This is the old example of WebServer refactored to use the new
features (also custom and inheritance annotaions).

@AnnotatedWebServer
public abstract class WebServer {

@Start
public void start() {
getJettyService().start();
}

@Stop
public void stop() {
getJettyService().stop();
}

public void setPort(String port) {
getJettyService().setPort(port);
}

//Composition, WebServer will handle the jettyService lifeCycle
@Compose(ref="httpService")
public abstract JettyService getJettyService();

@Compose(ref = "propertiesService")
@PropertiesService(propertiesFile="META-INF/web-server/web-
server.properties")
public abstract
org.jsemantic.jirepository.core.services.properties.PropertiesService
getPropertiesService();
// end of service composition

//Added functionality, you can create dynamic invoking methods from
any service
//that you may have in the container
@ImplementedBy(ref="httpService", refMethodName="getServerContext")
public abstract ServletContext getServletContext();

}

If you read the code you would notice:

- The abstract methods are implemented in real time, so you can use
then in the regular implemented methods.

- There are 2 new annotations @Start and Stop that replaces the old
startService and stopService.

- The service can be cast to Service (even though it does not need to
implement it).

- If you like the PropertiesService can be declared at class level,
this is just a choice, you have as much freedom as usual.

- @Compose new annotation: works like @Inject, but ties the lifecycle
of the composed service to the parent Service, not the container. In
other words, the composed service will be started and stopped by the
parent service. For example, if you declare the propertiesService at
class level the propertiesService will be handled by the container,
nor by the WebServer:

@AnnotatedWebServer
@PropertiesService(propertiesFile="META-INF/web-server/web-
server.properties")
public abstract class WebServer {

@Start
public void start() {
getJettyService().start();
}

@Stop
public void stop() {
getJettyService().stop();
}

public void setPort(String port) {
getJettyService().setPort(port);
}

//Composition, WebServer will handle the jettyService lifeCycle
@Compose(ref="httpService")
public abstract JettyService getJettyService();

}

In the case of the jettyService it makes sense its lifecyle it's tied
to the WebSever but you can also do this:

@AnnotatedWebServer
@PropertiesService(propertiesFile="META-INF/web-server/web-
server.properties")
public abstract class WebServer {

@Inject (you can use Compose here too), here the container will
handle the jettyService
private JettyService jettyService;

@Start
public void start() {
jettyService.start();
}

@Stop
public void stop() {
jettyService.stop();
}

public void setPort(String port) {
jettyService.setPort(port);
}

//Added functionality, you can create dynamic invoking methods
from any service
//that you may have in the container
@ImplementedBy(ref="httpService", refMethodName="getServerContext")
public abstract ServletContext getServletContext();

}

As you can see you have a lot of freedom to compose or create new
Services with the new features, you can annotate at class, method or
field leve, using abstract or regular methods.

You can also provide a interface for the service if you like or need
it.

The @AnnotatedWebServer ann looks like this:

public @interface AnnotatedWebServer {

/**
*
* @return
*/
String id() default "webServer";

/**
*
* @return
*/
Class inherits() default AbstractAnnotatedService.class;

/**
*
* @return
*/
Class[] resources() default { JettyServiceImpl.class };

}

- Integration testing framework integrated within the container and
services (jIntegration therefore is depecrated):

I've always felt that the testing process should be more integrated
into the development process so what I did was to include the testing
framework within the core framework and the services so now it's
availble at any time (I left the jUnit4 dependency optional though).

So basically now the core framework has an Assert class with some
useful classes and the same happens with the services.

For instance the core has Assert.getService(), Assert.existService()
and so on.

In order to setup a unit test class (or integration test class) you
need to use @Container and the @RunWith annotation. Keep in mind that
the Asserts are static classes so the created container must be
attached to the current thread, so you need to use the
prototype_by_thread annotation.

@RunWith(IntegrationTestClassRunner.class)
@Container(instanceType=ContainerInstanceType.PROTOTYPE_BY_THREAD)

@WebClient
@Include(resources=WebServer.class)
public class IntegrationWebServerTest {

//dispose the container between test methods invocations, if you want
to reuse the same within invocations, delete this method
@After
public void dispose() {
ContainerHolder.releaseCurrentThreadContainer();
}

@Test
public void test() {
WebServer server = (WebServer)Assert.getService("webServer");
assertNotNull(server);
}

}

As you see you don't need to create a container yourself,one will be
created for you by the testing framework.

- Ruby now it's a separate service and services can be fully
implemented with it. Have a look at the new CalculatorService example
that mix a complete ruby service with a java one.

- New Spring AOP Service.

- Core and services Refactored.

I have refactored some parts of the core but I will work more on this.
The services and annotations have been refactored as well and adapted
to the new features.

- Examples and case study.

I have completely refactored them and adapted to the new features,
trying always to simplify as much as possible.

The case study has been completely refactored and simplified (I have
removed GWT in this version), usign the new features and services. I'm
writing a complete paper about this, but I think you will find easier
to understand this time.

- RoadMap

As you can see a lot of effort has been put into this release, not
only to improve the past version but to look to into the future.
The @AsbtractAnnotateService and the annotation inheritance are 2
powerful features and examples of this. The idea is to implement all
the services and elements without any asbtract class (like
AbstractCMTService) and make the services more intelligent.

- Versions 0.1.3 to 0.2 - Maintenance and fixes. Improve Services and
examples . Complete documentation.

- Versions 0.2 ->1.0 - New features (removing the need of abstract
services etc) and new services. More scripting languages.

As I'm designing the new versions, please any features you think it
would be nice to have please let me know.

Special thanks to all of you that downloaded jEmbedded and helped me
to improve it. Your comments are always appreciated.

I will dedicate the next few weeks to upto date the documentation.
Please be patience, I promise I will do it :)

Thursday, 1 October 2009

jEmbedded - 0.1.3. RC-1 - Weekend Release

Hi,

Yes I know I've skipped 2 versions :) but the work has been progressing so well that I decided to wait a bit and release something more complete.

So I'm releasing a rc this weekend, it's still a bit rough on the edges but it contains most of the features that I'd wanted and works pretty well. Also it will fit with the new documentation that I''m going to start writing this weekend as well.

New features:

- Dynamic Injection/creation of Services: create services just with an
interface + annotations, no implementation neded, in case you are
just composing services:

@Repository(id = "serviceLayer", iocProviders = { "springRepository" }, parent = "persistenceLayer")

@AnnotatedService(id = "serviceLayer", resources= {InvoicingServiceImpl.class})

public interface ServicesLayer extends Service {

@Inject(ref="invoicingService")
public InvoicingService getInvoicingService();

@SpringRepository(configurationFile = "META-INF/invoices-app/layers/ persistence-layer.xml")
public Service getSpringRepository();

}

- Complete Spring integration: a service exporter (from jembedded) into the spring context, @Inject can reference a spring bean, a @SpringProvider annotation that will load a context as a service and can be referenced as well., a ContainerListener for web applications..
etc etc..

- More services: Validation-Service (using annotations, oval), dao-service, hibernate-service, agent-service, proxy-service.

- A payload validator for mule using the the validator-service, so you can validate your payload with annotations.

- More examples including an esb/integration case study including spring/spring-mvc, jms, mule, rules etc.. I think it shows very well what you can do with jEmbedded. Also it's an original cas study, it's not the typical aggregator of responses you can find all over the net.

- jIntegration-Test 1.0 (see the web services post).

- Fixes and more stuff.

Well I think it's pretty good for this version.

Adolfo

Sunday, 20 September 2009

And after the holidays...

I resumed my day job this last week and it wasn't very bad :) at all . So this weekend I resumed my work on jEmbedded. First of all, thanks to all the people who took the time to try it and sent me their comments, you have helped me a lot. Even though it was a early release it has given me a lot of insight in which direction I should go.

I decided to release the version 0.1.1 in the next few days that will be focused in:
  • Improved Spring Integration: The @Inject annotation will be able to reference a Spring Bean and more.
  • Improved Documentation.
  • Improved Web Support.
  • More examples: I'm adding several examples that I'm working on as a complete example of a Invoicing System including Spring MVC integration and a hierarchical services layer (you can have an early peek on the project website). That will show a lot of the jEmbedded features as creating and composing a service layer in a few minutes. Other examples will include jIntegrationTest-0.1, how to package services with jEmbedded etc...
  • Bug fixes and code refactoring.

Tuesday, 1 September 2009

jEmbedded - FAQ III

Well I'm going abroad for my holidays (it's time at last !!) so I won't be writing in a while.

I've just created a new discussion group jEmbedded Discussion Group so you are free to join and post your questions, requests etc...

After holidays want I'm going to do it's to write down a full documentation and upload more examples.

In the meantime here it's more Q/A:

* What's the difference between the @Include and @Repository annotations?

With these two annotations resources can be added to the container but in a different manner as @Repository will create a new container for the resources and @Include will just add them to the current container (default container in case you haven't provided the @Repository ann).

Use @Include if you only want to add some extra resources to the container and not to create a new one.

* Spring Integration, how to do it?

There are many different ways to do this. I've provided a spring-support-module that will help you, but in this stage it's not very comprehensive as I've focused to provide a stand alone IoC container.

In this module a FactoryBean class is provided so an instance of the embedded container can be stored into the spring-context. Then you can inject the container in any bean you want, get the container from Spring or just use ContainerHolder.getCurrentThreadContainer().
Please have a look at the spring-integration-module and the embedded-database example for more information.

You may ignore the integration module and write your own FactoryBean:

@Container(instanceType=
ContainerInstanceType.xxxx)
@Repository(id="database-service-layer", resources={EmbeddedDatabaseImpl.class})
public class EmbeddedDatabaseFactory implements FactoryBean {

public Object getObject() throws Exception {
return EmbeddedHandlerFactory.getInstance(getClass());
}

public Class getObjectType() {
return EmbeddedHandler.class;
}

public boolean isSingleton() {
return false;
}

}

Then you can retrieve the container like this:

ApplicationContex appContex; //SpringContext

EmbeddedHandler handler = (EmbeddedHandler)appContext.getBean("factory-bean-id");

Finally, you can create the container in any spring bean you'd like. Of course watch out what kind of bean it is (singleton, prototype etc...)

* Can the annotation @Inject be used to reference a Spring bean?

No at this moment, but you can inject the container to any spring bean or just accessing the container with ContainerHolder. I will add this feature in the near future.