9. Automatic Configuration
Autoscan Functionality
The following configuration activates the automatic configuration scanner:
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE granite-config PUBLIC "-//Granite Data Services//DTD granite-config internal//EN" "http://www.graniteds.org/public/dtd/2.0.0/granite-config.dtd"> <granite-config scan="true"> <!-- Other explicit configuration settings --> </granite-config>
This scanner has two functionalities; GraniteDS configuration and services configuration.
GraniteDS Configuration:
First, the scan="true" attribute instructs the GraniteDS startup class to scan all jars containing a META-INF/granite-config.properties and to look for configurable classes. This includes:
- Externalizers
- Exception converters
- Custom type converters
- Class getter
- Message interceptor
Externalizers and exception converters are automatically registered in GraniteDS; that is, all classes implementing respectively org.granite.messaging.amf.io.util.externalizer.Externalizer or org.granite.messaging.service.ExceptionConverter are handled.
Class getter, type converters, and message interceptor have to be defined in granite-config.properties:
classGetter=path.to.my.ClassGetter amf3MessageInterceptor=path.to.my.Amf3MessageInterceptor converter.1=path.to.my.Converter1 converter.2=path.to.my.Converter2 converter.3=path.to.my.Converter3 ... converter.(n)=path.to.my.Converter(n)
In most cases, this means that no particular configuration is needed in granite-config.xml, other than putting the library-specific granite jars in the server classpath. For example, granite-hibernate.jar already defines standard Hibernate externalizers, exception converters, and class getter.
Of course, it is also possible to use this for custom configuration. Just put a META-INF/granite-config.properties in the jar containing your custom externalizers and converters, and make sure this jar is accessible in the same class loader used by the standard granite.jar package (i.e., the classpath where granite.jar is declared must also contain your custom jar).
Automatic configuration is always overriden by anything defined in the granite-config.xml file.
Flex Services Configuration:
Secondly, and most importantly, the scanner will scan jars containing META-INF/services-config.properties. It will look for classes annotated with @RemoteDestination, and automatically register them as GDS services. As this depends on each server framework, more details are provided in the Integration with Server Frameworks section, mainly for EJB 3 and Spring.
Note that automatic configuration only works with RemoteObject(s) that are dynamically configured in your MXML or ActionScript3 code. For example, you may not use this kind of MXML declaration, because the Flex compiler won't be able to match the myDestination attribute against any services-config.xml declaration:
<mx:RemoteObject id="srv" destination="myDestination" />
Instead, you should create your RemoteObject this way:
[Bindable] private var srv:RemoteObject = null; private function init():void { srv = new RemoteObject(); // For Flex 2 only (may be skipped with Flex 3+) srv.endpoint = ServerConfig.getChannel("my-graniteamf").endpoint; srv.destination = "myDestination"; srv.channelSet = new ChannelSet(); srv.channelSet.addChannel(ServerConfig.getChannel("my-graniteamf")); ... }
Note that you still need a services-config.xml with a valid service, factory, and channel declaration at compilation time. For example, with an EJB 3 factory:
<?xml version="1.0" encoding="UTF-8"?> <services-config> <services> <service id="granite-service" class="flex.messaging.services.RemotingService" messageTypes="flex.messaging.messages.RemotingMessage"> <!-- No destination configuration needed --> </service> </services> <factories> <factory id="ejbFactory" class="org.granite.messaging.service.EjbServiceFactory"> <properties> <lookup>myApplication/{capitalized.destination.id}ServiceBean/local</lookup> </properties> </factory> </factories> <channels> <channel-definition id="my-graniteamf" class="mx.messaging.channels.AMFChannel"> <endpoint uri="http://{server.name}:{server.port}/{context.root}/graniteamf/amf" class="flex.messaging.endpoints.AMFEndpoint"/> </channel-definition> </channels> </services-config>
