Introduction
Errai thinks of everything in terms of services. Their original intent was to provide a way for client-side components to communicate with one another seamlessly. A producer sends a message...a consumer receives one.
That simplicity led to the ability for components deployed on the same server (but, say, in different WARs) to talk to one another (think RHQ Perspectives) with Errai providing the underlying interop infrastructure for those communicating components. Thus, you can have distinct features at the project level, but easily bind many projects together and have a larger integrated story.
Taking that concept one step further, they figure if it was possible to interop between disparate applications client-side, why can't that same concept be extended to the server too? And so they did. Today, server components can initiate requests to clients, just as easily as clients can request data from server services.
Current Usage
-
Drools Guvnor
-
Riftsaw Console
Serialization
Basically, anything object you want to be part of some Errai service API, you need to add @ExposedEntity to. It would be nice if Errai just scanned the classpath for anything with @Entity (Hibernate and JPA annotations). However, even though, RHQ has something like 130+ entities, it also has dozens of composite objects too. So the ideal solution would be to give Errai a classpath entry, and for it to treat all objects it finds there as exposed entities.
Mike Brock, Errai Project Lead, explains that they considered these other solutions, but ultimately decided there were security issues with those approached. By requiring explicit exposure, he continued, you're forcing people to have an awareness of what they're doing. Another concern was code-size penalties against exposing things by default, since Errai has to generate de/serializer stubs.
Luckily, Errai provides the ability for users to add configuration extensions to override the default bootstrapping behavior. For example, this is what the extension would look like which automatically exposed all entities:
@ExtensionComponent
public class ErraiPersistenceConfigurator implements ErraiConfigExtension {
private ErraiServiceConfigurator config;
private Logger logger = LoggerFactory.getLogger(this.getClass());
@Inject
public ErraiPersistenceConfigurator(config) {
this.config = config;
}
public void configure(Map<Class, Provider> bindings, Map<String, Provider> resourceProviders) {
ConfigUtil.visitAllTargets(roots, new ConfigVisitor() {
public void visit(Class<?> clazz) {
if (clazz.isAnnotationPresent(Entity.class)) {
cfg.getAllSerializedTypes().add(clazz);
}
});
}
}
For more info, see the Errai docs.