This, combined with the use of the JCR 2 bundle, is causing some test failures. It seems to be because AccessControlUtil.getAccessManager() attempts to call the getAccessManager() method specified by the javax.jcr.Session interface which isn't implemented by SessionImpl.
Possible fixes are: * Upgrade jackrabbit.server to JR 2. * Remove NamespaceMapper modifications to jcr.base and roll back to old jcr.api bundle in launchpad. WDYT? Justin On 2/11/10 8:17 AM, [email protected] wrote: > Author: cziegeler > Date: Thu Feb 11 13:17:47 2010 > New Revision: 908956 > > URL: http://svn.apache.org/viewvc?rev=908956&view=rev > Log: > SLING-1366 : Use dynamic proxy to handle session#impersonate call. > > Added: > > sling/trunk/bundles/jcr/base/src/main/java/org/apache/sling/jcr/base/SessionProxyHandler.java > (with props) > Modified: > > sling/trunk/bundles/jcr/base/src/main/java/org/apache/sling/jcr/base/AbstractSlingRepository.java > > Modified: > sling/trunk/bundles/jcr/base/src/main/java/org/apache/sling/jcr/base/AbstractSlingRepository.java > URL: > http://svn.apache.org/viewvc/sling/trunk/bundles/jcr/base/src/main/java/org/apache/sling/jcr/base/AbstractSlingRepository.java?rev=908956&r1=908955&r2=908956&view=diff > ============================================================================== > --- > sling/trunk/bundles/jcr/base/src/main/java/org/apache/sling/jcr/base/AbstractSlingRepository.java > (original) > +++ > sling/trunk/bundles/jcr/base/src/main/java/org/apache/sling/jcr/base/AbstractSlingRepository.java > Thu Feb 11 13:17:47 2010 > @@ -118,7 +118,11 @@ > > private char[] adminPass; > > - private Loader loader; > + /** Namespace handler. */ > + private Loader namespaceHandler; > + > + /** Session proxy handler. */ > + private SessionProxyHandler sessionProxyHandler; > > // the poll interval used while the repository is not active > private long pollTimeInActiveSeconds; > @@ -231,6 +235,11 @@ > > defineNamespacePrefixes(session); > > + // to support namespace prefixes if session.impersonate is called > + // we have to use a proxy > + if ( this.sessionProxyHandler != null ) { > + return this.sessionProxyHandler.createProxy(session); > + } > return session; > > } catch (NoSuchWorkspaceException nswe) { > @@ -390,7 +399,8 @@ > */ > protected void setupRepository(Repository repository) { > BundleContext bundleContext = componentContext.getBundleContext(); > - this.loader = new Loader(this, bundleContext.getBundles()); > + this.namespaceHandler = new Loader(this, bundleContext.getBundles()); > + this.sessionProxyHandler = new SessionProxyHandler(this); > } > > /** > @@ -496,10 +506,11 @@ > * @param repository > */ > protected void tearDown(Repository repository) { > - if (this.loader != null) { > - this.loader.dispose(); > - this.loader = null; > + if (this.namespaceHandler != null) { > + this.namespaceHandler.dispose(); > + this.namespaceHandler = null; > } > + this.sessionProxyHandler = null; > } > > /** > @@ -525,7 +536,7 @@ > */ > public void bundleChanged(BundleEvent event) { > // Take care: This is synchronous - take care to not block the > system !! > - Loader theLoader = this.loader; > + Loader theLoader = this.namespaceHandler; > if (theLoader != null) { > switch (event.getType()) { > case BundleEvent.INSTALLED: > @@ -693,10 +704,10 @@ > return false; > } > > - private void defineNamespacePrefixes(final Session session) throws > RepositoryException { > - if (this.loader != null) { > + void defineNamespacePrefixes(final Session session) throws > RepositoryException { > + if (this.namespaceHandler != null) { > // apply namespace mapping > - this.loader.defineNamespacePrefixes(session); > + this.namespaceHandler.defineNamespacePrefixes(session); > } > > // call post processors > > Added: > sling/trunk/bundles/jcr/base/src/main/java/org/apache/sling/jcr/base/SessionProxyHandler.java > URL: > http://svn.apache.org/viewvc/sling/trunk/bundles/jcr/base/src/main/java/org/apache/sling/jcr/base/SessionProxyHandler.java?rev=908956&view=auto > ============================================================================== > --- > sling/trunk/bundles/jcr/base/src/main/java/org/apache/sling/jcr/base/SessionProxyHandler.java > (added) > +++ > sling/trunk/bundles/jcr/base/src/main/java/org/apache/sling/jcr/base/SessionProxyHandler.java > Thu Feb 11 13:17:47 2010 > @@ -0,0 +1,142 @@ > +/* > + * Licensed to the Apache Software Foundation (ASF) under one > + * or more contributor license agreements. See the NOTICE file > + * distributed with this work for additional information > + * regarding copyright ownership. The ASF licenses this file > + * to you 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 org.apache.sling.jcr.base; > + > +import java.lang.reflect.InvocationHandler; > +import java.lang.reflect.InvocationTargetException; > +import java.lang.reflect.Method; > +import java.lang.reflect.Proxy; > +import java.util.HashSet; > +import java.util.Set; > + > +import javax.jcr.Credentials; > +import javax.jcr.Session; > + > +/** > + * The session proxy handler creates session proxies to handle > + * the namespace mapping support if impersonate is called on > + * the session. > + */ > +public class SessionProxyHandler { > + > + /** The array of proxied interfaces. */ > + private Class<?>[] interfaces; > + > + /** The repository */ > + private final AbstractSlingRepository repository; > + > + public SessionProxyHandler(final AbstractSlingRepository repo) { > + this.repository = repo; > + } > + > + /** Calculate the interfaces. > + * This is done only once - we simply assume that the same repository is > + * emitting session from the same class. > + */ > + private Class<?>[] getInterfaces(final Class<?> sessionClass) { > + if ( interfaces == null ) { > + synchronized ( SessionProxyHandler.class ) { > + if ( interfaces == null ) { > + final HashSet<Class<?>> workInterfaces = new > HashSet<Class<?>>(); > + > + // Get *all* interfaces > + guessWorkInterfaces( sessionClass, workInterfaces ); > + > + this.interfaces = workInterfaces.toArray( new > Class[workInterfaces.size()] ); > + > + } > + } > + } > + return interfaces; > + } > + > + /** > + * Create a proxy for the session. > + */ > + public Session createProxy(final Session session) { > + final Class<?> sessionClass = session.getClass(); > + return (Session)Proxy.newProxyInstance(sessionClass.getClassLoader(), > + getInterfaces(sessionClass), > + new SessionProxy(session, this.repository)); > + > + } > + > + > + public static final class SessionProxy implements InvocationHandler { > + private final Session delegatee; > + private final AbstractSlingRepository repository; > + > + public SessionProxy(final Session delegatee, final > AbstractSlingRepository repo) { > + this.delegatee = delegatee; > + this.repository = repo; > + } > + > + /** > + * @see java.lang.reflect.InvocationHandler#invoke(java.lang.Object, > java.lang.reflect.Method, java.lang.Object[]) > + */ > + public Object invoke(Object proxy, Method method, Object[] args) > + throws Throwable { > + if ( method.getName().equals("impersonate") && args != null && > args.length == 1) { > + final Session session = > this.delegatee.impersonate((Credentials)args[0]); > + this.repository.defineNamespacePrefixes(session); > + return new SessionProxy(session, this.repository); > + } > + try { > + return method.invoke(this.delegatee, args); > + } catch (InvocationTargetException ite) { > + throw ite.getTargetException(); > + } > + } > + } > + > + /** > + * Get a list of interfaces to proxy by scanning through > + * all interfaces a class implements. > + * > + * @param clazz the class > + * @param workInterfaces the set of current work interfaces > + */ > + private void guessWorkInterfaces( final Class<?> clazz, > + final Set<Class<?>> workInterfaces ) { > + if ( null != clazz ) { > + addInterfaces( clazz.getInterfaces(), workInterfaces ); > + > + guessWorkInterfaces( clazz.getSuperclass(), workInterfaces ); > + } > + } > + > + /** > + * Get a list of interfaces to proxy by scanning through > + * all interfaces a class implements. > + * > + * @param classInterfaces the array of interfaces > + * @param workInterfaces the set of current work interfaces > + */ > + private void addInterfaces( final Class<?>[] classInterfaces, > + final Set<Class<?>> workInterfaces ) { > + for ( int i = 0; i < classInterfaces.length; i++ ) { > + // to avoid problems we simply ignore all pre jsr 283 interfaces > - once we > + // moved to jcr 2.0 completly we can remove this check > + if ( > !classInterfaces[i].getName().startsWith("org.apache.jackrabbit.api.jsr283")) > { > + workInterfaces.add( classInterfaces[i] ); > + } > + addInterfaces(classInterfaces[i].getInterfaces(), > workInterfaces); > + } > + } > +} > > Propchange: > sling/trunk/bundles/jcr/base/src/main/java/org/apache/sling/jcr/base/SessionProxyHandler.java > ------------------------------------------------------------------------------ > svn:eol-style = native > > Propchange: > sling/trunk/bundles/jcr/base/src/main/java/org/apache/sling/jcr/base/SessionProxyHandler.java > ------------------------------------------------------------------------------ > svn:keywords = author date id revision rev url > > Propchange: > sling/trunk/bundles/jcr/base/src/main/java/org/apache/sling/jcr/base/SessionProxyHandler.java > ------------------------------------------------------------------------------ > svn:mime-type = text/plain > >
