Hello all,
I'm trying to get a setup similar to quikit but for working with
Struts2. Basically what I want is to have a Main class with a main()
method that kicks off a qi4j application. The application assemblies
are responsible for creatin a Jetty Server, adding the Struts2 filter,
and starting up the server.
I'm doing this following the petstore web example and the Quikit code.
The relevant bits are below
public class Main
{
public static void main(String[] args) throws Exception
{
ApplicationFactory appFactory = new ApplicationFactory();
Application application = appFactory.newApplication(new
Assembler[][][]
{
{ // Web layer
{
new ModuleName( "Web" ),
new JettyAssembler()
},
{
new ModuleName( "Web configuration" ),
new JettyConfigurationAssembler()
}
}
});
application.activate();
}
}
public class JettyAssembler implements Assembler {
@SuppressWarnings("unchecked")
public void assemble(ModuleAssembly module) throws AssemblyException {
// Add jetty service
module.addServices(JettyService.class).instantiateOnStartup().identifiedBy(jettyIdentity(module));
// Add the struts servlet
module.addServices(FilterDispatcherService.class)
.providedBy(FilterDispatcherServiceProviderComposite.class)
.setMetaInfo(new FilterConfiguration(urlPattern("*"),
dispatchers(REQUEST, FORWARD)));
module.addObjects(FilterDispatcher.class);
}
private String jettyIdentity(ModuleAssembly module) {
return module.name() + ":" + JettyService.class.getName();
}
}
public interface FilterDispatcherService extends Filter, ServiceComposite {
}
@Mixins({FilterDispatcherServiceProviderComposite.Mixin.class})
public interface FilterDispatcherServiceProviderComposite extends
Composite, ServiceInstanceFactory {
public final class Mixin implements ServiceInstanceFactory {
@Structure ObjectBuilderFactory objectBuilderFactory;
public final Object newInstance(ServiceDescriptor
serviceDescriptor) throws ServiceInstanceProviderException {
return objectBuilderFactory.newObject(FilterDispatcher.class);
}
public final void releaseInstance(Object instance) throws
ServiceInstanceProviderException {
FilterDispatcher filter = (FilterDispatcher) instance;
filter.destroy();
}
}
}
The problem I'm having is that the providedBy() part of registering
FilterDispatcherService is being ignored and qi4j is trying to create
the service as a composite. It fails because it can't find any
implementation for the servlet Filter methods.
Exception in thread "main"
org.qi4j.spi.composite.InvalidCompositeException: No implementation
found for method public abstract void
javax.servlet.Filter.init(javax.servlet.FilterConfig) throws
javax.servlet.ServletException in trinket.web.FilterDispatcherService
at
org.qi4j.runtime.composite.AbstractMixinsModel.implementMethod(AbstractMixinsModel.java:104)
at
org.qi4j.runtime.composite.CompositeMethodsModel.implementMixinType(CompositeMethodsModel.java:86)
at
org.qi4j.runtime.composite.CompositeMethodsModel.<init>(CompositeMethodsModel.java:49)
at
org.qi4j.runtime.composite.CompositeModel.newModel(CompositeModel.java:76)
at
org.qi4j.bootstrap.ModuleAssembly.assembleModule(ModuleAssembly.java:222)
at
org.qi4j.bootstrap.ApplicationFactory.newApplication(ApplicationFactory.java:110)
at
org.qi4j.bootstrap.ApplicationFactory.newApplication(ApplicationFactory.java:86)
I've looked at the ModuleAssembly.assembleModule() code and it looks
like if the service is a composite (which it actually has to be
according to the addServices() definition), then it tries to find a
composite model. If it can't, then it creates a new composite model.
But when it does that, it completely ignores the ServiceInstanceFactory
passed in the providedBy() method and the object provided in the
setMetaInfo() method.
Am I doing this wrong or is something broken?
Thanks,
Rich
_______________________________________________
qi4j-dev mailing list
[email protected]
http://lists.ops4j.org/mailman/listinfo/qi4j-dev