Well, the good news is that I took the approach of starting HiveMind in a
servlet context listener and binding it to the ServletContext. I then
overrode Tapestry's ApplicationServlet to get the registry from the
Servletcontext rather than create its own. It works (I can use daos from
HiveMind in spring beans), except for injecting Application State Objects
has broken. Whenever I try to inject the visit object into a page (where via
an annotation or the page specification) I get:
Error at context:/WEB-INF/Register.page, line 7, column 21: Method 'public
abstract app.Visit page.Register.getVisit()' (declared in class
page.Register) has no implementation in class page.Register (or enhanced
subclass $Register_0).
I have reverted back to using the original ApplicationServlet and not using
a hivemind context listener, and the page works no problem. The page also
works no problem with the hivemind listener approach as long as I don't try
to inject the visit object.
So I get a little nervous mucking around with Tapestry's Application
servlet. And I have been trying to isloate what exactly causes the app to
break. It's not overriding the ApplcationServlet; It's the context listener
that starts HiveMind. I also tried binding the registry using a different
key in the context listener (foo, instead of
org.apache.tapestry.Registry:...) and it still breaks. So I don't know what
the deal is. It is probably stuff that is beyond my pay grade.
Here is the code (note that "myServlet" is hardcoded as the name of the
servlet because I couldn't figure out how to get it dynamically):
--------------------------------------------------------------------------------
package listener;
import java.util.Locale;
import javax.servlet.ServletConfig;
import javax.servlet.ServletContext;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.hivemind.ClassResolver;
import org.apache.hivemind.ErrorHandler;
import org.apache.hivemind.Registry;
import org.apache.hivemind.Resource;
import org.apache.hivemind.impl.DefaultClassResolver;
import org.apache.hivemind.impl.RegistryBuilder;
import org.apache.hivemind.impl.StrictErrorHandler;
import org.apache.hivemind.impl.XmlModuleDescriptorProvider;
import org.apache.hivemind.util.ContextResource;
public class HiveMindRegBuilderContextListener implements
ServletContextListener {
private static final String REGISTRY_KEY_PREFIX =
"org.apache.tapestry.Registry:";
private static final Log LOG =
LogFactory.getLog(HiveMindRegBuilderContextListener.class);
private ClassResolver _resolver;
private String _registryKey;
private Registry _registry;
public void contextInitialized(ServletContextEvent event) {
_registryKey = REGISTRY_KEY_PREFIX +
"myServlet";//event.getServletContext().getServletContextName();
_resolver = createClassResolver();
try
{
_registry = constructRegistry(event.getServletContext());
event.getServletContext().setAttribute(_registryKey, _registry);
}
catch (Exception ex)
{
System.out.println("ERROR starting HiveMind: " + ex);
throw new
RuntimeException();//TapestryMessages.servletInitFailure(ex), ex);
}
System.out.println("HIVEMIND REGISTRY SET");
}
public void contextDestroyed(ServletContextEvent event) {
event.getServletContext().removeAttribute(_registryKey);
if (_registry != null)
{
_registry.shutdown();
_registry = null;
}
}
protected Registry constructRegistry(/*ServletConfig config*/ServletContext
context)
{
ErrorHandler errorHandler = new StrictErrorHandler();
RegistryBuilder builder = new RegistryBuilder(errorHandler);
builder.addModuleDescriptorProvider(new
XmlModuleDescriptorProvider(_resolver));
String name =
"rex";//context.getServletContextName();//config.getServletName();
//ServletContext context = config.getServletContext();
addModuleIfExists(builder, context, "/WEB-INF/" + name +
"/hivemodule.xml");
addModuleIfExists(builder, context, "/WEB-INF/hivemodule.xml");
return builder.constructRegistry(Locale.getDefault());
}
protected ClassResolver createClassResolver()
{
return new DefaultClassResolver();
}
protected ErrorHandler constructErrorHandler(ServletConfig config)
{
return new StrictErrorHandler();
}
protected void addModuleIfExists(RegistryBuilder builder, ServletContext
context, String path)
{
Resource r = new ContextResource(context, path);
if (r.getResourceURL() == null)
return;
builder.addModuleDescriptorProvider(new
XmlModuleDescriptorProvider(_resolver, r));
}
}
--------------------------------------------------------------------------------------
package servlet;
import javax.servlet.ServletConfig;
import org.apache.hivemind.Registry;
import org.apache.tapestry.ApplicationServlet;
public class HMRegRetrieverApplicationServlet extends ApplicationServlet {
private static final String REGISTRY_KEY_PREFIX =
"org.apache.tapestry.Registry:";
protected Registry constructRegistry(ServletConfig config) {
return
(Registry)config.getServletContext().getAttribute(REGISTRY_KEY_PREFIX +
"myServlet" /*config.getServletContext().getServletContextName()*/);
}
public void destroy() {
}
}
-----------------------------------------------------------------
package app.hivemind;
import java.io.IOException;
import java.net.URL;
import java.util.Locale;
import java.util.Enumeration;
import javax.servlet.*;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.hivemind.ClassResolver;
//import org.apache.hivemind.ErrorHandler;
import org.apache.hivemind.ModuleDescriptorProvider;
import org.apache.hivemind.Registry;
import org.apache.hivemind.Resource;
import org.apache.hivemind.impl.DefaultClassResolver;
//import org.apache.hivemind.impl.DefaultErrorHandler;
import org.apache.hivemind.impl.RegistryBuilder;
import org.apache.hivemind.impl.XmlModuleDescriptorProvider;
import org.apache.hivemind.parse.ModuleDescriptor;
import org.apache.hivemind.util.ClasspathResource;
import org.apache.hivemind.util.FileResource;
import org.springframework.beans.BeansException;
import org.springframework.beans.FatalBeanException;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.FactoryBean;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.ApplicationContextException;
import org.springframework.core.io.ClassPathResource;
import org.springframework.util.Assert;
import org.springframework.web.context.WebApplicationContext;
/**
* [EMAIL PROTECTED] FactoryBean} implementation that locates the HiveMind
[EMAIL PROTECTED]
Registry} for a Tapestry
* servlet. <p/> This assumes that the Tapestry servlet has already been
inited.
*/
public class RegistryFactoryBean implements FactoryBean, InitializingBean,
ApplicationContextAware {
// org.apache.tapestry.ApplicationServlet defines this but only
privately!
public static final String REGISTRY_KEY_PREFIX =
"org.apache.tapestry.Registry:";
private WebApplicationContext applicationContext;
private String tapestryServletName;
private Registry registry;
public Object getObject() throws Exception
{
return this.registry;
}
public Class getObjectType()
{
return Registry.class;
}
public boolean isSingleton()
{
return true;
}
public void setApplicationContext(ApplicationContext applicationContext)
throws BeansException
{
if (!(applicationContext instanceof WebApplicationContext))
throw new FatalBeanException(
"TapestryRegistryLocatorBean must be installed in a
Spring WebApplicationContext!");
this.applicationContext = (WebApplicationContext)
applicationContext;
}
public void afterPropertiesSet() throws Exception
{
ServletContext context = applicationContext.getServletContext();
String registryKey = REGISTRY_KEY_PREFIX + this.tapestryServletName;
registry = (Registry) context.getAttribute(registryKey);
}
public void setTapestryServletName(String tapestryServletName)
{
this.tapestryServletName = tapestryServletName;
}
}
----------------------------------------------------------------
/*
* Copyright 2002-2004 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package app.hivemind;
import org.apache.hivemind.Registry;
import org.springframework.beans.factory.FactoryBean;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.context.ApplicationContextException;
import org.springframework.util.Assert;
/**
* <code>FactoryBean</code> implementation that acts as an adapter to a
HiveMind <code>Registry</code>
* allowing for any HiveMind service to be exposed as a Spring bean.
* <p/>
* Both the <code>serviceInterface</code> and <code>registry</code>
properties are required. By default,
* services are retreived from the HiveMind <code>Registry</code> using the
service interface only.
* If a value is supplied for the <code>serviceName</code> property, then
both the service interface
* and service name will be used when looking for the service in HiveMind.
*
* @author Rob Harrop
* @author Thierry Templier
* @see Registry
* @see RegistryFactoryBean
* @see #setServiceInterface(Class)
* @see #setServiceName(String)
* @see #setRegistry(org.apache.hivemind.Registry)
*/
public class ServiceFactoryBean implements FactoryBean, InitializingBean {
/**
* The HiveMind <code>Registry</code> from which services are accessed.
*/
private Registry registry;
/**
* The name of the HiveMind service to access.
*/
private String serviceName;
/**
* The <code>Class</code> name of the of the HiveMind service.
*/
private Class serviceInterface;
/**
* Sets the interface of the HiveMind service to be accessed.
*/
public void setServiceInterface(Class serviceInterface) {
Assert.isTrue(serviceInterface.isInterface(), "Cannot use a Class for the
service interface");
this.serviceInterface = serviceInterface;
}
/**
* Sets the service name of the HiveMind service to be accessed.
*/
public void setServiceName(String serviceName) {
this.serviceName = serviceName;
}
/**
* Sets the HiveMind <code>Registry</code> used to load services.
*/
public void setRegistry(Registry registry) {
this.registry = registry;
}
/**
* Gets the Hivemind service from the <code>Registry</code>.
*/
public Object getObject() throws Exception {
return getServiceObject();
}
public Class getObjectType() {
// can we use singletons and cache here?
return getServiceObject().getClass();
}
public boolean isSingleton() {
return false;
}
/**
* Checks if the registry and serviceInterface properties are specified. If
no corresponding service is
* configured in the Hivemind <code>Registry</code>, an
<code>ApplicationContextException</code> is thrown.
*/
public void afterPropertiesSet() throws Exception {
if (registry == null) {
throw new ApplicationContextException("Property [registry] of class [" +
ServiceFactoryBean.class
+ "] is required.");
}
if (serviceInterface == null) {
throw new ApplicationContextException("Property [serviceInterface] of
class [" + ServiceFactoryBean.class
+ "] is required.");
}
// check that the service exists for fail fast behaviour
boolean containsService = false;
if (serviceName == null) {
containsService =
registry.containsService(serviceInterface);
}
else {
containsService = registry.containsService(serviceName,
serviceInterface);
}
if (!containsService) {
throw new ApplicationContextException("Service with interface [" +
serviceInterface.getName() +
"] and name [" + serviceName + "] is not
present in registry.");
}
}
/**
* Get the Hivemind service from the <code>Registry</code>.
*/
private Object getServiceObject() {
if (serviceName == null) {
return registry.getService(serviceInterface);
}
else {
return registry.getService(serviceName,
serviceInterface);
}
}
}
------------------------------------------------------------------
web.xml snippet:
<listener>
<listener-class>listener.HiveMindRegBuilderContextListener</listener-class>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<servlet>
<servlet-name>myServlet</servlet-name>
<servlet-class>servlet.HMRegRetrieverApplicationServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
--------------------------------------------------------------------
applicationContext.xml snippet:
<bean id="hivemindRegistry" class="app.hivemind.RegistryFactoryBean">
<property name="tapestryServletName">
<value>myServlet</value>
</property>
</bean>
<bean id="userService" class="app.hivemind.ServiceFactoryBean">
<property name="registry">
<ref local="hivemindRegistry"/>
</property>
<property name="serviceInterface">
<value>service.UserService</value>
</property>
</bean>
-------------------------------------------------------------------------
That's all.
----Original Message Follows----
From: Chris Nelson <[EMAIL PROTECTED]>
Reply-To: "Tapestry users" <[email protected]>
To: Tapestry users <[email protected]>
Subject: Re: Using Tapestry HiveMind services in Spring
Date: Mon, 2 Jan 2006 15:09:59 -0800 (PST)
MIME-Version: 1.0
Received: from mail.apache.org ([209.237.227.199]) by
bay0-mc8-f5.bay0.hotmail.com with Microsoft SMTPSVC(6.0.3790.211); Mon, 2
Jan 2006 15:10:34 -0800
Received: (qmail 38187 invoked by uid 500); 2 Jan 2006 23:10:21 -0000
Received: (qmail 38176 invoked by uid 99); 2 Jan 2006 23:10:21 -0000
Received: from asf.osuosl.org (HELO asf.osuosl.org) (140.211.166.49) by
apache.org (qpsmtpd/0.29) with ESMTP; Mon, 02 Jan 2006 15:10:21 -0800
Received: pass (asf.osuosl.org: local policy)
Received: from [66.218.93.173] (HELO web42005.mail.yahoo.com)
(66.218.93.173) by apache.org (qpsmtpd/0.29) with SMTP; Mon, 02 Jan 2006
15:10:19 -0800
Received: (qmail 6606 invoked by uid 60001); 2 Jan 2006 23:09:59 -0000
Received: from [64.241.37.140] by web42005.mail.yahoo.com via HTTP; Mon, 02
Jan 2006 15:09:59 PST
X-Message-Info: JGTYoYF78jEHjJx36Oi8+Z3TmmkSEdPtfpLB7P/ybN8=
Mailing-List: contact [EMAIL PROTECTED]; run by ezmlm
Precedence: bulk
List-Unsubscribe: <mailto:[EMAIL PROTECTED]>
List-Help: <mailto:[EMAIL PROTECTED]>
List-Post: <mailto:[email protected]>
List-Id: "Tapestry users" <tapestry-user.jakarta.apache.org>
Delivered-To: mailing list [email protected]
X-ASF-Spam-Status: No, hits=0.5 required=10.0tests=DNS_FROM_RFC_ABUSE
X-Spam-Check-By: apache.org
DomainKey-Signature: a=rsa-sha1; q=dns; c=nofws; s=s1024; d=yahoo.com;
h=Message-ID:Received:Date:From:Subject:To:In-Reply-To:MIME-Version:Content-Type:Content-Transfer-Encoding;
b=ORTiVwW6Jo0Wa0FZtzN9IC8OTtmc5xUnP+yBKzmagRATMkvZNhlKiq8biuzhRiPQWorsVNbzO9/buhq8C9n4zpANroFI0h41zVl0bl0aI0Hu0uQuLcyWS0GFgb4oyzN45T6HxULns8lHbWlMJqMwFjKFPynej1WA8sXaF0+NQJ4=
;
X-Virus-Checked: Checked by ClamAV on apache.org
Return-Path:
[EMAIL PROTECTED]
X-OriginalArrivalTime: 02 Jan 2006 23:10:34.0173 (UTC)
FILETIME=[BBF776D0:01C60FF1]
Yes, I was afraid that would be a problem. One thing
to point out, if you build a HiveMind context loader
listener (which seems like a good way to go) you will
also need to subclass the Tapestry ApplicationServlet
and override the contructRegistry method to pull off
the registry from the ServletContext instead of
creating a new one.
If you get all this working, I would really appreciate
if you posted the code. I will need this same thing
for Trails. Currently we have some really ugly code
in i18N for fetching the Locale from Hivemind and I
would like to replace it with proper Spring/Hivemind
integration.
TIA,
Chris
--- John Smith <[EMAIL PROTECTED]> wrote:
> This looks really good. I have been trying it out,
> but the assumption about
> HiveMind being already initiated is tripping me up.
> When the bean is
> creating, the HiveMind registry hasn't been created
> yet. So I am trying to
> either delay the lookup in the bean, or force
> HiveMind to come up first. No
> luck yet.
>
> In my web.xml, I have a context listener set up for
>
org.springframework.web.context.ContextLoaderListener.
> I am thinking that I
> will need to create a new context listener for
> starting HiveMind before
> spring.
>
> ----Original Message Follows----
> From: Geoff Longman <[EMAIL PROTECTED]>
> Reply-To: "Tapestry users"
> <[email protected]>
> To: Tapestry users
> <[email protected]>
> Subject: Re: Using Tapestry HiveMind services in
> Spring
> Date: Mon, 2 Jan 2006 14:39:57 -0500
> MIME-Version: 1.0
> Received: from mail.apache.org ([209.237.227.199])
> by
> bay0-mc12-f13.bay0.hotmail.com with Microsoft
> SMTPSVC(6.0.3790.211); Mon, 2
> Jan 2006 11:40:25 -0800
> Received: (qmail 13602 invoked by uid 500); 2 Jan
> 2006 19:40:21 -0000
> Received: (qmail 13591 invoked by uid 99); 2 Jan
> 2006 19:40:21 -0000
> Received: from asf.osuosl.org (HELO asf.osuosl.org)
> (140.211.166.49) by
> apache.org (qpsmtpd/0.29) with ESMTP; Mon, 02 Jan
> 2006 11:40:21 -0800
> Received: pass (asf.osuosl.org: domain of
> [EMAIL PROTECTED] designates
> 66.249.82.193 as permitted sender)
> Received: from [66.249.82.193] (HELO
> xproxy.gmail.com) (66.249.82.193) by
> apache.org (qpsmtpd/0.29) with ESMTP; Mon, 02 Jan
> 2006 11:40:18 -0800
> Received: by xproxy.gmail.com with SMTP id
> s9so1616262wxc for
> <[email protected]>; Mon, 02 Jan 2006
> 11:39:58 -0800 (PST)
> Received: by 10.70.74.3 with SMTP id
> w3mr12791026wxa; Mon, 02 Jan
> 2006 11:39:57 -0800 (PST)
> Received: by 10.70.27.19 with HTTP; Mon, 2 Jan 2006
> 11:39:57 -0800 (PST)
> X-Message-Info:
> JGTYoYF78jEHjJx36Oi8+Z3TmmkSEdPtfpLB7P/ybN8=
> Mailing-List: contact
> [EMAIL PROTECTED]; run by ezmlm
> Precedence: bulk
> List-Unsubscribe:
>
<mailto:[EMAIL PROTECTED]>
> List-Help:
> <mailto:[EMAIL PROTECTED]>
> List-Post: <mailto:[email protected]>
> List-Id: "Tapestry users"
> <tapestry-user.jakarta.apache.org>
> Delivered-To: mailing list
> [email protected]
> X-ASF-Spam-Status: No, hits=-0.0
> required=10.0tests=SPF_PASS
> X-Spam-Check-By: apache.org
> DomainKey-Signature: a=rsa-sha1; q=dns; c=nofws;
> s=beta; d=gmail.com;
>
>
h=received:message-id:date:from:to:subject:in-reply-to:mime-version:content-type:content-transfer-encoding:content-disposition:references;
>
>
>
b=FdoS8ng1Y6MgfsLZH/f07Tp4LjroBow4SLYUPdI80UiwGGMIyG2ca2OxuCopUVSy88Y6yWOftLu+jyNRlZBsnjmTzPVGLDebvMDLMXMGbTb74M5mB2aTwau11YV07C8VnvS8wrfjC1R5GMuNZaHDMEo9z+zhxAccoXVpP8KQn/0=
> References:
> <[EMAIL PROTECTED]>
> X-Virus-Checked: Checked by ClamAV on apache.org
> Return-Path:
>
[EMAIL PROTECTED]
> X-OriginalArrivalTime: 02 Jan 2006 19:40:25.0344
> (UTC)
> FILETIME=[6084D800:01C60FD4]
>
> I think you can replace thier RegistryFactoryBean
> with the following
> and still use thier ServiceFactoryBeans. (whipped
> this up, it's
> untested)
>
>
> Geoff
>
> /**
> * [EMAIL PROTECTED] FactoryBean} implementation that locates
> the HiveMind [EMAIL PROTECTED]
> Registry} for a Tapestry
> * servlet. <p/> This assumes that the Tapestry
> servlet has already been
> inited.
> */
> public class TapestryRegistryLocatorBean implements
> FactoryBean,
> InitializingBean,
> ApplicationContextAware
> {
>
> // org.apache.tapestry.ApplicationServlet
> defines this but only
> privately!
> public static final String REGISTRY_KEY_PREFIX
> =
> "org.apache.tapestry.Registry:";
>
> private WebApplicationContext
> applicationContext;
>
> private String tapestryServletName;
>
> private Registry registry;
>
> public Object getObject() throws Exception
> {
> return this.registry;
> }
>
> public Class getObjectType()
> {
> return Registry.class;
> }
>
> public boolean isSingleton()
> {
> return true;
> }
>
> public void
> setApplicationContext(ApplicationContext
> applicationContext) throws BeansException
> {
> if (!(applicationContext instanceof
> WebApplicationContext))
> throw new FatalBeanException(
> "TapestryRegistryLocatorBean
> must be installed in
> a Spring WebApplicationContext!");
>
> this.applicationContext =
> (WebApplicationContext)
> applicationContext;
> }
>
> public void afterPropertiesSet() throws
> Exception
> {
> ServletContext context =
> applicationContext.getServletContext();
>
> String registryKey = REGISTRY_KEY_PREFIX +
> this.tapestryServletName;
>
> registry = (Registry)
> context.getAttribute(registryKey);
>
> }
>
> public void setTapestryServletName(String
> tapestryServletName)
> {
> this.tapestryServletName =
> tapestryServletName;
> }
> }
>
>
>
> On 1/2/06, John Smith <[EMAIL PROTECTED]> wrote:
> > I am using acegi with spring for the web security
> of my site. However,
> the
> > login process needs to be able to query the
> database to get information
> > about the user account (something different than
> just validating username
> > and password). Then I need to set the username on
> the Visit object. I
> > already have acegi working, and I already have a
> DAO for user information
> > working in HveMind.
> >
> > Now I am trying to use the DAO from HivemMind in
> my acegi security beans.
> I
> > could just create a spring DAO and then just have
> two sets DAOs (one for
> > spring and one for hivemind), but I would like
> the
=== message truncated ===
__________________________________________
Yahoo! DSL Something to write home about.
Just $16.99/mo. or less.
dsl.yahoo.com
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]