You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@aries.apache.org by Alasdair Nottingham <no...@apache.org> on 2010/03/03 12:02:50 UTC

Re: svn commit: r917809 - in /incubator/aries/trunk/jndi/jndi-url: ./ src/main/java/org/apache/aries/jndi/services/ src/main/java/org/apache/aries/jndi/url/ src/test/java/org/apache/aries/jndi/url/

Hi,

Hmm, I suspect I am not correctly finding the appropriate
BundleContext to use. That would explain the CNFE because we now proxy
the services rather than returning the raw service. If it is being
listed as being used by the pax-web jsp bundle that would explain
things.

Do you have a stack trace for the ClassNotFoundException? That might
help to work out what went wrong.

Also can you check the thread context classloader before the lookup?

Thanks
Alasdair

On 2 March 2010 23:21, Joe Bohn <jo...@gmail.com> wrote:
>
> I think there are some issues with this change.   I'll have to dig some more
> and post more details later (don't have time right now) ... but in short I'm
> seeing the following:
>
> - AriesTrader is behaving very badly after this change.
> - From within a jsp we use jndi lookup to find an osgi service.
> - After this change I get a failure in my jsp with a CNFE.   This despite
> the fact that I can see the package is imported on the web bundle and
> appears to be wired correctly.
> - Even more strange: I notice that the application service I was looking for
> is listed as being used by the pax-web jsp bundle.  So it seems like we
> might be using the wrong bundle context at some point.
>
>
> Joe
>
>
>
> not@apache.org wrote:
>>
>> Author: not
>> Date: Mon Mar  1 23:53:18 2010
>> New Revision: 917809
>>
>> URL: http://svn.apache.org/viewvc?rev=917809&view=rev
>> Log:
>> ARIES-128 Implement OSGi spec url lookup scheme
>>
>> Added:
>>
>>  incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/OsgiName.java
>>      - copied, changed from r910238,
>> incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/ServiceRegistryName.java
>>
>>  incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/OsgiNameParser.java
>>      - copied, changed from r910238,
>> incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/ServiceRegistryNameParser.java
>>
>>  incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/ServiceRegistryListContext.java
>>
>>  incubator/aries/trunk/jndi/jndi-url/src/test/java/org/apache/aries/jndi/url/OsgiNameParserTest.java
>>      - copied, changed from r917002,
>> incubator/aries/trunk/jndi/jndi-url/src/test/java/org/apache/aries/jndi/url/ServiceRegistryNameParserTest.java
>> Removed:
>>
>>  incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/ServiceRegistryName.java
>>
>>  incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/ServiceRegistryNameParser.java
>>
>>  incubator/aries/trunk/jndi/jndi-url/src/test/java/org/apache/aries/jndi/url/ServiceHelperTest.java
>>
>>  incubator/aries/trunk/jndi/jndi-url/src/test/java/org/apache/aries/jndi/url/ServiceRegistryNameParserTest.java
>> Modified:
>>    incubator/aries/trunk/jndi/jndi-url/pom.xml
>>
>>  incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/services/ServiceHelper.java
>>
>>  incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/Activator.java
>>
>>  incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/OsgiURLContextFactory.java
>>
>>  incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/ServiceRegistryContext.java
>>
>>  incubator/aries/trunk/jndi/jndi-url/src/test/java/org/apache/aries/jndi/url/ServiceRegistryContextTest.java
>>
>> Modified: incubator/aries/trunk/jndi/jndi-url/pom.xml
>> URL:
>> http://svn.apache.org/viewvc/incubator/aries/trunk/jndi/jndi-url/pom.xml?rev=917809&r1=917808&r2=917809&view=diff
>>
>> ==============================================================================
>> --- incubator/aries/trunk/jndi/jndi-url/pom.xml (original)
>> +++ incubator/aries/trunk/jndi/jndi-url/pom.xml Mon Mar  1 23:53:18 2010
>> @@ -33,6 +33,10 @@
>>      <dependencies>
>>       <dependency>
>> +       <groupId>org.apache.aries</groupId>
>> +       <artifactId>org.apache.aries.util</artifactId>
>> +      </dependency>
>> +      <dependency>
>>           <groupId>org.osgi</groupId>
>>           <artifactId>org.osgi.core</artifactId>
>>           <scope>provided</scope>
>>
>> Modified:
>> incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/services/ServiceHelper.java
>> URL:
>> http://svn.apache.org/viewvc/incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/services/ServiceHelper.java?rev=917809&r1=917808&r2=917809&view=diff
>>
>> ==============================================================================
>> ---
>> incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/services/ServiceHelper.java
>> (original)
>> +++
>> incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/services/ServiceHelper.java
>> Mon Mar  1 23:53:18 2010
>> @@ -18,18 +18,30 @@
>>  */
>>  package org.apache.aries.jndi.services;
>>  +import java.lang.reflect.InvocationHandler;
>> +import java.lang.reflect.Method;
>> +import java.lang.reflect.Proxy;
>> +import java.security.AccessController;
>> +import java.security.PrivilegedAction;
>> +import java.util.ArrayList;
>>  import java.util.Arrays;
>>  import java.util.Comparator;
>>  import java.util.HashSet;
>>  import java.util.LinkedList;
>>  import java.util.List;
>> +import java.util.Map;
>>  import java.util.Set;
>>  import java.util.concurrent.ConcurrentHashMap;
>>  import java.util.concurrent.ConcurrentMap;
>>  +import javax.naming.NamingException;
>> +
>> +import org.apache.aries.util.BundleToClassLoaderAdapter;
>> +import org.osgi.framework.Bundle;
>>  import org.osgi.framework.BundleContext;
>>  import org.osgi.framework.BundleReference;
>>  import org.osgi.framework.InvalidSyntaxException;
>> +import org.osgi.framework.ServiceException;
>>  import org.osgi.framework.ServiceReference;
>>  /**
>> @@ -47,221 +59,206 @@
>>  */
>>  public final class ServiceHelper
>>  {
>> -  /** The bundle context used for service registry queries */
>> -  private static BundleContext context;
>> -  /** A cache of what service was returned last time the query was
>> performed */
>> -  private static ConcurrentMap<ServiceKey, Set<ServiceReference>> cache =
>> new ConcurrentHashMap<ServiceKey, Set<ServiceReference>>();
>> -
>> -  public static void setBundleContext(BundleContext ctx)
>> +  public static class StackFinder extends SecurityManager
>>   {
>> -    context = ctx;
>> +    public Class<?>[] getClassContext()
>> +    {
>> +      return super.getClassContext();
>> +    }
>>   }
>> -  -  /**
>> -   * This class is used as the key into the cache. It holds information
>> to identify -   * who performed the query, along with the className and
>> filter used. The thread context
>> -   * class loader is used in the key, so two different modules will
>> potentially get different
>> -   * services.
>> -   */
>> -  private static final class ServiceKey
>> +
>> +  private static class JNDIServiceDamper implements InvocationHandler
>>   {
>> -    /** The class loader of the invoking application */
>> -    private ClassLoader classLoader;
>> -    /** The name of the class being queried from the registry */
>> -    private String className;
>> -    /** the registry filter, this may be null */
>> +    private BundleContext ctx;
>> +    private ServicePair pair;
>> +    private String interfaceName;
>>     private String filter;
>> -    /** The cached hashCode */
>> -    private final int hashCode;
>> -
>> -    /**
>> -     * Boring unimportant comment.
>> -     * -     * @param cl
>> -     * @param cn
>> -     * @param f
>> -     */
>> -    public ServiceKey(ClassLoader cl, String cn, String f)
>> +    private boolean dynamic;
>> +    +    public JNDIServiceDamper(BundleContext context, String i, String
>> f, ServicePair service, boolean d)
>>     {
>> -      classLoader = cl;
>> -      className = cn;
>> +      ctx = context;
>> +      pair = service;
>> +      interfaceName = i;
>>       filter = f;
>> -      -      int classNameHash = (className == null) ? 0 :
>> className.hashCode();
>> -      hashCode = System.identityHashCode(classLoader) * 1000003 +
>> classNameHash;
>> +      dynamic = d;
>>     }
>> -
>> -    @Override
>> -    public int hashCode()
>> -    {
>> -      return hashCode;
>> -    }
>> -
>> -    @Override
>> -    public boolean equals(Object other)
>> +    +    public Object invoke(Object proxy, Method method, Object[] args)
>> throws Throwable
>>     {
>> -      if (other == this) return true;
>> -      if (other == null) return false;
>> -
>> -      if (other instanceof ServiceKey) {
>> -        ServiceKey otherKey = (ServiceKey) other;
>> -        if (hashCode != otherKey.hashCode) return false;
>> -
>> -        if (classLoader != otherKey.classLoader) return false;
>> -        if (!!!comparePossiblyNullObjects(className, otherKey.className))
>> return false;
>> -        return comparePossiblyNullObjects(filter, otherKey.filter);
>> -      }
>> -
>> -      return false;
>> -    }
>> -    -    /**
>> -     * Compares two objects where one or other (or both) may be null.
>> -     * -     * @param a the first object to compare.
>> -     * @param b the second object to compare.
>> -     * @return true if they are ==, both null or identity equals, false
>> otherwise.
>> -     */
>> -    public boolean comparePossiblyNullObjects(Object a, Object b) {
>> -      if (a == b) return true;
>> -      else if (a == null) return false;
>> -      else return a.equals(b);
>> +      if (pair.ref.getBundle() == null) {
>> +        if (dynamic) pair = findService(ctx, interfaceName, filter);
>> +        else pair = null;
>> +      }
>> +      +      if (pair == null) {
>> +        throw new ServiceException(interfaceName,
>> ServiceException.UNREGISTERED);
>> +      }
>> +      +      return method.invoke(pair.service, args);
>>     }
>>   }
>> -
>> -  /**
>> -   * This method is used to obtain a single instance of a desired service
>> from the OSGi
>> -   * service registry. If the filter and class name identify multiple
>> services the first
>> -   * one is returned. If no service is found null will be returned.
>> -   * -   * @param className The class name used to register the desired
>> service. If null is provided
>> -   *                  then all services are eligible to be returned.
>> -   * @param filter    An RFC 1960 query into the properties of the
>> registered services. e.g.
>> -   *                  (service.description=really useful)
>> -   * @return          The desired service
>> -   * -   * @throws IllegalArgumentException If the filter is not valid.
>> See RFC 1960 to work out what -   *                                  it
>> should be.
>> -   */
>> -  public static Object getService(String className, String filter) throws
>> IllegalArgumentException
>> +  +  private static class ServicePair
>>   {
>> -    Object service = null;
>> -    try {
>> -      BundleContext callerCtx = getBundleContext();
>> -      ServiceReference[] refs = callerCtx.getServiceReferences(className,
>> filter);
>> -      -      if (refs != null) {
>> -        // we need to sort the references returned in case they are out
>> of order
>> -        // we need to sort in the reverse natural order, services with
>> higher -        // ranking or lower id should be processed first so should
>> be earlier in the array.
>> -        Arrays.sort(refs, new Comparator<ServiceReference>() {
>> -          public int compare(ServiceReference o1, ServiceReference o2)
>> -          {
>> -            return o2.compareTo(o1);
>> -          }
>> -        });
>> -        -        for (ServiceReference ref : refs) {
>> -          List<Object> services = getServices(callerCtx, className,
>> filter, ref);
>> -          if (!!!services.isEmpty()) {
>> -            service = services.get(0);
>> -            break;
>> -          }
>> -        }
>> -      }      -    } catch (InvalidSyntaxException e) {
>> -      throw new IllegalArgumentException(e.getMessage(), e);
>> -    }
>> -    -    return service;
>> +    private ServiceReference ref;
>> +    private Object service;
>>   }
>>      /**
>> -   * This method is used to obtain a list of service instances from the
>> OSGi
>> -   * service registry. If no service is found an empty list will be
>> returned.
>> -   * -   * @param className The class name used to register the desired
>> service. If null is provided
>> -   *                  then all services are eligible to be returned.
>> -   * @param filter    An RFC 1960 query into the properties of the
>> registered services. e.g.
>> -   *                  (service.description=really useful)
>> -   * @return          A list of matching services.
>> -   * -   * @throws IllegalArgumentException If the filter is not valid.
>> See RFC 1960 to work out what -   *                                  it
>> should be.
>> +   * @param env +   * @return the bundle context for the caller.
>> +   * @throws NamingException     */
>> -  public static List<?> getServices(String className, String filter)
>> -      throws IllegalArgumentException
>> +  public static BundleContext getBundleContext(Map<String, Object> env)
>> throws NamingException
>>   {
>> -    List<Object> services;
>> -    try {
>> -      BundleContext callerCtx = getBundleContext();
>> -      ServiceReference[] refs =
>> callerCtx.getAllServiceReferences(className, filter);
>> +    BundleContext result = null;
>> +    +    Object bc = env.get("osgi.service.jndi.bundleContext");
>> +    +    if (bc != null && bc instanceof BundleContext) result =
>> (BundleContext) bc;
>> +    else {
>> +      ClassLoader cl = AccessController.doPrivileged(new
>> PrivilegedAction<ClassLoader>() {
>> +        public ClassLoader run()
>> +        {
>> +          return Thread.currentThread().getContextClassLoader();
>> +        }
>> +      });
>>       -      services = getServices(callerCtx, className, filter, refs);
>> -    } catch (InvalidSyntaxException e) {
>> -      throw new IllegalArgumentException(e.getMessage(), e);
>> +      result = getBundleContext(cl);
>> +    }
>> +    +    if (result == null) {
>> +      StackTraceElement[] stackTrace = AccessController.doPrivileged(new
>> PrivilegedAction<StackTraceElement[]>() {
>> +        public StackTraceElement[] run()
>> +        {
>> +          return Thread.currentThread().getStackTrace();
>> +        }
>> +      });
>> +      +      StackFinder finder = new StackFinder();
>> +      Class<?>[] classStack = finder.getClassContext();
>> +      +      boolean found = false;
>> +      boolean foundLookup = false;
>> +      int i = 0;
>> +      for (; i < stackTrace.length && !!!found; i++) {
>> +        if (!!!foundLookup &&
>> "lookup".equals(stackTrace[i].getMethodName())) {
>> +          foundLookup = true;
>> +        } else if (foundLookup &&
>> !!!(stackTrace[i].getClassName().startsWith("org.apache.aries.jndi") ||
>> +
>>  stackTrace[i].getClassName().startsWith("javax.naming"))) {
>> +          found = true;
>> +        }
>> +      }
>> +      +      if (found) {
>> +        Set<Integer> classLoadersChecked = new HashSet<Integer>();
>> +        for (; i < classStack.length && result == null; i++) {
>> +          ClassLoader cl = classStack[i].getClassLoader();
>> +          int hash = System.identityHashCode(cl);
>> +          if (!!!classLoadersChecked.contains(hash)) {
>> +            classLoadersChecked.add(hash);
>> +            result = getBundleContext(cl);
>> +          }
>> +        }
>> +        // Now we walk the stack looking for the BundleContext
>> +      }
>>     }
>>     -    return services;
>> +    if (result == null) throw new NamingException("Unable to find
>> BundleContext");
>> +    +    return result;
>>   }
>> -  -  /**
>> -   * @return the bundle context for the caller.
>> -   */
>> -  private static BundleContext getBundleContext()
>> +
>> +  private static BundleContext getBundleContext(ClassLoader cl)
>>   {
>>     BundleContext result = null;
>> -    ClassLoader cl = Thread.currentThread().getContextClassLoader();
>>     while (result == null && cl != null) {
>>       if (cl instanceof BundleReference) {
>>         result = ((BundleReference)cl).getBundle().getBundleContext();
>>       } else if (cl != null) {
>>         cl = cl.getParent();
>>       }
>> -    } +    }
>>     -    if (result == null) result = context;
>>     return result;
>>   }
>>  -  /**
>> -   * This worker method obtains the requested service(s) and if the
>> service(s) -   * exist updates the cache and releases the previous
>> service(s).
>> -   * -   * @param callerCtx The caller context.
>> -   * @param className The class name used to query for the service.
>> -   * @param filter    The filter name used to query for the service.
>> -   * @param refs      The references to get.
>> -   * @return          The service, if one was found, or null.
>> -   */
>> -  private static List<Object> getServices(BundleContext callerCtx, String
>> className, String filter, ServiceReference...refs)
>> +  public static Object getService(String interface1, String filter,
>> String serviceName, boolean dynamicRebind, Map<String, Object> env) throws
>> NamingException
>>   {
>> -    List<Object> data = new LinkedList<Object>();
>> +    Object result = null;
>> +    +    BundleContext ctx = getBundleContext(env);
>> +    +    ServicePair pair = findService(ctx, interface1, filter);
>>     -    if (refs != null) {
>> -      Set<ServiceReference> refSet = new HashSet<ServiceReference>();
>> -      for (ServiceReference ref : refs) {
>> -        Object service = callerCtx.getService(ref);
>> -        if (service != null) {
>> -          data.add(service);
>> -          refSet.add(ref);
>> +    if (pair == null) {
>> +      interface1 = null;
>> +      filter = "(osgi.jndi.serviceName=" + serviceName + ")";
>> +      pair = findService(ctx, interface1, filter);
>> +    }
>> +    +    if (pair != null) {
>> +      String[] interfaces = (String[])
>> pair.ref.getProperty("objectClass");
>> +      +      List<Class<?>> clazz = new
>> ArrayList<Class<?>>(interfaces.length);
>> +      +      Bundle b = ctx.getBundle();
>> +      +      for (String interfaceName : interfaces) {
>> +        try {
>> +          clazz.add(b.loadClass(interfaceName));
>> +        } catch (ClassNotFoundException e) {
>> +          // TODO Auto-generated catch block
>> +          e.printStackTrace();
>>         }
>>       }
>>       -      ClassLoader cl =
>> Thread.currentThread().getContextClassLoader();
>> -      ServiceKey key = new ServiceKey(cl, className, filter);
>> +      if (clazz.isEmpty()) {
>> +        throw new IllegalArgumentException();
>> +      }
>>       -      // we do not need any synchronization around this. The map is
>> concurrent
>> -      // and until here we do not touch any shared state.
>> -      refSet = cache.put(key, refSet);
>> +      InvocationHandler ih = new JNDIServiceDamper(ctx, interface1,
>> filter, pair, dynamicRebind);
>>       -      if (refSet != null) {
>> -        for (ServiceReference ref : refSet) {
>> -          callerCtx.ungetService(ref);
>> +      result = Proxy.newProxyInstance(new BundleToClassLoaderAdapter(b),
>> clazz.toArray(new Class<?>[clazz.size()]), ih);
>> +    }
>> +    +    return result;
>> +  }
>> +
>> +  private static ServicePair findService(BundleContext ctx, String
>> interface1, String filter)
>> +  {
>> +    ServicePair p = null;
>> +    +    try {
>> +      ServiceReference[] refs = ctx.getServiceReferences(interface1,
>> filter);
>> +      +      if (refs != null) {
>> +        // natural order is the exact opposite of the order we desire.
>> +        Arrays.sort(refs, new Comparator<ServiceReference>() {
>> +          public int compare(ServiceReference o1, ServiceReference o2)
>> +          {
>> +            return o2.compareTo(o1);
>> +          }
>> +        });
>> +        +        for (ServiceReference ref : refs) {
>> +          Object service = ctx.getService(ref);
>> +          +          if (service != null) {
>> +            p = new ServicePair();
>> +            p.ref = ref;
>> +            p.service = service;
>> +            break;
>> +          }
>>         }
>>       }
>> +      +    } catch (InvalidSyntaxException e) {
>> +      // TODO Auto-generated catch block
>> +      e.printStackTrace();
>>     }
>>     -    return data;
>> +    return p;
>>   }
>>  }
>>
>> Modified:
>> incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/Activator.java
>> URL:
>> http://svn.apache.org/viewvc/incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/Activator.java?rev=917809&r1=917808&r2=917809&view=diff
>>
>> ==============================================================================
>> ---
>> incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/Activator.java
>> (original)
>> +++
>> incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/Activator.java
>> Mon Mar  1 23:53:18 2010
>> @@ -34,8 +34,6 @@
>>
>>   public void start(BundleContext context)
>>   {
>> -    ServiceHelper.setBundleContext(context);
>> -         Hashtable<Object, Object> props = new Hashtable<Object,
>> Object>();
>>     props.put("osgi.jndi.urlScheme", new String[] {"osgi", "aries"} );
>>     reg = context.registerService(ObjectFactory.class.getName(), new
>> OsgiURLContextFactory(), props);
>>
>> Copied:
>> incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/OsgiName.java
>> (from r910238,
>> incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/ServiceRegistryName.java)
>> URL:
>> http://svn.apache.org/viewvc/incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/OsgiName.java?p2=incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/OsgiName.java&p1=incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/ServiceRegistryName.java&r1=910238&r2=917809&rev=917809&view=diff
>>
>> ==============================================================================
>> ---
>> incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/ServiceRegistryName.java
>> (original)
>> +++
>> incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/OsgiName.java
>> Mon Mar  1 23:53:18 2010
>> @@ -21,28 +21,104 @@
>>  import java.util.Enumeration;
>>  import javax.naming.CompositeName;
>> +import javax.naming.InvalidNameException;
>> +import javax.naming.Name;
>>  /**
>> - * A composite name for the aries namespace. We only have this so that we
>> can
>> - * provide a nicer toString()
>> + * A composite name for the aries namespace. This provides useful utility
>> methods
>> + * for accessing the name.
>> + * + * component 0: osgi:service, aries:services, osgi:servicelist
>> + * component 1: interface
>> + * component 2: filter
>>  */
>> -public final class ServiceRegistryName extends CompositeName
>> +public final class OsgiName extends CompositeName
>>  {
>>   /** The serial version UID */
>>   private static final long serialVersionUID = 6617580228852444656L;
>> +  public static final String OSGI_SCHEME = "osgi";
>> +  public static final String ARIES_SCHEME = "aries";
>> +  public static final String SERVICE_PATH = "service";
>> +  public static final String SERVICES_PATH = "services";
>> +  public static final String SERVICE_LIST_PATH = "servicelist";
>> +  public static final String FRAMEWORK_PATH = "framework";
>>   -  @Override
>> -  public String toString()
>> +  public OsgiName(String name) throws InvalidNameException
>>   {
>> -    StringBuilder buffer = new StringBuilder();
>> +    super(name);
>> +  }
>> +
>> +  public OsgiName(Name name) throws InvalidNameException
>> +  {
>> +    this(name.toString());
>> +  }
>> +
>> +  public boolean hasFilter()
>> +  {
>> +    return size() == 3;
>> +  }
>> +  +  public boolean isServiceNameBased()
>> +  {
>> +    return size() > 3;
>> +  }
>> +  +  public String getScheme()
>> +  {
>> +    String part0 = get(0);
>> +    int index = part0.indexOf(':');
>> +    +    String result;
>> +    +    if (index > 0) {
>> +      result = part0.substring(0, index);
>> +    } else {
>> +      result = null;
>> +    }
>> +    +    return result;
>> +  }
>> +  +  public String getSchemePath()
>> +  {
>> +    String part0 = get(0);
>> +    int index = part0.indexOf(':');
>> +    +    String result;
>>     -    buffer.append("aries:services");
>> -    Enumeration<String> components = getAll();
>> -    while (components.hasMoreElements()) {
>> -      buffer.append('/');
>> -      buffer.append(components.nextElement());
>> +    if (index > 0) {
>> +      result = part0.substring(index + 1);
>> +    } else {
>> +      result = null;
>>     }
>>     -    return buffer.toString();
>> +    return result;
>> +  }
>> +  +  public String getInterface()
>> +  {
>> +    return get(1);
>> +  }
>> +  +  public String getFilter()
>> +  {
>> +    return hasFilter() ? get(2) : null;
>> +  }
>> +  +  public String getServiceName()
>> +  {
>> +    Enumeration<String> parts = getAll();
>> +    parts.nextElement();
>> +    +    StringBuilder builder = new StringBuilder();
>> +    +    while (parts.hasMoreElements()) {
>> +      builder.append(parts.nextElement());
>> +      builder.append('/');
>> +    }
>> +    +    builder.deleteCharAt(builder.length() - 1);
>> +    +    return builder.toString();
>>   }
>>  }
>> \ No newline at end of file
>>
>> Copied:
>> incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/OsgiNameParser.java
>> (from r910238,
>> incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/ServiceRegistryNameParser.java)
>> URL:
>> http://svn.apache.org/viewvc/incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/OsgiNameParser.java?p2=incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/OsgiNameParser.java&p1=incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/ServiceRegistryNameParser.java&r1=910238&r2=917809&rev=917809&view=diff
>>
>> ==============================================================================
>> ---
>> incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/ServiceRegistryNameParser.java
>> (original)
>> +++
>> incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/OsgiNameParser.java
>> Mon Mar  1 23:53:18 2010
>> @@ -26,31 +26,40 @@
>>  /**
>>  * A parser for the aries namespace
>>  */
>> -public final class ServiceRegistryNameParser implements NameParser
>> +public final class OsgiNameParser implements NameParser
>>  {
>> -
>> +  private static final String OSGI_SCHEME = "osgi";
>> +  private static final String ARIES_SCHEME = "aries";
>> +  private static final String SERVICE_PATH = "service";
>> +  private static final String SERVICES_PATH = "services";
>> +  private static final String SERVICE_LIST_PATH = "servicelist";
>> +  private static final String FRAMEWORK_PATH = "framework";
>> +     public Name parse(String name) throws NamingException
>>   {
>> -    if (!!!name.startsWith("aries:services/") &&
>> -        !!!name.startsWith("osgi:services/")) throw new
>> InvalidNameException("The JNDI name did not start with aries:, or osgi:");
>> +    OsgiName result = new OsgiName(name);
>> +    +    if (result.size() < 2) throw new InvalidNameException(name);
>>     -    name = name.substring(name.indexOf('/') + 1);
>> +    String urlScheme = result.getScheme();
>> +    String schemePath = result.getSchemePath();
>>     -    int slashIndex = name.indexOf('/');
>> -    String interfaceName = name;
>> -    String filter = null;
>> -    -    if (slashIndex != -1) {
>> -      interfaceName = name.substring(0, slashIndex);
>> -      filter = name.substring(slashIndex + 1);
>> +    if (!!!(OSGI_SCHEME.equals(urlScheme) ||
>> ARIES_SCHEME.equals(urlScheme))) {
>> +      throw new InvalidNameException(name);
>>     }
>>     -    if (interfaceName.length() == 0) throw new
>> InvalidNameException("No interface name was specified");
>> +    if (ARIES_SCHEME.equals(urlScheme) &&
>> !!!SERVICES_PATH.equals(schemePath)) {
>> +      throw new InvalidNameException(name);
>> +    }
>> +    +    if (OSGI_SCHEME.equals(urlScheme) && !!!(
>> SERVICE_PATH.equals(schemePath) || +
>>      SERVICE_LIST_PATH.equals(schemePath) || +
>>                FRAMEWORK_PATH.equals(schemePath))) {
>> +      throw new InvalidNameException(name);
>> +    }
>>     -    Name result = new ServiceRegistryName();
>> -    result.add(interfaceName);
>> -    if (filter != null) {
>> -      result.add(filter);
>> +    if (result.getInterface() == null || result.getInterface().length()
>> == 0) {
>> +      throw new InvalidNameException(name);
>>     }
>>          return result;
>> @@ -59,7 +68,7 @@
>>   @Override
>>   public boolean equals(Object other)
>>   {
>> -    return other instanceof ServiceRegistryNameParser;
>> +    return other instanceof OsgiNameParser;
>>   }
>>      @Override
>>
>> Modified:
>> incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/OsgiURLContextFactory.java
>> URL:
>> http://svn.apache.org/viewvc/incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/OsgiURLContextFactory.java?rev=917809&r1=917808&r2=917809&view=diff
>>
>> ==============================================================================
>> ---
>> incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/OsgiURLContextFactory.java
>> (original)
>> +++
>> incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/OsgiURLContextFactory.java
>> Mon Mar  1 23:53:18 2010
>> @@ -49,7 +49,7 @@
>>     } else if (obj instanceof String[]) {
>>       // Try each URL until either lookup succeeds or they all fail
>>       String[] urls = (String[])obj;
>> -      if (urls.length == 0) throw new
>> ConfigurationException("ariesURLContextFactory: empty URL array");
>> +      if (urls.length == 0) throw new ConfigurationException("0");
>>       Context context = new ServiceRegistryContext(environment);
>>       try
>>       {
>>
>> Modified:
>> incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/ServiceRegistryContext.java
>> URL:
>> http://svn.apache.org/viewvc/incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/ServiceRegistryContext.java?rev=917809&r1=917808&r2=917809&view=diff
>>
>> ==============================================================================
>> ---
>> incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/ServiceRegistryContext.java
>> (original)
>> +++
>> incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/ServiceRegistryContext.java
>> Mon Mar  1 23:53:18 2010
>> @@ -42,9 +42,9 @@
>>  {
>>   private static final String ARIES_SERVICES = "aries:services/";
>>   /** The name parser for the service registry name space */
>> -  private NameParser parser = new ServiceRegistryNameParser();
>> +  private NameParser parser = new OsgiNameParser();
>>   /** The environment for this context */
>> -  private Map<Object, Object> env;
>> +  private Map<String, Object> env;
>>      /**
>>    * Why Mr Java this class does indeed take a fine copy of the provided
>> @@ -53,10 +53,11 @@
>>    *     * @param environment
>>    */
>> +  @SuppressWarnings("unchecked")
>>   public ServiceRegistryContext(Hashtable<?, ?> environment)
>>   {
>> -    env = new HashMap<Object, Object>();
>> -    env.putAll(environment);
>> +    env = new HashMap<String, Object>();
>> +    env.putAll((Map<? extends String, ? extends Object>) environment);
>>   }
>>    public Object addToEnvironment(String propName, Object propVal) throws
>> NamingException
>> @@ -153,7 +154,7 @@
>>    public NamingEnumeration<NameClassPair> list(final Name name) throws
>> NamingException
>>   {
>> -    throw new NamingException("Not a Context");
>> +    return new ServiceRegistryListContext(env, convert(name)).list("");
>>   }
>>    public NamingEnumeration<NameClassPair> list(String name) throws
>> NamingException
>> @@ -163,7 +164,7 @@
>>    public NamingEnumeration<Binding> listBindings(final Name name) throws
>> NamingException
>>   {
>> -    throw new NamingException("Not a Context");
>> +    return new ServiceRegistryListContext(env,
>> convert(name)).listBindings("");
>>   }
>>    public NamingEnumeration<Binding> listBindings(String name) throws
>> NamingException
>> @@ -173,28 +174,43 @@
>>    public Object lookup(Name name) throws NamingException
>>   {
>> -    int nameSize = validateName(name);
>> -    String className = name.get(0);
>> -
>> -    String filter = null;
>> +    Object result;
>> +    +    OsgiName validName = convert(name);
>>     -    if (nameSize == 2) {
>> -      filter = name.get(1);
>> +    String pathFragment = validName.getSchemePath();
>> +    String serviceName = validName.getServiceName();
>> +    String schemeName = validName.getScheme();
>> +    +    if (OsgiName.FRAMEWORK_PATH.equals(pathFragment) &&
>> "bundleContext".equals(validName.getServiceName())) {
>> +      result = ServiceHelper.getBundleContext(env);
>> +    } else if ((OsgiName.SERVICE_PATH.equals(pathFragment) &&
>> OsgiName.OSGI_SCHEME.equals(schemeName)) ||
>> +               (OsgiName.SERVICES_PATH.equals(pathFragment) &&
>> OsgiName.ARIES_SCHEME.equals(schemeName))) {
>> +      result = ServiceHelper.getService(validName.getInterface(),
>> validName.getFilter(), serviceName, true, env);
>> +    } else if (OsgiName.SERVICE_LIST_PATH.equals(pathFragment)) {
>> +      result = new ServiceRegistryListContext(env, validName);
>> +    } else {
>> +      result = null;
>>     }
>>     -    try {
>> -      Object result = ServiceHelper.getService(className, filter);
>> -      -      if (result == null) {
>> -        throw new NameNotFoundException("We couldn't find an object in
>> the registry matching the query " + name);
>> -      }
>> -      -      return result;
>> -    } catch (IllegalArgumentException e) {
>> -      NamingException ne = new NamingException(e.getMessage());
>> -      ne.initCause(e);
>> -      throw ne;
>> +    if (result == null) {
>> +      throw new NameNotFoundException(name.toString());
>> +    }
>> +    +    return result;
>> +  }
>> +
>> +  private OsgiName convert(Name name) throws InvalidNameException
>> +  {
>> +    OsgiName result;
>> +    +    if (name instanceof OsgiName) {
>> +      result = (OsgiName) name;
>> +    } else {
>> +      result = new OsgiName(name);
>>     }
>> +    +    return result;
>>   }
>>    public Object lookup(String name) throws NamingException
>> @@ -246,27 +262,4 @@
>>   {
>>     throw new OperationNotSupportedException();
>>   }
>> -  -  /**
>> -   * Check that the name conforms to the expected format
>> -   * @param name
>> -   * @return the size of the name
>> -   * @throws InvalidNameException
>> -   */
>> -  private int validateName(final Name name) throws InvalidNameException
>> -  {
>> -    int nameSize = name.size();
>> -    if (nameSize == 0) {
>> -      throw new InvalidNameException("The provided name does not have any
>> components" + name);
>> -    } -    -    if ("aries:services".equals(name.get(0))) {
>> -      throw new InvalidNameException("The composite name should not start
>> with aries:services");
>> -    }
>> -    -    if (nameSize > 2) {
>> -      throw new InvalidNameException("This JNDI context only expects 2
>> components, but it found " + nameSize);
>> -    }
>> -    return nameSize;
>> -  }
>>  }
>> \ No newline at end of file
>>
>> Added:
>> incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/ServiceRegistryListContext.java
>> URL:
>> http://svn.apache.org/viewvc/incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/ServiceRegistryListContext.java?rev=917809&view=auto
>>
>> ==============================================================================
>> ---
>> incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/ServiceRegistryListContext.java
>> (added)
>> +++
>> incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/ServiceRegistryListContext.java
>> Mon Mar  1 23:53:18 2010
>> @@ -0,0 +1,197 @@
>> +/*
>> + * 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.aries.jndi.url;
>> +
>> +import java.util.HashMap;
>> +import java.util.Hashtable;
>> +import java.util.Map;
>> +
>> +import javax.naming.Binding;
>> +import javax.naming.Context;
>> +import javax.naming.Name;
>> +import javax.naming.NameClassPair;
>> +import javax.naming.NameParser;
>> +import javax.naming.NamingEnumeration;
>> +import javax.naming.NamingException;
>> +import javax.naming.OperationNotSupportedException;
>> +
>> +public class ServiceRegistryListContext implements Context
>> +{
>> +  private Map<String, Object> env;
>> +  /** The name parser for the service registry name space */
>> +  private NameParser parser = new OsgiNameParser();
>> +  +  public ServiceRegistryListContext(Map<String, Object> env, OsgiName
>> validName)
>> +  {
>> +    this.env = new HashMap<String, Object>(env);
>> +  }
>> +
>> +  public Object addToEnvironment(String propName, Object propVal) throws
>> NamingException
>> +  {
>> +    return env.put(propName, propVal);
>> +  }
>> +
>> +  public void bind(Name name, Object obj) throws NamingException
>> +  {
>> +    throw new OperationNotSupportedException();
>> +  }
>> +
>> +  public void bind(String name, Object obj) throws NamingException
>> +  {
>> +    throw new OperationNotSupportedException();
>> +  }
>> +
>> +  public void close() throws NamingException
>> +  {
>> +    env = null;
>> +    parser = null;
>> +  }
>> +
>> +  public Name composeName(Name name, Name prefix) throws NamingException
>> +  {
>> +    // TODO Auto-generated method stub
>> +    return null;
>> +  }
>> +
>> +  public String composeName(String name, String prefix) throws
>> NamingException
>> +  {
>> +    // TODO Auto-generated method stub
>> +    return null;
>> +  }
>> +
>> +  public Context createSubcontext(Name name) throws NamingException
>> +  {
>> +    throw new OperationNotSupportedException();
>> +  }
>> +
>> +  public Context createSubcontext(String name) throws NamingException
>> +  {
>> +    throw new OperationNotSupportedException();
>> +  }
>> +
>> +  public void destroySubcontext(Name name) throws NamingException
>> +  {
>> +    //No-op we don't support sub-contexts in our context
>> +  }
>> +
>> +  public void destroySubcontext(String name) throws NamingException
>> +  {
>> +    //No-op we don't support sub-contexts in our context
>> +  }
>> +
>> +  public Hashtable<?, ?> getEnvironment() throws NamingException
>> +  {
>> +    Hashtable<Object, Object> environment = new Hashtable<Object,
>> Object>();
>> +    environment.putAll(env);
>> +    return environment;
>> +  }
>> +
>> +  public String getNameInNamespace() throws NamingException
>> +  {
>> +    // TODO Auto-generated method stub
>> +    return null;
>> +  }
>> +
>> +  public NameParser getNameParser(Name name) throws NamingException
>> +  {
>> +    return parser;
>> +  }
>> +
>> +  public NameParser getNameParser(String name) throws NamingException
>> +  {
>> +    return parser;
>> +  }
>> +
>> +  public NamingEnumeration<NameClassPair> list(Name name) throws
>> NamingException
>> +  {
>> +    return list(name.toString());
>> +  }
>> +
>> +  public NamingEnumeration<NameClassPair> list(String name) throws
>> NamingException
>> +  {
>> +    // TODO Auto-generated method stub
>> +    return null;
>> +  }
>> +
>> +  public NamingEnumeration<Binding> listBindings(Name name) throws
>> NamingException
>> +  {
>> +    return listBindings(name.toString());
>> +  }
>> +
>> +  public NamingEnumeration<Binding> listBindings(String name) throws
>> NamingException
>> +  {
>> +    // TODO Auto-generated method stub
>> +    return null;
>> +  }
>> +
>> +  public Object lookup(Name name) throws NamingException
>> +  {
>> +    return lookup(name.toString());
>> +  }
>> +
>> +  public Object lookup(String name) throws NamingException
>> +  {
>> +    return null;
>> +  }
>> +
>> +  public Object lookupLink(Name name) throws NamingException
>> +  {
>> +    throw new OperationNotSupportedException();
>> +  }
>> +
>> +  public Object lookupLink(String name) throws NamingException
>> +  {
>> +    throw new OperationNotSupportedException();
>> +  }
>> +
>> +  public void rebind(Name name, Object obj) throws NamingException
>> +  {
>> +    throw new OperationNotSupportedException();
>> +  }
>> +
>> +  public void rebind(String name, Object obj) throws NamingException
>> +  {
>> +    throw new OperationNotSupportedException();
>> +  }
>> +
>> +  public Object removeFromEnvironment(String propName) throws
>> NamingException
>> +  {
>> +    return env.remove(propName);
>> +  }
>> +
>> +  public void rename(Name oldName, Name newName) throws NamingException
>> +  {
>> +    throw new OperationNotSupportedException();
>> +  }
>> +
>> +  public void rename(String oldName, String newName) throws
>> NamingException
>> +  {
>> +    throw new OperationNotSupportedException();
>> +  }
>> +
>> +  public void unbind(Name name) throws NamingException
>> +  {
>> +    throw new OperationNotSupportedException();
>> +  }
>> +
>> +  public void unbind(String name) throws NamingException
>> +  {
>> +    throw new OperationNotSupportedException();
>> +  }
>> +}
>> \ No newline at end of file
>>
>> Copied:
>> incubator/aries/trunk/jndi/jndi-url/src/test/java/org/apache/aries/jndi/url/OsgiNameParserTest.java
>> (from r917002,
>> incubator/aries/trunk/jndi/jndi-url/src/test/java/org/apache/aries/jndi/url/ServiceRegistryNameParserTest.java)
>> URL:
>> http://svn.apache.org/viewvc/incubator/aries/trunk/jndi/jndi-url/src/test/java/org/apache/aries/jndi/url/OsgiNameParserTest.java?p2=incubator/aries/trunk/jndi/jndi-url/src/test/java/org/apache/aries/jndi/url/OsgiNameParserTest.java&p1=incubator/aries/trunk/jndi/jndi-url/src/test/java/org/apache/aries/jndi/url/ServiceRegistryNameParserTest.java&r1=917002&r2=917809&rev=917809&view=diff
>>
>> ==============================================================================
>> ---
>> incubator/aries/trunk/jndi/jndi-url/src/test/java/org/apache/aries/jndi/url/ServiceRegistryNameParserTest.java
>> (original)
>> +++
>> incubator/aries/trunk/jndi/jndi-url/src/test/java/org/apache/aries/jndi/url/OsgiNameParserTest.java
>> Mon Mar  1 23:53:18 2010
>> @@ -18,11 +18,11 @@
>>  */
>>  package org.apache.aries.jndi.url;
>>  -import static org.junit.Assert.assertNotNull;
>>  import static org.junit.Assert.assertEquals;
>> +import static org.junit.Assert.assertFalse;
>> +import static org.junit.Assert.assertTrue;
>>  import javax.naming.InvalidNameException;
>> -import javax.naming.Name;
>>  import javax.naming.NameParser;
>>  import javax.naming.NamingException;
>>  @@ -31,10 +31,10 @@
>>  /**
>>  * This is where we test the service registry name parser.
>>  */
>> -public class ServiceRegistryNameParserTest
>> +public class OsgiNameParserTest
>>  {
>>   /** The parser we are going to use for testing */
>> -  private NameParser parser = new ServiceRegistryNameParser();
>> +  private NameParser parser = new OsgiNameParser();
>>    /**
>>    * OK, so we check that we can call checkNames multiple times.
>> @@ -43,8 +43,14 @@
>>   @Test
>>   public void checkValidNames() throws NamingException
>>   {
>> -    checkName("aries:services/java.lang.Runnable/(a=b)");
>> -    checkName("aries:services/java.lang.Runnable");
>> +    checkName("aries","services","java.lang.Runnable","(a=b)");
>> +    checkName("aries","services","java.lang.Runnable");
>> +    checkName("osgi","service","java.lang.Runnable");
>> +    checkName("osgi","service","java.lang.Runnable", "(a=b)");
>> +    checkName("osgi","servicelist","java.lang.Runnable");
>> +    checkName("osgi","servicelist","java.lang.Runnable", "(a=b)");
>> +    checkName("osgi","servicelist","jdbc", "grok", "DataSource");
>> +    checkName("osgi", "framework", "bundleContext");
>>   }
>>      /**
>> @@ -54,7 +60,7 @@
>>   @Test(expected=InvalidNameException.class)
>>   public void checkOutsideNamespace() throws NamingException
>>   {
>> -    checkName("java:comp/env/jms/cf");
>> +    checkName("java","comp","env","jms","cf");
>>   }
>>      /**
>> @@ -64,7 +70,7 @@
>>   @Test(expected=InvalidNameException.class)
>>   public void checkMissingInterface() throws NamingException
>>   {
>> -    checkName("aries:services");
>> +    checkName("aries","services");
>>   }
>>      /**
>> @@ -75,20 +81,64 @@
>>   @Test(expected=InvalidNameException.class)
>>   public void checkMissingInterface2() throws NamingException
>>   {
>> -    checkName("aries:services/");
>> +    checkName("aries","services", "");
>>   }
>> -
>> -  /**
>> -   * This method parses the name and then makes sure what was parsed was
>> parsed
>> -   * correctly.
>> -   * -   * @param name
>> -   * @throws NamingException
>> -   */
>> -  private void checkName(String name) throws NamingException
>> +  +  @Test(expected=InvalidNameException.class)
>> +  public void checkIncorrectPath() throws NamingException
>> +  {
>> +    checkName("osgi", "services", "java.lang.Runnable"); +  }
>> +  +  @Test(expected=InvalidNameException.class)
>> +  public void checkIllegalPath() throws NamingException
>>   {
>> -    Name n = parser.parse(name);
>> -    assertNotNull("We got a null name back, which is not allowed.", n);
>> -    assertEquals("The name's toString does not produce the original
>> value", name, n.toString());
>> +    checkName("osgi", "wibble", "java.lang.Runnable"); +  }
>> +  +  private void checkName(String scheme, String path, String ...
>> elements)
>> +    throws NamingException
>> +  {
>> +    StringBuilder builder = new StringBuilder();
>> +    StringBuilder serviceName = new StringBuilder();
>> +    +    builder.append(scheme);
>> +    builder.append(':');
>> +    builder.append(path);
>> +
>> +    if (elements.length > 0) {
>> +      builder.append('/');
>> +      +      for (String element : elements) {
>> +        serviceName.append(element);
>> +        serviceName.append('/');
>> +      }
>> +  +      serviceName.deleteCharAt(serviceName.length() - 1);
>> +      +      builder.append(serviceName);
>> +    }
>> +    +    OsgiName n = (OsgiName) parser.parse(builder.toString());
>> +    +    assertEquals(scheme, n.getScheme());
>> +    assertEquals(path, n.getSchemePath());
>> +    +    if (elements.length > 1) {
>> +      assertEquals(elements[0], n.getInterface());
>> +    }
>> +    +    if (elements.length == 1) {
>> +      assertFalse(n.hasFilter());
>> +    }
>> +    +    if (elements.length > 2) {
>> +      if (elements.length == 2) {
>> +        assertTrue(n.hasFilter());
>> +        assertEquals(elements[1], n.getFilter());
>> +      } else assertFalse(n.hasFilter());
>> +    }
>> +    +    assertEquals(serviceName.toString(), n.getServiceName());
>>   }
>>  }
>> \ No newline at end of file
>>
>> Modified:
>> incubator/aries/trunk/jndi/jndi-url/src/test/java/org/apache/aries/jndi/url/ServiceRegistryContextTest.java
>> URL:
>> http://svn.apache.org/viewvc/incubator/aries/trunk/jndi/jndi-url/src/test/java/org/apache/aries/jndi/url/ServiceRegistryContextTest.java?rev=917809&r1=917808&r2=917809&view=diff
>>
>> ==============================================================================
>> ---
>> incubator/aries/trunk/jndi/jndi-url/src/test/java/org/apache/aries/jndi/url/ServiceRegistryContextTest.java
>> (original)
>> +++
>> incubator/aries/trunk/jndi/jndi-url/src/test/java/org/apache/aries/jndi/url/ServiceRegistryContextTest.java
>> Mon Mar  1 23:53:18 2010
>> @@ -21,7 +21,6 @@
>>  import static org.junit.Assert.assertEquals;
>>  import static org.junit.Assert.assertFalse;
>>  import static org.junit.Assert.assertNotNull;
>> -import static org.junit.Assert.assertSame;
>>  import static org.junit.Assert.assertTrue;
>>  import java.lang.reflect.Field;
>> @@ -37,6 +36,12 @@
>>  import javax.naming.NamingException;
>>  import javax.naming.spi.ObjectFactory;
>>  +import org.apache.aries.jndi.ContextHelper;
>> +import org.apache.aries.jndi.OSGiObjectFactoryBuilder;
>> +import org.apache.aries.mocks.BundleContextMock;
>> +import org.apache.aries.mocks.BundleMock;
>> +import org.apache.aries.unittest.mocks.MethodCall;
>> +import org.apache.aries.unittest.mocks.Skeleton;
>>  import org.junit.After;
>>  import org.junit.Before;
>>  import org.junit.Test;
>> @@ -47,22 +52,13 @@
>>  import org.osgi.framework.ServiceReference;
>>  import org.osgi.framework.ServiceRegistration;
>>  -import org.apache.aries.unittest.mocks.MethodCall;
>> -import org.apache.aries.unittest.mocks.Skeleton;
>> -import org.apache.aries.jndi.ContextHelper;
>> -import org.apache.aries.jndi.OSGiObjectFactoryBuilder;
>> -import org.apache.aries.jndi.services.ServiceHelper;
>> -import org.apache.aries.jndi.url.Activator;
>> -import org.apache.aries.mocks.BundleContextMock;
>> -import org.apache.aries.mocks.BundleMock;
>> -
>>  /**
>>  * Tests for our JNDI implementation for the service registry.
>>  */
>>  public class ServiceRegistryContextTest
>>  {
>>   /** The service we register by default */
>> -  private Thread service;
>> +  private Runnable service;
>>   /** The bundle context for the test */
>>   private BundleContext bc;
>>   /** The service registration for the service */
>> @@ -83,10 +79,7 @@
>>     new Activator().start(bc);
>>     new org.apache.aries.jndi.startup.Activator().start(bc);
>>     -    Field f = ServiceHelper.class.getDeclaredField("context");
>> -    f.setAccessible(true);
>> -    f.set(null, bc);
>> -    f = ContextHelper.class.getDeclaredField("context");
>> +    Field f = ContextHelper.class.getDeclaredField("context");
>>     f.setAccessible(true);
>>     f.set(null, bc);
>>     f = OSGiObjectFactoryBuilder.class.getDeclaredField("context");
>> @@ -94,7 +87,7 @@
>>     f.set(null, bc);
>>  -    service = new Thread();
>> +    service = Skeleton.newMock(Runnable.class);
>>          registerService(service);
>>   }
>> @@ -104,7 +97,7 @@
>>    *     * @param service2 The service to register.
>>    */
>> -  private void registerService(Thread service2)
>> +  private void registerService(Runnable service2)
>>   {
>>     ServiceFactory factory = Skeleton.newMock(ServiceFactory.class);
>>     Skeleton skel = Skeleton.getSkeleton(factory);
>> @@ -159,11 +152,13 @@
>>
>>  Thread.currentThread().setContextClassLoader(mock.getClassLoader());
>>     -    Object s = ctx.lookup("aries:services/java.lang.Runnable");
>> +    Runnable s = (Runnable)
>> ctx.lookup("aries:services/java.lang.Runnable");
>>          assertNotNull("We didn't get a service back from our lookup :(",
>> s);
>>     -    assertEquals("The SR did not return the object we expected",
>> service, s);
>> +    s.run();
>> +    +    Skeleton.getSkeleton(service).assertCalledExactNumberOfTimes(new
>> MethodCall(Runnable.class, "run"), 1);
>>          Skeleton skel = Skeleton.getSkeleton(mock.getBundleContext());
>>     @@ -173,7 +168,7 @@
>>
>>  Thread.currentThread().setContextClassLoader(mock.getClassLoader());
>>  -    s = ctx.lookup("osgi:services/java.lang.Runnable");
>> +    s = (Runnable) ctx.lookup("osgi:service/java.lang.Runnable");
>>          // Check we have the packages set correctly
>>     @@ -181,10 +176,11 @@
>>          assertTrue(ctx.getEnvironment().containsValue(packages));
>>  -         assertNotNull("We didn't get a service back from our lookup
>> :(", s);
>> +
>> +    s.run();
>>     -    assertEquals("The SR did not return the object we expected",
>> service, s);
>> +    Skeleton.getSkeleton(service).assertCalledExactNumberOfTimes(new
>> MethodCall(Runnable.class, "run"), 2);
>>      skel = Skeleton.getSkeleton(mock.getBundleContext());
>>     skel.assertCalled(new MethodCall(BundleContext.class,
>> "getServiceReferences", "java.lang.Runnable", null));
>> @@ -201,15 +197,21 @@
>>   @Test
>>   public void jndiLookupWithFilter() throws NamingException
>>   {
>> +    BundleMock mock = new BundleMock("scooby.doo", new Properties());
>> +    +
>>  Thread.currentThread().setContextClassLoader(mock.getClassLoader());
>> +
>>     InitialContext ctx = new InitialContext();
>>          Object s =
>> ctx.lookup("aries:services/java.lang.Runnable/(rubbish=smelly)");
>>          assertNotNull("We didn't get a service back from our lookup :(",
>> s);
>>     -    assertEquals("The SR did not return the object we expected",
>> service, s);
>> +    service.run();
>>     -    Skeleton.getSkeleton(bc).assertCalled(new
>> MethodCall(BundleContext.class, "getServiceReferences",
>> "java.lang.Runnable", "(rubbish=smelly)"));
>> +    Skeleton.getSkeleton(service).assertCalledExactNumberOfTimes(new
>> MethodCall(Runnable.class, "run"), 1);
>> +
>> +    Skeleton.getSkeleton(mock.getBundleContext()).assertCalled(new
>> MethodCall(BundleContext.class, "getServiceReferences",
>> "java.lang.Runnable", "(rubbish=smelly)"));
>>   }
>>      /**
>> @@ -222,6 +224,11 @@
>>   public void testLookupWhenServiceHasBeenRemoved() throws NamingException
>>   {
>>     reg.unregister();
>> +
>> +    BundleMock mock = new BundleMock("scooby.doo", new Properties());
>> +    +
>>  Thread.currentThread().setContextClassLoader(mock.getClassLoader());
>> +
>>     InitialContext ctx = new InitialContext();
>>          ctx.lookup("aries:services/java.lang.Runnable");
>> @@ -236,6 +243,10 @@
>>   @Test(expected=NameNotFoundException.class)
>>   public void testLookupForServiceWeNeverHad() throws NamingException
>>   {
>> +    BundleMock mock = new BundleMock("scooby.doo", new Properties());
>> +    +
>>  Thread.currentThread().setContextClassLoader(mock.getClassLoader());
>> +
>>     InitialContext ctx = new InitialContext();
>>          ctx.lookup("aries:services/java.lang.Integer");
>> @@ -271,14 +282,53 @@
>>   }
>>    @Test
>> +  public void checkProxyDynamism() throws NamingException
>> +  {
>> +    BundleMock mock = new BundleMock("scooby.doo", new Properties());
>> +    +
>>  Thread.currentThread().setContextClassLoader(mock.getClassLoader());
>> +
>> +    InitialContext ctx = new InitialContext();
>> +    +    String className = Runnable.class.getName();
>> +    +    Runnable t = Skeleton.newMock(Runnable.class);
>> +    Runnable t2 = Skeleton.newMock(Runnable.class);
>> +    +    // we don't want the default service
>> +    reg.unregister();
>> +    +    ServiceRegistration reg = bc.registerService(className, t,
>> null);
>> +    bc.registerService(className, t2, null);
>> +    +    Runnable r = (Runnable)
>> ctx.lookup("osgi:service/java.lang.Runnable");
>> +    +    r.run();
>> +    +    Skeleton.getSkeleton(t).assertCalledExactNumberOfTimes(new
>> MethodCall(Runnable.class, "run"), 1);
>> +    Skeleton.getSkeleton(t2).assertNotCalled(new
>> MethodCall(Runnable.class, "run"));
>> +    +    reg.unregister();
>> +    +    r.run();
>> +    +    Skeleton.getSkeleton(t).assertCalledExactNumberOfTimes(new
>> MethodCall(Runnable.class, "run"), 1);
>> +    Skeleton.getSkeleton(t2).assertCalledExactNumberOfTimes(new
>> MethodCall(Runnable.class, "run"), 1);
>> +  }  +
>> +  @Test
>>   public void checkServiceOrderObserved() throws NamingException
>>   {
>> +    BundleMock mock = new BundleMock("scooby.doo", new Properties());
>> +    +
>>  Thread.currentThread().setContextClassLoader(mock.getClassLoader());
>> +
>>     InitialContext ctx = new InitialContext();
>>          String className = Runnable.class.getName();
>>     -    Thread t = new Thread();
>> -    Thread t2 = new Thread();
>> +    Runnable t = Skeleton.newMock(Runnable.class);
>> +    Runnable t2 = Skeleton.newMock(Runnable.class);
>>          // we don't want the default service
>>     reg.unregister();
>> @@ -286,9 +336,12 @@
>>     ServiceRegistration reg = bc.registerService(className, t, null);
>>     ServiceRegistration reg2 = bc.registerService(className, t2, null);
>>     -    Runnable r = (Runnable)
>> ctx.lookup("osgi:services/java.lang.Runnable");
>> +    Runnable r = (Runnable)
>> ctx.lookup("osgi:service/java.lang.Runnable");
>>     -    assertSame("The wrong runnable was returned", t, r);
>> +    r.run();
>> +    +    Skeleton.getSkeleton(t).assertCalledExactNumberOfTimes(new
>> MethodCall(Runnable.class, "run"), 1);
>> +    Skeleton.getSkeleton(t2).assertNotCalled(new
>> MethodCall(Runnable.class, "run"));
>>          reg.unregister();
>>     reg2.unregister();
>> @@ -296,12 +349,18 @@
>>     Hashtable<String, Object> props = new Hashtable<String, Object>();
>>     props.put(Constants.SERVICE_RANKING, 55);
>>     +    t = Skeleton.newMock(Runnable.class);
>> +    t2 = Skeleton.newMock(Runnable.class);
>> +
>>     reg = bc.registerService(className, t, null);
>>     reg2 = bc.registerService(className, t2, props);
>>     -    r = (Runnable) ctx.lookup("osgi:services/java.lang.Runnable");
>> +    r = (Runnable) ctx.lookup("osgi:service/java.lang.Runnable");
>> +    +    r.run();
>>     -    assertSame("The wrong runnable was returned", t2, r);
>> +    Skeleton.getSkeleton(t).assertNotCalled(new
>> MethodCall(Runnable.class, "run"));
>> +    Skeleton.getSkeleton(t2).assertCalledExactNumberOfTimes(new
>> MethodCall(Runnable.class, "run"), 1);
>>   }
>>      /**
>>
>>
>>
>
>
> --
> Joe
>



-- 
Alasdair Nottingham
not@apache.org

Re: svn commit: r917809 - in /incubator/aries/trunk/jndi/jndi-url: ./ src/main/java/org/apache/aries/jndi/services/ src/main/java/org/apache/aries/jndi/url/ src/test/java/org/apache/aries/jndi/url/

Posted by Joe Bohn <jo...@gmail.com>.
You can follow the instructions on the wiki to setup and run the sample:
http://incubator.apache.org/aries/ariestrader.html

To see the problem you will need select the "Configuration" tab and then 
the "Configure AriesTrader run-time parameters" choice.

Joe


Alasdair Nottingham wrote:
> I'm a little confused because we can do a lookup for the
> TradeServicesManager, but not load the class it is published under,
> which shouldn't happen.
> 
> Are there any instructions on how to reproduce the problem?
> 
> Thanks
> Alasdair
> 
> On 3 March 2010 18:57, Joe Bohn <jo...@gmail.com> wrote:
>> This seemed to do the trick for Blog-Sample but for some reason I'm still
>> getting very much the same failure with AriesTrader.  Perhaps it is related
>> to AriesTrader's use of pax-web-jsp (and this seems to be coming from within
>> a jsp) whereas Blog-Sample does not pull in this bundle or use JSPs?
>>
>> Here is the stack trace for the CNFE:
>>
>> [1945910404@qtp-1489647491-1 -
>> /org.apache.aries.ariestrader.modules.ariestrader-web/config] DEBUG
>> org.apache.aries.blueprint.container.ServiceRecipe - Calling listeners for
>> initial service registration
>> java.lang.ClassNotFoundException:
>> org.apache.aries.samples.ariestrader.api.TradeServicesManager
>>        at
>> org.eclipse.osgi.internal.loader.BundleLoader.findClassInternal(BundleLoader.java:489)
>>        at
>> org.eclipse.osgi.internal.loader.BundleLoader.findClass(BundleLoader.java:405)
>>        at
>> org.eclipse.osgi.internal.loader.BundleLoader.findClass(BundleLoader.java:393)
>>        at
>> org.eclipse.osgi.internal.baseadaptor.DefaultClassLoader.loadClass(DefaultClassLoader.java:105)
>>        at java.lang.ClassLoader.loadClass(ClassLoader.java:250)
>>        at
>> org.eclipse.osgi.internal.loader.BundleLoader.loadClass(BundleLoader.java:321)
>>        at
>> org.eclipse.osgi.framework.internal.core.BundleHost.loadClass(BundleHost.java:231)
>>        at
>> org.eclipse.osgi.framework.internal.core.AbstractBundle.loadClass(AbstractBundle.java:1193)
>>        at
>> org.apache.aries.jndi.services.ServiceHelper.getService(ServiceHelper.java:206)
>>        at
>> org.apache.aries.jndi.url.ServiceRegistryContext.lookup(ServiceRegistryContext.java:189)
>>        at
>> org.apache.aries.jndi.url.ServiceRegistryContext.lookup(ServiceRegistryContext.java:218)
>>        at
>> org.apache.aries.jndi.DelegateContext.lookup(DelegateContext.java:160)
>>        at javax.naming.InitialContext.lookup(InitialContext.java:392)
>>        at
>> org.apache.aries.samples.ariestrader.util.ServiceUtilities.getOSGIService(ServiceUtilities.java:60)
>>        at
>> org.apache.aries.samples.ariestrader.util.ServiceUtilities.getOSGIService(ServiceUtilities.java:41)
>>        at
>> org.apache.aries.samples.ariestrader.api.TradeServiceUtilities.getTradeServicesManager(TradeServiceUtilities.java:63)
>>        at org.apache.jsp.config_jsp._jspService(config_jsp.java:83)
>>        at org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:70)
>>        at javax.servlet.http.HttpServlet.service(HttpServlet.java:820)
>>        at
>> org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:374)
>>        at
>> org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:342)
>>        at org.apache.jasper.servlet.JspServlet.service(JspServlet.java:267)
>>        at javax.servlet.http.HttpServlet.service(HttpServlet.java:820)
>>        at
>> org.ops4j.pax.web.jsp.JspServletWrapper$2.call(JspServletWrapper.java:132)
>>        at
>> org.ops4j.pax.web.jsp.JspServletWrapper$2.call(JspServletWrapper.java:127)
>>        at
>> org.ops4j.pax.swissbox.core.ContextClassLoaderUtils.doWithClassLoader(ContextClassLoaderUtils.java:60)
>>        at
>> org.ops4j.pax.web.jsp.JspServletWrapper.service(JspServletWrapper.java:124)
>>        at
>> org.mortbay.jetty.servlet.ServletHolder.handle(ServletHolder.java:502)
>>        at
>> org.mortbay.jetty.servlet.ServletHandler.handle(ServletHandler.java:389)
>>        at
>> org.ops4j.pax.web.service.jetty.internal.HttpServiceServletHandler.handle(HttpServiceServletHandler.java:64)
>>        at
>> org.mortbay.jetty.servlet.SessionHandler.handle(SessionHandler.java:181)
>>        at
>> org.mortbay.jetty.handler.ContextHandler.handle(ContextHandler.java:765)
>>        at
>> org.ops4j.pax.web.service.jetty.internal.HttpServiceContext.handle(HttpServiceContext.java:111)
>>        at org.mortbay.jetty.servlet.Dispatcher.include(Dispatcher.java:192)
>>        at
>> org.apache.aries.samples.ariestrader.web.TradeConfigServlet.doConfigDisplay(TradeConfigServlet.java:62)
>>        at
>> org.apache.aries.samples.ariestrader.web.TradeConfigServlet.service(TradeConfigServlet.java:403)
>>        at javax.servlet.http.HttpServlet.service(HttpServlet.java:820)
>>        at
>> org.mortbay.jetty.servlet.ServletHolder.handle(ServletHolder.java:502)
>>        at
>> org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)
>>        at
>> org.ops4j.pax.web.service.internal.WelcomeFilesFilter.doFilter(WelcomeFilesFilter.java:169)
>>        at
>> org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1148)
>>        at
>> org.mortbay.jetty.servlet.ServletHandler.handle(ServletHandler.java:387)
>>        at
>> org.ops4j.pax.web.service.jetty.internal.HttpServiceServletHandler.handle(HttpServiceServletHandler.java:64)
>>        at
>> org.mortbay.jetty.servlet.SessionHandler.handle(SessionHandler.java:181)
>>        at
>> org.mortbay.jetty.handler.ContextHandler.handle(ContextHandler.java:765)
>>        at
>> org.ops4j.pax.web.service.jetty.internal.HttpServiceContext.handle(HttpServiceContext.java:111)
>>        at
>> org.ops4j.pax.web.service.jetty.internal.JettyServerHandlerCollection.handle(JettyServerHandlerCollection.java:64)
>>        at
>> org.mortbay.jetty.handler.HandlerWrapper.handle(HandlerWrapper.java:152)
>>        at org.mortbay.jetty.Server.handle(Server.java:322)
>>        at
>> org.mortbay.jetty.HttpConnection.handleRequest(HttpConnection.java:534)
>>        at
>> org.mortbay.jetty.HttpConnection$RequestHandler.headerComplete(HttpConnection.java:864)
>>        at org.mortbay.jetty.HttpParser.parseNext(HttpParser.java:539)
>>        at org.mortbay.jetty.HttpParser.parseAvailable(HttpParser.java:212)
>>        at org.mortbay.jetty.HttpConnection.handle(HttpConnection.java:404)
>>        at
>> org.mortbay.io.nio.SelectChannelEndPoint.run(SelectChannelEndPoint.java:409)
>>        at
>> org.mortbay.thread.QueuedThreadPool$PoolThread.run(QueuedThreadPool.java:520)
>>
>>
>>
>>
>>
>> Alasdair Nottingham wrote:
>>> Hi,
>>>
>>> I just committed a fix. On a related note I see that the pax web guy's
>>> put a Thread context classloader on the thread, but it doesn't
>>> implement BundleReference. Does anyone know how we can raise this with
>>> them?
>>>
>>> Thanks
>>> Alasdair
>>>
>>> On 3 March 2010 14:16, Joe Bohn <jo...@gmail.com> wrote:
>>>> It looks like Blog-Sample is having the same issue and it doesn't use
>>>> JSPs.
>>>>  Here's a similar stack trace from blog-sample:
>>>>
>>>> [1643210767@qtp-2131869628-0 -
>>>> /org.apache.aries.samples.blog-servlet/ViewBlog] DEBUG
>>>> org.apache.aries.blueprint.container.ServiceRecipe - Retrieving service
>>>> for
>>>> bundle org.ops4j.pax.web.pax-web-jetty-bundle_0.7.2 [6] and service
>>>> registration
>>>>
>>>> {org.apache.aries.samples.blog.api.BloggingService}={osgi.service.blueprint.compname=bloggingServiceComponent,
>>>> service.id=52}
>>>> java.lang.ClassNotFoundException:
>>>> org.apache.aries.samples.blog.api.BloggingService
>>>>       at
>>>>
>>>> org.eclipse.osgi.internal.loader.BundleLoader.findClassInternal(BundleLoader.java:489)
>>>>       at
>>>>
>>>> org.eclipse.osgi.internal.loader.BundleLoader.findClass(BundleLoader.java:405)
>>>>       at
>>>>
>>>> org.eclipse.osgi.internal.loader.BundleLoader.findClass(BundleLoader.java:393)
>>>>       at
>>>>
>>>> org.eclipse.osgi.internal.baseadaptor.DefaultClassLoader.loadClass(DefaultClassLoader.java:105)
>>>>       at java.lang.ClassLoader.loadClass(ClassLoader.java:250)
>>>>       at
>>>>
>>>> org.eclipse.osgi.internal.loader.BundleLoader.loadClass(BundleLoader.java:321)
>>>>       at
>>>>
>>>> org.eclipse.osgi.framework.internal.core.BundleHost.loadClass(BundleHost.java:231)
>>>>       at
>>>>
>>>> org.eclipse.osgi.framework.internal.core.AbstractBundle.loadClass(AbstractBundle.java:1193)
>>>>       at
>>>>
>>>> org.apache.aries.jndi.services.ServiceHelper.getService(ServiceHelper.java:210)
>>>>       at
>>>>
>>>> org.apache.aries.jndi.url.ServiceRegistryContext.lookup(ServiceRegistryContext.java:189)
>>>>       at
>>>>
>>>> org.apache.aries.jndi.url.ServiceRegistryContext.lookup(ServiceRegistryContext.java:218)
>>>>       at
>>>> org.apache.aries.jndi.DelegateContext.lookup(DelegateContext.java:160)
>>>>       at javax.naming.InitialContext.lookup(InitialContext.java:392)
>>>>       at
>>>>
>>>> org.apache.aries.samples.blog.web.util.JNDIHelper.getBloggingService(JNDIHelper.java:33)
>>>>       at
>>>> org.apache.aries.samples.blog.web.ViewBlog.doGet(ViewBlog.java:53)
>>>>       at javax.servlet.http.HttpServlet.service(HttpServlet.java:707)
>>>>       at javax.servlet.http.HttpServlet.service(HttpServlet.java:820)
>>>>       at
>>>> org.mortbay.jetty.servlet.ServletHolder.handle(ServletHolder.java:502)
>>>>       at
>>>>
>>>> org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)
>>>>       at
>>>>
>>>> org.ops4j.pax.web.service.internal.WelcomeFilesFilter.doFilter(WelcomeFilesFilter.java:169)
>>>>       at
>>>>
>>>> org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1148)
>>>>       at
>>>> org.mortbay.jetty.servlet.ServletHandler.handle(ServletHandler.java:387)
>>>>       at
>>>>
>>>> org.ops4j.pax.web.service.jetty.internal.HttpServiceServletHandler.handle(HttpServiceServletHandler.java:64)
>>>>       at
>>>> org.mortbay.jetty.servlet.SessionHandler.handle(SessionHandler.java:181)
>>>>       at
>>>> org.mortbay.jetty.handler.ContextHandler.handle(ContextHandler.java:765)
>>>>       at
>>>>
>>>> org.ops4j.pax.web.service.jetty.internal.HttpServiceContext.handle(HttpServiceContext.java:111)
>>>>       at
>>>>
>>>> org.ops4j.pax.web.service.jetty.internal.JettyServerHandlerCollection.handle(JettyServerHandlerCollection.java:64)
>>>>       at
>>>> org.mortbay.jetty.handler.HandlerWrapper.handle(HandlerWrapper.java:152)
>>>>       at org.mortbay.jetty.Server.handle(Server.java:322)
>>>>       at
>>>> org.mortbay.jetty.HttpConnection.handleRequest(HttpConnection.java:534)
>>>>       at
>>>>
>>>> org.mortbay.jetty.HttpConnection$RequestHandler.headerComplete(HttpConnection.java:864)
>>>>       at org.mortbay.jetty.HttpParser.parseNext(HttpParser.java:539)
>>>>       at org.mortbay.jetty.HttpParser.parseAvailable(HttpParser.java:212)
>>>>       at org.mortbay.jetty.HttpConnection.handle(HttpConnection.java:404)
>>>>       at
>>>>
>>>> org.mortbay.io.nio.SelectChannelEndPoint.run(SelectChannelEndPoint.java:409)
>>>>       at
>>>>
>>>> org.mortbay.thread.QueuedThreadPool$PoolThread.run(QueuedThreadPool.java:520)
>>>>
>>>>
>>>> Joe Bohn wrote:
>>>>> And here's the thread context classloader before the lookup ...
>>>>>
>>>>>
>>>>>
>>>>> JasperClassLoader{bundleClassLoader=BundleClassLoader{bundle=org.apache.aries.ariestrader.modules.ariestrader-web_1.0.0.incubating-SNAPSHOT
>>>>>
>>>>> [35],parent=org.eclipse.osgi.internal.baseadaptor.DefaultClassLoader@78ecf608}}
>>>>>
>>>>>
>>>>> Joe
>>>>>
>>>>> Joe Bohn wrote:
>>>>>> Here's the stack trace for the CNFE.  I'll have to work on getting the
>>>>>> thread context classloader.
>>>>>>
>>>>>> [112793090@qtp-2020456228-2 -
>>>>>> /org.apache.aries.ariestrader.modules.ariestrader-web/config] DEBUG
>>>>>> org.apache.aries.blueprint.container.ServiceRecipe - Calling listeners
>>>>>> for
>>>>>> initial service registration
>>>>>> java.lang.ClassNotFoundException:
>>>>>> org.apache.aries.samples.ariestrader.api.TradeServicesManager
>>>>>>       at
>>>>>>
>>>>>> org.eclipse.osgi.internal.loader.BundleLoader.findClassInternal(BundleLoader.java:489)
>>>>>>       at
>>>>>>
>>>>>> org.eclipse.osgi.internal.loader.BundleLoader.findClass(BundleLoader.java:405)
>>>>>>       at
>>>>>>
>>>>>> org.eclipse.osgi.internal.loader.BundleLoader.findClass(BundleLoader.java:393)
>>>>>>       at
>>>>>>
>>>>>> org.eclipse.osgi.internal.baseadaptor.DefaultClassLoader.loadClass(DefaultClassLoader.java:105)
>>>>>>       at java.lang.ClassLoader.loadClass(ClassLoader.java:250)
>>>>>>       at
>>>>>>
>>>>>> org.eclipse.osgi.internal.loader.BundleLoader.loadClass(BundleLoader.java:321)
>>>>>>       at
>>>>>>
>>>>>> org.eclipse.osgi.framework.internal.core.BundleHost.loadClass(BundleHost.java:231)
>>>>>>       at
>>>>>>
>>>>>> org.eclipse.osgi.framework.internal.core.AbstractBundle.loadClass(AbstractBundle.java:1193)
>>>>>>       at
>>>>>>
>>>>>> org.apache.aries.jndi.services.ServiceHelper.getService(ServiceHelper.java:210)
>>>>>>       at
>>>>>>
>>>>>> org.apache.aries.jndi.url.ServiceRegistryContext.lookup(ServiceRegistryContext.java:189)
>>>>>>       at
>>>>>>
>>>>>> org.apache.aries.jndi.url.ServiceRegistryContext.lookup(ServiceRegistryContext.java:218)
>>>>>>       at
>>>>>> org.apache.aries.jndi.DelegateContext.lookup(DelegateContext.java:160)
>>>>>>       at javax.naming.InitialContext.lookup(InitialContext.java:392)
>>>>>>       at
>>>>>>
>>>>>> org.apache.aries.samples.ariestrader.util.ServiceUtilities.getOSGIService(ServiceUtilities.java:60)
>>>>>>       at
>>>>>>
>>>>>> org.apache.aries.samples.ariestrader.util.ServiceUtilities.getOSGIService(ServiceUtilities.java:41)
>>>>>>       at
>>>>>>
>>>>>> org.apache.aries.samples.ariestrader.api.TradeServiceUtilities.getTradeServicesManager(TradeServiceUtilities.java:63)
>>>>>>       at org.apache.jsp.config_jsp._jspService(config_jsp.java:86)
>>>>>>       at
>>>>>> org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:70)
>>>>>>       at javax.servlet.http.HttpServlet.service(HttpServlet.java:820)
>>>>>>       at
>>>>>>
>>>>>> org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:374)
>>>>>>       at
>>>>>>
>>>>>> org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:342)
>>>>>>       at
>>>>>> org.apache.jasper.servlet.JspServlet.service(JspServlet.java:267)
>>>>>>       at javax.servlet.http.HttpServlet.service(HttpServlet.java:820)
>>>>>>       at
>>>>>>
>>>>>> org.ops4j.pax.web.jsp.JspServletWrapper$2.call(JspServletWrapper.java:132)
>>>>>>       at
>>>>>>
>>>>>> org.ops4j.pax.web.jsp.JspServletWrapper$2.call(JspServletWrapper.java:127)
>>>>>>       at
>>>>>>
>>>>>> org.ops4j.pax.swissbox.core.ContextClassLoaderUtils.doWithClassLoader(ContextClassLoaderUtils.java:60)
>>>>>>       at
>>>>>>
>>>>>> org.ops4j.pax.web.jsp.JspServletWrapper.service(JspServletWrapper.java:124)
>>>>>>       at
>>>>>> org.mortbay.jetty.servlet.ServletHolder.handle(ServletHolder.java:502)
>>>>>>       at
>>>>>>
>>>>>> org.mortbay.jetty.servlet.ServletHandler.handle(ServletHandler.java:389)
>>>>>>       at
>>>>>>
>>>>>> org.ops4j.pax.web.service.jetty.internal.HttpServiceServletHandler.handle(HttpServiceServletHandler.java:64)
>>>>>>       at
>>>>>>
>>>>>> org.mortbay.jetty.servlet.SessionHandler.handle(SessionHandler.java:181)
>>>>>>       at
>>>>>>
>>>>>> org.mortbay.jetty.handler.ContextHandler.handle(ContextHandler.java:765)
>>>>>>       at
>>>>>>
>>>>>> org.ops4j.pax.web.service.jetty.internal.HttpServiceContext.handle(HttpServiceContext.java:111)
>>>>>>       at
>>>>>> org.mortbay.jetty.servlet.Dispatcher.include(Dispatcher.java:192)
>>>>>>       at
>>>>>>
>>>>>> org.apache.aries.samples.ariestrader.web.TradeConfigServlet.doConfigDisplay(TradeConfigServlet.java:62)
>>>>>>       at
>>>>>>
>>>>>> org.apache.aries.samples.ariestrader.web.TradeConfigServlet.service(TradeConfigServlet.java:403)
>>>>>>       at javax.servlet.http.HttpServlet.service(HttpServlet.java:820)
>>>>>>       at
>>>>>> org.mortbay.jetty.servlet.ServletHolder.handle(ServletHolder.java:502)
>>>>>>       at
>>>>>>
>>>>>> org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)
>>>>>>       at
>>>>>>
>>>>>> org.ops4j.pax.web.service.internal.WelcomeFilesFilter.doFilter(WelcomeFilesFilter.java:169)
>>>>>>       at
>>>>>>
>>>>>> org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1148)
>>>>>>       at
>>>>>>
>>>>>> org.mortbay.jetty.servlet.ServletHandler.handle(ServletHandler.java:387)
>>>>>>       at
>>>>>>
>>>>>> org.ops4j.pax.web.service.jetty.internal.HttpServiceServletHandler.handle(HttpServiceServletHandler.java:64)
>>>>>>       at
>>>>>>
>>>>>> org.mortbay.jetty.servlet.SessionHandler.handle(SessionHandler.java:181)
>>>>>>       at
>>>>>>
>>>>>> org.mortbay.jetty.handler.ContextHandler.handle(ContextHandler.java:765)
>>>>>>       at
>>>>>>
>>>>>> org.ops4j.pax.web.service.jetty.internal.HttpServiceContext.handle(HttpServiceContext.java:111)
>>>>>>       at
>>>>>>
>>>>>> org.ops4j.pax.web.service.jetty.internal.JettyServerHandlerCollection.handle(JettyServerHandlerCollection.java:64)
>>>>>>       at
>>>>>>
>>>>>> org.mortbay.jetty.handler.HandlerWrapper.handle(HandlerWrapper.java:152)
>>>>>>       at org.mortbay.jetty.Server.handle(Server.java:322)
>>>>>>       at
>>>>>> org.mortbay.jetty.HttpConnection.handleRequest(HttpConnection.java:534)
>>>>>>       at
>>>>>>
>>>>>> org.mortbay.jetty.HttpConnection$RequestHandler.headerComplete(HttpConnection.java:864)
>>>>>>       at org.mortbay.jetty.HttpParser.parseNext(HttpParser.java:539)
>>>>>>       at
>>>>>> org.mortbay.jetty.HttpParser.parseAvailable(HttpParser.java:212)
>>>>>>       at
>>>>>> org.mortbay.jetty.HttpConnection.handle(HttpConnection.java:404)
>>>>>>       at
>>>>>>
>>>>>> org.mortbay.io.nio.SelectChannelEndPoint.run(SelectChannelEndPoint.java:409)
>>>>>>       at
>>>>>>
>>>>>> org.mortbay.thread.QueuedThreadPool$PoolThread.run(QueuedThreadPool.java:520)
>>>>>>
>>>>>> Alasdair Nottingham wrote:
>>>>>>> Hi,
>>>>>>>
>>>>>>> Hmm, I suspect I am not correctly finding the appropriate
>>>>>>> BundleContext to use. That would explain the CNFE because we now proxy
>>>>>>> the services rather than returning the raw service. If it is being
>>>>>>> listed as being used by the pax-web jsp bundle that would explain
>>>>>>> things.
>>>>>>>
>>>>>>> Do you have a stack trace for the ClassNotFoundException? That might
>>>>>>> help to work out what went wrong.
>>>>>>>
>>>>>>> Also can you check the thread context classloader before the lookup?
>>>>>>>
>>>>>>> Thanks
>>>>>>> Alasdair
>>>>>>>
>>>>>>> On 2 March 2010 23:21, Joe Bohn <jo...@gmail.com> wrote:
>>>>>>>> I think there are some issues with this change.   I'll have to dig
>>>>>>>> some
>>>>>>>> more
>>>>>>>> and post more details later (don't have time right now) ... but in
>>>>>>>> short I'm
>>>>>>>> seeing the following:
>>>>>>>>
>>>>>>>> - AriesTrader is behaving very badly after this change.
>>>>>>>> - From within a jsp we use jndi lookup to find an osgi service.
>>>>>>>> - After this change I get a failure in my jsp with a CNFE.   This
>>>>>>>> despite
>>>>>>>> the fact that I can see the package is imported on the web bundle and
>>>>>>>> appears to be wired correctly.
>>>>>>>> - Even more strange: I notice that the application service I was
>>>>>>>> looking for
>>>>>>>> is listed as being used by the pax-web jsp bundle.  So it seems like
>>>>>>>> we
>>>>>>>> might be using the wrong bundle context at some point.
>>>>>>>>
>>>>>>>>
>>>>>>>> Joe
>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>> not@apache.org wrote:
>>>>>>>>> Author: not
>>>>>>>>> Date: Mon Mar  1 23:53:18 2010
>>>>>>>>> New Revision: 917809
>>>>>>>>>
>>>>>>>>> URL: http://svn.apache.org/viewvc?rev=917809&view=rev
>>>>>>>>> Log:
>>>>>>>>> ARIES-128 Implement OSGi spec url lookup scheme
>>>>>>>>>
>>>>>>>>> Added:
>>>>>>>>>
>>>>>>>>>
>>>>>>>>>
>>>>>>>>>  incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/OsgiName.java
>>>>>>>>>    - copied, changed from r910238,
>>>>>>>>>
>>>>>>>>>
>>>>>>>>> incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/ServiceRegistryName.java
>>>>>>>>>
>>>>>>>>>
>>>>>>>>>
>>>>>>>>>  incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/OsgiNameParser.java
>>>>>>>>>    - copied, changed from r910238,
>>>>>>>>>
>>>>>>>>>
>>>>>>>>> incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/ServiceRegistryNameParser.java
>>>>>>>>>
>>>>>>>>>
>>>>>>>>>
>>>>>>>>>  incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/ServiceRegistryListContext.java
>>>>>>>>>
>>>>>>>>>
>>>>>>>>>
>>>>>>>>>  incubator/aries/trunk/jndi/jndi-url/src/test/java/org/apache/aries/jndi/url/OsgiNameParserTest.java
>>>>>>>>>    - copied, changed from r917002,
>>>>>>>>>
>>>>>>>>>
>>>>>>>>> incubator/aries/trunk/jndi/jndi-url/src/test/java/org/apache/aries/jndi/url/ServiceRegistryNameParserTest.java
>>>>>>>>> Removed:
>>>>>>>>>
>>>>>>>>>
>>>>>>>>>
>>>>>>>>>  incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/ServiceRegistryName.java
>>>>>>>>>
>>>>>>>>>
>>>>>>>>>
>>>>>>>>>  incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/ServiceRegistryNameParser.java
>>>>>>>>>
>>>>>>>>>
>>>>>>>>>
>>>>>>>>>  incubator/aries/trunk/jndi/jndi-url/src/test/java/org/apache/aries/jndi/url/ServiceHelperTest.java
>>>>>>>>>
>>>>>>>>>
>>>>>>>>>
>>>>>>>>>  incubator/aries/trunk/jndi/jndi-url/src/test/java/org/apache/aries/jndi/url/ServiceRegistryNameParserTest.java
>>>>>>>>> Modified:
>>>>>>>>>  incubator/aries/trunk/jndi/jndi-url/pom.xml
>>>>>>>>>
>>>>>>>>>
>>>>>>>>>
>>>>>>>>>  incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/services/ServiceHelper.java
>>>>>>>>>
>>>>>>>>>
>>>>>>>>>
>>>>>>>>>  incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/Activator.java
>>>>>>>>>
>>>>>>>>>
>>>>>>>>>
>>>>>>>>>  incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/OsgiURLContextFactory.java
>>>>>>>>>
>>>>>>>>>
>>>>>>>>>
>>>>>>>>>  incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/ServiceRegistryContext.java
>>>>>>>>>
>>>>>>>>>
>>>>>>>>>
>>>>>>>>>  incubator/aries/trunk/jndi/jndi-url/src/test/java/org/apache/aries/jndi/url/ServiceRegistryContextTest.java
>>>>>>>>>
>>>>>>>>> Modified: incubator/aries/trunk/jndi/jndi-url/pom.xml
>>>>>>>>> URL:
>>>>>>>>>
>>>>>>>>>
>>>>>>>>> http://svn.apache.org/viewvc/incubator/aries/trunk/jndi/jndi-url/pom.xml?rev=917809&r1=917808&r2=917809&view=diff
>>>>>>>>>
>>>>>>>>>
>>>>>>>>>
>>>>>>>>> ==============================================================================
>>>>>>>>> --- incubator/aries/trunk/jndi/jndi-url/pom.xml (original)
>>>>>>>>> +++ incubator/aries/trunk/jndi/jndi-url/pom.xml Mon Mar  1 23:53:18
>>>>>>>>> 2010
>>>>>>>>> @@ -33,6 +33,10 @@
>>>>>>>>>    <dependencies>
>>>>>>>>>     <dependency>
>>>>>>>>> +       <groupId>org.apache.aries</groupId>
>>>>>>>>> +       <artifactId>org.apache.aries.util</artifactId>
>>>>>>>>> +      </dependency>
>>>>>>>>> +      <dependency>
>>>>>>>>>         <groupId>org.osgi</groupId>
>>>>>>>>>         <artifactId>org.osgi.core</artifactId>
>>>>>>>>>         <scope>provided</scope>
>>>>>>>>>
>>>>>>>>> Modified:
>>>>>>>>>
>>>>>>>>>
>>>>>>>>> incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/services/ServiceHelper.java
>>>>>>>>> URL:
>>>>>>>>>
>>>>>>>>>
>>>>>>>>> http://svn.apache.org/viewvc/incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/services/ServiceHelper.java?rev=917809&r1=917808&r2=917809&view=diff
>>>>>>>>>
>>>>>>>>>
>>>>>>>>>
>>>>>>>>> ==============================================================================
>>>>>>>>> ---
>>>>>>>>>
>>>>>>>>>
>>>>>>>>> incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/services/ServiceHelper.java
>>>>>>>>> (original)
>>>>>>>>> +++
>>>>>>>>>
>>>>>>>>>
>>>>>>>>> incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/services/ServiceHelper.java
>>>>>>>>> Mon Mar  1 23:53:18 2010
>>>>>>>>> @@ -18,18 +18,30 @@
>>>>>>>>>  */
>>>>>>>>>  package org.apache.aries.jndi.services;
>>>>>>>>>  +import java.lang.reflect.InvocationHandler;
>>>>>>>>> +import java.lang.reflect.Method;
>>>>>>>>> +import java.lang.reflect.Proxy;
>>>>>>>>> +import java.security.AccessController;
>>>>>>>>> +import java.security.PrivilegedAction;
>>>>>>>>> +import java.util.ArrayList;
>>>>>>>>>  import java.util.Arrays;
>>>>>>>>>  import java.util.Comparator;
>>>>>>>>>  import java.util.HashSet;
>>>>>>>>>  import java.util.LinkedList;
>>>>>>>>>  import java.util.List;
>>>>>>>>> +import java.util.Map;
>>>>>>>>>  import java.util.Set;
>>>>>>>>>  import java.util.concurrent.ConcurrentHashMap;
>>>>>>>>>  import java.util.concurrent.ConcurrentMap;
>>>>>>>>>  +import javax.naming.NamingException;
>>>>>>>>> +
>>>>>>>>> +import org.apache.aries.util.BundleToClassLoaderAdapter;
>>>>>>>>> +import org.osgi.framework.Bundle;
>>>>>>>>>  import org.osgi.framework.BundleContext;
>>>>>>>>>  import org.osgi.framework.BundleReference;
>>>>>>>>>  import org.osgi.framework.InvalidSyntaxException;
>>>>>>>>> +import org.osgi.framework.ServiceException;
>>>>>>>>>  import org.osgi.framework.ServiceReference;
>>>>>>>>>  /**
>>>>>>>>> @@ -47,221 +59,206 @@
>>>>>>>>>  */
>>>>>>>>>  public final class ServiceHelper
>>>>>>>>>  {
>>>>>>>>> -  /** The bundle context used for service registry queries */
>>>>>>>>> -  private static BundleContext context;
>>>>>>>>> -  /** A cache of what service was returned last time the query was
>>>>>>>>> performed */
>>>>>>>>> -  private static ConcurrentMap<ServiceKey, Set<ServiceReference>>
>>>>>>>>> cache =
>>>>>>>>> new ConcurrentHashMap<ServiceKey, Set<ServiceReference>>();
>>>>>>>>> -
>>>>>>>>> -  public static void setBundleContext(BundleContext ctx)
>>>>>>>>> +  public static class StackFinder extends SecurityManager
>>>>>>>>>  {
>>>>>>>>> -    context = ctx;
>>>>>>>>> +    public Class<?>[] getClassContext()
>>>>>>>>> +    {
>>>>>>>>> +      return super.getClassContext();
>>>>>>>>> +    }
>>>>>>>>>  }
>>>>>>>>> -  -  /**
>>>>>>>>> -   * This class is used as the key into the cache. It holds
>>>>>>>>> information
>>>>>>>>> to identify -   * who performed the query, along with the className
>>>>>>>>> and
>>>>>>>>> filter used. The thread context
>>>>>>>>> -   * class loader is used in the key, so two different modules will
>>>>>>>>> potentially get different
>>>>>>>>> -   * services.
>>>>>>>>> -   */
>>>>>>>>> -  private static final class ServiceKey
>>>>>>>>> +
>>>>>>>>> +  private static class JNDIServiceDamper implements
>>>>>>>>> InvocationHandler
>>>>>>>>>  {
>>>>>>>>> -    /** The class loader of the invoking application */
>>>>>>>>> -    private ClassLoader classLoader;
>>>>>>>>> -    /** The name of the class being queried from the registry */
>>>>>>>>> -    private String className;
>>>>>>>>> -    /** the registry filter, this may be null */
>>>>>>>>> +    private BundleContext ctx;
>>>>>>>>> +    private ServicePair pair;
>>>>>>>>> +    private String interfaceName;
>>>>>>>>>   private String filter;
>>>>>>>>> -    /** The cached hashCode */
>>>>>>>>> -    private final int hashCode;
>>>>>>>>> -
>>>>>>>>> -    /**
>>>>>>>>> -     * Boring unimportant comment.
>>>>>>>>> -     * -     * @param cl
>>>>>>>>> -     * @param cn
>>>>>>>>> -     * @param f
>>>>>>>>> -     */
>>>>>>>>> -    public ServiceKey(ClassLoader cl, String cn, String f)
>>>>>>>>> +    private boolean dynamic;
>>>>>>>>> +    +    public JNDIServiceDamper(BundleContext context, String i,
>>>>>>>>> String
>>>>>>>>> f, ServicePair service, boolean d)
>>>>>>>>>   {
>>>>>>>>> -      classLoader = cl;
>>>>>>>>> -      className = cn;
>>>>>>>>> +      ctx = context;
>>>>>>>>> +      pair = service;
>>>>>>>>> +      interfaceName = i;
>>>>>>>>>     filter = f;
>>>>>>>>> -      -      int classNameHash = (className == null) ? 0 :
>>>>>>>>> className.hashCode();
>>>>>>>>> -      hashCode = System.identityHashCode(classLoader) * 1000003 +
>>>>>>>>> classNameHash;
>>>>>>>>> +      dynamic = d;
>>>>>>>>>   }
>>>>>>>>> -
>>>>>>>>> -    @Override
>>>>>>>>> -    public int hashCode()
>>>>>>>>> -    {
>>>>>>>>> -      return hashCode;
>>>>>>>>> -    }
>>>>>>>>> -
>>>>>>>>> -    @Override
>>>>>>>>> -    public boolean equals(Object other)
>>>>>>>>> +    +    public Object invoke(Object proxy, Method method, Object[]
>>>>>>>>> args)
>>>>>>>>> throws Throwable
>>>>>>>>>   {
>>>>>>>>> -      if (other == this) return true;
>>>>>>>>> -      if (other == null) return false;
>>>>>>>>> -
>>>>>>>>> -      if (other instanceof ServiceKey) {
>>>>>>>>> -        ServiceKey otherKey = (ServiceKey) other;
>>>>>>>>> -        if (hashCode != otherKey.hashCode) return false;
>>>>>>>>> -
>>>>>>>>> -        if (classLoader != otherKey.classLoader) return false;
>>>>>>>>> -        if (!!!comparePossiblyNullObjects(className,
>>>>>>>>> otherKey.className))
>>>>>>>>> return false;
>>>>>>>>> -        return comparePossiblyNullObjects(filter, otherKey.filter);
>>>>>>>>> -      }
>>>>>>>>> -
>>>>>>>>> -      return false;
>>>>>>>>> -    }
>>>>>>>>> -    -    /**
>>>>>>>>> -     * Compares two objects where one or other (or both) may be
>>>>>>>>> null.
>>>>>>>>> -     * -     * @param a the first object to compare.
>>>>>>>>> -     * @param b the second object to compare.
>>>>>>>>> -     * @return true if they are ==, both null or identity equals,
>>>>>>>>> false
>>>>>>>>> otherwise.
>>>>>>>>> -     */
>>>>>>>>> -    public boolean comparePossiblyNullObjects(Object a, Object b) {
>>>>>>>>> -      if (a == b) return true;
>>>>>>>>> -      else if (a == null) return false;
>>>>>>>>> -      else return a.equals(b);
>>>>>>>>> +      if (pair.ref.getBundle() == null) {
>>>>>>>>> +        if (dynamic) pair = findService(ctx, interfaceName,
>>>>>>>>> filter);
>>>>>>>>> +        else pair = null;
>>>>>>>>> +      }
>>>>>>>>> +      +      if (pair == null) {
>>>>>>>>> +        throw new ServiceException(interfaceName,
>>>>>>>>> ServiceException.UNREGISTERED);
>>>>>>>>> +      }
>>>>>>>>> +      +      return method.invoke(pair.service, args);
>>>>>>>>>   }
>>>>>>>>>  }
>>>>>>>>> -
>>>>>>>>> -  /**
>>>>>>>>> -   * This method is used to obtain a single instance of a desired
>>>>>>>>> service
>>>>>>>>> from the OSGi
>>>>>>>>> -   * service registry. If the filter and class name identify
>>>>>>>>> multiple
>>>>>>>>> services the first
>>>>>>>>> -   * one is returned. If no service is found null will be returned.
>>>>>>>>> -   * -   * @param className The class name used to register the
>>>>>>>>> desired
>>>>>>>>> service. If null is provided
>>>>>>>>> -   *                  then all services are eligible to be
>>>>>>>>> returned.
>>>>>>>>> -   * @param filter    An RFC 1960 query into the properties of the
>>>>>>>>> registered services. e.g.
>>>>>>>>> -   *                  (service.description=really useful)
>>>>>>>>> -   * @return          The desired service
>>>>>>>>> -   * -   * @throws IllegalArgumentException If the filter is not
>>>>>>>>> valid.
>>>>>>>>> See RFC 1960 to work out what -   *
>>>>>>>>>  it
>>>>>>>>> should be.
>>>>>>>>> -   */
>>>>>>>>> -  public static Object getService(String className, String filter)
>>>>>>>>> throws
>>>>>>>>> IllegalArgumentException
>>>>>>>>> +  +  private static class ServicePair
>>>>>>>>>  {
>>>>>>>>> -    Object service = null;
>>>>>>>>> -    try {
>>>>>>>>> -      BundleContext callerCtx = getBundleContext();
>>>>>>>>> -      ServiceReference[] refs =
>>>>>>>>> callerCtx.getServiceReferences(className,
>>>>>>>>> filter);
>>>>>>>>> -      -      if (refs != null) {
>>>>>>>>> -        // we need to sort the references returned in case they are
>>>>>>>>> out
>>>>>>>>> of order
>>>>>>>>> -        // we need to sort in the reverse natural order, services
>>>>>>>>> with
>>>>>>>>> higher -        // ranking or lower id should be processed first so
>>>>>>>>> should
>>>>>>>>> be earlier in the array.
>>>>>>>>> -        Arrays.sort(refs, new Comparator<ServiceReference>() {
>>>>>>>>> -          public int compare(ServiceReference o1, ServiceReference
>>>>>>>>> o2)
>>>>>>>>> -          {
>>>>>>>>> -            return o2.compareTo(o1);
>>>>>>>>> -          }
>>>>>>>>> -        });
>>>>>>>>> -        -        for (ServiceReference ref : refs) {
>>>>>>>>> -          List<Object> services = getServices(callerCtx, className,
>>>>>>>>> filter, ref);
>>>>>>>>> -          if (!!!services.isEmpty()) {
>>>>>>>>> -            service = services.get(0);
>>>>>>>>> -            break;
>>>>>>>>> -          }
>>>>>>>>> -        }
>>>>>>>>> -      }      -    } catch (InvalidSyntaxException e) {
>>>>>>>>> -      throw new IllegalArgumentException(e.getMessage(), e);
>>>>>>>>> -    }
>>>>>>>>> -    -    return service;
>>>>>>>>> +    private ServiceReference ref;
>>>>>>>>> +    private Object service;
>>>>>>>>>  }
>>>>>>>>>    /**
>>>>>>>>> -   * This method is used to obtain a list of service instances from
>>>>>>>>> the
>>>>>>>>> OSGi
>>>>>>>>> -   * service registry. If no service is found an empty list will be
>>>>>>>>> returned.
>>>>>>>>> -   * -   * @param className The class name used to register the
>>>>>>>>> desired
>>>>>>>>> service. If null is provided
>>>>>>>>> -   *                  then all services are eligible to be
>>>>>>>>> returned.
>>>>>>>>> -   * @param filter    An RFC 1960 query into the properties of the
>>>>>>>>> registered services. e.g.
>>>>>>>>> -   *                  (service.description=really useful)
>>>>>>>>> -   * @return          A list of matching services.
>>>>>>>>> -   * -   * @throws IllegalArgumentException If the filter is not
>>>>>>>>> valid.
>>>>>>>>> See RFC 1960 to work out what -   *
>>>>>>>>>  it
>>>>>>>>> should be.
>>>>>>>>> +   * @param env +   * @return the bundle context for the caller.
>>>>>>>>> +   * @throws NamingException     */
>>>>>>>>> -  public static List<?> getServices(String className, String
>>>>>>>>> filter)
>>>>>>>>> -      throws IllegalArgumentException
>>>>>>>>> +  public static BundleContext getBundleContext(Map<String, Object>
>>>>>>>>> env)
>>>>>>>>> throws NamingException
>>>>>>>>>  {
>>>>>>>>> -    List<Object> services;
>>>>>>>>> -    try {
>>>>>>>>> -      BundleContext callerCtx = getBundleContext();
>>>>>>>>> -      ServiceReference[] refs =
>>>>>>>>> callerCtx.getAllServiceReferences(className, filter);
>>>>>>>>> +    BundleContext result = null;
>>>>>>>>> +    +    Object bc = env.get("osgi.service.jndi.bundleContext");
>>>>>>>>> +    +    if (bc != null && bc instanceof BundleContext) result =
>>>>>>>>> (BundleContext) bc;
>>>>>>>>> +    else {
>>>>>>>>> +      ClassLoader cl = AccessController.doPrivileged(new
>>>>>>>>> PrivilegedAction<ClassLoader>() {
>>>>>>>>> +        public ClassLoader run()
>>>>>>>>> +        {
>>>>>>>>> +          return Thread.currentThread().getContextClassLoader();
>>>>>>>>> +        }
>>>>>>>>> +      });
>>>>>>>>>     -      services = getServices(callerCtx, className, filter,
>>>>>>>>> refs);
>>>>>>>>> -    } catch (InvalidSyntaxException e) {
>>>>>>>>> -      throw new IllegalArgumentException(e.getMessage(), e);
>>>>>>>>> +      result = getBundleContext(cl);
>>>>>>>>> +    }
>>>>>>>>> +    +    if (result == null) {
>>>>>>>>> +      StackTraceElement[] stackTrace =
>>>>>>>>> AccessController.doPrivileged(new
>>>>>>>>> PrivilegedAction<StackTraceElement[]>() {
>>>>>>>>> +        public StackTraceElement[] run()
>>>>>>>>> +        {
>>>>>>>>> +          return Thread.currentThread().getStackTrace();
>>>>>>>>> +        }
>>>>>>>>> +      });
>>>>>>>>> +      +      StackFinder finder = new StackFinder();
>>>>>>>>> +      Class<?>[] classStack = finder.getClassContext();
>>>>>>>>> +      +      boolean found = false;
>>>>>>>>> +      boolean foundLookup = false;
>>>>>>>>> +      int i = 0;
>>>>>>>>> +      for (; i < stackTrace.length && !!!found; i++) {
>>>>>>>>> +        if (!!!foundLookup &&
>>>>>>>>> "lookup".equals(stackTrace[i].getMethodName())) {
>>>>>>>>> +          foundLookup = true;
>>>>>>>>> +        } else if (foundLookup &&
>>>>>>>>> !!!(stackTrace[i].getClassName().startsWith("org.apache.aries.jndi")
>>>>>>>>> ||
>>>>>>>>> +
>>>>>>>>>  stackTrace[i].getClassName().startsWith("javax.naming"))) {
>>>>>>>>> +          found = true;
>>>>>>>>> +        }
>>>>>>>>> +      }
>>>>>>>>> +      +      if (found) {
>>>>>>>>> +        Set<Integer> classLoadersChecked = new HashSet<Integer>();
>>>>>>>>> +        for (; i < classStack.length && result == null; i++) {
>>>>>>>>> +          ClassLoader cl = classStack[i].getClassLoader();
>>>>>>>>> +          int hash = System.identityHashCode(cl);
>>>>>>>>> +          if (!!!classLoadersChecked.contains(hash)) {
>>>>>>>>> +            classLoadersChecked.add(hash);
>>>>>>>>> +            result = getBundleContext(cl);
>>>>>>>>> +          }
>>>>>>>>> +        }
>>>>>>>>> +        // Now we walk the stack looking for the BundleContext
>>>>>>>>> +      }
>>>>>>>>>   }
>>>>>>>>>   -    return services;
>>>>>>>>> +    if (result == null) throw new NamingException("Unable to find
>>>>>>>>> BundleContext");
>>>>>>>>> +    +    return result;
>>>>>>>>>  }
>>>>>>>>> -  -  /**
>>>>>>>>> -   * @return the bundle context for the caller.
>>>>>>>>> -   */
>>>>>>>>> -  private static BundleContext getBundleContext()
>>>>>>>>> +
>>>>>>>>> +  private static BundleContext getBundleContext(ClassLoader cl)
>>>>>>>>>  {
>>>>>>>>>   BundleContext result = null;
>>>>>>>>> -    ClassLoader cl =
>>>>>>>>> Thread.currentThread().getContextClassLoader();
>>>>>>>>>   while (result == null && cl != null) {
>>>>>>>>>     if (cl instanceof BundleReference) {
>>>>>>>>>       result = ((BundleReference)cl).getBundle().getBundleContext();
>>>>>>>>>     } else if (cl != null) {
>>>>>>>>>       cl = cl.getParent();
>>>>>>>>>     }
>>>>>>>>> -    } +    }
>>>>>>>>>   -    if (result == null) result = context;
>>>>>>>>>   return result;
>>>>>>>>>  }
>>>>>>>>>  -  /**
>>>>>>>>> -   * This worker method obtains the requested service(s) and if the
>>>>>>>>> service(s) -   * exist updates the cache and releases the previous
>>>>>>>>> service(s).
>>>>>>>>> -   * -   * @param callerCtx The caller context.
>>>>>>>>> -   * @param className The class name used to query for the service.
>>>>>>>>> -   * @param filter    The filter name used to query for the
>>>>>>>>> service.
>>>>>>>>> -   * @param refs      The references to get.
>>>>>>>>> -   * @return          The service, if one was found, or null.
>>>>>>>>> -   */
>>>>>>>>> -  private static List<Object> getServices(BundleContext callerCtx,
>>>>>>>>> String
>>>>>>>>> className, String filter, ServiceReference...refs)
>>>>>>>>> +  public static Object getService(String interface1, String filter,
>>>>>>>>> String serviceName, boolean dynamicRebind, Map<String, Object> env)
>>>>>>>>> throws
>>>>>>>>> NamingException
>>>>>>>>>  {
>>>>>>>>> -    List<Object> data = new LinkedList<Object>();
>>>>>>>>> +    Object result = null;
>>>>>>>>> +    +    BundleContext ctx = getBundleContext(env);
>>>>>>>>> +    +    ServicePair pair = findService(ctx, interface1, filter);
>>>>>>>>>   -    if (refs != null) {
>>>>>>>>> -      Set<ServiceReference> refSet = new
>>>>>>>>> HashSet<ServiceReference>();
>>>>>>>>> -      for (ServiceReference ref : refs) {
>>>>>>>>> -        Object service = callerCtx.getService(ref);
>>>>>>>>> -        if (service != null) {
>>>>>>>>> -          data.add(service);
>>>>>>>>> -          refSet.add(ref);
>>>>>>>>> +    if (pair == null) {
>>>>>>>>> +      interface1 = null;
>>>>>>>>> +      filter = "(osgi.jndi.serviceName=" + serviceName + ")";
>>>>>>>>> +      pair = findService(ctx, interface1, filter);
>>>>>>>>> +    }
>>>>>>>>> +    +    if (pair != null) {
>>>>>>>>> +      String[] interfaces = (String[])
>>>>>>>>> pair.ref.getProperty("objectClass");
>>>>>>>>> +      +      List<Class<?>> clazz = new
>>>>>>>>> ArrayList<Class<?>>(interfaces.length);
>>>>>>>>> +      +      Bundle b = ctx.getBundle();
>>>>>>>>> +      +      for (String interfaceName : interfaces) {
>>>>>>>>> +        try {
>>>>>>>>> +          clazz.add(b.loadClass(interfaceName));
>>>>>>>>> +        } catch (ClassNotFoundException e) {
>>>>>>>>> +          // TODO Auto-generated catch block
>>>>>>>>> +          e.printStackTrace();
>>>>>>>>>       }
>>>>>>>>>     }
>>>>>>>>>     -      ClassLoader cl =
>>>>>>>>> Thread.currentThread().getContextClassLoader();
>>>>>>>>> -      ServiceKey key = new ServiceKey(cl, className, filter);
>>>>>>>>> +      if (clazz.isEmpty()) {
>>>>>>>>> +        throw new IllegalArgumentException();
>>>>>>>>> +      }
>>>>>>>>>     -      // we do not need any synchronization around this. The
>>>>>>>>> map
>>>>>>>>> is
>>>>>>>>> concurrent
>>>>>>>>> -      // and until here we do not touch any shared state.
>>>>>>>>> -      refSet = cache.put(key, refSet);
>>>>>>>>> +      InvocationHandler ih = new JNDIServiceDamper(ctx, interface1,
>>>>>>>>> filter, pair, dynamicRebind);
>>>>>>>>>     -      if (refSet != null) {
>>>>>>>>> -        for (ServiceReference ref : refSet) {
>>>>>>>>> -          callerCtx.ungetService(ref);
>>>>>>>>> +      result = Proxy.newProxyInstance(new
>>>>>>>>> BundleToClassLoaderAdapter(b),
>>>>>>>>> clazz.toArray(new Class<?>[clazz.size()]), ih);
>>>>>>>>> +    }
>>>>>>>>> +    +    return result;
>>>>>>>>> +  }
>>>>>>>>> +
>>>>>>>>> +  private static ServicePair findService(BundleContext ctx, String
>>>>>>>>> interface1, String filter)
>>>>>>>>> +  {
>>>>>>>>> +    ServicePair p = null;
>>>>>>>>> +    +    try {
>>>>>>>>> +      ServiceReference[] refs =
>>>>>>>>> ctx.getServiceReferences(interface1,
>>>>>>>>> filter);
>>>>>>>>> +      +      if (refs != null) {
>>>>>>>>> +        // natural order is the exact opposite of the order we
>>>>>>>>> desire.
>>>>>>>>> +        Arrays.sort(refs, new Comparator<ServiceReference>() {
>>>>>>>>> +          public int compare(ServiceReference o1, ServiceReference
>>>>>>>>> o2)
>>>>>>>>> +          {
>>>>>>>>> +            return o2.compareTo(o1);
>>>>>>>>> +          }
>>>>>>>>> +        });
>>>>>>>>> +        +        for (ServiceReference ref : refs) {
>>>>>>>>> +          Object service = ctx.getService(ref);
>>>>>>>>> +          +          if (service != null) {
>>>>>>>>> +            p = new ServicePair();
>>>>>>>>> +            p.ref = ref;
>>>>>>>>> +            p.service = service;
>>>>>>>>> +            break;
>>>>>>>>> +          }
>>>>>>>>>       }
>>>>>>>>>     }
>>>>>>>>> +      +    } catch (InvalidSyntaxException e) {
>>>>>>>>> +      // TODO Auto-generated catch block
>>>>>>>>> +      e.printStackTrace();
>>>>>>>>>   }
>>>>>>>>>   -    return data;
>>>>>>>>> +    return p;
>>>>>>>>>  }
>>>>>>>>>  }
>>>>>>>>>
>>>>>>>>> Modified:
>>>>>>>>>
>>>>>>>>>
>>>>>>>>> incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/Activator.java
>>>>>>>>> URL:
>>>>>>>>>
>>>>>>>>>
>>>>>>>>> http://svn.apache.org/viewvc/incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/Activator.java?rev=917809&r1=917808&r2=917809&view=diff
>>>>>>>>>
>>>>>>>>>
>>>>>>>>>
>>>>>>>>> ==============================================================================
>>>>>>>>> ---
>>>>>>>>>
>>>>>>>>>
>>>>>>>>> incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/Activator.java
>>>>>>>>> (original)
>>>>>>>>> +++
>>>>>>>>>
>>>>>>>>>
>>>>>>>>> incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/Activator.java
>>>>>>>>> Mon Mar  1 23:53:18 2010
>>>>>>>>> @@ -34,8 +34,6 @@
>>>>>>>>>
>>>>>>>>>  public void start(BundleContext context)
>>>>>>>>>  {
>>>>>>>>> -    ServiceHelper.setBundleContext(context);
>>>>>>>>> -         Hashtable<Object, Object> props = new Hashtable<Object,
>>>>>>>>> Object>();
>>>>>>>>>   props.put("osgi.jndi.urlScheme", new String[] {"osgi", "aries"} );
>>>>>>>>>   reg = context.registerService(ObjectFactory.class.getName(), new
>>>>>>>>> OsgiURLContextFactory(), props);
>>>>>>>>>
>>>>>>>>> Copied:
>>>>>>>>>
>>>>>>>>>
>>>>>>>>> incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/OsgiName.java
>>>>>>>>> (from r910238,
>>>>>>>>>
>>>>>>>>>
>>>>>>>>> incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/ServiceRegistryName.java)
>>>>>>>>> URL:
>>>>>>>>>
>>>>>>>>>
>>>>>>>>> http://svn.apache.org/viewvc/incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/OsgiName.java?p2=incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/OsgiName.java&p1=incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/ServiceRegistryName.java&r1=910238&r2=917809&rev=917809&view=diff
>>>>>>>>>
>>>>>>>>>
>>>>>>>>>
>>>>>>>>> ==============================================================================
>>>>>>>>> ---
>>>>>>>>>
>>>>>>>>>
>>>>>>>>> incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/ServiceRegistryName.java
>>>>>>>>> (original)
>>>>>>>>> +++
>>>>>>>>>
>>>>>>>>>
>>>>>>>>> incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/OsgiName.java
>>>>>>>>> Mon Mar  1 23:53:18 2010
>>>>>>>>> @@ -21,28 +21,104 @@
>>>>>>>>>  import java.util.Enumeration;
>>>>>>>>>  import javax.naming.CompositeName;
>>>>>>>>> +import javax.naming.InvalidNameException;
>>>>>>>>> +import javax.naming.Name;
>>>>>>>>>  /**
>>>>>>>>> - * A composite name for the aries namespace. We only have this so
>>>>>>>>> that we
>>>>>>>>> can
>>>>>>>>> - * provide a nicer toString()
>>>>>>>>> + * A composite name for the aries namespace. This provides useful
>>>>>>>>> utility
>>>>>>>>> methods
>>>>>>>>> + * for accessing the name.
>>>>>>>>> + * + * component 0: osgi:service, aries:services, osgi:servicelist
>>>>>>>>> + * component 1: interface
>>>>>>>>> + * component 2: filter
>>>>>>>>>  */
>>>>>>>>> -public final class ServiceRegistryName extends CompositeName
>>>>>>>>> +public final class OsgiName extends CompositeName
>>>>>>>>>  {
>>>>>>>>>  /** The serial version UID */
>>>>>>>>>  private static final long serialVersionUID = 6617580228852444656L;
>>>>>>>>> +  public static final String OSGI_SCHEME = "osgi";
>>>>>>>>> +  public static final String ARIES_SCHEME = "aries";
>>>>>>>>> +  public static final String SERVICE_PATH = "service";
>>>>>>>>> +  public static final String SERVICES_PATH = "services";
>>>>>>>>> +  public static final String SERVICE_LIST_PATH = "servicelist";
>>>>>>>>> +  public static final String FRAMEWORK_PATH = "framework";
>>>>>>>>>  -  @Override
>>>>>>>>> -  public String toString()
>>>>>>>>> +  public OsgiName(String name) throws InvalidNameException
>>>>>>>>>  {
>>>>>>>>> -    StringBuilder buffer = new StringBuilder();
>>>>>>>>> +    super(name);
>>>>>>>>> +  }
>>>>>>>>> +
>>>>>>>>> +  public OsgiName(Name name) throws InvalidNameException
>>>>>>>>> +  {
>>>>>>>>> +    this(name.toString());
>>>>>>>>> +  }
>>>>>>>>> +
>>>>>>>>> +  public boolean hasFilter()
>>>>>>>>> +  {
>>>>>>>>> +    return size() == 3;
>>>>>>>>> +  }
>>>>>>>>> +  +  public boolean isServiceNameBased()
>>>>>>>>> +  {
>>>>>>>>> +    return size() > 3;
>>>>>>>>> +  }
>>>>>>>>> +  +  public String getScheme()
>>>>>>>>> +  {
>>>>>>>>> +    String part0 = get(0);
>>>>>>>>> +    int index = part0.indexOf(':');
>>>>>>>>> +    +    String result;
>>>>>>>>> +    +    if (index > 0) {
>>>>>>>>> +      result = part0.substring(0, index);
>>>>>>>>> +    } else {
>>>>>>>>> +      result = null;
>>>>>>>>> +    }
>>>>>>>>> +    +    return result;
>>>>>>>>> +  }
>>>>>>>>> +  +  public String getSchemePath()
>>>>>>>>> +  {
>>>>>>>>> +    String part0 = get(0);
>>>>>>>>> +    int index = part0.indexOf(':');
>>>>>>>>> +    +    String result;
>>>>>>>>>   -    buffer.append("aries:services");
>>>>>>>>> -    Enumeration<String> components = getAll();
>>>>>>>>> -    while (components.hasMoreElements()) {
>>>>>>>>> -      buffer.append('/');
>>>>>>>>> -      buffer.append(components.nextElement());
>>>>>>>>> +    if (index > 0) {
>>>>>>>>> +      result = part0.substring(index + 1);
>>>>>>>>> +    } else {
>>>>>>>>> +      result = null;
>>>>>>>>>   }
>>>>>>>>>   -    return buffer.toString();
>>>>>>>>> +    return result;
>>>>>>>>> +  }
>>>>>>>>> +  +  public String getInterface()
>>>>>>>>> +  {
>>>>>>>>> +    return get(1);
>>>>>>>>> +  }
>>>>>>>>> +  +  public String getFilter()
>>>>>>>>> +  {
>>>>>>>>> +    return hasFilter() ? get(2) : null;
>>>>>>>>> +  }
>>>>>>>>> +  +  public String getServiceName()
>>>>>>>>> +  {
>>>>>>>>> +    Enumeration<String> parts = getAll();
>>>>>>>>> +    parts.nextElement();
>>>>>>>>> +    +    StringBuilder builder = new StringBuilder();
>>>>>>>>> +    +    while (parts.hasMoreElements()) {
>>>>>>>>> +      builder.append(parts.nextElement());
>>>>>>>>> +      builder.append('/');
>>>>>>>>> +    }
>>>>>>>>> +    +    builder.deleteCharAt(builder.length() - 1);
>>>>>>>>> +    +    return builder.toString();
>>>>>>>>>  }
>>>>>>>>>  }
>>>>>>>>> \ No newline at end of file
>>>>>>>>>
>>>>>>>>> Copied:
>>>>>>>>>
>>>>>>>>>
>>>>>>>>> incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/OsgiNameParser.java
>>>>>>>>> (from r910238,
>>>>>>>>>
>>>>>>>>>
>>>>>>>>> incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/ServiceRegistryNameParser.java)
>>>>>>>>> URL:
>>>>>>>>>
>>>>>>>>>
>>>>>>>>> http://svn.apache.org/viewvc/incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/OsgiNameParser.java?p2=incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/OsgiNameParser.java&p1=incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/ServiceRegistryNameParser.java&r1=910238&r2=917809&rev=917809&view=diff
>>>>>>>>>
>>>>>>>>>
>>>>>>>>>
>>>>>>>>> ==============================================================================
>>>>>>>>> ---
>>>>>>>>>
>>>>>>>>>
>>>>>>>>> incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/ServiceRegistryNameParser.java
>>>>>>>>> (original)
>>>>>>>>> +++
>>>>>>>>>
>>>>>>>>>
>>>>>>>>> incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/OsgiNameParser.java
>>>>>>>>> Mon Mar  1 23:53:18 2010
>>>>>>>>> @@ -26,31 +26,40 @@
>>>>>>>>>  /**
>>>>>>>>>  * A parser for the aries namespace
>>>>>>>>>  */
>>>>>>>>> -public final class ServiceRegistryNameParser implements NameParser
>>>>>>>>> +public final class OsgiNameParser implements NameParser
>>>>>>>>>  {
>>>>>>>>> -
>>>>>>>>> +  private static final String OSGI_SCHEME = "osgi";
>>>>>>>>> +  private static final String ARIES_SCHEME = "aries";
>>>>>>>>> +  private static final String SERVICE_PATH = "service";
>>>>>>>>> +  private static final String SERVICES_PATH = "services";
>>>>>>>>> +  private static final String SERVICE_LIST_PATH = "servicelist";
>>>>>>>>> +  private static final String FRAMEWORK_PATH = "framework";
>>>>>>>>> +     public Name parse(String name) throws NamingException
>>>>>>>>>  {
>>>>>>>>> -    if (!!!name.startsWith("aries:services/") &&
>>>>>>>>> -        !!!name.startsWith("osgi:services/")) throw new
>>>>>>>>> InvalidNameException("The JNDI name did not start with aries:, or
>>>>>>>>> osgi:");
>>>>>>>>> +    OsgiName result = new OsgiName(name);
>>>>>>>>> +    +    if (result.size() < 2) throw new
>>>>>>>>> InvalidNameException(name);
>>>>>>>>>   -    name = name.substring(name.indexOf('/') + 1);
>>>>>>>>> +    String urlScheme = result.getScheme();
>>>>>>>>> +    String schemePath = result.getSchemePath();
>>>>>>>>>   -    int slashIndex = name.indexOf('/');
>>>>>>>>> -    String interfaceName = name;
>>>>>>>>> -    String filter = null;
>>>>>>>>> -    -    if (slashIndex != -1) {
>>>>>>>>> -      interfaceName = name.substring(0, slashIndex);
>>>>>>>>> -      filter = name.substring(slashIndex + 1);
>>>>>>>>> +    if (!!!(OSGI_SCHEME.equals(urlScheme) ||
>>>>>>>>> ARIES_SCHEME.equals(urlScheme))) {
>>>>>>>>> +      throw new InvalidNameException(name);
>>>>>>>>>   }
>>>>>>>>>   -    if (interfaceName.length() == 0) throw new
>>>>>>>>> InvalidNameException("No interface name was specified");
>>>>>>>>> +    if (ARIES_SCHEME.equals(urlScheme) &&
>>>>>>>>> !!!SERVICES_PATH.equals(schemePath)) {
>>>>>>>>> +      throw new InvalidNameException(name);
>>>>>>>>> +    }
>>>>>>>>> +    +    if (OSGI_SCHEME.equals(urlScheme) && !!!(
>>>>>>>>> SERVICE_PATH.equals(schemePath) || +
>>>>>>>>>    SERVICE_LIST_PATH.equals(schemePath) || +
>>>>>>>>>              FRAMEWORK_PATH.equals(schemePath))) {
>>>>>>>>> +      throw new InvalidNameException(name);
>>>>>>>>> +    }
>>>>>>>>>   -    Name result = new ServiceRegistryName();
>>>>>>>>> -    result.add(interfaceName);
>>>>>>>>> -    if (filter != null) {
>>>>>>>>> -      result.add(filter);
>>>>>>>>> +    if (result.getInterface() == null ||
>>>>>>>>> result.getInterface().length()
>>>>>>>>> == 0) {
>>>>>>>>> +      throw new InvalidNameException(name);
>>>>>>>>>   }
>>>>>>>>>        return result;
>>>>>>>>> @@ -59,7 +68,7 @@
>>>>>>>>>  @Override
>>>>>>>>>  public boolean equals(Object other)
>>>>>>>>>  {
>>>>>>>>> -    return other instanceof ServiceRegistryNameParser;
>>>>>>>>> +    return other instanceof OsgiNameParser;
>>>>>>>>>  }
>>>>>>>>>    @Override
>>>>>>>>>
>>>>>>>>> Modified:
>>>>>>>>>
>>>>>>>>>
>>>>>>>>> incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/OsgiURLContextFactory.java
>>>>>>>>> URL:
>>>>>>>>>
>>>>>>>>>
>>>>>>>>> http://svn.apache.org/viewvc/incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/OsgiURLContextFactory.java?rev=917809&r1=917808&r2=917809&view=diff
>>>>>>>>>
>>>>>>>>>
>>>>>>>>>
>>>>>>>>> ==============================================================================
>>>>>>>>> ---
>>>>>>>>>
>>>>>>>>>
>>>>>>>>> incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/OsgiURLContextFactory.java
>>>>>>>>> (original)
>>>>>>>>> +++
>>>>>>>>>
>>>>>>>>>
>>>>>>>>> incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/OsgiURLContextFactory.java
>>>>>>>>> Mon Mar  1 23:53:18 2010
>>>>>>>>> @@ -49,7 +49,7 @@
>>>>>>>>>   } else if (obj instanceof String[]) {
>>>>>>>>>     // Try each URL until either lookup succeeds or they all fail
>>>>>>>>>     String[] urls = (String[])obj;
>>>>>>>>> -      if (urls.length == 0) throw new
>>>>>>>>> ConfigurationException("ariesURLContextFactory: empty URL array");
>>>>>>>>> +      if (urls.length == 0) throw new ConfigurationException("0");
>>>>>>>>>     Context context = new ServiceRegistryContext(environment);
>>>>>>>>>     try
>>>>>>>>>     {
>>>>>>>>>
>>>>>>>>> Modified:
>>>>>>>>>
>>>>>>>>>
>>>>>>>>> incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/ServiceRegistryContext.java
>>>>>>>>> URL:
>>>>>>>>>
>>>>>>>>>
>>>>>>>>> http://svn.apache.org/viewvc/incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/ServiceRegistryContext.java?rev=917809&r1=917808&r2=917809&view=diff
>>>>>>>>>
>>>>>>>>>
>>>>>>>>>
>>>>>>>>> ==============================================================================
>>>>>>>>> ---
>>>>>>>>>
>>>>>>>>>
>>>>>>>>> incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/ServiceRegistryContext.java
>>>>>>>>> (original)
>>>>>>>>> +++
>>>>>>>>>
>>>>>>>>>
>>>>>>>>> incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/ServiceRegistryContext.java
>>>>>>>>> Mon Mar  1 23:53:18 2010
>>>>>>>>> @@ -42,9 +42,9 @@
>>>>>>>>>  {
>>>>>>>>>  private static final String ARIES_SERVICES = "aries:services/";
>>>>>>>>>  /** The name parser for the service registry name space */
>>>>>>>>> -  private NameParser parser = new ServiceRegistryNameParser();
>>>>>>>>> +  private NameParser parser = new OsgiNameParser();
>>>>>>>>>  /** The environment for this context */
>>>>>>>>> -  private Map<Object, Object> env;
>>>>>>>>> +  private Map<String, Object> env;
>>>>>>>>>    /**
>>>>>>>>>  * Why Mr Java this class does indeed take a fine copy of the
>>>>>>>>> provided
>>>>>>>>> @@ -53,10 +53,11 @@
>>>>>>>>>  *     * @param environment
>>>>>>>>>  */
>>>>>>>>> +  @SuppressWarnings("unchecked")
>>>>>>>>>  public ServiceRegistryContext(Hashtable<?, ?> environment)
>>>>>>>>>  {
>>>>>>>>> -    env = new HashMap<Object, Object>();
>>>>>>>>> -    env.putAll(environment);
>>>>>>>>> +    env = new HashMap<String, Object>();
>>>>>>>>> +    env.putAll((Map<? extends String, ? extends Object>)
>>>>>>>>> environment);
>>>>>>>>>  }
>>>>>>>>>  public Object addToEnvironment(String propName, Object propVal)
>>>>>>>>> throws
>>>>>>>>> NamingException
>>>>>>>>> @@ -153,7 +154,7 @@
>>>>>>>>>  public NamingEnumeration<NameClassPair> list(final Name name)
>>>>>>>>> throws
>>>>>>>>> NamingException
>>>>>>>>>  {
>>>>>>>>> -    throw new NamingException("Not a Context");
>>>>>>>>> +    return new ServiceRegistryListContext(env,
>>>>>>>>> convert(name)).list("");
>>>>>>>>>  }
>>>>>>>>>  public NamingEnumeration<NameClassPair> list(String name) throws
>>>>>>>>> NamingException
>>>>>>>>> @@ -163,7 +164,7 @@
>>>>>>>>>  public NamingEnumeration<Binding> listBindings(final Name name)
>>>>>>>>> throws
>>>>>>>>> NamingException
>>>>>>>>>  {
>>>>>>>>> -    throw new NamingException("Not a Context");
>>>>>>>>> +    return new ServiceRegistryListContext(env,
>>>>>>>>> convert(name)).listBindings("");
>>>>>>>>>  }
>>>>>>>>>  public NamingEnumeration<Binding> listBindings(String name) throws
>>>>>>>>> NamingException
>>>>>>>>> @@ -173,28 +174,43 @@
>>>>>>>>>  public Object lookup(Name name) throws NamingException
>>>>>>>>>  {
>>>>>>>>> -    int nameSize = validateName(name);
>>>>>>>>> -    String className = name.get(0);
>>>>>>>>> -
>>>>>>>>> -    String filter = null;
>>>>>>>>> +    Object result;
>>>>>>>>> +    +    OsgiName validName = convert(name);
>>>>>>>>>   -    if (nameSize == 2) {
>>>>>>>>> -      filter = name.get(1);
>>>>>>>>> +    String pathFragment = validName.getSchemePath();
>>>>>>>>> +    String serviceName = validName.getServiceName();
>>>>>>>>> +    String schemeName = validName.getScheme();
>>>>>>>>> +    +    if (OsgiName.FRAMEWORK_PATH.equals(pathFragment) &&
>>>>>>>>> "bundleContext".equals(validName.getServiceName())) {
>>>>>>>>> +      result = ServiceHelper.getBundleContext(env);
>>>>>>>>> +    } else if ((OsgiName.SERVICE_PATH.equals(pathFragment) &&
>>>>>>>>> OsgiName.OSGI_SCHEME.equals(schemeName)) ||
>>>>>>>>> +               (OsgiName.SERVICES_PATH.equals(pathFragment) &&
>>>>>>>>> OsgiName.ARIES_SCHEME.equals(schemeName))) {
>>>>>>>>> +      result = ServiceHelper.getService(validName.getInterface(),
>>>>>>>>> validName.getFilter(), serviceName, true, env);
>>>>>>>>> +    } else if (OsgiName.SERVICE_LIST_PATH.equals(pathFragment)) {
>>>>>>>>> +      result = new ServiceRegistryListContext(env, validName);
>>>>>>>>> +    } else {
>>>>>>>>> +      result = null;
>>>>>>>>>   }
>>>>>>>>>   -    try {
>>>>>>>>> -      Object result = ServiceHelper.getService(className, filter);
>>>>>>>>> -      -      if (result == null) {
>>>>>>>>> -        throw new NameNotFoundException("We couldn't find an object
>>>>>>>>> in
>>>>>>>>> the registry matching the query " + name);
>>>>>>>>> -      }
>>>>>>>>> -      -      return result;
>>>>>>>>> -    } catch (IllegalArgumentException e) {
>>>>>>>>> -      NamingException ne = new NamingException(e.getMessage());
>>>>>>>>> -      ne.initCause(e);
>>>>>>>>> -      throw ne;
>>>>>>>>> +    if (result == null) {
>>>>>>>>> +      throw new NameNotFoundException(name.toString());
>>>>>>>>> +    }
>>>>>>>>> +    +    return result;
>>>>>>>>> +  }
>>>>>>>>> +
>>>>>>>>> +  private OsgiName convert(Name name) throws InvalidNameException
>>>>>>>>> +  {
>>>>>>>>> +    OsgiName result;
>>>>>>>>> +    +    if (name instanceof OsgiName) {
>>>>>>>>> +      result = (OsgiName) name;
>>>>>>>>> +    } else {
>>>>>>>>> +      result = new OsgiName(name);
>>>>>>>>>   }
>>>>>>>>> +    +    return result;
>>>>>>>>>  }
>>>>>>>>>  public Object lookup(String name) throws NamingException
>>>>>>>>> @@ -246,27 +262,4 @@
>>>>>>>>>  {
>>>>>>>>>   throw new OperationNotSupportedException();
>>>>>>>>>  }
>>>>>>>>> -  -  /**
>>>>>>>>> -   * Check that the name conforms to the expected format
>>>>>>>>> -   * @param name
>>>>>>>>> -   * @return the size of the name
>>>>>>>>> -   * @throws InvalidNameException
>>>>>>>>> -   */
>>>>>>>>> -  private int validateName(final Name name) throws
>>>>>>>>> InvalidNameException
>>>>>>>>> -  {
>>>>>>>>> -    int nameSize = name.size();
>>>>>>>>> -    if (nameSize == 0) {
>>>>>>>>> -      throw new InvalidNameException("The provided name does not
>>>>>>>>> have
>>>>>>>>> any
>>>>>>>>> components" + name);
>>>>>>>>> -    } -    -    if ("aries:services".equals(name.get(0))) {
>>>>>>>>> -      throw new InvalidNameException("The composite name should not
>>>>>>>>> start
>>>>>>>>> with aries:services");
>>>>>>>>> -    }
>>>>>>>>> -    -    if (nameSize > 2) {
>>>>>>>>> -      throw new InvalidNameException("This JNDI context only
>>>>>>>>> expects
>>>>>>>>> 2
>>>>>>>>> components, but it found " + nameSize);
>>>>>>>>> -    }
>>>>>>>>> -    return nameSize;
>>>>>>>>> -  }
>>>>>>>>>  }
>>>>>>>>> \ No newline at end of file
>>>>>>>>>
>>>>>>>>> Added:
>>>>>>>>>
>>>>>>>>>
>>>>>>>>> incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/ServiceRegistryListContext.java
>>>>>>>>> URL:
>>>>>>>>>
>>>>>>>>>
>>>>>>>>> http://svn.apache.org/viewvc/incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/ServiceRegistryListContext.java?rev=917809&view=auto
>>>>>>>>>
>>>>>>>>>
>>>>>>>>>
>>>>>>>>> ==============================================================================
>>>>>>>>> ---
>>>>>>>>>
>>>>>>>>>
>>>>>>>>> incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/ServiceRegistryListContext.java
>>>>>>>>> (added)
>>>>>>>>> +++
>>>>>>>>>
>>>>>>>>>
>>>>>>>>> incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/ServiceRegistryListContext.java
>>>>>>>>> Mon Mar  1 23:53:18 2010
>>>>>>>>> @@ -0,0 +1,197 @@
>>>>>>>>> +/*
>>>>>>>>> + * 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.aries.jndi.url;
>>>>>>>>> +
>>>>>>>>> +import java.util.HashMap;
>>>>>>>>> +import java.util.Hashtable;
>>>>>>>>> +import java.util.Map;
>>>>>>>>> +
>>>>>>>>> +import javax.naming.Binding;
>>>>>>>>> +import javax.naming.Context;
>>>>>>>>> +import javax.naming.Name;
>>>>>>>>> +import javax.naming.NameClassPair;
>>>>>>>>> +import javax.naming.NameParser;
>>>>>>>>> +import javax.naming.NamingEnumeration;
>>>>>>>>> +import javax.naming.NamingException;
>>>>>>>>> +import javax.naming.OperationNotSupportedException;
>>>>>>>>> +
>>>>>>>>> +public class ServiceRegistryListContext implements Context
>>>>>>>>> +{
>>>>>>>>> +  private Map<String, Object> env;
>>>>>>>>> +  /** The name parser for the service registry name space */
>>>>>>>>> +  private NameParser parser = new OsgiNameParser();
>>>>>>>>> +  +  public ServiceRegistryListContext(Map<String, Object> env,
>>>>>>>>> OsgiName
>>>>>>>>> validName)
>>>>>>>>> +  {
>>>>>>>>> +    this.env = new HashMap<String, Object>(env);
>>>>>>>>> +  }
>>>>>>>>> +
>>>>>>>>> +  public Object addToEnvironment(String propName, Object propVal)
>>>>>>>>> throws
>>>>>>>>> NamingException
>>>>>>>>> +  {
>>>>>>>>> +    return env.put(propName, propVal);
>>>>>>>>> +  }
>>>>>>>>> +
>>>>>>>>> +  public void bind(Name name, Object obj) throws NamingException
>>>>>>>>> +  {
>>>>>>>>> +    throw new OperationNotSupportedException();
>>>>>>>>> +  }
>>>>>>>>> +
>>>>>>>>> +  public void bind(String name, Object obj) throws NamingException
>>>>>>>>> +  {
>>>>>>>>> +    throw new OperationNotSupportedException();
>>>>>>>>> +  }
>>>>>>>>> +
>>>>>>>>> +  public void close() throws NamingException
>>>>>>>>> +  {
>>>>>>>>> +    env = null;
>>>>>>>>> +    parser = null;
>>>>>>>>> +  }
>>>>>>>>> +
>>>>>>>>> +  public Name composeName(Name name, Name prefix) throws
>>>>>>>>> NamingException
>>>>>>>>> +  {
>>>>>>>>> +    // TODO Auto-generated method stub
>>>>>>>>> +    return null;
>>>>>>>>> +  }
>>>>>>>>> +
>>>>>>>>> +  public String composeName(String name, String prefix) throws
>>>>>>>>> NamingException
>>>>>>>>> +  {
>>>>>>>>> +    // TODO Auto-generated method stub
>>>>>>>>> +    return null;
>>>>>>>>> +  }
>>>>>>>>> +
>>>>>>>>> +  public Context createSubcontext(Name name) throws NamingException
>>>>>>>>> +  {
>>>>>>>>> +    throw new OperationNotSupportedException();
>>>>>>>>> +  }
>>>>>>>>> +
>>>>>>>>> +  public Context createSubcontext(String name) throws
>>>>>>>>> NamingException
>>>>>>>>> +  {
>>>>>>>>> +    throw new OperationNotSupportedException();
>>>>>>>>> +  }
>>>>>>>>> +
>>>>>>>>> +  public void destroySubcontext(Name name) throws NamingException
>>>>>>>>> +  {
>>>>>>>>> +    //No-op we don't support sub-contexts in our context
>>>>>>>>> +  }
>>>>>>>>> +
>>>>>>>>> +  public void destroySubcontext(String name) throws NamingException
>>>>>>>>> +  {
>>>>>>>>> +    //No-op we don't support sub-contexts in our context
>>>>>>>>> +  }
>>>>>>>>> +
>>>>>>>>> +  public Hashtable<?, ?> getEnvironment() throws NamingException
>>>>>>>>> +  {
>>>>>>>>> +    Hashtable<Object, Object> environment = new Hashtable<Object,
>>>>>>>>> Object>();
>>>>>>>>> +    environment.putAll(env);
>>>>>>>>> +    return environment;
>>>>>>>>> +  }
>>>>>>>>> +
>>>>>>>>> +  public String getNameInNamespace() throws NamingException
>>>>>>>>> +  {
>>>>>>>>> +    // TODO Auto-generated method stub
>>>>>>>>> +    return null;
>>>>>>>>> +  }
>>>>>>>>> +
>>>>>>>>> +  public NameParser getNameParser(Name name) throws NamingException
>>>>>>>>> +  {
>>>>>>>>> +    return parser;
>>>>>>>>> +  }
>>>>>>>>> +
>>>>>>>>> +  public NameParser getNameParser(String name) throws
>>>>>>>>> NamingException
>>>>>>>>> +  {
>>>>>>>>> +    return parser;
>>>>>>>>> +  }
>>>>>>>>> +
>>>>>>>>> +  public NamingEnumeration<NameClassPair> list(Name name) throws
>>>>>>>>> NamingException
>>>>>>>>> +  {
>>>>>>>>> +    return list(name.toString());
>>>>>>>>> +  }
>>>>>>>>> +
>>>>>>>>> +  public NamingEnumeration<NameClassPair> list(String name) throws
>>>>>>>>> NamingException
>>>>>>>>> +  {
>>>>>>>>> +    // TODO Auto-generated method stub
>>>>>>>>> +    return null;
>>>>>>>>> +  }
>>>>>>>>> +
>>>>>>>>> +  public NamingEnumeration<Binding> listBindings(Name name) throws
>>>>>>>>> NamingException
>>>>>>>>> +  {
>>>>>>>>> +    return listBindings(name.toString());
>>>>>>>>> +  }
>>>>>>>>> +
>>>>>>>>> +  public NamingEnumeration<Binding> listBindings(String name)
>>>>>>>>> throws
>>>>>>>>> NamingException
>>>>>>>>> +  {
>>>>>>>>> +    // TODO Auto-generated method stub
>>>>>>>>> +    return null;
>>>>>>>>> +  }
>>>>>>>>> +
>>>>>>>>> +  public Object lookup(Name name) throws NamingException
>>>>>>>>> +  {
>>>>>>>>> +    return lookup(name.toString());
>>>>>>>>> +  }
>>>>>>>>> +
>>>>>>>>> +  public Object lookup(String name) throws NamingException
>>>>>>>>> +  {
>>>>>>>>> +    return null;
>>>>>>>>> +  }
>>>>>>>>> +
>>>>>>>>> +  public Object lookupLink(Name name) throws NamingException
>>>>>>>>> +  {
>>>>>>>>> +    throw new OperationNotSupportedException();
>>>>>>>>> +  }
>>>>>>>>> +
>>>>>>>>> +  public Object lookupLink(String name) throws NamingException
>>>>>>>>> +  {
>>>>>>>>> +    throw new OperationNotSupportedException();
>>>>>>>>> +  }
>>>>>>>>> +
>>>>>>>>> +  public void rebind(Name name, Object obj) throws NamingException
>>>>>>>>> +  {
>>>>>>>>> +    throw new OperationNotSupportedException();
>>>>>>>>> +  }
>>>>>>>>> +
>>>>>>>>> +  public void rebind(String name, Object obj) throws
>>>>>>>>> NamingException
>>>>>>>>> +  {
>>>>>>>>> +    throw new OperationNotSupportedException();
>>>>>>>>> +  }
>>>>>>>>> +
>>>>>>>>> +  public Object removeFromEnvironment(String propName) throws
>>>>>>>>> NamingException
>>>>>>>>> +  {
>>>>>>>>> +    return env.remove(propName);
>>>>>>>>> +  }
>>>>>>>>> +
>>>>>>>>> +  public void rename(Name oldName, Name newName) throws
>>>>>>>>> NamingException
>>>>>>>>> +  {
>>>>>>>>> +    throw new OperationNotSupportedException();
>>>>>>>>> +  }
>>>>>>>>> +
>>>>>>>>> +  public void rename(String oldName, String newName) throws
>>>>>>>>> NamingException
>>>>>>>>> +  {
>>>>>>>>> +    throw new OperationNotSupportedException();
>>>>>>>>> +  }
>>>>>>>>> +
>>>>>>>>> +  public void unbind(Name name) throws NamingException
>>>>>>>>> +  {
>>>>>>>>> +    throw new OperationNotSupportedException();
>>>>>>>>> +  }
>>>>>>>>> +
>>>>>>>>> +  public void unbind(String name) throws NamingException
>>>>>>>>> +  {
>>>>>>>>> +    throw new OperationNotSupportedException();
>>>>>>>>> +  }
>>>>>>>>> +}
>>>>>>>>> \ No newline at end of file
>>>>>>>>>
>>>>>>>>> Copied:
>>>>>>>>>
>>>>>>>>>
>>>>>>>>> incubator/aries/trunk/jndi/jndi-url/src/test/java/org/apache/aries/jndi/url/OsgiNameParserTest.java
>>>>>>>>> (from r917002,
>>>>>>>>>
>>>>>>>>>
>>>>>>>>> incubator/aries/trunk/jndi/jndi-url/src/test/java/org/apache/aries/jndi/url/ServiceRegistryNameParserTest.java)
>>>>>>>>> URL:
>>>>>>>>>
>>>>>>>>>
>>>>>>>>> http://svn.apache.org/viewvc/incubator/aries/trunk/jndi/jndi-url/src/test/java/org/apache/aries/jndi/url/OsgiNameParserTest.java?p2=incubator/aries/trunk/jndi/jndi-url/src/test/java/org/apache/aries/jndi/url/OsgiNameParserTest.java&p1=incubator/aries/trunk/jndi/jndi-url/src/test/java/org/apache/aries/jndi/url/ServiceRegistryNameParserTest.java&r1=917002&r2=917809&rev=917809&view=diff
>>>>>>>>>
>>>>>>>>>
>>>>>>>>>
>>>>>>>>> ==============================================================================
>>>>>>>>> ---
>>>>>>>>>
>>>>>>>>>
>>>>>>>>> incubator/aries/trunk/jndi/jndi-url/src/test/java/org/apache/aries/jndi/url/ServiceRegistryNameParserTest.java
>>>>>>>>> (original)
>>>>>>>>> +++
>>>>>>>>>
>>>>>>>>>
>>>>>>>>> incubator/aries/trunk/jndi/jndi-url/src/test/java/org/apache/aries/jndi/url/OsgiNameParserTest.java
>>>>>>>>> Mon Mar  1 23:53:18 2010
>>>>>>>>> @@ -18,11 +18,11 @@
>>>>>>>>>  */
>>>>>>>>>  package org.apache.aries.jndi.url;
>>>>>>>>>  -import static org.junit.Assert.assertNotNull;
>>>>>>>>>  import static org.junit.Assert.assertEquals;
>>>>>>>>> +import static org.junit.Assert.assertFalse;
>>>>>>>>> +import static org.junit.Assert.assertTrue;
>>>>>>>>>  import javax.naming.InvalidNameException;
>>>>>>>>> -import javax.naming.Name;
>>>>>>>>>  import javax.naming.NameParser;
>>>>>>>>>  import javax.naming.NamingException;
>>>>>>>>>  @@ -31,10 +31,10 @@
>>>>>>>>>  /**
>>>>>>>>>  * This is where we test the service registry name parser.
>>>>>>>>>  */
>>>>>>>>> -public class ServiceRegistryNameParserTest
>>>>>>>>> +public class OsgiNameParserTest
>>>>>>>>>  {
>>>>>>>>>  /** The parser we are going to use for testing */
>>>>>>>>> -  private NameParser parser = new ServiceRegistryNameParser();
>>>>>>>>> +  private NameParser parser = new OsgiNameParser();
>>>>>>>>>  /**
>>>>>>>>>  * OK, so we check that we can call checkNames multiple times.
>>>>>>>>> @@ -43,8 +43,14 @@
>>>>>>>>>  @Test
>>>>>>>>>  public void checkValidNames() throws NamingException
>>>>>>>>>  {
>>>>>>>>> -    checkName("aries:services/java.lang.Runnable/(a=b)");
>>>>>>>>> -    checkName("aries:services/java.lang.Runnable");
>>>>>>>>> +    checkName("aries","services","java.lang.Runnable","(a=b)");
>>>>>>>>> +    checkName("aries","services","java.lang.Runnable");
>>>>>>>>> +    checkName("osgi","service","java.lang.Runnable");
>>>>>>>>> +    checkName("osgi","service","java.lang.Runnable", "(a=b)");
>>>>>>>>> +    checkName("osgi","servicelist","java.lang.Runnable");
>>>>>>>>> +    checkName("osgi","servicelist","java.lang.Runnable", "(a=b)");
>>>>>>>>> +    checkName("osgi","servicelist","jdbc", "grok", "DataSource");
>>>>>>>>> +    checkName("osgi", "framework", "bundleContext");
>>>>>>>>>  }
>>>>>>>>>    /**
>>>>>>>>> @@ -54,7 +60,7 @@
>>>>>>>>>  @Test(expected=InvalidNameException.class)
>>>>>>>>>  public void checkOutsideNamespace() throws NamingException
>>>>>>>>>  {
>>>>>>>>> -    checkName("java:comp/env/jms/cf");
>>>>>>>>> +    checkName("java","comp","env","jms","cf");
>>>>>>>>>  }
>>>>>>>>>    /**
>>>>>>>>> @@ -64,7 +70,7 @@
>>>>>>>>>  @Test(expected=InvalidNameException.class)
>>>>>>>>>  public void checkMissingInterface() throws NamingException
>>>>>>>>>  {
>>>>>>>>> -    checkName("aries:services");
>>>>>>>>> +    checkName("aries","services");
>>>>>>>>>  }
>>>>>>>>>    /**
>>>>>>>>> @@ -75,20 +81,64 @@
>>>>>>>>>  @Test(expected=InvalidNameException.class)
>>>>>>>>>  public void checkMissingInterface2() throws NamingException
>>>>>>>>>  {
>>>>>>>>> -    checkName("aries:services/");
>>>>>>>>> +    checkName("aries","services", "");
>>>>>>>>>  }
>>>>>>>>> -
>>>>>>>>> -  /**
>>>>>>>>> -   * This method parses the name and then makes sure what was
>>>>>>>>> parsed
>>>>>>>>> was
>>>>>>>>> parsed
>>>>>>>>> -   * correctly.
>>>>>>>>> -   * -   * @param name
>>>>>>>>> -   * @throws NamingException
>>>>>>>>> -   */
>>>>>>>>> -  private void checkName(String name) throws NamingException
>>>>>>>>> +  +  @Test(expected=InvalidNameException.class)
>>>>>>>>> +  public void checkIncorrectPath() throws NamingException
>>>>>>>>> +  {
>>>>>>>>> +    checkName("osgi", "services", "java.lang.Runnable"); +  }
>>>>>>>>> +  +  @Test(expected=InvalidNameException.class)
>>>>>>>>> +  public void checkIllegalPath() throws NamingException
>>>>>>>>>  {
>>>>>>>>> -    Name n = parser.parse(name);
>>>>>>>>> -    assertNotNull("We got a null name back, which is not allowed.",
>>>>>>>>> n);
>>>>>>>>> -    assertEquals("The name's toString does not produce the original
>>>>>>>>> value", name, n.toString());
>>>>>>>>> +    checkName("osgi", "wibble", "java.lang.Runnable"); +  }
>>>>>>>>> +  +  private void checkName(String scheme, String path, String ...
>>>>>>>>> elements)
>>>>>>>>> +    throws NamingException
>>>>>>>>> +  {
>>>>>>>>> +    StringBuilder builder = new StringBuilder();
>>>>>>>>> +    StringBuilder serviceName = new StringBuilder();
>>>>>>>>> +    +    builder.append(scheme);
>>>>>>>>> +    builder.append(':');
>>>>>>>>> +    builder.append(path);
>>>>>>>>> +
>>>>>>>>> +    if (elements.length > 0) {
>>>>>>>>> +      builder.append('/');
>>>>>>>>> +      +      for (String element : elements) {
>>>>>>>>> +        serviceName.append(element);
>>>>>>>>> +        serviceName.append('/');
>>>>>>>>> +      }
>>>>>>>>> +  +      serviceName.deleteCharAt(serviceName.length() - 1);
>>>>>>>>> +      +      builder.append(serviceName);
>>>>>>>>> +    }
>>>>>>>>> +    +    OsgiName n = (OsgiName) parser.parse(builder.toString());
>>>>>>>>> +    +    assertEquals(scheme, n.getScheme());
>>>>>>>>> +    assertEquals(path, n.getSchemePath());
>>>>>>>>> +    +    if (elements.length > 1) {
>>>>>>>>> +      assertEquals(elements[0], n.getInterface());
>>>>>>>>> +    }
>>>>>>>>> +    +    if (elements.length == 1) {
>>>>>>>>> +      assertFalse(n.hasFilter());
>>>>>>>>> +    }
>>>>>>>>> +    +    if (elements.length > 2) {
>>>>>>>>> +      if (elements.length == 2) {
>>>>>>>>> +        assertTrue(n.hasFilter());
>>>>>>>>> +        assertEquals(elements[1], n.getFilter());
>>>>>>>>> +      } else assertFalse(n.hasFilter());
>>>>>>>>> +    }
>>>>>>>>> +    +    assertEquals(serviceName.toString(), n.getServiceName());
>>>>>>>>>  }
>>>>>>>>>  }
>>>>>>>>> \ No newline at end of file
>>>>>>>>>
>>>>>>>>> Modified:
>>>>>>>>>
>>>>>>>>>
>>>>>>>>> incubator/aries/trunk/jndi/jndi-url/src/test/java/org/apache/aries/jndi/url/ServiceRegistryContextTest.java
>>>>>>>>> URL:
>>>>>>>>>
>>>>>>>>>
>>>>>>>>> http://svn.apache.org/viewvc/incubator/aries/trunk/jndi/jndi-url/src/test/java/org/apache/aries/jndi/url/ServiceRegistryContextTest.java?rev=917809&r1=917808&r2=917809&view=diff
>>>>>>>>>
>>>>>>>>>
>>>>>>>>>
>>>>>>>>> ==============================================================================
>>>>>>>>> ---
>>>>>>>>>
>>>>>>>>>
>>>>>>>>> incubator/aries/trunk/jndi/jndi-url/src/test/java/org/apache/aries/jndi/url/ServiceRegistryContextTest.java
>>>>>>>>> (original)
>>>>>>>>> +++
>>>>>>>>>
>>>>>>>>>
>>>>>>>>> incubator/aries/trunk/jndi/jndi-url/src/test/java/org/apache/aries/jndi/url/ServiceRegistryContextTest.java
>>>>>>>>> Mon Mar  1 23:53:18 2010
>>>>>>>>> @@ -21,7 +21,6 @@
>>>>>>>>>  import static org.junit.Assert.assertEquals;
>>>>>>>>>  import static org.junit.Assert.assertFalse;
>>>>>>>>>  import static org.junit.Assert.assertNotNull;
>>>>>>>>> -import static org.junit.Assert.assertSame;
>>>>>>>>>  import static org.junit.Assert.assertTrue;
>>>>>>>>>  import java.lang.reflect.Field;
>>>>>>>>> @@ -37,6 +36,12 @@
>>>>>>>>>  import javax.naming.NamingException;
>>>>>>>>>  import javax.naming.spi.ObjectFactory;
>>>>>>>>>  +import org.apache.aries.jndi.ContextHelper;
>>>>>>>>> +import org.apache.aries.jndi.OSGiObjectFactoryBuilder;
>>>>>>>>> +import org.apache.aries.mocks.BundleContextMock;
>>>>>>>>> +import org.apache.aries.mocks.BundleMock;
>>>>>>>>> +import org.apache.aries.unittest.mocks.MethodCall;
>>>>>>>>> +import org.apache.aries.unittest.mocks.Skeleton;
>>>>>>>>>  import org.junit.After;
>>>>>>>>>  import org.junit.Before;
>>>>>>>>>  import org.junit.Test;
>>>>>>>>> @@ -47,22 +52,13 @@
>>>>>>>>>  import org.osgi.framework.ServiceReference;
>>>>>>>>>  import org.osgi.framework.ServiceRegistration;
>>>>>>>>>  -import org.apache.aries.unittest.mocks.MethodCall;
>>>>>>>>> -import org.apache.aries.unittest.mocks.Skeleton;
>>>>>>>>> -import org.apache.aries.jndi.ContextHelper;
>>>>>>>>> -import org.apache.aries.jndi.OSGiObjectFactoryBuilder;
>>>>>>>>> -import org.apache.aries.jndi.services.ServiceHelper;
>>>>>>>>> -import org.apache.aries.jndi.url.Activator;
>>>>>>>>> -import org.apache.aries.mocks.BundleContextMock;
>>>>>>>>> -import org.apache.aries.mocks.BundleMock;
>>>>>>>>> -
>>>>>>>>>  /**
>>>>>>>>>  * Tests for our JNDI implementation for the service registry.
>>>>>>>>>  */
>>>>>>>>>  public class ServiceRegistryContextTest
>>>>>>>>>  {
>>>>>>>>>  /** The service we register by default */
>>>>>>>>> -  private Thread service;
>>>>>>>>> +  private Runnable service;
>>>>>>>>>  /** The bundle context for the test */
>>>>>>>>>  private BundleContext bc;
>>>>>>>>>  /** The service registration for the service */
>>>>>>>>> @@ -83,10 +79,7 @@
>>>>>>>>>   new Activator().start(bc);
>>>>>>>>>   new org.apache.aries.jndi.startup.Activator().start(bc);
>>>>>>>>>   -    Field f = ServiceHelper.class.getDeclaredField("context");
>>>>>>>>> -    f.setAccessible(true);
>>>>>>>>> -    f.set(null, bc);
>>>>>>>>> -    f = ContextHelper.class.getDeclaredField("context");
>>>>>>>>> +    Field f = ContextHelper.class.getDeclaredField("context");
>>>>>>>>>   f.setAccessible(true);
>>>>>>>>>   f.set(null, bc);
>>>>>>>>>   f = OSGiObjectFactoryBuilder.class.getDeclaredField("context");
>>>>>>>>> @@ -94,7 +87,7 @@
>>>>>>>>>   f.set(null, bc);
>>>>>>>>>  -    service = new Thread();
>>>>>>>>> +    service = Skeleton.newMock(Runnable.class);
>>>>>>>>>        registerService(service);
>>>>>>>>>  }
>>>>>>>>> @@ -104,7 +97,7 @@
>>>>>>>>>  *     * @param service2 The service to register.
>>>>>>>>>  */
>>>>>>>>> -  private void registerService(Thread service2)
>>>>>>>>> +  private void registerService(Runnable service2)
>>>>>>>>>  {
>>>>>>>>>   ServiceFactory factory = Skeleton.newMock(ServiceFactory.class);
>>>>>>>>>   Skeleton skel = Skeleton.getSkeleton(factory);
>>>>>>>>> @@ -159,11 +152,13 @@
>>>>>>>>>
>>>>>>>>>
>>>>>>>>>  Thread.currentThread().setContextClassLoader(mock.getClassLoader());
>>>>>>>>>   -    Object s = ctx.lookup("aries:services/java.lang.Runnable");
>>>>>>>>> +    Runnable s = (Runnable)
>>>>>>>>> ctx.lookup("aries:services/java.lang.Runnable");
>>>>>>>>>        assertNotNull("We didn't get a service back from our lookup
>>>>>>>>> :(",
>>>>>>>>> s);
>>>>>>>>>   -    assertEquals("The SR did not return the object we expected",
>>>>>>>>> service, s);
>>>>>>>>> +    s.run();
>>>>>>>>> +    +
>>>>>>>>>  Skeleton.getSkeleton(service).assertCalledExactNumberOfTimes(new
>>>>>>>>> MethodCall(Runnable.class, "run"), 1);
>>>>>>>>>        Skeleton skel =
>>>>>>>>> Skeleton.getSkeleton(mock.getBundleContext());
>>>>>>>>>   @@ -173,7 +168,7 @@
>>>>>>>>>
>>>>>>>>>
>>>>>>>>>  Thread.currentThread().setContextClassLoader(mock.getClassLoader());
>>>>>>>>>  -    s = ctx.lookup("osgi:services/java.lang.Runnable");
>>>>>>>>> +    s = (Runnable) ctx.lookup("osgi:service/java.lang.Runnable");
>>>>>>>>>        // Check we have the packages set correctly
>>>>>>>>>   @@ -181,10 +176,11 @@
>>>>>>>>>        assertTrue(ctx.getEnvironment().containsValue(packages));
>>>>>>>>>  -         assertNotNull("We didn't get a service back from our
>>>>>>>>> lookup
>>>>>>>>> :(", s);
>>>>>>>>> +
>>>>>>>>> +    s.run();
>>>>>>>>>   -    assertEquals("The SR did not return the object we expected",
>>>>>>>>> service, s);
>>>>>>>>> +
>>>>>>>>>  Skeleton.getSkeleton(service).assertCalledExactNumberOfTimes(new
>>>>>>>>> MethodCall(Runnable.class, "run"), 2);
>>>>>>>>>    skel = Skeleton.getSkeleton(mock.getBundleContext());
>>>>>>>>>   skel.assertCalled(new MethodCall(BundleContext.class,
>>>>>>>>> "getServiceReferences", "java.lang.Runnable", null));
>>>>>>>>> @@ -201,15 +197,21 @@
>>>>>>>>>  @Test
>>>>>>>>>  public void jndiLookupWithFilter() throws NamingException
>>>>>>>>>  {
>>>>>>>>> +    BundleMock mock = new BundleMock("scooby.doo", new
>>>>>>>>> Properties());
>>>>>>>>> +    +
>>>>>>>>>
>>>>>>>>>  Thread.currentThread().setContextClassLoader(mock.getClassLoader());
>>>>>>>>> +
>>>>>>>>>   InitialContext ctx = new InitialContext();
>>>>>>>>>        Object s =
>>>>>>>>> ctx.lookup("aries:services/java.lang.Runnable/(rubbish=smelly)");
>>>>>>>>>        assertNotNull("We didn't get a service back from our lookup
>>>>>>>>> :(",
>>>>>>>>> s);
>>>>>>>>>   -    assertEquals("The SR did not return the object we expected",
>>>>>>>>> service, s);
>>>>>>>>> +    service.run();
>>>>>>>>>   -    Skeleton.getSkeleton(bc).assertCalled(new
>>>>>>>>> MethodCall(BundleContext.class, "getServiceReferences",
>>>>>>>>> "java.lang.Runnable", "(rubbish=smelly)"));
>>>>>>>>> +
>>>>>>>>>  Skeleton.getSkeleton(service).assertCalledExactNumberOfTimes(new
>>>>>>>>> MethodCall(Runnable.class, "run"), 1);
>>>>>>>>> +
>>>>>>>>> +    Skeleton.getSkeleton(mock.getBundleContext()).assertCalled(new
>>>>>>>>> MethodCall(BundleContext.class, "getServiceReferences",
>>>>>>>>> "java.lang.Runnable", "(rubbish=smelly)"));
>>>>>>>>>  }
>>>>>>>>>    /**
>>>>>>>>> @@ -222,6 +224,11 @@
>>>>>>>>>  public void testLookupWhenServiceHasBeenRemoved() throws
>>>>>>>>> NamingException
>>>>>>>>>  {
>>>>>>>>>   reg.unregister();
>>>>>>>>> +
>>>>>>>>> +    BundleMock mock = new BundleMock("scooby.doo", new
>>>>>>>>> Properties());
>>>>>>>>> +    +
>>>>>>>>>
>>>>>>>>>  Thread.currentThread().setContextClassLoader(mock.getClassLoader());
>>>>>>>>> +
>>>>>>>>>   InitialContext ctx = new InitialContext();
>>>>>>>>>        ctx.lookup("aries:services/java.lang.Runnable");
>>>>>>>>> @@ -236,6 +243,10 @@
>>>>>>>>>  @Test(expected=NameNotFoundException.class)
>>>>>>>>>  public void testLookupForServiceWeNeverHad() throws NamingException
>>>>>>>>>  {
>>>>>>>>> +    BundleMock mock = new BundleMock("scooby.doo", new
>>>>>>>>> Properties());
>>>>>>>>> +    +
>>>>>>>>>
>>>>>>>>>  Thread.currentThread().setContextClassLoader(mock.getClassLoader());
>>>>>>>>> +
>>>>>>>>>   InitialContext ctx = new InitialContext();
>>>>>>>>>        ctx.lookup("aries:services/java.lang.Integer");
>>>>>>>>> @@ -271,14 +282,53 @@
>>>>>>>>>  }
>>>>>>>>>  @Test
>>>>>>>>> +  public void checkProxyDynamism() throws NamingException
>>>>>>>>> +  {
>>>>>>>>> +    BundleMock mock = new BundleMock("scooby.doo", new
>>>>>>>>> Properties());
>>>>>>>>> +    +
>>>>>>>>>
>>>>>>>>>  Thread.currentThread().setContextClassLoader(mock.getClassLoader());
>>>>>>>>> +
>>>>>>>>> +    InitialContext ctx = new InitialContext();
>>>>>>>>> +    +    String className = Runnable.class.getName();
>>>>>>>>> +    +    Runnable t = Skeleton.newMock(Runnable.class);
>>>>>>>>> +    Runnable t2 = Skeleton.newMock(Runnable.class);
>>>>>>>>> +    +    // we don't want the default service
>>>>>>>>> +    reg.unregister();
>>>>>>>>> +    +    ServiceRegistration reg = bc.registerService(className, t,
>>>>>>>>> null);
>>>>>>>>> +    bc.registerService(className, t2, null);
>>>>>>>>> +    +    Runnable r = (Runnable)
>>>>>>>>> ctx.lookup("osgi:service/java.lang.Runnable");
>>>>>>>>> +    +    r.run();
>>>>>>>>> +    +    Skeleton.getSkeleton(t).assertCalledExactNumberOfTimes(new
>>>>>>>>> MethodCall(Runnable.class, "run"), 1);
>>>>>>>>> +    Skeleton.getSkeleton(t2).assertNotCalled(new
>>>>>>>>> MethodCall(Runnable.class, "run"));
>>>>>>>>> +    +    reg.unregister();
>>>>>>>>> +    +    r.run();
>>>>>>>>> +    +    Skeleton.getSkeleton(t).assertCalledExactNumberOfTimes(new
>>>>>>>>> MethodCall(Runnable.class, "run"), 1);
>>>>>>>>> +    Skeleton.getSkeleton(t2).assertCalledExactNumberOfTimes(new
>>>>>>>>> MethodCall(Runnable.class, "run"), 1);
>>>>>>>>> +  }  +
>>>>>>>>> +  @Test
>>>>>>>>>  public void checkServiceOrderObserved() throws NamingException
>>>>>>>>>  {
>>>>>>>>> +    BundleMock mock = new BundleMock("scooby.doo", new
>>>>>>>>> Properties());
>>>>>>>>> +    +
>>>>>>>>>
>>>>>>>>>  Thread.currentThread().setContextClassLoader(mock.getClassLoader());
>>>>>>>>> +
>>>>>>>>>   InitialContext ctx = new InitialContext();
>>>>>>>>>        String className = Runnable.class.getName();
>>>>>>>>>   -    Thread t = new Thread();
>>>>>>>>> -    Thread t2 = new Thread();
>>>>>>>>> +    Runnable t = Skeleton.newMock(Runnable.class);
>>>>>>>>> +    Runnable t2 = Skeleton.newMock(Runnable.class);
>>>>>>>>>        // we don't want the default service
>>>>>>>>>   reg.unregister();
>>>>>>>>> @@ -286,9 +336,12 @@
>>>>>>>>>   ServiceRegistration reg = bc.registerService(className, t, null);
>>>>>>>>>   ServiceRegistration reg2 = bc.registerService(className, t2,
>>>>>>>>> null);
>>>>>>>>>   -    Runnable r = (Runnable)
>>>>>>>>> ctx.lookup("osgi:services/java.lang.Runnable");
>>>>>>>>> +    Runnable r = (Runnable)
>>>>>>>>> ctx.lookup("osgi:service/java.lang.Runnable");
>>>>>>>>>   -    assertSame("The wrong runnable was returned", t, r);
>>>>>>>>> +    r.run();
>>>>>>>>> +    +    Skeleton.getSkeleton(t).assertCalledExactNumberOfTimes(new
>>>>>>>>> MethodCall(Runnable.class, "run"), 1);
>>>>>>>>> +    Skeleton.getSkeleton(t2).assertNotCalled(new
>>>>>>>>> MethodCall(Runnable.class, "run"));
>>>>>>>>>        reg.unregister();
>>>>>>>>>   reg2.unregister();
>>>>>>>>> @@ -296,12 +349,18 @@
>>>>>>>>>   Hashtable<String, Object> props = new Hashtable<String, Object>();
>>>>>>>>>   props.put(Constants.SERVICE_RANKING, 55);
>>>>>>>>>   +    t = Skeleton.newMock(Runnable.class);
>>>>>>>>> +    t2 = Skeleton.newMock(Runnable.class);
>>>>>>>>> +
>>>>>>>>>   reg = bc.registerService(className, t, null);
>>>>>>>>>   reg2 = bc.registerService(className, t2, props);
>>>>>>>>>   -    r = (Runnable)
>>>>>>>>> ctx.lookup("osgi:services/java.lang.Runnable");
>>>>>>>>> +    r = (Runnable) ctx.lookup("osgi:service/java.lang.Runnable");
>>>>>>>>> +    +    r.run();
>>>>>>>>>   -    assertSame("The wrong runnable was returned", t2, r);
>>>>>>>>> +    Skeleton.getSkeleton(t).assertNotCalled(new
>>>>>>>>> MethodCall(Runnable.class, "run"));
>>>>>>>>> +    Skeleton.getSkeleton(t2).assertCalledExactNumberOfTimes(new
>>>>>>>>> MethodCall(Runnable.class, "run"), 1);
>>>>>>>>>  }
>>>>>>>>>    /**
>>>>>>>>>
>>>>>>>>>
>>>>>>>>>
>>>>>>>> --
>>>>>>>> Joe
>>>>>>>>
>>>>>>>
>>>> --
>>>> Joe
>>>>
>>>
>>>
>>
>> --
>> Joe
>>
> 
> 
> 


-- 
Joe

Re: svn commit: r917809 - in /incubator/aries/trunk/jndi/jndi-url: ./ src/main/java/org/apache/aries/jndi/services/ src/main/java/org/apache/aries/jndi/url/ src/test/java/org/apache/aries/jndi/url/

Posted by Alasdair Nottingham <no...@apache.org>.
I'm a little confused because we can do a lookup for the
TradeServicesManager, but not load the class it is published under,
which shouldn't happen.

Are there any instructions on how to reproduce the problem?

Thanks
Alasdair

On 3 March 2010 18:57, Joe Bohn <jo...@gmail.com> wrote:
>
> This seemed to do the trick for Blog-Sample but for some reason I'm still
> getting very much the same failure with AriesTrader.  Perhaps it is related
> to AriesTrader's use of pax-web-jsp (and this seems to be coming from within
> a jsp) whereas Blog-Sample does not pull in this bundle or use JSPs?
>
> Here is the stack trace for the CNFE:
>
> [1945910404@qtp-1489647491-1 -
> /org.apache.aries.ariestrader.modules.ariestrader-web/config] DEBUG
> org.apache.aries.blueprint.container.ServiceRecipe - Calling listeners for
> initial service registration
> java.lang.ClassNotFoundException:
> org.apache.aries.samples.ariestrader.api.TradeServicesManager
>        at
> org.eclipse.osgi.internal.loader.BundleLoader.findClassInternal(BundleLoader.java:489)
>        at
> org.eclipse.osgi.internal.loader.BundleLoader.findClass(BundleLoader.java:405)
>        at
> org.eclipse.osgi.internal.loader.BundleLoader.findClass(BundleLoader.java:393)
>        at
> org.eclipse.osgi.internal.baseadaptor.DefaultClassLoader.loadClass(DefaultClassLoader.java:105)
>        at java.lang.ClassLoader.loadClass(ClassLoader.java:250)
>        at
> org.eclipse.osgi.internal.loader.BundleLoader.loadClass(BundleLoader.java:321)
>        at
> org.eclipse.osgi.framework.internal.core.BundleHost.loadClass(BundleHost.java:231)
>        at
> org.eclipse.osgi.framework.internal.core.AbstractBundle.loadClass(AbstractBundle.java:1193)
>        at
> org.apache.aries.jndi.services.ServiceHelper.getService(ServiceHelper.java:206)
>        at
> org.apache.aries.jndi.url.ServiceRegistryContext.lookup(ServiceRegistryContext.java:189)
>        at
> org.apache.aries.jndi.url.ServiceRegistryContext.lookup(ServiceRegistryContext.java:218)
>        at
> org.apache.aries.jndi.DelegateContext.lookup(DelegateContext.java:160)
>        at javax.naming.InitialContext.lookup(InitialContext.java:392)
>        at
> org.apache.aries.samples.ariestrader.util.ServiceUtilities.getOSGIService(ServiceUtilities.java:60)
>        at
> org.apache.aries.samples.ariestrader.util.ServiceUtilities.getOSGIService(ServiceUtilities.java:41)
>        at
> org.apache.aries.samples.ariestrader.api.TradeServiceUtilities.getTradeServicesManager(TradeServiceUtilities.java:63)
>        at org.apache.jsp.config_jsp._jspService(config_jsp.java:83)
>        at org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:70)
>        at javax.servlet.http.HttpServlet.service(HttpServlet.java:820)
>        at
> org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:374)
>        at
> org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:342)
>        at org.apache.jasper.servlet.JspServlet.service(JspServlet.java:267)
>        at javax.servlet.http.HttpServlet.service(HttpServlet.java:820)
>        at
> org.ops4j.pax.web.jsp.JspServletWrapper$2.call(JspServletWrapper.java:132)
>        at
> org.ops4j.pax.web.jsp.JspServletWrapper$2.call(JspServletWrapper.java:127)
>        at
> org.ops4j.pax.swissbox.core.ContextClassLoaderUtils.doWithClassLoader(ContextClassLoaderUtils.java:60)
>        at
> org.ops4j.pax.web.jsp.JspServletWrapper.service(JspServletWrapper.java:124)
>        at
> org.mortbay.jetty.servlet.ServletHolder.handle(ServletHolder.java:502)
>        at
> org.mortbay.jetty.servlet.ServletHandler.handle(ServletHandler.java:389)
>        at
> org.ops4j.pax.web.service.jetty.internal.HttpServiceServletHandler.handle(HttpServiceServletHandler.java:64)
>        at
> org.mortbay.jetty.servlet.SessionHandler.handle(SessionHandler.java:181)
>        at
> org.mortbay.jetty.handler.ContextHandler.handle(ContextHandler.java:765)
>        at
> org.ops4j.pax.web.service.jetty.internal.HttpServiceContext.handle(HttpServiceContext.java:111)
>        at org.mortbay.jetty.servlet.Dispatcher.include(Dispatcher.java:192)
>        at
> org.apache.aries.samples.ariestrader.web.TradeConfigServlet.doConfigDisplay(TradeConfigServlet.java:62)
>        at
> org.apache.aries.samples.ariestrader.web.TradeConfigServlet.service(TradeConfigServlet.java:403)
>        at javax.servlet.http.HttpServlet.service(HttpServlet.java:820)
>        at
> org.mortbay.jetty.servlet.ServletHolder.handle(ServletHolder.java:502)
>        at
> org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)
>        at
> org.ops4j.pax.web.service.internal.WelcomeFilesFilter.doFilter(WelcomeFilesFilter.java:169)
>        at
> org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1148)
>        at
> org.mortbay.jetty.servlet.ServletHandler.handle(ServletHandler.java:387)
>        at
> org.ops4j.pax.web.service.jetty.internal.HttpServiceServletHandler.handle(HttpServiceServletHandler.java:64)
>        at
> org.mortbay.jetty.servlet.SessionHandler.handle(SessionHandler.java:181)
>        at
> org.mortbay.jetty.handler.ContextHandler.handle(ContextHandler.java:765)
>        at
> org.ops4j.pax.web.service.jetty.internal.HttpServiceContext.handle(HttpServiceContext.java:111)
>        at
> org.ops4j.pax.web.service.jetty.internal.JettyServerHandlerCollection.handle(JettyServerHandlerCollection.java:64)
>        at
> org.mortbay.jetty.handler.HandlerWrapper.handle(HandlerWrapper.java:152)
>        at org.mortbay.jetty.Server.handle(Server.java:322)
>        at
> org.mortbay.jetty.HttpConnection.handleRequest(HttpConnection.java:534)
>        at
> org.mortbay.jetty.HttpConnection$RequestHandler.headerComplete(HttpConnection.java:864)
>        at org.mortbay.jetty.HttpParser.parseNext(HttpParser.java:539)
>        at org.mortbay.jetty.HttpParser.parseAvailable(HttpParser.java:212)
>        at org.mortbay.jetty.HttpConnection.handle(HttpConnection.java:404)
>        at
> org.mortbay.io.nio.SelectChannelEndPoint.run(SelectChannelEndPoint.java:409)
>        at
> org.mortbay.thread.QueuedThreadPool$PoolThread.run(QueuedThreadPool.java:520)
>
>
>
>
>
> Alasdair Nottingham wrote:
>>
>> Hi,
>>
>> I just committed a fix. On a related note I see that the pax web guy's
>> put a Thread context classloader on the thread, but it doesn't
>> implement BundleReference. Does anyone know how we can raise this with
>> them?
>>
>> Thanks
>> Alasdair
>>
>> On 3 March 2010 14:16, Joe Bohn <jo...@gmail.com> wrote:
>>>
>>> It looks like Blog-Sample is having the same issue and it doesn't use
>>> JSPs.
>>>  Here's a similar stack trace from blog-sample:
>>>
>>> [1643210767@qtp-2131869628-0 -
>>> /org.apache.aries.samples.blog-servlet/ViewBlog] DEBUG
>>> org.apache.aries.blueprint.container.ServiceRecipe - Retrieving service
>>> for
>>> bundle org.ops4j.pax.web.pax-web-jetty-bundle_0.7.2 [6] and service
>>> registration
>>>
>>> {org.apache.aries.samples.blog.api.BloggingService}={osgi.service.blueprint.compname=bloggingServiceComponent,
>>> service.id=52}
>>> java.lang.ClassNotFoundException:
>>> org.apache.aries.samples.blog.api.BloggingService
>>>       at
>>>
>>> org.eclipse.osgi.internal.loader.BundleLoader.findClassInternal(BundleLoader.java:489)
>>>       at
>>>
>>> org.eclipse.osgi.internal.loader.BundleLoader.findClass(BundleLoader.java:405)
>>>       at
>>>
>>> org.eclipse.osgi.internal.loader.BundleLoader.findClass(BundleLoader.java:393)
>>>       at
>>>
>>> org.eclipse.osgi.internal.baseadaptor.DefaultClassLoader.loadClass(DefaultClassLoader.java:105)
>>>       at java.lang.ClassLoader.loadClass(ClassLoader.java:250)
>>>       at
>>>
>>> org.eclipse.osgi.internal.loader.BundleLoader.loadClass(BundleLoader.java:321)
>>>       at
>>>
>>> org.eclipse.osgi.framework.internal.core.BundleHost.loadClass(BundleHost.java:231)
>>>       at
>>>
>>> org.eclipse.osgi.framework.internal.core.AbstractBundle.loadClass(AbstractBundle.java:1193)
>>>       at
>>>
>>> org.apache.aries.jndi.services.ServiceHelper.getService(ServiceHelper.java:210)
>>>       at
>>>
>>> org.apache.aries.jndi.url.ServiceRegistryContext.lookup(ServiceRegistryContext.java:189)
>>>       at
>>>
>>> org.apache.aries.jndi.url.ServiceRegistryContext.lookup(ServiceRegistryContext.java:218)
>>>       at
>>> org.apache.aries.jndi.DelegateContext.lookup(DelegateContext.java:160)
>>>       at javax.naming.InitialContext.lookup(InitialContext.java:392)
>>>       at
>>>
>>> org.apache.aries.samples.blog.web.util.JNDIHelper.getBloggingService(JNDIHelper.java:33)
>>>       at
>>> org.apache.aries.samples.blog.web.ViewBlog.doGet(ViewBlog.java:53)
>>>       at javax.servlet.http.HttpServlet.service(HttpServlet.java:707)
>>>       at javax.servlet.http.HttpServlet.service(HttpServlet.java:820)
>>>       at
>>> org.mortbay.jetty.servlet.ServletHolder.handle(ServletHolder.java:502)
>>>       at
>>>
>>> org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)
>>>       at
>>>
>>> org.ops4j.pax.web.service.internal.WelcomeFilesFilter.doFilter(WelcomeFilesFilter.java:169)
>>>       at
>>>
>>> org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1148)
>>>       at
>>> org.mortbay.jetty.servlet.ServletHandler.handle(ServletHandler.java:387)
>>>       at
>>>
>>> org.ops4j.pax.web.service.jetty.internal.HttpServiceServletHandler.handle(HttpServiceServletHandler.java:64)
>>>       at
>>> org.mortbay.jetty.servlet.SessionHandler.handle(SessionHandler.java:181)
>>>       at
>>> org.mortbay.jetty.handler.ContextHandler.handle(ContextHandler.java:765)
>>>       at
>>>
>>> org.ops4j.pax.web.service.jetty.internal.HttpServiceContext.handle(HttpServiceContext.java:111)
>>>       at
>>>
>>> org.ops4j.pax.web.service.jetty.internal.JettyServerHandlerCollection.handle(JettyServerHandlerCollection.java:64)
>>>       at
>>> org.mortbay.jetty.handler.HandlerWrapper.handle(HandlerWrapper.java:152)
>>>       at org.mortbay.jetty.Server.handle(Server.java:322)
>>>       at
>>> org.mortbay.jetty.HttpConnection.handleRequest(HttpConnection.java:534)
>>>       at
>>>
>>> org.mortbay.jetty.HttpConnection$RequestHandler.headerComplete(HttpConnection.java:864)
>>>       at org.mortbay.jetty.HttpParser.parseNext(HttpParser.java:539)
>>>       at org.mortbay.jetty.HttpParser.parseAvailable(HttpParser.java:212)
>>>       at org.mortbay.jetty.HttpConnection.handle(HttpConnection.java:404)
>>>       at
>>>
>>> org.mortbay.io.nio.SelectChannelEndPoint.run(SelectChannelEndPoint.java:409)
>>>       at
>>>
>>> org.mortbay.thread.QueuedThreadPool$PoolThread.run(QueuedThreadPool.java:520)
>>>
>>>
>>> Joe Bohn wrote:
>>>>
>>>> And here's the thread context classloader before the lookup ...
>>>>
>>>>
>>>>
>>>> JasperClassLoader{bundleClassLoader=BundleClassLoader{bundle=org.apache.aries.ariestrader.modules.ariestrader-web_1.0.0.incubating-SNAPSHOT
>>>>
>>>> [35],parent=org.eclipse.osgi.internal.baseadaptor.DefaultClassLoader@78ecf608}}
>>>>
>>>>
>>>> Joe
>>>>
>>>> Joe Bohn wrote:
>>>>>
>>>>> Here's the stack trace for the CNFE.  I'll have to work on getting the
>>>>> thread context classloader.
>>>>>
>>>>> [112793090@qtp-2020456228-2 -
>>>>> /org.apache.aries.ariestrader.modules.ariestrader-web/config] DEBUG
>>>>> org.apache.aries.blueprint.container.ServiceRecipe - Calling listeners
>>>>> for
>>>>> initial service registration
>>>>> java.lang.ClassNotFoundException:
>>>>> org.apache.aries.samples.ariestrader.api.TradeServicesManager
>>>>>       at
>>>>>
>>>>> org.eclipse.osgi.internal.loader.BundleLoader.findClassInternal(BundleLoader.java:489)
>>>>>       at
>>>>>
>>>>> org.eclipse.osgi.internal.loader.BundleLoader.findClass(BundleLoader.java:405)
>>>>>       at
>>>>>
>>>>> org.eclipse.osgi.internal.loader.BundleLoader.findClass(BundleLoader.java:393)
>>>>>       at
>>>>>
>>>>> org.eclipse.osgi.internal.baseadaptor.DefaultClassLoader.loadClass(DefaultClassLoader.java:105)
>>>>>       at java.lang.ClassLoader.loadClass(ClassLoader.java:250)
>>>>>       at
>>>>>
>>>>> org.eclipse.osgi.internal.loader.BundleLoader.loadClass(BundleLoader.java:321)
>>>>>       at
>>>>>
>>>>> org.eclipse.osgi.framework.internal.core.BundleHost.loadClass(BundleHost.java:231)
>>>>>       at
>>>>>
>>>>> org.eclipse.osgi.framework.internal.core.AbstractBundle.loadClass(AbstractBundle.java:1193)
>>>>>       at
>>>>>
>>>>> org.apache.aries.jndi.services.ServiceHelper.getService(ServiceHelper.java:210)
>>>>>       at
>>>>>
>>>>> org.apache.aries.jndi.url.ServiceRegistryContext.lookup(ServiceRegistryContext.java:189)
>>>>>       at
>>>>>
>>>>> org.apache.aries.jndi.url.ServiceRegistryContext.lookup(ServiceRegistryContext.java:218)
>>>>>       at
>>>>> org.apache.aries.jndi.DelegateContext.lookup(DelegateContext.java:160)
>>>>>       at javax.naming.InitialContext.lookup(InitialContext.java:392)
>>>>>       at
>>>>>
>>>>> org.apache.aries.samples.ariestrader.util.ServiceUtilities.getOSGIService(ServiceUtilities.java:60)
>>>>>       at
>>>>>
>>>>> org.apache.aries.samples.ariestrader.util.ServiceUtilities.getOSGIService(ServiceUtilities.java:41)
>>>>>       at
>>>>>
>>>>> org.apache.aries.samples.ariestrader.api.TradeServiceUtilities.getTradeServicesManager(TradeServiceUtilities.java:63)
>>>>>       at org.apache.jsp.config_jsp._jspService(config_jsp.java:86)
>>>>>       at
>>>>> org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:70)
>>>>>       at javax.servlet.http.HttpServlet.service(HttpServlet.java:820)
>>>>>       at
>>>>>
>>>>> org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:374)
>>>>>       at
>>>>>
>>>>> org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:342)
>>>>>       at
>>>>> org.apache.jasper.servlet.JspServlet.service(JspServlet.java:267)
>>>>>       at javax.servlet.http.HttpServlet.service(HttpServlet.java:820)
>>>>>       at
>>>>>
>>>>> org.ops4j.pax.web.jsp.JspServletWrapper$2.call(JspServletWrapper.java:132)
>>>>>       at
>>>>>
>>>>> org.ops4j.pax.web.jsp.JspServletWrapper$2.call(JspServletWrapper.java:127)
>>>>>       at
>>>>>
>>>>> org.ops4j.pax.swissbox.core.ContextClassLoaderUtils.doWithClassLoader(ContextClassLoaderUtils.java:60)
>>>>>       at
>>>>>
>>>>> org.ops4j.pax.web.jsp.JspServletWrapper.service(JspServletWrapper.java:124)
>>>>>       at
>>>>> org.mortbay.jetty.servlet.ServletHolder.handle(ServletHolder.java:502)
>>>>>       at
>>>>>
>>>>> org.mortbay.jetty.servlet.ServletHandler.handle(ServletHandler.java:389)
>>>>>       at
>>>>>
>>>>> org.ops4j.pax.web.service.jetty.internal.HttpServiceServletHandler.handle(HttpServiceServletHandler.java:64)
>>>>>       at
>>>>>
>>>>> org.mortbay.jetty.servlet.SessionHandler.handle(SessionHandler.java:181)
>>>>>       at
>>>>>
>>>>> org.mortbay.jetty.handler.ContextHandler.handle(ContextHandler.java:765)
>>>>>       at
>>>>>
>>>>> org.ops4j.pax.web.service.jetty.internal.HttpServiceContext.handle(HttpServiceContext.java:111)
>>>>>       at
>>>>> org.mortbay.jetty.servlet.Dispatcher.include(Dispatcher.java:192)
>>>>>       at
>>>>>
>>>>> org.apache.aries.samples.ariestrader.web.TradeConfigServlet.doConfigDisplay(TradeConfigServlet.java:62)
>>>>>       at
>>>>>
>>>>> org.apache.aries.samples.ariestrader.web.TradeConfigServlet.service(TradeConfigServlet.java:403)
>>>>>       at javax.servlet.http.HttpServlet.service(HttpServlet.java:820)
>>>>>       at
>>>>> org.mortbay.jetty.servlet.ServletHolder.handle(ServletHolder.java:502)
>>>>>       at
>>>>>
>>>>> org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)
>>>>>       at
>>>>>
>>>>> org.ops4j.pax.web.service.internal.WelcomeFilesFilter.doFilter(WelcomeFilesFilter.java:169)
>>>>>       at
>>>>>
>>>>> org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1148)
>>>>>       at
>>>>>
>>>>> org.mortbay.jetty.servlet.ServletHandler.handle(ServletHandler.java:387)
>>>>>       at
>>>>>
>>>>> org.ops4j.pax.web.service.jetty.internal.HttpServiceServletHandler.handle(HttpServiceServletHandler.java:64)
>>>>>       at
>>>>>
>>>>> org.mortbay.jetty.servlet.SessionHandler.handle(SessionHandler.java:181)
>>>>>       at
>>>>>
>>>>> org.mortbay.jetty.handler.ContextHandler.handle(ContextHandler.java:765)
>>>>>       at
>>>>>
>>>>> org.ops4j.pax.web.service.jetty.internal.HttpServiceContext.handle(HttpServiceContext.java:111)
>>>>>       at
>>>>>
>>>>> org.ops4j.pax.web.service.jetty.internal.JettyServerHandlerCollection.handle(JettyServerHandlerCollection.java:64)
>>>>>       at
>>>>>
>>>>> org.mortbay.jetty.handler.HandlerWrapper.handle(HandlerWrapper.java:152)
>>>>>       at org.mortbay.jetty.Server.handle(Server.java:322)
>>>>>       at
>>>>> org.mortbay.jetty.HttpConnection.handleRequest(HttpConnection.java:534)
>>>>>       at
>>>>>
>>>>> org.mortbay.jetty.HttpConnection$RequestHandler.headerComplete(HttpConnection.java:864)
>>>>>       at org.mortbay.jetty.HttpParser.parseNext(HttpParser.java:539)
>>>>>       at
>>>>> org.mortbay.jetty.HttpParser.parseAvailable(HttpParser.java:212)
>>>>>       at
>>>>> org.mortbay.jetty.HttpConnection.handle(HttpConnection.java:404)
>>>>>       at
>>>>>
>>>>> org.mortbay.io.nio.SelectChannelEndPoint.run(SelectChannelEndPoint.java:409)
>>>>>       at
>>>>>
>>>>> org.mortbay.thread.QueuedThreadPool$PoolThread.run(QueuedThreadPool.java:520)
>>>>>
>>>>> Alasdair Nottingham wrote:
>>>>>>
>>>>>> Hi,
>>>>>>
>>>>>> Hmm, I suspect I am not correctly finding the appropriate
>>>>>> BundleContext to use. That would explain the CNFE because we now proxy
>>>>>> the services rather than returning the raw service. If it is being
>>>>>> listed as being used by the pax-web jsp bundle that would explain
>>>>>> things.
>>>>>>
>>>>>> Do you have a stack trace for the ClassNotFoundException? That might
>>>>>> help to work out what went wrong.
>>>>>>
>>>>>> Also can you check the thread context classloader before the lookup?
>>>>>>
>>>>>> Thanks
>>>>>> Alasdair
>>>>>>
>>>>>> On 2 March 2010 23:21, Joe Bohn <jo...@gmail.com> wrote:
>>>>>>>
>>>>>>> I think there are some issues with this change.   I'll have to dig
>>>>>>> some
>>>>>>> more
>>>>>>> and post more details later (don't have time right now) ... but in
>>>>>>> short I'm
>>>>>>> seeing the following:
>>>>>>>
>>>>>>> - AriesTrader is behaving very badly after this change.
>>>>>>> - From within a jsp we use jndi lookup to find an osgi service.
>>>>>>> - After this change I get a failure in my jsp with a CNFE.   This
>>>>>>> despite
>>>>>>> the fact that I can see the package is imported on the web bundle and
>>>>>>> appears to be wired correctly.
>>>>>>> - Even more strange: I notice that the application service I was
>>>>>>> looking for
>>>>>>> is listed as being used by the pax-web jsp bundle.  So it seems like
>>>>>>> we
>>>>>>> might be using the wrong bundle context at some point.
>>>>>>>
>>>>>>>
>>>>>>> Joe
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>> not@apache.org wrote:
>>>>>>>>
>>>>>>>> Author: not
>>>>>>>> Date: Mon Mar  1 23:53:18 2010
>>>>>>>> New Revision: 917809
>>>>>>>>
>>>>>>>> URL: http://svn.apache.org/viewvc?rev=917809&view=rev
>>>>>>>> Log:
>>>>>>>> ARIES-128 Implement OSGi spec url lookup scheme
>>>>>>>>
>>>>>>>> Added:
>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>>  incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/OsgiName.java
>>>>>>>>    - copied, changed from r910238,
>>>>>>>>
>>>>>>>>
>>>>>>>> incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/ServiceRegistryName.java
>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>>  incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/OsgiNameParser.java
>>>>>>>>    - copied, changed from r910238,
>>>>>>>>
>>>>>>>>
>>>>>>>> incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/ServiceRegistryNameParser.java
>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>>  incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/ServiceRegistryListContext.java
>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>>  incubator/aries/trunk/jndi/jndi-url/src/test/java/org/apache/aries/jndi/url/OsgiNameParserTest.java
>>>>>>>>    - copied, changed from r917002,
>>>>>>>>
>>>>>>>>
>>>>>>>> incubator/aries/trunk/jndi/jndi-url/src/test/java/org/apache/aries/jndi/url/ServiceRegistryNameParserTest.java
>>>>>>>> Removed:
>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>>  incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/ServiceRegistryName.java
>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>>  incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/ServiceRegistryNameParser.java
>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>>  incubator/aries/trunk/jndi/jndi-url/src/test/java/org/apache/aries/jndi/url/ServiceHelperTest.java
>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>>  incubator/aries/trunk/jndi/jndi-url/src/test/java/org/apache/aries/jndi/url/ServiceRegistryNameParserTest.java
>>>>>>>> Modified:
>>>>>>>>  incubator/aries/trunk/jndi/jndi-url/pom.xml
>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>>  incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/services/ServiceHelper.java
>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>>  incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/Activator.java
>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>>  incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/OsgiURLContextFactory.java
>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>>  incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/ServiceRegistryContext.java
>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>>  incubator/aries/trunk/jndi/jndi-url/src/test/java/org/apache/aries/jndi/url/ServiceRegistryContextTest.java
>>>>>>>>
>>>>>>>> Modified: incubator/aries/trunk/jndi/jndi-url/pom.xml
>>>>>>>> URL:
>>>>>>>>
>>>>>>>>
>>>>>>>> http://svn.apache.org/viewvc/incubator/aries/trunk/jndi/jndi-url/pom.xml?rev=917809&r1=917808&r2=917809&view=diff
>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>> ==============================================================================
>>>>>>>> --- incubator/aries/trunk/jndi/jndi-url/pom.xml (original)
>>>>>>>> +++ incubator/aries/trunk/jndi/jndi-url/pom.xml Mon Mar  1 23:53:18
>>>>>>>> 2010
>>>>>>>> @@ -33,6 +33,10 @@
>>>>>>>>    <dependencies>
>>>>>>>>     <dependency>
>>>>>>>> +       <groupId>org.apache.aries</groupId>
>>>>>>>> +       <artifactId>org.apache.aries.util</artifactId>
>>>>>>>> +      </dependency>
>>>>>>>> +      <dependency>
>>>>>>>>         <groupId>org.osgi</groupId>
>>>>>>>>         <artifactId>org.osgi.core</artifactId>
>>>>>>>>         <scope>provided</scope>
>>>>>>>>
>>>>>>>> Modified:
>>>>>>>>
>>>>>>>>
>>>>>>>> incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/services/ServiceHelper.java
>>>>>>>> URL:
>>>>>>>>
>>>>>>>>
>>>>>>>> http://svn.apache.org/viewvc/incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/services/ServiceHelper.java?rev=917809&r1=917808&r2=917809&view=diff
>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>> ==============================================================================
>>>>>>>> ---
>>>>>>>>
>>>>>>>>
>>>>>>>> incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/services/ServiceHelper.java
>>>>>>>> (original)
>>>>>>>> +++
>>>>>>>>
>>>>>>>>
>>>>>>>> incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/services/ServiceHelper.java
>>>>>>>> Mon Mar  1 23:53:18 2010
>>>>>>>> @@ -18,18 +18,30 @@
>>>>>>>>  */
>>>>>>>>  package org.apache.aries.jndi.services;
>>>>>>>>  +import java.lang.reflect.InvocationHandler;
>>>>>>>> +import java.lang.reflect.Method;
>>>>>>>> +import java.lang.reflect.Proxy;
>>>>>>>> +import java.security.AccessController;
>>>>>>>> +import java.security.PrivilegedAction;
>>>>>>>> +import java.util.ArrayList;
>>>>>>>>  import java.util.Arrays;
>>>>>>>>  import java.util.Comparator;
>>>>>>>>  import java.util.HashSet;
>>>>>>>>  import java.util.LinkedList;
>>>>>>>>  import java.util.List;
>>>>>>>> +import java.util.Map;
>>>>>>>>  import java.util.Set;
>>>>>>>>  import java.util.concurrent.ConcurrentHashMap;
>>>>>>>>  import java.util.concurrent.ConcurrentMap;
>>>>>>>>  +import javax.naming.NamingException;
>>>>>>>> +
>>>>>>>> +import org.apache.aries.util.BundleToClassLoaderAdapter;
>>>>>>>> +import org.osgi.framework.Bundle;
>>>>>>>>  import org.osgi.framework.BundleContext;
>>>>>>>>  import org.osgi.framework.BundleReference;
>>>>>>>>  import org.osgi.framework.InvalidSyntaxException;
>>>>>>>> +import org.osgi.framework.ServiceException;
>>>>>>>>  import org.osgi.framework.ServiceReference;
>>>>>>>>  /**
>>>>>>>> @@ -47,221 +59,206 @@
>>>>>>>>  */
>>>>>>>>  public final class ServiceHelper
>>>>>>>>  {
>>>>>>>> -  /** The bundle context used for service registry queries */
>>>>>>>> -  private static BundleContext context;
>>>>>>>> -  /** A cache of what service was returned last time the query was
>>>>>>>> performed */
>>>>>>>> -  private static ConcurrentMap<ServiceKey, Set<ServiceReference>>
>>>>>>>> cache =
>>>>>>>> new ConcurrentHashMap<ServiceKey, Set<ServiceReference>>();
>>>>>>>> -
>>>>>>>> -  public static void setBundleContext(BundleContext ctx)
>>>>>>>> +  public static class StackFinder extends SecurityManager
>>>>>>>>  {
>>>>>>>> -    context = ctx;
>>>>>>>> +    public Class<?>[] getClassContext()
>>>>>>>> +    {
>>>>>>>> +      return super.getClassContext();
>>>>>>>> +    }
>>>>>>>>  }
>>>>>>>> -  -  /**
>>>>>>>> -   * This class is used as the key into the cache. It holds
>>>>>>>> information
>>>>>>>> to identify -   * who performed the query, along with the className
>>>>>>>> and
>>>>>>>> filter used. The thread context
>>>>>>>> -   * class loader is used in the key, so two different modules will
>>>>>>>> potentially get different
>>>>>>>> -   * services.
>>>>>>>> -   */
>>>>>>>> -  private static final class ServiceKey
>>>>>>>> +
>>>>>>>> +  private static class JNDIServiceDamper implements
>>>>>>>> InvocationHandler
>>>>>>>>  {
>>>>>>>> -    /** The class loader of the invoking application */
>>>>>>>> -    private ClassLoader classLoader;
>>>>>>>> -    /** The name of the class being queried from the registry */
>>>>>>>> -    private String className;
>>>>>>>> -    /** the registry filter, this may be null */
>>>>>>>> +    private BundleContext ctx;
>>>>>>>> +    private ServicePair pair;
>>>>>>>> +    private String interfaceName;
>>>>>>>>   private String filter;
>>>>>>>> -    /** The cached hashCode */
>>>>>>>> -    private final int hashCode;
>>>>>>>> -
>>>>>>>> -    /**
>>>>>>>> -     * Boring unimportant comment.
>>>>>>>> -     * -     * @param cl
>>>>>>>> -     * @param cn
>>>>>>>> -     * @param f
>>>>>>>> -     */
>>>>>>>> -    public ServiceKey(ClassLoader cl, String cn, String f)
>>>>>>>> +    private boolean dynamic;
>>>>>>>> +    +    public JNDIServiceDamper(BundleContext context, String i,
>>>>>>>> String
>>>>>>>> f, ServicePair service, boolean d)
>>>>>>>>   {
>>>>>>>> -      classLoader = cl;
>>>>>>>> -      className = cn;
>>>>>>>> +      ctx = context;
>>>>>>>> +      pair = service;
>>>>>>>> +      interfaceName = i;
>>>>>>>>     filter = f;
>>>>>>>> -      -      int classNameHash = (className == null) ? 0 :
>>>>>>>> className.hashCode();
>>>>>>>> -      hashCode = System.identityHashCode(classLoader) * 1000003 +
>>>>>>>> classNameHash;
>>>>>>>> +      dynamic = d;
>>>>>>>>   }
>>>>>>>> -
>>>>>>>> -    @Override
>>>>>>>> -    public int hashCode()
>>>>>>>> -    {
>>>>>>>> -      return hashCode;
>>>>>>>> -    }
>>>>>>>> -
>>>>>>>> -    @Override
>>>>>>>> -    public boolean equals(Object other)
>>>>>>>> +    +    public Object invoke(Object proxy, Method method, Object[]
>>>>>>>> args)
>>>>>>>> throws Throwable
>>>>>>>>   {
>>>>>>>> -      if (other == this) return true;
>>>>>>>> -      if (other == null) return false;
>>>>>>>> -
>>>>>>>> -      if (other instanceof ServiceKey) {
>>>>>>>> -        ServiceKey otherKey = (ServiceKey) other;
>>>>>>>> -        if (hashCode != otherKey.hashCode) return false;
>>>>>>>> -
>>>>>>>> -        if (classLoader != otherKey.classLoader) return false;
>>>>>>>> -        if (!!!comparePossiblyNullObjects(className,
>>>>>>>> otherKey.className))
>>>>>>>> return false;
>>>>>>>> -        return comparePossiblyNullObjects(filter, otherKey.filter);
>>>>>>>> -      }
>>>>>>>> -
>>>>>>>> -      return false;
>>>>>>>> -    }
>>>>>>>> -    -    /**
>>>>>>>> -     * Compares two objects where one or other (or both) may be
>>>>>>>> null.
>>>>>>>> -     * -     * @param a the first object to compare.
>>>>>>>> -     * @param b the second object to compare.
>>>>>>>> -     * @return true if they are ==, both null or identity equals,
>>>>>>>> false
>>>>>>>> otherwise.
>>>>>>>> -     */
>>>>>>>> -    public boolean comparePossiblyNullObjects(Object a, Object b) {
>>>>>>>> -      if (a == b) return true;
>>>>>>>> -      else if (a == null) return false;
>>>>>>>> -      else return a.equals(b);
>>>>>>>> +      if (pair.ref.getBundle() == null) {
>>>>>>>> +        if (dynamic) pair = findService(ctx, interfaceName,
>>>>>>>> filter);
>>>>>>>> +        else pair = null;
>>>>>>>> +      }
>>>>>>>> +      +      if (pair == null) {
>>>>>>>> +        throw new ServiceException(interfaceName,
>>>>>>>> ServiceException.UNREGISTERED);
>>>>>>>> +      }
>>>>>>>> +      +      return method.invoke(pair.service, args);
>>>>>>>>   }
>>>>>>>>  }
>>>>>>>> -
>>>>>>>> -  /**
>>>>>>>> -   * This method is used to obtain a single instance of a desired
>>>>>>>> service
>>>>>>>> from the OSGi
>>>>>>>> -   * service registry. If the filter and class name identify
>>>>>>>> multiple
>>>>>>>> services the first
>>>>>>>> -   * one is returned. If no service is found null will be returned.
>>>>>>>> -   * -   * @param className The class name used to register the
>>>>>>>> desired
>>>>>>>> service. If null is provided
>>>>>>>> -   *                  then all services are eligible to be
>>>>>>>> returned.
>>>>>>>> -   * @param filter    An RFC 1960 query into the properties of the
>>>>>>>> registered services. e.g.
>>>>>>>> -   *                  (service.description=really useful)
>>>>>>>> -   * @return          The desired service
>>>>>>>> -   * -   * @throws IllegalArgumentException If the filter is not
>>>>>>>> valid.
>>>>>>>> See RFC 1960 to work out what -   *
>>>>>>>>  it
>>>>>>>> should be.
>>>>>>>> -   */
>>>>>>>> -  public static Object getService(String className, String filter)
>>>>>>>> throws
>>>>>>>> IllegalArgumentException
>>>>>>>> +  +  private static class ServicePair
>>>>>>>>  {
>>>>>>>> -    Object service = null;
>>>>>>>> -    try {
>>>>>>>> -      BundleContext callerCtx = getBundleContext();
>>>>>>>> -      ServiceReference[] refs =
>>>>>>>> callerCtx.getServiceReferences(className,
>>>>>>>> filter);
>>>>>>>> -      -      if (refs != null) {
>>>>>>>> -        // we need to sort the references returned in case they are
>>>>>>>> out
>>>>>>>> of order
>>>>>>>> -        // we need to sort in the reverse natural order, services
>>>>>>>> with
>>>>>>>> higher -        // ranking or lower id should be processed first so
>>>>>>>> should
>>>>>>>> be earlier in the array.
>>>>>>>> -        Arrays.sort(refs, new Comparator<ServiceReference>() {
>>>>>>>> -          public int compare(ServiceReference o1, ServiceReference
>>>>>>>> o2)
>>>>>>>> -          {
>>>>>>>> -            return o2.compareTo(o1);
>>>>>>>> -          }
>>>>>>>> -        });
>>>>>>>> -        -        for (ServiceReference ref : refs) {
>>>>>>>> -          List<Object> services = getServices(callerCtx, className,
>>>>>>>> filter, ref);
>>>>>>>> -          if (!!!services.isEmpty()) {
>>>>>>>> -            service = services.get(0);
>>>>>>>> -            break;
>>>>>>>> -          }
>>>>>>>> -        }
>>>>>>>> -      }      -    } catch (InvalidSyntaxException e) {
>>>>>>>> -      throw new IllegalArgumentException(e.getMessage(), e);
>>>>>>>> -    }
>>>>>>>> -    -    return service;
>>>>>>>> +    private ServiceReference ref;
>>>>>>>> +    private Object service;
>>>>>>>>  }
>>>>>>>>    /**
>>>>>>>> -   * This method is used to obtain a list of service instances from
>>>>>>>> the
>>>>>>>> OSGi
>>>>>>>> -   * service registry. If no service is found an empty list will be
>>>>>>>> returned.
>>>>>>>> -   * -   * @param className The class name used to register the
>>>>>>>> desired
>>>>>>>> service. If null is provided
>>>>>>>> -   *                  then all services are eligible to be
>>>>>>>> returned.
>>>>>>>> -   * @param filter    An RFC 1960 query into the properties of the
>>>>>>>> registered services. e.g.
>>>>>>>> -   *                  (service.description=really useful)
>>>>>>>> -   * @return          A list of matching services.
>>>>>>>> -   * -   * @throws IllegalArgumentException If the filter is not
>>>>>>>> valid.
>>>>>>>> See RFC 1960 to work out what -   *
>>>>>>>>  it
>>>>>>>> should be.
>>>>>>>> +   * @param env +   * @return the bundle context for the caller.
>>>>>>>> +   * @throws NamingException     */
>>>>>>>> -  public static List<?> getServices(String className, String
>>>>>>>> filter)
>>>>>>>> -      throws IllegalArgumentException
>>>>>>>> +  public static BundleContext getBundleContext(Map<String, Object>
>>>>>>>> env)
>>>>>>>> throws NamingException
>>>>>>>>  {
>>>>>>>> -    List<Object> services;
>>>>>>>> -    try {
>>>>>>>> -      BundleContext callerCtx = getBundleContext();
>>>>>>>> -      ServiceReference[] refs =
>>>>>>>> callerCtx.getAllServiceReferences(className, filter);
>>>>>>>> +    BundleContext result = null;
>>>>>>>> +    +    Object bc = env.get("osgi.service.jndi.bundleContext");
>>>>>>>> +    +    if (bc != null && bc instanceof BundleContext) result =
>>>>>>>> (BundleContext) bc;
>>>>>>>> +    else {
>>>>>>>> +      ClassLoader cl = AccessController.doPrivileged(new
>>>>>>>> PrivilegedAction<ClassLoader>() {
>>>>>>>> +        public ClassLoader run()
>>>>>>>> +        {
>>>>>>>> +          return Thread.currentThread().getContextClassLoader();
>>>>>>>> +        }
>>>>>>>> +      });
>>>>>>>>     -      services = getServices(callerCtx, className, filter,
>>>>>>>> refs);
>>>>>>>> -    } catch (InvalidSyntaxException e) {
>>>>>>>> -      throw new IllegalArgumentException(e.getMessage(), e);
>>>>>>>> +      result = getBundleContext(cl);
>>>>>>>> +    }
>>>>>>>> +    +    if (result == null) {
>>>>>>>> +      StackTraceElement[] stackTrace =
>>>>>>>> AccessController.doPrivileged(new
>>>>>>>> PrivilegedAction<StackTraceElement[]>() {
>>>>>>>> +        public StackTraceElement[] run()
>>>>>>>> +        {
>>>>>>>> +          return Thread.currentThread().getStackTrace();
>>>>>>>> +        }
>>>>>>>> +      });
>>>>>>>> +      +      StackFinder finder = new StackFinder();
>>>>>>>> +      Class<?>[] classStack = finder.getClassContext();
>>>>>>>> +      +      boolean found = false;
>>>>>>>> +      boolean foundLookup = false;
>>>>>>>> +      int i = 0;
>>>>>>>> +      for (; i < stackTrace.length && !!!found; i++) {
>>>>>>>> +        if (!!!foundLookup &&
>>>>>>>> "lookup".equals(stackTrace[i].getMethodName())) {
>>>>>>>> +          foundLookup = true;
>>>>>>>> +        } else if (foundLookup &&
>>>>>>>> !!!(stackTrace[i].getClassName().startsWith("org.apache.aries.jndi")
>>>>>>>> ||
>>>>>>>> +
>>>>>>>>  stackTrace[i].getClassName().startsWith("javax.naming"))) {
>>>>>>>> +          found = true;
>>>>>>>> +        }
>>>>>>>> +      }
>>>>>>>> +      +      if (found) {
>>>>>>>> +        Set<Integer> classLoadersChecked = new HashSet<Integer>();
>>>>>>>> +        for (; i < classStack.length && result == null; i++) {
>>>>>>>> +          ClassLoader cl = classStack[i].getClassLoader();
>>>>>>>> +          int hash = System.identityHashCode(cl);
>>>>>>>> +          if (!!!classLoadersChecked.contains(hash)) {
>>>>>>>> +            classLoadersChecked.add(hash);
>>>>>>>> +            result = getBundleContext(cl);
>>>>>>>> +          }
>>>>>>>> +        }
>>>>>>>> +        // Now we walk the stack looking for the BundleContext
>>>>>>>> +      }
>>>>>>>>   }
>>>>>>>>   -    return services;
>>>>>>>> +    if (result == null) throw new NamingException("Unable to find
>>>>>>>> BundleContext");
>>>>>>>> +    +    return result;
>>>>>>>>  }
>>>>>>>> -  -  /**
>>>>>>>> -   * @return the bundle context for the caller.
>>>>>>>> -   */
>>>>>>>> -  private static BundleContext getBundleContext()
>>>>>>>> +
>>>>>>>> +  private static BundleContext getBundleContext(ClassLoader cl)
>>>>>>>>  {
>>>>>>>>   BundleContext result = null;
>>>>>>>> -    ClassLoader cl =
>>>>>>>> Thread.currentThread().getContextClassLoader();
>>>>>>>>   while (result == null && cl != null) {
>>>>>>>>     if (cl instanceof BundleReference) {
>>>>>>>>       result = ((BundleReference)cl).getBundle().getBundleContext();
>>>>>>>>     } else if (cl != null) {
>>>>>>>>       cl = cl.getParent();
>>>>>>>>     }
>>>>>>>> -    } +    }
>>>>>>>>   -    if (result == null) result = context;
>>>>>>>>   return result;
>>>>>>>>  }
>>>>>>>>  -  /**
>>>>>>>> -   * This worker method obtains the requested service(s) and if the
>>>>>>>> service(s) -   * exist updates the cache and releases the previous
>>>>>>>> service(s).
>>>>>>>> -   * -   * @param callerCtx The caller context.
>>>>>>>> -   * @param className The class name used to query for the service.
>>>>>>>> -   * @param filter    The filter name used to query for the
>>>>>>>> service.
>>>>>>>> -   * @param refs      The references to get.
>>>>>>>> -   * @return          The service, if one was found, or null.
>>>>>>>> -   */
>>>>>>>> -  private static List<Object> getServices(BundleContext callerCtx,
>>>>>>>> String
>>>>>>>> className, String filter, ServiceReference...refs)
>>>>>>>> +  public static Object getService(String interface1, String filter,
>>>>>>>> String serviceName, boolean dynamicRebind, Map<String, Object> env)
>>>>>>>> throws
>>>>>>>> NamingException
>>>>>>>>  {
>>>>>>>> -    List<Object> data = new LinkedList<Object>();
>>>>>>>> +    Object result = null;
>>>>>>>> +    +    BundleContext ctx = getBundleContext(env);
>>>>>>>> +    +    ServicePair pair = findService(ctx, interface1, filter);
>>>>>>>>   -    if (refs != null) {
>>>>>>>> -      Set<ServiceReference> refSet = new
>>>>>>>> HashSet<ServiceReference>();
>>>>>>>> -      for (ServiceReference ref : refs) {
>>>>>>>> -        Object service = callerCtx.getService(ref);
>>>>>>>> -        if (service != null) {
>>>>>>>> -          data.add(service);
>>>>>>>> -          refSet.add(ref);
>>>>>>>> +    if (pair == null) {
>>>>>>>> +      interface1 = null;
>>>>>>>> +      filter = "(osgi.jndi.serviceName=" + serviceName + ")";
>>>>>>>> +      pair = findService(ctx, interface1, filter);
>>>>>>>> +    }
>>>>>>>> +    +    if (pair != null) {
>>>>>>>> +      String[] interfaces = (String[])
>>>>>>>> pair.ref.getProperty("objectClass");
>>>>>>>> +      +      List<Class<?>> clazz = new
>>>>>>>> ArrayList<Class<?>>(interfaces.length);
>>>>>>>> +      +      Bundle b = ctx.getBundle();
>>>>>>>> +      +      for (String interfaceName : interfaces) {
>>>>>>>> +        try {
>>>>>>>> +          clazz.add(b.loadClass(interfaceName));
>>>>>>>> +        } catch (ClassNotFoundException e) {
>>>>>>>> +          // TODO Auto-generated catch block
>>>>>>>> +          e.printStackTrace();
>>>>>>>>       }
>>>>>>>>     }
>>>>>>>>     -      ClassLoader cl =
>>>>>>>> Thread.currentThread().getContextClassLoader();
>>>>>>>> -      ServiceKey key = new ServiceKey(cl, className, filter);
>>>>>>>> +      if (clazz.isEmpty()) {
>>>>>>>> +        throw new IllegalArgumentException();
>>>>>>>> +      }
>>>>>>>>     -      // we do not need any synchronization around this. The
>>>>>>>> map
>>>>>>>> is
>>>>>>>> concurrent
>>>>>>>> -      // and until here we do not touch any shared state.
>>>>>>>> -      refSet = cache.put(key, refSet);
>>>>>>>> +      InvocationHandler ih = new JNDIServiceDamper(ctx, interface1,
>>>>>>>> filter, pair, dynamicRebind);
>>>>>>>>     -      if (refSet != null) {
>>>>>>>> -        for (ServiceReference ref : refSet) {
>>>>>>>> -          callerCtx.ungetService(ref);
>>>>>>>> +      result = Proxy.newProxyInstance(new
>>>>>>>> BundleToClassLoaderAdapter(b),
>>>>>>>> clazz.toArray(new Class<?>[clazz.size()]), ih);
>>>>>>>> +    }
>>>>>>>> +    +    return result;
>>>>>>>> +  }
>>>>>>>> +
>>>>>>>> +  private static ServicePair findService(BundleContext ctx, String
>>>>>>>> interface1, String filter)
>>>>>>>> +  {
>>>>>>>> +    ServicePair p = null;
>>>>>>>> +    +    try {
>>>>>>>> +      ServiceReference[] refs =
>>>>>>>> ctx.getServiceReferences(interface1,
>>>>>>>> filter);
>>>>>>>> +      +      if (refs != null) {
>>>>>>>> +        // natural order is the exact opposite of the order we
>>>>>>>> desire.
>>>>>>>> +        Arrays.sort(refs, new Comparator<ServiceReference>() {
>>>>>>>> +          public int compare(ServiceReference o1, ServiceReference
>>>>>>>> o2)
>>>>>>>> +          {
>>>>>>>> +            return o2.compareTo(o1);
>>>>>>>> +          }
>>>>>>>> +        });
>>>>>>>> +        +        for (ServiceReference ref : refs) {
>>>>>>>> +          Object service = ctx.getService(ref);
>>>>>>>> +          +          if (service != null) {
>>>>>>>> +            p = new ServicePair();
>>>>>>>> +            p.ref = ref;
>>>>>>>> +            p.service = service;
>>>>>>>> +            break;
>>>>>>>> +          }
>>>>>>>>       }
>>>>>>>>     }
>>>>>>>> +      +    } catch (InvalidSyntaxException e) {
>>>>>>>> +      // TODO Auto-generated catch block
>>>>>>>> +      e.printStackTrace();
>>>>>>>>   }
>>>>>>>>   -    return data;
>>>>>>>> +    return p;
>>>>>>>>  }
>>>>>>>>  }
>>>>>>>>
>>>>>>>> Modified:
>>>>>>>>
>>>>>>>>
>>>>>>>> incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/Activator.java
>>>>>>>> URL:
>>>>>>>>
>>>>>>>>
>>>>>>>> http://svn.apache.org/viewvc/incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/Activator.java?rev=917809&r1=917808&r2=917809&view=diff
>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>> ==============================================================================
>>>>>>>> ---
>>>>>>>>
>>>>>>>>
>>>>>>>> incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/Activator.java
>>>>>>>> (original)
>>>>>>>> +++
>>>>>>>>
>>>>>>>>
>>>>>>>> incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/Activator.java
>>>>>>>> Mon Mar  1 23:53:18 2010
>>>>>>>> @@ -34,8 +34,6 @@
>>>>>>>>
>>>>>>>>  public void start(BundleContext context)
>>>>>>>>  {
>>>>>>>> -    ServiceHelper.setBundleContext(context);
>>>>>>>> -         Hashtable<Object, Object> props = new Hashtable<Object,
>>>>>>>> Object>();
>>>>>>>>   props.put("osgi.jndi.urlScheme", new String[] {"osgi", "aries"} );
>>>>>>>>   reg = context.registerService(ObjectFactory.class.getName(), new
>>>>>>>> OsgiURLContextFactory(), props);
>>>>>>>>
>>>>>>>> Copied:
>>>>>>>>
>>>>>>>>
>>>>>>>> incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/OsgiName.java
>>>>>>>> (from r910238,
>>>>>>>>
>>>>>>>>
>>>>>>>> incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/ServiceRegistryName.java)
>>>>>>>> URL:
>>>>>>>>
>>>>>>>>
>>>>>>>> http://svn.apache.org/viewvc/incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/OsgiName.java?p2=incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/OsgiName.java&p1=incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/ServiceRegistryName.java&r1=910238&r2=917809&rev=917809&view=diff
>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>> ==============================================================================
>>>>>>>> ---
>>>>>>>>
>>>>>>>>
>>>>>>>> incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/ServiceRegistryName.java
>>>>>>>> (original)
>>>>>>>> +++
>>>>>>>>
>>>>>>>>
>>>>>>>> incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/OsgiName.java
>>>>>>>> Mon Mar  1 23:53:18 2010
>>>>>>>> @@ -21,28 +21,104 @@
>>>>>>>>  import java.util.Enumeration;
>>>>>>>>  import javax.naming.CompositeName;
>>>>>>>> +import javax.naming.InvalidNameException;
>>>>>>>> +import javax.naming.Name;
>>>>>>>>  /**
>>>>>>>> - * A composite name for the aries namespace. We only have this so
>>>>>>>> that we
>>>>>>>> can
>>>>>>>> - * provide a nicer toString()
>>>>>>>> + * A composite name for the aries namespace. This provides useful
>>>>>>>> utility
>>>>>>>> methods
>>>>>>>> + * for accessing the name.
>>>>>>>> + * + * component 0: osgi:service, aries:services, osgi:servicelist
>>>>>>>> + * component 1: interface
>>>>>>>> + * component 2: filter
>>>>>>>>  */
>>>>>>>> -public final class ServiceRegistryName extends CompositeName
>>>>>>>> +public final class OsgiName extends CompositeName
>>>>>>>>  {
>>>>>>>>  /** The serial version UID */
>>>>>>>>  private static final long serialVersionUID = 6617580228852444656L;
>>>>>>>> +  public static final String OSGI_SCHEME = "osgi";
>>>>>>>> +  public static final String ARIES_SCHEME = "aries";
>>>>>>>> +  public static final String SERVICE_PATH = "service";
>>>>>>>> +  public static final String SERVICES_PATH = "services";
>>>>>>>> +  public static final String SERVICE_LIST_PATH = "servicelist";
>>>>>>>> +  public static final String FRAMEWORK_PATH = "framework";
>>>>>>>>  -  @Override
>>>>>>>> -  public String toString()
>>>>>>>> +  public OsgiName(String name) throws InvalidNameException
>>>>>>>>  {
>>>>>>>> -    StringBuilder buffer = new StringBuilder();
>>>>>>>> +    super(name);
>>>>>>>> +  }
>>>>>>>> +
>>>>>>>> +  public OsgiName(Name name) throws InvalidNameException
>>>>>>>> +  {
>>>>>>>> +    this(name.toString());
>>>>>>>> +  }
>>>>>>>> +
>>>>>>>> +  public boolean hasFilter()
>>>>>>>> +  {
>>>>>>>> +    return size() == 3;
>>>>>>>> +  }
>>>>>>>> +  +  public boolean isServiceNameBased()
>>>>>>>> +  {
>>>>>>>> +    return size() > 3;
>>>>>>>> +  }
>>>>>>>> +  +  public String getScheme()
>>>>>>>> +  {
>>>>>>>> +    String part0 = get(0);
>>>>>>>> +    int index = part0.indexOf(':');
>>>>>>>> +    +    String result;
>>>>>>>> +    +    if (index > 0) {
>>>>>>>> +      result = part0.substring(0, index);
>>>>>>>> +    } else {
>>>>>>>> +      result = null;
>>>>>>>> +    }
>>>>>>>> +    +    return result;
>>>>>>>> +  }
>>>>>>>> +  +  public String getSchemePath()
>>>>>>>> +  {
>>>>>>>> +    String part0 = get(0);
>>>>>>>> +    int index = part0.indexOf(':');
>>>>>>>> +    +    String result;
>>>>>>>>   -    buffer.append("aries:services");
>>>>>>>> -    Enumeration<String> components = getAll();
>>>>>>>> -    while (components.hasMoreElements()) {
>>>>>>>> -      buffer.append('/');
>>>>>>>> -      buffer.append(components.nextElement());
>>>>>>>> +    if (index > 0) {
>>>>>>>> +      result = part0.substring(index + 1);
>>>>>>>> +    } else {
>>>>>>>> +      result = null;
>>>>>>>>   }
>>>>>>>>   -    return buffer.toString();
>>>>>>>> +    return result;
>>>>>>>> +  }
>>>>>>>> +  +  public String getInterface()
>>>>>>>> +  {
>>>>>>>> +    return get(1);
>>>>>>>> +  }
>>>>>>>> +  +  public String getFilter()
>>>>>>>> +  {
>>>>>>>> +    return hasFilter() ? get(2) : null;
>>>>>>>> +  }
>>>>>>>> +  +  public String getServiceName()
>>>>>>>> +  {
>>>>>>>> +    Enumeration<String> parts = getAll();
>>>>>>>> +    parts.nextElement();
>>>>>>>> +    +    StringBuilder builder = new StringBuilder();
>>>>>>>> +    +    while (parts.hasMoreElements()) {
>>>>>>>> +      builder.append(parts.nextElement());
>>>>>>>> +      builder.append('/');
>>>>>>>> +    }
>>>>>>>> +    +    builder.deleteCharAt(builder.length() - 1);
>>>>>>>> +    +    return builder.toString();
>>>>>>>>  }
>>>>>>>>  }
>>>>>>>> \ No newline at end of file
>>>>>>>>
>>>>>>>> Copied:
>>>>>>>>
>>>>>>>>
>>>>>>>> incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/OsgiNameParser.java
>>>>>>>> (from r910238,
>>>>>>>>
>>>>>>>>
>>>>>>>> incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/ServiceRegistryNameParser.java)
>>>>>>>> URL:
>>>>>>>>
>>>>>>>>
>>>>>>>> http://svn.apache.org/viewvc/incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/OsgiNameParser.java?p2=incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/OsgiNameParser.java&p1=incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/ServiceRegistryNameParser.java&r1=910238&r2=917809&rev=917809&view=diff
>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>> ==============================================================================
>>>>>>>> ---
>>>>>>>>
>>>>>>>>
>>>>>>>> incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/ServiceRegistryNameParser.java
>>>>>>>> (original)
>>>>>>>> +++
>>>>>>>>
>>>>>>>>
>>>>>>>> incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/OsgiNameParser.java
>>>>>>>> Mon Mar  1 23:53:18 2010
>>>>>>>> @@ -26,31 +26,40 @@
>>>>>>>>  /**
>>>>>>>>  * A parser for the aries namespace
>>>>>>>>  */
>>>>>>>> -public final class ServiceRegistryNameParser implements NameParser
>>>>>>>> +public final class OsgiNameParser implements NameParser
>>>>>>>>  {
>>>>>>>> -
>>>>>>>> +  private static final String OSGI_SCHEME = "osgi";
>>>>>>>> +  private static final String ARIES_SCHEME = "aries";
>>>>>>>> +  private static final String SERVICE_PATH = "service";
>>>>>>>> +  private static final String SERVICES_PATH = "services";
>>>>>>>> +  private static final String SERVICE_LIST_PATH = "servicelist";
>>>>>>>> +  private static final String FRAMEWORK_PATH = "framework";
>>>>>>>> +     public Name parse(String name) throws NamingException
>>>>>>>>  {
>>>>>>>> -    if (!!!name.startsWith("aries:services/") &&
>>>>>>>> -        !!!name.startsWith("osgi:services/")) throw new
>>>>>>>> InvalidNameException("The JNDI name did not start with aries:, or
>>>>>>>> osgi:");
>>>>>>>> +    OsgiName result = new OsgiName(name);
>>>>>>>> +    +    if (result.size() < 2) throw new
>>>>>>>> InvalidNameException(name);
>>>>>>>>   -    name = name.substring(name.indexOf('/') + 1);
>>>>>>>> +    String urlScheme = result.getScheme();
>>>>>>>> +    String schemePath = result.getSchemePath();
>>>>>>>>   -    int slashIndex = name.indexOf('/');
>>>>>>>> -    String interfaceName = name;
>>>>>>>> -    String filter = null;
>>>>>>>> -    -    if (slashIndex != -1) {
>>>>>>>> -      interfaceName = name.substring(0, slashIndex);
>>>>>>>> -      filter = name.substring(slashIndex + 1);
>>>>>>>> +    if (!!!(OSGI_SCHEME.equals(urlScheme) ||
>>>>>>>> ARIES_SCHEME.equals(urlScheme))) {
>>>>>>>> +      throw new InvalidNameException(name);
>>>>>>>>   }
>>>>>>>>   -    if (interfaceName.length() == 0) throw new
>>>>>>>> InvalidNameException("No interface name was specified");
>>>>>>>> +    if (ARIES_SCHEME.equals(urlScheme) &&
>>>>>>>> !!!SERVICES_PATH.equals(schemePath)) {
>>>>>>>> +      throw new InvalidNameException(name);
>>>>>>>> +    }
>>>>>>>> +    +    if (OSGI_SCHEME.equals(urlScheme) && !!!(
>>>>>>>> SERVICE_PATH.equals(schemePath) || +
>>>>>>>>    SERVICE_LIST_PATH.equals(schemePath) || +
>>>>>>>>              FRAMEWORK_PATH.equals(schemePath))) {
>>>>>>>> +      throw new InvalidNameException(name);
>>>>>>>> +    }
>>>>>>>>   -    Name result = new ServiceRegistryName();
>>>>>>>> -    result.add(interfaceName);
>>>>>>>> -    if (filter != null) {
>>>>>>>> -      result.add(filter);
>>>>>>>> +    if (result.getInterface() == null ||
>>>>>>>> result.getInterface().length()
>>>>>>>> == 0) {
>>>>>>>> +      throw new InvalidNameException(name);
>>>>>>>>   }
>>>>>>>>        return result;
>>>>>>>> @@ -59,7 +68,7 @@
>>>>>>>>  @Override
>>>>>>>>  public boolean equals(Object other)
>>>>>>>>  {
>>>>>>>> -    return other instanceof ServiceRegistryNameParser;
>>>>>>>> +    return other instanceof OsgiNameParser;
>>>>>>>>  }
>>>>>>>>    @Override
>>>>>>>>
>>>>>>>> Modified:
>>>>>>>>
>>>>>>>>
>>>>>>>> incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/OsgiURLContextFactory.java
>>>>>>>> URL:
>>>>>>>>
>>>>>>>>
>>>>>>>> http://svn.apache.org/viewvc/incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/OsgiURLContextFactory.java?rev=917809&r1=917808&r2=917809&view=diff
>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>> ==============================================================================
>>>>>>>> ---
>>>>>>>>
>>>>>>>>
>>>>>>>> incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/OsgiURLContextFactory.java
>>>>>>>> (original)
>>>>>>>> +++
>>>>>>>>
>>>>>>>>
>>>>>>>> incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/OsgiURLContextFactory.java
>>>>>>>> Mon Mar  1 23:53:18 2010
>>>>>>>> @@ -49,7 +49,7 @@
>>>>>>>>   } else if (obj instanceof String[]) {
>>>>>>>>     // Try each URL until either lookup succeeds or they all fail
>>>>>>>>     String[] urls = (String[])obj;
>>>>>>>> -      if (urls.length == 0) throw new
>>>>>>>> ConfigurationException("ariesURLContextFactory: empty URL array");
>>>>>>>> +      if (urls.length == 0) throw new ConfigurationException("0");
>>>>>>>>     Context context = new ServiceRegistryContext(environment);
>>>>>>>>     try
>>>>>>>>     {
>>>>>>>>
>>>>>>>> Modified:
>>>>>>>>
>>>>>>>>
>>>>>>>> incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/ServiceRegistryContext.java
>>>>>>>> URL:
>>>>>>>>
>>>>>>>>
>>>>>>>> http://svn.apache.org/viewvc/incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/ServiceRegistryContext.java?rev=917809&r1=917808&r2=917809&view=diff
>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>> ==============================================================================
>>>>>>>> ---
>>>>>>>>
>>>>>>>>
>>>>>>>> incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/ServiceRegistryContext.java
>>>>>>>> (original)
>>>>>>>> +++
>>>>>>>>
>>>>>>>>
>>>>>>>> incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/ServiceRegistryContext.java
>>>>>>>> Mon Mar  1 23:53:18 2010
>>>>>>>> @@ -42,9 +42,9 @@
>>>>>>>>  {
>>>>>>>>  private static final String ARIES_SERVICES = "aries:services/";
>>>>>>>>  /** The name parser for the service registry name space */
>>>>>>>> -  private NameParser parser = new ServiceRegistryNameParser();
>>>>>>>> +  private NameParser parser = new OsgiNameParser();
>>>>>>>>  /** The environment for this context */
>>>>>>>> -  private Map<Object, Object> env;
>>>>>>>> +  private Map<String, Object> env;
>>>>>>>>    /**
>>>>>>>>  * Why Mr Java this class does indeed take a fine copy of the
>>>>>>>> provided
>>>>>>>> @@ -53,10 +53,11 @@
>>>>>>>>  *     * @param environment
>>>>>>>>  */
>>>>>>>> +  @SuppressWarnings("unchecked")
>>>>>>>>  public ServiceRegistryContext(Hashtable<?, ?> environment)
>>>>>>>>  {
>>>>>>>> -    env = new HashMap<Object, Object>();
>>>>>>>> -    env.putAll(environment);
>>>>>>>> +    env = new HashMap<String, Object>();
>>>>>>>> +    env.putAll((Map<? extends String, ? extends Object>)
>>>>>>>> environment);
>>>>>>>>  }
>>>>>>>>  public Object addToEnvironment(String propName, Object propVal)
>>>>>>>> throws
>>>>>>>> NamingException
>>>>>>>> @@ -153,7 +154,7 @@
>>>>>>>>  public NamingEnumeration<NameClassPair> list(final Name name)
>>>>>>>> throws
>>>>>>>> NamingException
>>>>>>>>  {
>>>>>>>> -    throw new NamingException("Not a Context");
>>>>>>>> +    return new ServiceRegistryListContext(env,
>>>>>>>> convert(name)).list("");
>>>>>>>>  }
>>>>>>>>  public NamingEnumeration<NameClassPair> list(String name) throws
>>>>>>>> NamingException
>>>>>>>> @@ -163,7 +164,7 @@
>>>>>>>>  public NamingEnumeration<Binding> listBindings(final Name name)
>>>>>>>> throws
>>>>>>>> NamingException
>>>>>>>>  {
>>>>>>>> -    throw new NamingException("Not a Context");
>>>>>>>> +    return new ServiceRegistryListContext(env,
>>>>>>>> convert(name)).listBindings("");
>>>>>>>>  }
>>>>>>>>  public NamingEnumeration<Binding> listBindings(String name) throws
>>>>>>>> NamingException
>>>>>>>> @@ -173,28 +174,43 @@
>>>>>>>>  public Object lookup(Name name) throws NamingException
>>>>>>>>  {
>>>>>>>> -    int nameSize = validateName(name);
>>>>>>>> -    String className = name.get(0);
>>>>>>>> -
>>>>>>>> -    String filter = null;
>>>>>>>> +    Object result;
>>>>>>>> +    +    OsgiName validName = convert(name);
>>>>>>>>   -    if (nameSize == 2) {
>>>>>>>> -      filter = name.get(1);
>>>>>>>> +    String pathFragment = validName.getSchemePath();
>>>>>>>> +    String serviceName = validName.getServiceName();
>>>>>>>> +    String schemeName = validName.getScheme();
>>>>>>>> +    +    if (OsgiName.FRAMEWORK_PATH.equals(pathFragment) &&
>>>>>>>> "bundleContext".equals(validName.getServiceName())) {
>>>>>>>> +      result = ServiceHelper.getBundleContext(env);
>>>>>>>> +    } else if ((OsgiName.SERVICE_PATH.equals(pathFragment) &&
>>>>>>>> OsgiName.OSGI_SCHEME.equals(schemeName)) ||
>>>>>>>> +               (OsgiName.SERVICES_PATH.equals(pathFragment) &&
>>>>>>>> OsgiName.ARIES_SCHEME.equals(schemeName))) {
>>>>>>>> +      result = ServiceHelper.getService(validName.getInterface(),
>>>>>>>> validName.getFilter(), serviceName, true, env);
>>>>>>>> +    } else if (OsgiName.SERVICE_LIST_PATH.equals(pathFragment)) {
>>>>>>>> +      result = new ServiceRegistryListContext(env, validName);
>>>>>>>> +    } else {
>>>>>>>> +      result = null;
>>>>>>>>   }
>>>>>>>>   -    try {
>>>>>>>> -      Object result = ServiceHelper.getService(className, filter);
>>>>>>>> -      -      if (result == null) {
>>>>>>>> -        throw new NameNotFoundException("We couldn't find an object
>>>>>>>> in
>>>>>>>> the registry matching the query " + name);
>>>>>>>> -      }
>>>>>>>> -      -      return result;
>>>>>>>> -    } catch (IllegalArgumentException e) {
>>>>>>>> -      NamingException ne = new NamingException(e.getMessage());
>>>>>>>> -      ne.initCause(e);
>>>>>>>> -      throw ne;
>>>>>>>> +    if (result == null) {
>>>>>>>> +      throw new NameNotFoundException(name.toString());
>>>>>>>> +    }
>>>>>>>> +    +    return result;
>>>>>>>> +  }
>>>>>>>> +
>>>>>>>> +  private OsgiName convert(Name name) throws InvalidNameException
>>>>>>>> +  {
>>>>>>>> +    OsgiName result;
>>>>>>>> +    +    if (name instanceof OsgiName) {
>>>>>>>> +      result = (OsgiName) name;
>>>>>>>> +    } else {
>>>>>>>> +      result = new OsgiName(name);
>>>>>>>>   }
>>>>>>>> +    +    return result;
>>>>>>>>  }
>>>>>>>>  public Object lookup(String name) throws NamingException
>>>>>>>> @@ -246,27 +262,4 @@
>>>>>>>>  {
>>>>>>>>   throw new OperationNotSupportedException();
>>>>>>>>  }
>>>>>>>> -  -  /**
>>>>>>>> -   * Check that the name conforms to the expected format
>>>>>>>> -   * @param name
>>>>>>>> -   * @return the size of the name
>>>>>>>> -   * @throws InvalidNameException
>>>>>>>> -   */
>>>>>>>> -  private int validateName(final Name name) throws
>>>>>>>> InvalidNameException
>>>>>>>> -  {
>>>>>>>> -    int nameSize = name.size();
>>>>>>>> -    if (nameSize == 0) {
>>>>>>>> -      throw new InvalidNameException("The provided name does not
>>>>>>>> have
>>>>>>>> any
>>>>>>>> components" + name);
>>>>>>>> -    } -    -    if ("aries:services".equals(name.get(0))) {
>>>>>>>> -      throw new InvalidNameException("The composite name should not
>>>>>>>> start
>>>>>>>> with aries:services");
>>>>>>>> -    }
>>>>>>>> -    -    if (nameSize > 2) {
>>>>>>>> -      throw new InvalidNameException("This JNDI context only
>>>>>>>> expects
>>>>>>>> 2
>>>>>>>> components, but it found " + nameSize);
>>>>>>>> -    }
>>>>>>>> -    return nameSize;
>>>>>>>> -  }
>>>>>>>>  }
>>>>>>>> \ No newline at end of file
>>>>>>>>
>>>>>>>> Added:
>>>>>>>>
>>>>>>>>
>>>>>>>> incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/ServiceRegistryListContext.java
>>>>>>>> URL:
>>>>>>>>
>>>>>>>>
>>>>>>>> http://svn.apache.org/viewvc/incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/ServiceRegistryListContext.java?rev=917809&view=auto
>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>> ==============================================================================
>>>>>>>> ---
>>>>>>>>
>>>>>>>>
>>>>>>>> incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/ServiceRegistryListContext.java
>>>>>>>> (added)
>>>>>>>> +++
>>>>>>>>
>>>>>>>>
>>>>>>>> incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/ServiceRegistryListContext.java
>>>>>>>> Mon Mar  1 23:53:18 2010
>>>>>>>> @@ -0,0 +1,197 @@
>>>>>>>> +/*
>>>>>>>> + * 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.aries.jndi.url;
>>>>>>>> +
>>>>>>>> +import java.util.HashMap;
>>>>>>>> +import java.util.Hashtable;
>>>>>>>> +import java.util.Map;
>>>>>>>> +
>>>>>>>> +import javax.naming.Binding;
>>>>>>>> +import javax.naming.Context;
>>>>>>>> +import javax.naming.Name;
>>>>>>>> +import javax.naming.NameClassPair;
>>>>>>>> +import javax.naming.NameParser;
>>>>>>>> +import javax.naming.NamingEnumeration;
>>>>>>>> +import javax.naming.NamingException;
>>>>>>>> +import javax.naming.OperationNotSupportedException;
>>>>>>>> +
>>>>>>>> +public class ServiceRegistryListContext implements Context
>>>>>>>> +{
>>>>>>>> +  private Map<String, Object> env;
>>>>>>>> +  /** The name parser for the service registry name space */
>>>>>>>> +  private NameParser parser = new OsgiNameParser();
>>>>>>>> +  +  public ServiceRegistryListContext(Map<String, Object> env,
>>>>>>>> OsgiName
>>>>>>>> validName)
>>>>>>>> +  {
>>>>>>>> +    this.env = new HashMap<String, Object>(env);
>>>>>>>> +  }
>>>>>>>> +
>>>>>>>> +  public Object addToEnvironment(String propName, Object propVal)
>>>>>>>> throws
>>>>>>>> NamingException
>>>>>>>> +  {
>>>>>>>> +    return env.put(propName, propVal);
>>>>>>>> +  }
>>>>>>>> +
>>>>>>>> +  public void bind(Name name, Object obj) throws NamingException
>>>>>>>> +  {
>>>>>>>> +    throw new OperationNotSupportedException();
>>>>>>>> +  }
>>>>>>>> +
>>>>>>>> +  public void bind(String name, Object obj) throws NamingException
>>>>>>>> +  {
>>>>>>>> +    throw new OperationNotSupportedException();
>>>>>>>> +  }
>>>>>>>> +
>>>>>>>> +  public void close() throws NamingException
>>>>>>>> +  {
>>>>>>>> +    env = null;
>>>>>>>> +    parser = null;
>>>>>>>> +  }
>>>>>>>> +
>>>>>>>> +  public Name composeName(Name name, Name prefix) throws
>>>>>>>> NamingException
>>>>>>>> +  {
>>>>>>>> +    // TODO Auto-generated method stub
>>>>>>>> +    return null;
>>>>>>>> +  }
>>>>>>>> +
>>>>>>>> +  public String composeName(String name, String prefix) throws
>>>>>>>> NamingException
>>>>>>>> +  {
>>>>>>>> +    // TODO Auto-generated method stub
>>>>>>>> +    return null;
>>>>>>>> +  }
>>>>>>>> +
>>>>>>>> +  public Context createSubcontext(Name name) throws NamingException
>>>>>>>> +  {
>>>>>>>> +    throw new OperationNotSupportedException();
>>>>>>>> +  }
>>>>>>>> +
>>>>>>>> +  public Context createSubcontext(String name) throws
>>>>>>>> NamingException
>>>>>>>> +  {
>>>>>>>> +    throw new OperationNotSupportedException();
>>>>>>>> +  }
>>>>>>>> +
>>>>>>>> +  public void destroySubcontext(Name name) throws NamingException
>>>>>>>> +  {
>>>>>>>> +    //No-op we don't support sub-contexts in our context
>>>>>>>> +  }
>>>>>>>> +
>>>>>>>> +  public void destroySubcontext(String name) throws NamingException
>>>>>>>> +  {
>>>>>>>> +    //No-op we don't support sub-contexts in our context
>>>>>>>> +  }
>>>>>>>> +
>>>>>>>> +  public Hashtable<?, ?> getEnvironment() throws NamingException
>>>>>>>> +  {
>>>>>>>> +    Hashtable<Object, Object> environment = new Hashtable<Object,
>>>>>>>> Object>();
>>>>>>>> +    environment.putAll(env);
>>>>>>>> +    return environment;
>>>>>>>> +  }
>>>>>>>> +
>>>>>>>> +  public String getNameInNamespace() throws NamingException
>>>>>>>> +  {
>>>>>>>> +    // TODO Auto-generated method stub
>>>>>>>> +    return null;
>>>>>>>> +  }
>>>>>>>> +
>>>>>>>> +  public NameParser getNameParser(Name name) throws NamingException
>>>>>>>> +  {
>>>>>>>> +    return parser;
>>>>>>>> +  }
>>>>>>>> +
>>>>>>>> +  public NameParser getNameParser(String name) throws
>>>>>>>> NamingException
>>>>>>>> +  {
>>>>>>>> +    return parser;
>>>>>>>> +  }
>>>>>>>> +
>>>>>>>> +  public NamingEnumeration<NameClassPair> list(Name name) throws
>>>>>>>> NamingException
>>>>>>>> +  {
>>>>>>>> +    return list(name.toString());
>>>>>>>> +  }
>>>>>>>> +
>>>>>>>> +  public NamingEnumeration<NameClassPair> list(String name) throws
>>>>>>>> NamingException
>>>>>>>> +  {
>>>>>>>> +    // TODO Auto-generated method stub
>>>>>>>> +    return null;
>>>>>>>> +  }
>>>>>>>> +
>>>>>>>> +  public NamingEnumeration<Binding> listBindings(Name name) throws
>>>>>>>> NamingException
>>>>>>>> +  {
>>>>>>>> +    return listBindings(name.toString());
>>>>>>>> +  }
>>>>>>>> +
>>>>>>>> +  public NamingEnumeration<Binding> listBindings(String name)
>>>>>>>> throws
>>>>>>>> NamingException
>>>>>>>> +  {
>>>>>>>> +    // TODO Auto-generated method stub
>>>>>>>> +    return null;
>>>>>>>> +  }
>>>>>>>> +
>>>>>>>> +  public Object lookup(Name name) throws NamingException
>>>>>>>> +  {
>>>>>>>> +    return lookup(name.toString());
>>>>>>>> +  }
>>>>>>>> +
>>>>>>>> +  public Object lookup(String name) throws NamingException
>>>>>>>> +  {
>>>>>>>> +    return null;
>>>>>>>> +  }
>>>>>>>> +
>>>>>>>> +  public Object lookupLink(Name name) throws NamingException
>>>>>>>> +  {
>>>>>>>> +    throw new OperationNotSupportedException();
>>>>>>>> +  }
>>>>>>>> +
>>>>>>>> +  public Object lookupLink(String name) throws NamingException
>>>>>>>> +  {
>>>>>>>> +    throw new OperationNotSupportedException();
>>>>>>>> +  }
>>>>>>>> +
>>>>>>>> +  public void rebind(Name name, Object obj) throws NamingException
>>>>>>>> +  {
>>>>>>>> +    throw new OperationNotSupportedException();
>>>>>>>> +  }
>>>>>>>> +
>>>>>>>> +  public void rebind(String name, Object obj) throws
>>>>>>>> NamingException
>>>>>>>> +  {
>>>>>>>> +    throw new OperationNotSupportedException();
>>>>>>>> +  }
>>>>>>>> +
>>>>>>>> +  public Object removeFromEnvironment(String propName) throws
>>>>>>>> NamingException
>>>>>>>> +  {
>>>>>>>> +    return env.remove(propName);
>>>>>>>> +  }
>>>>>>>> +
>>>>>>>> +  public void rename(Name oldName, Name newName) throws
>>>>>>>> NamingException
>>>>>>>> +  {
>>>>>>>> +    throw new OperationNotSupportedException();
>>>>>>>> +  }
>>>>>>>> +
>>>>>>>> +  public void rename(String oldName, String newName) throws
>>>>>>>> NamingException
>>>>>>>> +  {
>>>>>>>> +    throw new OperationNotSupportedException();
>>>>>>>> +  }
>>>>>>>> +
>>>>>>>> +  public void unbind(Name name) throws NamingException
>>>>>>>> +  {
>>>>>>>> +    throw new OperationNotSupportedException();
>>>>>>>> +  }
>>>>>>>> +
>>>>>>>> +  public void unbind(String name) throws NamingException
>>>>>>>> +  {
>>>>>>>> +    throw new OperationNotSupportedException();
>>>>>>>> +  }
>>>>>>>> +}
>>>>>>>> \ No newline at end of file
>>>>>>>>
>>>>>>>> Copied:
>>>>>>>>
>>>>>>>>
>>>>>>>> incubator/aries/trunk/jndi/jndi-url/src/test/java/org/apache/aries/jndi/url/OsgiNameParserTest.java
>>>>>>>> (from r917002,
>>>>>>>>
>>>>>>>>
>>>>>>>> incubator/aries/trunk/jndi/jndi-url/src/test/java/org/apache/aries/jndi/url/ServiceRegistryNameParserTest.java)
>>>>>>>> URL:
>>>>>>>>
>>>>>>>>
>>>>>>>> http://svn.apache.org/viewvc/incubator/aries/trunk/jndi/jndi-url/src/test/java/org/apache/aries/jndi/url/OsgiNameParserTest.java?p2=incubator/aries/trunk/jndi/jndi-url/src/test/java/org/apache/aries/jndi/url/OsgiNameParserTest.java&p1=incubator/aries/trunk/jndi/jndi-url/src/test/java/org/apache/aries/jndi/url/ServiceRegistryNameParserTest.java&r1=917002&r2=917809&rev=917809&view=diff
>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>> ==============================================================================
>>>>>>>> ---
>>>>>>>>
>>>>>>>>
>>>>>>>> incubator/aries/trunk/jndi/jndi-url/src/test/java/org/apache/aries/jndi/url/ServiceRegistryNameParserTest.java
>>>>>>>> (original)
>>>>>>>> +++
>>>>>>>>
>>>>>>>>
>>>>>>>> incubator/aries/trunk/jndi/jndi-url/src/test/java/org/apache/aries/jndi/url/OsgiNameParserTest.java
>>>>>>>> Mon Mar  1 23:53:18 2010
>>>>>>>> @@ -18,11 +18,11 @@
>>>>>>>>  */
>>>>>>>>  package org.apache.aries.jndi.url;
>>>>>>>>  -import static org.junit.Assert.assertNotNull;
>>>>>>>>  import static org.junit.Assert.assertEquals;
>>>>>>>> +import static org.junit.Assert.assertFalse;
>>>>>>>> +import static org.junit.Assert.assertTrue;
>>>>>>>>  import javax.naming.InvalidNameException;
>>>>>>>> -import javax.naming.Name;
>>>>>>>>  import javax.naming.NameParser;
>>>>>>>>  import javax.naming.NamingException;
>>>>>>>>  @@ -31,10 +31,10 @@
>>>>>>>>  /**
>>>>>>>>  * This is where we test the service registry name parser.
>>>>>>>>  */
>>>>>>>> -public class ServiceRegistryNameParserTest
>>>>>>>> +public class OsgiNameParserTest
>>>>>>>>  {
>>>>>>>>  /** The parser we are going to use for testing */
>>>>>>>> -  private NameParser parser = new ServiceRegistryNameParser();
>>>>>>>> +  private NameParser parser = new OsgiNameParser();
>>>>>>>>  /**
>>>>>>>>  * OK, so we check that we can call checkNames multiple times.
>>>>>>>> @@ -43,8 +43,14 @@
>>>>>>>>  @Test
>>>>>>>>  public void checkValidNames() throws NamingException
>>>>>>>>  {
>>>>>>>> -    checkName("aries:services/java.lang.Runnable/(a=b)");
>>>>>>>> -    checkName("aries:services/java.lang.Runnable");
>>>>>>>> +    checkName("aries","services","java.lang.Runnable","(a=b)");
>>>>>>>> +    checkName("aries","services","java.lang.Runnable");
>>>>>>>> +    checkName("osgi","service","java.lang.Runnable");
>>>>>>>> +    checkName("osgi","service","java.lang.Runnable", "(a=b)");
>>>>>>>> +    checkName("osgi","servicelist","java.lang.Runnable");
>>>>>>>> +    checkName("osgi","servicelist","java.lang.Runnable", "(a=b)");
>>>>>>>> +    checkName("osgi","servicelist","jdbc", "grok", "DataSource");
>>>>>>>> +    checkName("osgi", "framework", "bundleContext");
>>>>>>>>  }
>>>>>>>>    /**
>>>>>>>> @@ -54,7 +60,7 @@
>>>>>>>>  @Test(expected=InvalidNameException.class)
>>>>>>>>  public void checkOutsideNamespace() throws NamingException
>>>>>>>>  {
>>>>>>>> -    checkName("java:comp/env/jms/cf");
>>>>>>>> +    checkName("java","comp","env","jms","cf");
>>>>>>>>  }
>>>>>>>>    /**
>>>>>>>> @@ -64,7 +70,7 @@
>>>>>>>>  @Test(expected=InvalidNameException.class)
>>>>>>>>  public void checkMissingInterface() throws NamingException
>>>>>>>>  {
>>>>>>>> -    checkName("aries:services");
>>>>>>>> +    checkName("aries","services");
>>>>>>>>  }
>>>>>>>>    /**
>>>>>>>> @@ -75,20 +81,64 @@
>>>>>>>>  @Test(expected=InvalidNameException.class)
>>>>>>>>  public void checkMissingInterface2() throws NamingException
>>>>>>>>  {
>>>>>>>> -    checkName("aries:services/");
>>>>>>>> +    checkName("aries","services", "");
>>>>>>>>  }
>>>>>>>> -
>>>>>>>> -  /**
>>>>>>>> -   * This method parses the name and then makes sure what was
>>>>>>>> parsed
>>>>>>>> was
>>>>>>>> parsed
>>>>>>>> -   * correctly.
>>>>>>>> -   * -   * @param name
>>>>>>>> -   * @throws NamingException
>>>>>>>> -   */
>>>>>>>> -  private void checkName(String name) throws NamingException
>>>>>>>> +  +  @Test(expected=InvalidNameException.class)
>>>>>>>> +  public void checkIncorrectPath() throws NamingException
>>>>>>>> +  {
>>>>>>>> +    checkName("osgi", "services", "java.lang.Runnable"); +  }
>>>>>>>> +  +  @Test(expected=InvalidNameException.class)
>>>>>>>> +  public void checkIllegalPath() throws NamingException
>>>>>>>>  {
>>>>>>>> -    Name n = parser.parse(name);
>>>>>>>> -    assertNotNull("We got a null name back, which is not allowed.",
>>>>>>>> n);
>>>>>>>> -    assertEquals("The name's toString does not produce the original
>>>>>>>> value", name, n.toString());
>>>>>>>> +    checkName("osgi", "wibble", "java.lang.Runnable"); +  }
>>>>>>>> +  +  private void checkName(String scheme, String path, String ...
>>>>>>>> elements)
>>>>>>>> +    throws NamingException
>>>>>>>> +  {
>>>>>>>> +    StringBuilder builder = new StringBuilder();
>>>>>>>> +    StringBuilder serviceName = new StringBuilder();
>>>>>>>> +    +    builder.append(scheme);
>>>>>>>> +    builder.append(':');
>>>>>>>> +    builder.append(path);
>>>>>>>> +
>>>>>>>> +    if (elements.length > 0) {
>>>>>>>> +      builder.append('/');
>>>>>>>> +      +      for (String element : elements) {
>>>>>>>> +        serviceName.append(element);
>>>>>>>> +        serviceName.append('/');
>>>>>>>> +      }
>>>>>>>> +  +      serviceName.deleteCharAt(serviceName.length() - 1);
>>>>>>>> +      +      builder.append(serviceName);
>>>>>>>> +    }
>>>>>>>> +    +    OsgiName n = (OsgiName) parser.parse(builder.toString());
>>>>>>>> +    +    assertEquals(scheme, n.getScheme());
>>>>>>>> +    assertEquals(path, n.getSchemePath());
>>>>>>>> +    +    if (elements.length > 1) {
>>>>>>>> +      assertEquals(elements[0], n.getInterface());
>>>>>>>> +    }
>>>>>>>> +    +    if (elements.length == 1) {
>>>>>>>> +      assertFalse(n.hasFilter());
>>>>>>>> +    }
>>>>>>>> +    +    if (elements.length > 2) {
>>>>>>>> +      if (elements.length == 2) {
>>>>>>>> +        assertTrue(n.hasFilter());
>>>>>>>> +        assertEquals(elements[1], n.getFilter());
>>>>>>>> +      } else assertFalse(n.hasFilter());
>>>>>>>> +    }
>>>>>>>> +    +    assertEquals(serviceName.toString(), n.getServiceName());
>>>>>>>>  }
>>>>>>>>  }
>>>>>>>> \ No newline at end of file
>>>>>>>>
>>>>>>>> Modified:
>>>>>>>>
>>>>>>>>
>>>>>>>> incubator/aries/trunk/jndi/jndi-url/src/test/java/org/apache/aries/jndi/url/ServiceRegistryContextTest.java
>>>>>>>> URL:
>>>>>>>>
>>>>>>>>
>>>>>>>> http://svn.apache.org/viewvc/incubator/aries/trunk/jndi/jndi-url/src/test/java/org/apache/aries/jndi/url/ServiceRegistryContextTest.java?rev=917809&r1=917808&r2=917809&view=diff
>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>> ==============================================================================
>>>>>>>> ---
>>>>>>>>
>>>>>>>>
>>>>>>>> incubator/aries/trunk/jndi/jndi-url/src/test/java/org/apache/aries/jndi/url/ServiceRegistryContextTest.java
>>>>>>>> (original)
>>>>>>>> +++
>>>>>>>>
>>>>>>>>
>>>>>>>> incubator/aries/trunk/jndi/jndi-url/src/test/java/org/apache/aries/jndi/url/ServiceRegistryContextTest.java
>>>>>>>> Mon Mar  1 23:53:18 2010
>>>>>>>> @@ -21,7 +21,6 @@
>>>>>>>>  import static org.junit.Assert.assertEquals;
>>>>>>>>  import static org.junit.Assert.assertFalse;
>>>>>>>>  import static org.junit.Assert.assertNotNull;
>>>>>>>> -import static org.junit.Assert.assertSame;
>>>>>>>>  import static org.junit.Assert.assertTrue;
>>>>>>>>  import java.lang.reflect.Field;
>>>>>>>> @@ -37,6 +36,12 @@
>>>>>>>>  import javax.naming.NamingException;
>>>>>>>>  import javax.naming.spi.ObjectFactory;
>>>>>>>>  +import org.apache.aries.jndi.ContextHelper;
>>>>>>>> +import org.apache.aries.jndi.OSGiObjectFactoryBuilder;
>>>>>>>> +import org.apache.aries.mocks.BundleContextMock;
>>>>>>>> +import org.apache.aries.mocks.BundleMock;
>>>>>>>> +import org.apache.aries.unittest.mocks.MethodCall;
>>>>>>>> +import org.apache.aries.unittest.mocks.Skeleton;
>>>>>>>>  import org.junit.After;
>>>>>>>>  import org.junit.Before;
>>>>>>>>  import org.junit.Test;
>>>>>>>> @@ -47,22 +52,13 @@
>>>>>>>>  import org.osgi.framework.ServiceReference;
>>>>>>>>  import org.osgi.framework.ServiceRegistration;
>>>>>>>>  -import org.apache.aries.unittest.mocks.MethodCall;
>>>>>>>> -import org.apache.aries.unittest.mocks.Skeleton;
>>>>>>>> -import org.apache.aries.jndi.ContextHelper;
>>>>>>>> -import org.apache.aries.jndi.OSGiObjectFactoryBuilder;
>>>>>>>> -import org.apache.aries.jndi.services.ServiceHelper;
>>>>>>>> -import org.apache.aries.jndi.url.Activator;
>>>>>>>> -import org.apache.aries.mocks.BundleContextMock;
>>>>>>>> -import org.apache.aries.mocks.BundleMock;
>>>>>>>> -
>>>>>>>>  /**
>>>>>>>>  * Tests for our JNDI implementation for the service registry.
>>>>>>>>  */
>>>>>>>>  public class ServiceRegistryContextTest
>>>>>>>>  {
>>>>>>>>  /** The service we register by default */
>>>>>>>> -  private Thread service;
>>>>>>>> +  private Runnable service;
>>>>>>>>  /** The bundle context for the test */
>>>>>>>>  private BundleContext bc;
>>>>>>>>  /** The service registration for the service */
>>>>>>>> @@ -83,10 +79,7 @@
>>>>>>>>   new Activator().start(bc);
>>>>>>>>   new org.apache.aries.jndi.startup.Activator().start(bc);
>>>>>>>>   -    Field f = ServiceHelper.class.getDeclaredField("context");
>>>>>>>> -    f.setAccessible(true);
>>>>>>>> -    f.set(null, bc);
>>>>>>>> -    f = ContextHelper.class.getDeclaredField("context");
>>>>>>>> +    Field f = ContextHelper.class.getDeclaredField("context");
>>>>>>>>   f.setAccessible(true);
>>>>>>>>   f.set(null, bc);
>>>>>>>>   f = OSGiObjectFactoryBuilder.class.getDeclaredField("context");
>>>>>>>> @@ -94,7 +87,7 @@
>>>>>>>>   f.set(null, bc);
>>>>>>>>  -    service = new Thread();
>>>>>>>> +    service = Skeleton.newMock(Runnable.class);
>>>>>>>>        registerService(service);
>>>>>>>>  }
>>>>>>>> @@ -104,7 +97,7 @@
>>>>>>>>  *     * @param service2 The service to register.
>>>>>>>>  */
>>>>>>>> -  private void registerService(Thread service2)
>>>>>>>> +  private void registerService(Runnable service2)
>>>>>>>>  {
>>>>>>>>   ServiceFactory factory = Skeleton.newMock(ServiceFactory.class);
>>>>>>>>   Skeleton skel = Skeleton.getSkeleton(factory);
>>>>>>>> @@ -159,11 +152,13 @@
>>>>>>>>
>>>>>>>>
>>>>>>>>  Thread.currentThread().setContextClassLoader(mock.getClassLoader());
>>>>>>>>   -    Object s = ctx.lookup("aries:services/java.lang.Runnable");
>>>>>>>> +    Runnable s = (Runnable)
>>>>>>>> ctx.lookup("aries:services/java.lang.Runnable");
>>>>>>>>        assertNotNull("We didn't get a service back from our lookup
>>>>>>>> :(",
>>>>>>>> s);
>>>>>>>>   -    assertEquals("The SR did not return the object we expected",
>>>>>>>> service, s);
>>>>>>>> +    s.run();
>>>>>>>> +    +
>>>>>>>>  Skeleton.getSkeleton(service).assertCalledExactNumberOfTimes(new
>>>>>>>> MethodCall(Runnable.class, "run"), 1);
>>>>>>>>        Skeleton skel =
>>>>>>>> Skeleton.getSkeleton(mock.getBundleContext());
>>>>>>>>   @@ -173,7 +168,7 @@
>>>>>>>>
>>>>>>>>
>>>>>>>>  Thread.currentThread().setContextClassLoader(mock.getClassLoader());
>>>>>>>>  -    s = ctx.lookup("osgi:services/java.lang.Runnable");
>>>>>>>> +    s = (Runnable) ctx.lookup("osgi:service/java.lang.Runnable");
>>>>>>>>        // Check we have the packages set correctly
>>>>>>>>   @@ -181,10 +176,11 @@
>>>>>>>>        assertTrue(ctx.getEnvironment().containsValue(packages));
>>>>>>>>  -         assertNotNull("We didn't get a service back from our
>>>>>>>> lookup
>>>>>>>> :(", s);
>>>>>>>> +
>>>>>>>> +    s.run();
>>>>>>>>   -    assertEquals("The SR did not return the object we expected",
>>>>>>>> service, s);
>>>>>>>> +
>>>>>>>>  Skeleton.getSkeleton(service).assertCalledExactNumberOfTimes(new
>>>>>>>> MethodCall(Runnable.class, "run"), 2);
>>>>>>>>    skel = Skeleton.getSkeleton(mock.getBundleContext());
>>>>>>>>   skel.assertCalled(new MethodCall(BundleContext.class,
>>>>>>>> "getServiceReferences", "java.lang.Runnable", null));
>>>>>>>> @@ -201,15 +197,21 @@
>>>>>>>>  @Test
>>>>>>>>  public void jndiLookupWithFilter() throws NamingException
>>>>>>>>  {
>>>>>>>> +    BundleMock mock = new BundleMock("scooby.doo", new
>>>>>>>> Properties());
>>>>>>>> +    +
>>>>>>>>
>>>>>>>>  Thread.currentThread().setContextClassLoader(mock.getClassLoader());
>>>>>>>> +
>>>>>>>>   InitialContext ctx = new InitialContext();
>>>>>>>>        Object s =
>>>>>>>> ctx.lookup("aries:services/java.lang.Runnable/(rubbish=smelly)");
>>>>>>>>        assertNotNull("We didn't get a service back from our lookup
>>>>>>>> :(",
>>>>>>>> s);
>>>>>>>>   -    assertEquals("The SR did not return the object we expected",
>>>>>>>> service, s);
>>>>>>>> +    service.run();
>>>>>>>>   -    Skeleton.getSkeleton(bc).assertCalled(new
>>>>>>>> MethodCall(BundleContext.class, "getServiceReferences",
>>>>>>>> "java.lang.Runnable", "(rubbish=smelly)"));
>>>>>>>> +
>>>>>>>>  Skeleton.getSkeleton(service).assertCalledExactNumberOfTimes(new
>>>>>>>> MethodCall(Runnable.class, "run"), 1);
>>>>>>>> +
>>>>>>>> +    Skeleton.getSkeleton(mock.getBundleContext()).assertCalled(new
>>>>>>>> MethodCall(BundleContext.class, "getServiceReferences",
>>>>>>>> "java.lang.Runnable", "(rubbish=smelly)"));
>>>>>>>>  }
>>>>>>>>    /**
>>>>>>>> @@ -222,6 +224,11 @@
>>>>>>>>  public void testLookupWhenServiceHasBeenRemoved() throws
>>>>>>>> NamingException
>>>>>>>>  {
>>>>>>>>   reg.unregister();
>>>>>>>> +
>>>>>>>> +    BundleMock mock = new BundleMock("scooby.doo", new
>>>>>>>> Properties());
>>>>>>>> +    +
>>>>>>>>
>>>>>>>>  Thread.currentThread().setContextClassLoader(mock.getClassLoader());
>>>>>>>> +
>>>>>>>>   InitialContext ctx = new InitialContext();
>>>>>>>>        ctx.lookup("aries:services/java.lang.Runnable");
>>>>>>>> @@ -236,6 +243,10 @@
>>>>>>>>  @Test(expected=NameNotFoundException.class)
>>>>>>>>  public void testLookupForServiceWeNeverHad() throws NamingException
>>>>>>>>  {
>>>>>>>> +    BundleMock mock = new BundleMock("scooby.doo", new
>>>>>>>> Properties());
>>>>>>>> +    +
>>>>>>>>
>>>>>>>>  Thread.currentThread().setContextClassLoader(mock.getClassLoader());
>>>>>>>> +
>>>>>>>>   InitialContext ctx = new InitialContext();
>>>>>>>>        ctx.lookup("aries:services/java.lang.Integer");
>>>>>>>> @@ -271,14 +282,53 @@
>>>>>>>>  }
>>>>>>>>  @Test
>>>>>>>> +  public void checkProxyDynamism() throws NamingException
>>>>>>>> +  {
>>>>>>>> +    BundleMock mock = new BundleMock("scooby.doo", new
>>>>>>>> Properties());
>>>>>>>> +    +
>>>>>>>>
>>>>>>>>  Thread.currentThread().setContextClassLoader(mock.getClassLoader());
>>>>>>>> +
>>>>>>>> +    InitialContext ctx = new InitialContext();
>>>>>>>> +    +    String className = Runnable.class.getName();
>>>>>>>> +    +    Runnable t = Skeleton.newMock(Runnable.class);
>>>>>>>> +    Runnable t2 = Skeleton.newMock(Runnable.class);
>>>>>>>> +    +    // we don't want the default service
>>>>>>>> +    reg.unregister();
>>>>>>>> +    +    ServiceRegistration reg = bc.registerService(className, t,
>>>>>>>> null);
>>>>>>>> +    bc.registerService(className, t2, null);
>>>>>>>> +    +    Runnable r = (Runnable)
>>>>>>>> ctx.lookup("osgi:service/java.lang.Runnable");
>>>>>>>> +    +    r.run();
>>>>>>>> +    +    Skeleton.getSkeleton(t).assertCalledExactNumberOfTimes(new
>>>>>>>> MethodCall(Runnable.class, "run"), 1);
>>>>>>>> +    Skeleton.getSkeleton(t2).assertNotCalled(new
>>>>>>>> MethodCall(Runnable.class, "run"));
>>>>>>>> +    +    reg.unregister();
>>>>>>>> +    +    r.run();
>>>>>>>> +    +    Skeleton.getSkeleton(t).assertCalledExactNumberOfTimes(new
>>>>>>>> MethodCall(Runnable.class, "run"), 1);
>>>>>>>> +    Skeleton.getSkeleton(t2).assertCalledExactNumberOfTimes(new
>>>>>>>> MethodCall(Runnable.class, "run"), 1);
>>>>>>>> +  }  +
>>>>>>>> +  @Test
>>>>>>>>  public void checkServiceOrderObserved() throws NamingException
>>>>>>>>  {
>>>>>>>> +    BundleMock mock = new BundleMock("scooby.doo", new
>>>>>>>> Properties());
>>>>>>>> +    +
>>>>>>>>
>>>>>>>>  Thread.currentThread().setContextClassLoader(mock.getClassLoader());
>>>>>>>> +
>>>>>>>>   InitialContext ctx = new InitialContext();
>>>>>>>>        String className = Runnable.class.getName();
>>>>>>>>   -    Thread t = new Thread();
>>>>>>>> -    Thread t2 = new Thread();
>>>>>>>> +    Runnable t = Skeleton.newMock(Runnable.class);
>>>>>>>> +    Runnable t2 = Skeleton.newMock(Runnable.class);
>>>>>>>>        // we don't want the default service
>>>>>>>>   reg.unregister();
>>>>>>>> @@ -286,9 +336,12 @@
>>>>>>>>   ServiceRegistration reg = bc.registerService(className, t, null);
>>>>>>>>   ServiceRegistration reg2 = bc.registerService(className, t2,
>>>>>>>> null);
>>>>>>>>   -    Runnable r = (Runnable)
>>>>>>>> ctx.lookup("osgi:services/java.lang.Runnable");
>>>>>>>> +    Runnable r = (Runnable)
>>>>>>>> ctx.lookup("osgi:service/java.lang.Runnable");
>>>>>>>>   -    assertSame("The wrong runnable was returned", t, r);
>>>>>>>> +    r.run();
>>>>>>>> +    +    Skeleton.getSkeleton(t).assertCalledExactNumberOfTimes(new
>>>>>>>> MethodCall(Runnable.class, "run"), 1);
>>>>>>>> +    Skeleton.getSkeleton(t2).assertNotCalled(new
>>>>>>>> MethodCall(Runnable.class, "run"));
>>>>>>>>        reg.unregister();
>>>>>>>>   reg2.unregister();
>>>>>>>> @@ -296,12 +349,18 @@
>>>>>>>>   Hashtable<String, Object> props = new Hashtable<String, Object>();
>>>>>>>>   props.put(Constants.SERVICE_RANKING, 55);
>>>>>>>>   +    t = Skeleton.newMock(Runnable.class);
>>>>>>>> +    t2 = Skeleton.newMock(Runnable.class);
>>>>>>>> +
>>>>>>>>   reg = bc.registerService(className, t, null);
>>>>>>>>   reg2 = bc.registerService(className, t2, props);
>>>>>>>>   -    r = (Runnable)
>>>>>>>> ctx.lookup("osgi:services/java.lang.Runnable");
>>>>>>>> +    r = (Runnable) ctx.lookup("osgi:service/java.lang.Runnable");
>>>>>>>> +    +    r.run();
>>>>>>>>   -    assertSame("The wrong runnable was returned", t2, r);
>>>>>>>> +    Skeleton.getSkeleton(t).assertNotCalled(new
>>>>>>>> MethodCall(Runnable.class, "run"));
>>>>>>>> +    Skeleton.getSkeleton(t2).assertCalledExactNumberOfTimes(new
>>>>>>>> MethodCall(Runnable.class, "run"), 1);
>>>>>>>>  }
>>>>>>>>    /**
>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>> --
>>>>>>> Joe
>>>>>>>
>>>>>>
>>>>>>
>>>>>
>>>>
>>>
>>> --
>>> Joe
>>>
>>
>>
>>
>
>
> --
> Joe
>



-- 
Alasdair Nottingham
not@apache.org

Re: svn commit: r917809 - in /incubator/aries/trunk/jndi/jndi-url: ./ src/main/java/org/apache/aries/jndi/services/ src/main/java/org/apache/aries/jndi/url/ src/test/java/org/apache/aries/jndi/url/

Posted by Joe Bohn <jo...@gmail.com>.
This seemed to do the trick for Blog-Sample but for some reason I'm 
still getting very much the same failure with AriesTrader.  Perhaps it 
is related to AriesTrader's use of pax-web-jsp (and this seems to be 
coming from within a jsp) whereas Blog-Sample does not pull in this 
bundle or use JSPs?

Here is the stack trace for the CNFE:

[1945910404@qtp-1489647491-1 - 
/org.apache.aries.ariestrader.modules.ariestrader-web/config] DEBUG 
org.apache.aries.blueprint.container.ServiceRecipe - Calling listeners 
for initial service registration
java.lang.ClassNotFoundException: 
org.apache.aries.samples.ariestrader.api.TradeServicesManager
         at 
org.eclipse.osgi.internal.loader.BundleLoader.findClassInternal(BundleLoader.java:489)
         at 
org.eclipse.osgi.internal.loader.BundleLoader.findClass(BundleLoader.java:405)
         at 
org.eclipse.osgi.internal.loader.BundleLoader.findClass(BundleLoader.java:393)
         at 
org.eclipse.osgi.internal.baseadaptor.DefaultClassLoader.loadClass(DefaultClassLoader.java:105)
         at java.lang.ClassLoader.loadClass(ClassLoader.java:250)
         at 
org.eclipse.osgi.internal.loader.BundleLoader.loadClass(BundleLoader.java:321)
         at 
org.eclipse.osgi.framework.internal.core.BundleHost.loadClass(BundleHost.java:231)
         at 
org.eclipse.osgi.framework.internal.core.AbstractBundle.loadClass(AbstractBundle.java:1193)
         at 
org.apache.aries.jndi.services.ServiceHelper.getService(ServiceHelper.java:206)
         at 
org.apache.aries.jndi.url.ServiceRegistryContext.lookup(ServiceRegistryContext.java:189)
         at 
org.apache.aries.jndi.url.ServiceRegistryContext.lookup(ServiceRegistryContext.java:218)
         at 
org.apache.aries.jndi.DelegateContext.lookup(DelegateContext.java:160)
         at javax.naming.InitialContext.lookup(InitialContext.java:392)
         at 
org.apache.aries.samples.ariestrader.util.ServiceUtilities.getOSGIService(ServiceUtilities.java:60)
         at 
org.apache.aries.samples.ariestrader.util.ServiceUtilities.getOSGIService(ServiceUtilities.java:41)
         at 
org.apache.aries.samples.ariestrader.api.TradeServiceUtilities.getTradeServicesManager(TradeServiceUtilities.java:63)
         at org.apache.jsp.config_jsp._jspService(config_jsp.java:83)
         at 
org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:70)
         at javax.servlet.http.HttpServlet.service(HttpServlet.java:820)
         at 
org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:374)
         at 
org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:342)
         at 
org.apache.jasper.servlet.JspServlet.service(JspServlet.java:267)
         at javax.servlet.http.HttpServlet.service(HttpServlet.java:820)
         at 
org.ops4j.pax.web.jsp.JspServletWrapper$2.call(JspServletWrapper.java:132)
         at 
org.ops4j.pax.web.jsp.JspServletWrapper$2.call(JspServletWrapper.java:127)
         at 
org.ops4j.pax.swissbox.core.ContextClassLoaderUtils.doWithClassLoader(ContextClassLoaderUtils.java:60)
         at 
org.ops4j.pax.web.jsp.JspServletWrapper.service(JspServletWrapper.java:124)
         at 
org.mortbay.jetty.servlet.ServletHolder.handle(ServletHolder.java:502)
         at 
org.mortbay.jetty.servlet.ServletHandler.handle(ServletHandler.java:389)
         at 
org.ops4j.pax.web.service.jetty.internal.HttpServiceServletHandler.handle(HttpServiceServletHandler.java:64)
         at 
org.mortbay.jetty.servlet.SessionHandler.handle(SessionHandler.java:181)
         at 
org.mortbay.jetty.handler.ContextHandler.handle(ContextHandler.java:765)
         at 
org.ops4j.pax.web.service.jetty.internal.HttpServiceContext.handle(HttpServiceContext.java:111)
         at 
org.mortbay.jetty.servlet.Dispatcher.include(Dispatcher.java:192)
         at 
org.apache.aries.samples.ariestrader.web.TradeConfigServlet.doConfigDisplay(TradeConfigServlet.java:62)
         at 
org.apache.aries.samples.ariestrader.web.TradeConfigServlet.service(TradeConfigServlet.java:403)
         at javax.servlet.http.HttpServlet.service(HttpServlet.java:820)
         at 
org.mortbay.jetty.servlet.ServletHolder.handle(ServletHolder.java:502)
         at 
org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)
         at 
org.ops4j.pax.web.service.internal.WelcomeFilesFilter.doFilter(WelcomeFilesFilter.java:169)
         at 
org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1148)
         at 
org.mortbay.jetty.servlet.ServletHandler.handle(ServletHandler.java:387)
         at 
org.ops4j.pax.web.service.jetty.internal.HttpServiceServletHandler.handle(HttpServiceServletHandler.java:64)
         at 
org.mortbay.jetty.servlet.SessionHandler.handle(SessionHandler.java:181)
         at 
org.mortbay.jetty.handler.ContextHandler.handle(ContextHandler.java:765)
         at 
org.ops4j.pax.web.service.jetty.internal.HttpServiceContext.handle(HttpServiceContext.java:111)
         at 
org.ops4j.pax.web.service.jetty.internal.JettyServerHandlerCollection.handle(JettyServerHandlerCollection.java:64)
         at 
org.mortbay.jetty.handler.HandlerWrapper.handle(HandlerWrapper.java:152)
         at org.mortbay.jetty.Server.handle(Server.java:322)
         at 
org.mortbay.jetty.HttpConnection.handleRequest(HttpConnection.java:534)
         at 
org.mortbay.jetty.HttpConnection$RequestHandler.headerComplete(HttpConnection.java:864)
         at org.mortbay.jetty.HttpParser.parseNext(HttpParser.java:539)
         at org.mortbay.jetty.HttpParser.parseAvailable(HttpParser.java:212)
         at org.mortbay.jetty.HttpConnection.handle(HttpConnection.java:404)
         at 
org.mortbay.io.nio.SelectChannelEndPoint.run(SelectChannelEndPoint.java:409)
         at 
org.mortbay.thread.QueuedThreadPool$PoolThread.run(QueuedThreadPool.java:520)





Alasdair Nottingham wrote:
> Hi,
> 
> I just committed a fix. On a related note I see that the pax web guy's
> put a Thread context classloader on the thread, but it doesn't
> implement BundleReference. Does anyone know how we can raise this with
> them?
> 
> Thanks
> Alasdair
> 
> On 3 March 2010 14:16, Joe Bohn <jo...@gmail.com> wrote:
>> It looks like Blog-Sample is having the same issue and it doesn't use JSPs.
>>   Here's a similar stack trace from blog-sample:
>>
>> [1643210767@qtp-2131869628-0 -
>> /org.apache.aries.samples.blog-servlet/ViewBlog] DEBUG
>> org.apache.aries.blueprint.container.ServiceRecipe - Retrieving service for
>> bundle org.ops4j.pax.web.pax-web-jetty-bundle_0.7.2 [6] and service
>> registration
>> {org.apache.aries.samples.blog.api.BloggingService}={osgi.service.blueprint.compname=bloggingServiceComponent,
>> service.id=52}
>> java.lang.ClassNotFoundException:
>> org.apache.aries.samples.blog.api.BloggingService
>>        at
>> org.eclipse.osgi.internal.loader.BundleLoader.findClassInternal(BundleLoader.java:489)
>>        at
>> org.eclipse.osgi.internal.loader.BundleLoader.findClass(BundleLoader.java:405)
>>        at
>> org.eclipse.osgi.internal.loader.BundleLoader.findClass(BundleLoader.java:393)
>>        at
>> org.eclipse.osgi.internal.baseadaptor.DefaultClassLoader.loadClass(DefaultClassLoader.java:105)
>>        at java.lang.ClassLoader.loadClass(ClassLoader.java:250)
>>        at
>> org.eclipse.osgi.internal.loader.BundleLoader.loadClass(BundleLoader.java:321)
>>        at
>> org.eclipse.osgi.framework.internal.core.BundleHost.loadClass(BundleHost.java:231)
>>        at
>> org.eclipse.osgi.framework.internal.core.AbstractBundle.loadClass(AbstractBundle.java:1193)
>>        at
>> org.apache.aries.jndi.services.ServiceHelper.getService(ServiceHelper.java:210)
>>        at
>> org.apache.aries.jndi.url.ServiceRegistryContext.lookup(ServiceRegistryContext.java:189)
>>        at
>> org.apache.aries.jndi.url.ServiceRegistryContext.lookup(ServiceRegistryContext.java:218)
>>        at
>> org.apache.aries.jndi.DelegateContext.lookup(DelegateContext.java:160)
>>        at javax.naming.InitialContext.lookup(InitialContext.java:392)
>>        at
>> org.apache.aries.samples.blog.web.util.JNDIHelper.getBloggingService(JNDIHelper.java:33)
>>        at org.apache.aries.samples.blog.web.ViewBlog.doGet(ViewBlog.java:53)
>>        at javax.servlet.http.HttpServlet.service(HttpServlet.java:707)
>>        at javax.servlet.http.HttpServlet.service(HttpServlet.java:820)
>>        at
>> org.mortbay.jetty.servlet.ServletHolder.handle(ServletHolder.java:502)
>>        at
>> org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)
>>        at
>> org.ops4j.pax.web.service.internal.WelcomeFilesFilter.doFilter(WelcomeFilesFilter.java:169)
>>        at
>> org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1148)
>>        at
>> org.mortbay.jetty.servlet.ServletHandler.handle(ServletHandler.java:387)
>>        at
>> org.ops4j.pax.web.service.jetty.internal.HttpServiceServletHandler.handle(HttpServiceServletHandler.java:64)
>>        at
>> org.mortbay.jetty.servlet.SessionHandler.handle(SessionHandler.java:181)
>>        at
>> org.mortbay.jetty.handler.ContextHandler.handle(ContextHandler.java:765)
>>        at
>> org.ops4j.pax.web.service.jetty.internal.HttpServiceContext.handle(HttpServiceContext.java:111)
>>        at
>> org.ops4j.pax.web.service.jetty.internal.JettyServerHandlerCollection.handle(JettyServerHandlerCollection.java:64)
>>        at
>> org.mortbay.jetty.handler.HandlerWrapper.handle(HandlerWrapper.java:152)
>>        at org.mortbay.jetty.Server.handle(Server.java:322)
>>        at
>> org.mortbay.jetty.HttpConnection.handleRequest(HttpConnection.java:534)
>>        at
>> org.mortbay.jetty.HttpConnection$RequestHandler.headerComplete(HttpConnection.java:864)
>>        at org.mortbay.jetty.HttpParser.parseNext(HttpParser.java:539)
>>        at org.mortbay.jetty.HttpParser.parseAvailable(HttpParser.java:212)
>>        at org.mortbay.jetty.HttpConnection.handle(HttpConnection.java:404)
>>        at
>> org.mortbay.io.nio.SelectChannelEndPoint.run(SelectChannelEndPoint.java:409)
>>        at
>> org.mortbay.thread.QueuedThreadPool$PoolThread.run(QueuedThreadPool.java:520)
>>
>>
>> Joe Bohn wrote:
>>> And here's the thread context classloader before the lookup ...
>>>
>>>
>>> JasperClassLoader{bundleClassLoader=BundleClassLoader{bundle=org.apache.aries.ariestrader.modules.ariestrader-web_1.0.0.incubating-SNAPSHOT
>>> [35],parent=org.eclipse.osgi.internal.baseadaptor.DefaultClassLoader@78ecf608}}
>>>
>>>
>>> Joe
>>>
>>> Joe Bohn wrote:
>>>> Here's the stack trace for the CNFE.  I'll have to work on getting the
>>>> thread context classloader.
>>>>
>>>> [112793090@qtp-2020456228-2 -
>>>> /org.apache.aries.ariestrader.modules.ariestrader-web/config] DEBUG
>>>> org.apache.aries.blueprint.container.ServiceRecipe - Calling listeners for
>>>> initial service registration
>>>> java.lang.ClassNotFoundException:
>>>> org.apache.aries.samples.ariestrader.api.TradeServicesManager
>>>>        at
>>>> org.eclipse.osgi.internal.loader.BundleLoader.findClassInternal(BundleLoader.java:489)
>>>>        at
>>>> org.eclipse.osgi.internal.loader.BundleLoader.findClass(BundleLoader.java:405)
>>>>        at
>>>> org.eclipse.osgi.internal.loader.BundleLoader.findClass(BundleLoader.java:393)
>>>>        at
>>>> org.eclipse.osgi.internal.baseadaptor.DefaultClassLoader.loadClass(DefaultClassLoader.java:105)
>>>>        at java.lang.ClassLoader.loadClass(ClassLoader.java:250)
>>>>        at
>>>> org.eclipse.osgi.internal.loader.BundleLoader.loadClass(BundleLoader.java:321)
>>>>        at
>>>> org.eclipse.osgi.framework.internal.core.BundleHost.loadClass(BundleHost.java:231)
>>>>        at
>>>> org.eclipse.osgi.framework.internal.core.AbstractBundle.loadClass(AbstractBundle.java:1193)
>>>>        at
>>>> org.apache.aries.jndi.services.ServiceHelper.getService(ServiceHelper.java:210)
>>>>        at
>>>> org.apache.aries.jndi.url.ServiceRegistryContext.lookup(ServiceRegistryContext.java:189)
>>>>        at
>>>> org.apache.aries.jndi.url.ServiceRegistryContext.lookup(ServiceRegistryContext.java:218)
>>>>        at
>>>> org.apache.aries.jndi.DelegateContext.lookup(DelegateContext.java:160)
>>>>        at javax.naming.InitialContext.lookup(InitialContext.java:392)
>>>>        at
>>>> org.apache.aries.samples.ariestrader.util.ServiceUtilities.getOSGIService(ServiceUtilities.java:60)
>>>>        at
>>>> org.apache.aries.samples.ariestrader.util.ServiceUtilities.getOSGIService(ServiceUtilities.java:41)
>>>>        at
>>>> org.apache.aries.samples.ariestrader.api.TradeServiceUtilities.getTradeServicesManager(TradeServiceUtilities.java:63)
>>>>        at org.apache.jsp.config_jsp._jspService(config_jsp.java:86)
>>>>        at
>>>> org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:70)
>>>>        at javax.servlet.http.HttpServlet.service(HttpServlet.java:820)
>>>>        at
>>>> org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:374)
>>>>        at
>>>> org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:342)
>>>>        at
>>>> org.apache.jasper.servlet.JspServlet.service(JspServlet.java:267)
>>>>        at javax.servlet.http.HttpServlet.service(HttpServlet.java:820)
>>>>        at
>>>> org.ops4j.pax.web.jsp.JspServletWrapper$2.call(JspServletWrapper.java:132)
>>>>        at
>>>> org.ops4j.pax.web.jsp.JspServletWrapper$2.call(JspServletWrapper.java:127)
>>>>        at
>>>> org.ops4j.pax.swissbox.core.ContextClassLoaderUtils.doWithClassLoader(ContextClassLoaderUtils.java:60)
>>>>        at
>>>> org.ops4j.pax.web.jsp.JspServletWrapper.service(JspServletWrapper.java:124)
>>>>        at
>>>> org.mortbay.jetty.servlet.ServletHolder.handle(ServletHolder.java:502)
>>>>        at
>>>> org.mortbay.jetty.servlet.ServletHandler.handle(ServletHandler.java:389)
>>>>        at
>>>> org.ops4j.pax.web.service.jetty.internal.HttpServiceServletHandler.handle(HttpServiceServletHandler.java:64)
>>>>        at
>>>> org.mortbay.jetty.servlet.SessionHandler.handle(SessionHandler.java:181)
>>>>        at
>>>> org.mortbay.jetty.handler.ContextHandler.handle(ContextHandler.java:765)
>>>>        at
>>>> org.ops4j.pax.web.service.jetty.internal.HttpServiceContext.handle(HttpServiceContext.java:111)
>>>>        at
>>>> org.mortbay.jetty.servlet.Dispatcher.include(Dispatcher.java:192)
>>>>        at
>>>> org.apache.aries.samples.ariestrader.web.TradeConfigServlet.doConfigDisplay(TradeConfigServlet.java:62)
>>>>        at
>>>> org.apache.aries.samples.ariestrader.web.TradeConfigServlet.service(TradeConfigServlet.java:403)
>>>>        at javax.servlet.http.HttpServlet.service(HttpServlet.java:820)
>>>>        at
>>>> org.mortbay.jetty.servlet.ServletHolder.handle(ServletHolder.java:502)
>>>>        at
>>>> org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)
>>>>        at
>>>> org.ops4j.pax.web.service.internal.WelcomeFilesFilter.doFilter(WelcomeFilesFilter.java:169)
>>>>        at
>>>> org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1148)
>>>>        at
>>>> org.mortbay.jetty.servlet.ServletHandler.handle(ServletHandler.java:387)
>>>>        at
>>>> org.ops4j.pax.web.service.jetty.internal.HttpServiceServletHandler.handle(HttpServiceServletHandler.java:64)
>>>>        at
>>>> org.mortbay.jetty.servlet.SessionHandler.handle(SessionHandler.java:181)
>>>>        at
>>>> org.mortbay.jetty.handler.ContextHandler.handle(ContextHandler.java:765)
>>>>        at
>>>> org.ops4j.pax.web.service.jetty.internal.HttpServiceContext.handle(HttpServiceContext.java:111)
>>>>        at
>>>> org.ops4j.pax.web.service.jetty.internal.JettyServerHandlerCollection.handle(JettyServerHandlerCollection.java:64)
>>>>        at
>>>> org.mortbay.jetty.handler.HandlerWrapper.handle(HandlerWrapper.java:152)
>>>>        at org.mortbay.jetty.Server.handle(Server.java:322)
>>>>        at
>>>> org.mortbay.jetty.HttpConnection.handleRequest(HttpConnection.java:534)
>>>>        at
>>>> org.mortbay.jetty.HttpConnection$RequestHandler.headerComplete(HttpConnection.java:864)
>>>>        at org.mortbay.jetty.HttpParser.parseNext(HttpParser.java:539)
>>>>        at
>>>> org.mortbay.jetty.HttpParser.parseAvailable(HttpParser.java:212)
>>>>        at
>>>> org.mortbay.jetty.HttpConnection.handle(HttpConnection.java:404)
>>>>        at
>>>> org.mortbay.io.nio.SelectChannelEndPoint.run(SelectChannelEndPoint.java:409)
>>>>        at
>>>> org.mortbay.thread.QueuedThreadPool$PoolThread.run(QueuedThreadPool.java:520)
>>>>
>>>> Alasdair Nottingham wrote:
>>>>> Hi,
>>>>>
>>>>> Hmm, I suspect I am not correctly finding the appropriate
>>>>> BundleContext to use. That would explain the CNFE because we now proxy
>>>>> the services rather than returning the raw service. If it is being
>>>>> listed as being used by the pax-web jsp bundle that would explain
>>>>> things.
>>>>>
>>>>> Do you have a stack trace for the ClassNotFoundException? That might
>>>>> help to work out what went wrong.
>>>>>
>>>>> Also can you check the thread context classloader before the lookup?
>>>>>
>>>>> Thanks
>>>>> Alasdair
>>>>>
>>>>> On 2 March 2010 23:21, Joe Bohn <jo...@gmail.com> wrote:
>>>>>> I think there are some issues with this change.   I'll have to dig some
>>>>>> more
>>>>>> and post more details later (don't have time right now) ... but in
>>>>>> short I'm
>>>>>> seeing the following:
>>>>>>
>>>>>> - AriesTrader is behaving very badly after this change.
>>>>>> - From within a jsp we use jndi lookup to find an osgi service.
>>>>>> - After this change I get a failure in my jsp with a CNFE.   This
>>>>>> despite
>>>>>> the fact that I can see the package is imported on the web bundle and
>>>>>> appears to be wired correctly.
>>>>>> - Even more strange: I notice that the application service I was
>>>>>> looking for
>>>>>> is listed as being used by the pax-web jsp bundle.  So it seems like we
>>>>>> might be using the wrong bundle context at some point.
>>>>>>
>>>>>>
>>>>>> Joe
>>>>>>
>>>>>>
>>>>>>
>>>>>> not@apache.org wrote:
>>>>>>> Author: not
>>>>>>> Date: Mon Mar  1 23:53:18 2010
>>>>>>> New Revision: 917809
>>>>>>>
>>>>>>> URL: http://svn.apache.org/viewvc?rev=917809&view=rev
>>>>>>> Log:
>>>>>>> ARIES-128 Implement OSGi spec url lookup scheme
>>>>>>>
>>>>>>> Added:
>>>>>>>
>>>>>>>
>>>>>>>  incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/OsgiName.java
>>>>>>>     - copied, changed from r910238,
>>>>>>>
>>>>>>> incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/ServiceRegistryName.java
>>>>>>>
>>>>>>>
>>>>>>>  incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/OsgiNameParser.java
>>>>>>>     - copied, changed from r910238,
>>>>>>>
>>>>>>> incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/ServiceRegistryNameParser.java
>>>>>>>
>>>>>>>
>>>>>>>  incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/ServiceRegistryListContext.java
>>>>>>>
>>>>>>>
>>>>>>>  incubator/aries/trunk/jndi/jndi-url/src/test/java/org/apache/aries/jndi/url/OsgiNameParserTest.java
>>>>>>>     - copied, changed from r917002,
>>>>>>>
>>>>>>> incubator/aries/trunk/jndi/jndi-url/src/test/java/org/apache/aries/jndi/url/ServiceRegistryNameParserTest.java
>>>>>>> Removed:
>>>>>>>
>>>>>>>
>>>>>>>  incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/ServiceRegistryName.java
>>>>>>>
>>>>>>>
>>>>>>>  incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/ServiceRegistryNameParser.java
>>>>>>>
>>>>>>>
>>>>>>>  incubator/aries/trunk/jndi/jndi-url/src/test/java/org/apache/aries/jndi/url/ServiceHelperTest.java
>>>>>>>
>>>>>>>
>>>>>>>  incubator/aries/trunk/jndi/jndi-url/src/test/java/org/apache/aries/jndi/url/ServiceRegistryNameParserTest.java
>>>>>>> Modified:
>>>>>>>   incubator/aries/trunk/jndi/jndi-url/pom.xml
>>>>>>>
>>>>>>>
>>>>>>>  incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/services/ServiceHelper.java
>>>>>>>
>>>>>>>
>>>>>>>  incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/Activator.java
>>>>>>>
>>>>>>>
>>>>>>>  incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/OsgiURLContextFactory.java
>>>>>>>
>>>>>>>
>>>>>>>  incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/ServiceRegistryContext.java
>>>>>>>
>>>>>>>
>>>>>>>  incubator/aries/trunk/jndi/jndi-url/src/test/java/org/apache/aries/jndi/url/ServiceRegistryContextTest.java
>>>>>>>
>>>>>>> Modified: incubator/aries/trunk/jndi/jndi-url/pom.xml
>>>>>>> URL:
>>>>>>>
>>>>>>> http://svn.apache.org/viewvc/incubator/aries/trunk/jndi/jndi-url/pom.xml?rev=917809&r1=917808&r2=917809&view=diff
>>>>>>>
>>>>>>>
>>>>>>> ==============================================================================
>>>>>>> --- incubator/aries/trunk/jndi/jndi-url/pom.xml (original)
>>>>>>> +++ incubator/aries/trunk/jndi/jndi-url/pom.xml Mon Mar  1 23:53:18
>>>>>>> 2010
>>>>>>> @@ -33,6 +33,10 @@
>>>>>>>     <dependencies>
>>>>>>>      <dependency>
>>>>>>> +       <groupId>org.apache.aries</groupId>
>>>>>>> +       <artifactId>org.apache.aries.util</artifactId>
>>>>>>> +      </dependency>
>>>>>>> +      <dependency>
>>>>>>>          <groupId>org.osgi</groupId>
>>>>>>>          <artifactId>org.osgi.core</artifactId>
>>>>>>>          <scope>provided</scope>
>>>>>>>
>>>>>>> Modified:
>>>>>>>
>>>>>>> incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/services/ServiceHelper.java
>>>>>>> URL:
>>>>>>>
>>>>>>> http://svn.apache.org/viewvc/incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/services/ServiceHelper.java?rev=917809&r1=917808&r2=917809&view=diff
>>>>>>>
>>>>>>>
>>>>>>> ==============================================================================
>>>>>>> ---
>>>>>>>
>>>>>>> incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/services/ServiceHelper.java
>>>>>>> (original)
>>>>>>> +++
>>>>>>>
>>>>>>> incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/services/ServiceHelper.java
>>>>>>> Mon Mar  1 23:53:18 2010
>>>>>>> @@ -18,18 +18,30 @@
>>>>>>>  */
>>>>>>>  package org.apache.aries.jndi.services;
>>>>>>>  +import java.lang.reflect.InvocationHandler;
>>>>>>> +import java.lang.reflect.Method;
>>>>>>> +import java.lang.reflect.Proxy;
>>>>>>> +import java.security.AccessController;
>>>>>>> +import java.security.PrivilegedAction;
>>>>>>> +import java.util.ArrayList;
>>>>>>>  import java.util.Arrays;
>>>>>>>  import java.util.Comparator;
>>>>>>>  import java.util.HashSet;
>>>>>>>  import java.util.LinkedList;
>>>>>>>  import java.util.List;
>>>>>>> +import java.util.Map;
>>>>>>>  import java.util.Set;
>>>>>>>  import java.util.concurrent.ConcurrentHashMap;
>>>>>>>  import java.util.concurrent.ConcurrentMap;
>>>>>>>  +import javax.naming.NamingException;
>>>>>>> +
>>>>>>> +import org.apache.aries.util.BundleToClassLoaderAdapter;
>>>>>>> +import org.osgi.framework.Bundle;
>>>>>>>  import org.osgi.framework.BundleContext;
>>>>>>>  import org.osgi.framework.BundleReference;
>>>>>>>  import org.osgi.framework.InvalidSyntaxException;
>>>>>>> +import org.osgi.framework.ServiceException;
>>>>>>>  import org.osgi.framework.ServiceReference;
>>>>>>>  /**
>>>>>>> @@ -47,221 +59,206 @@
>>>>>>>  */
>>>>>>>  public final class ServiceHelper
>>>>>>>  {
>>>>>>> -  /** The bundle context used for service registry queries */
>>>>>>> -  private static BundleContext context;
>>>>>>> -  /** A cache of what service was returned last time the query was
>>>>>>> performed */
>>>>>>> -  private static ConcurrentMap<ServiceKey, Set<ServiceReference>>
>>>>>>> cache =
>>>>>>> new ConcurrentHashMap<ServiceKey, Set<ServiceReference>>();
>>>>>>> -
>>>>>>> -  public static void setBundleContext(BundleContext ctx)
>>>>>>> +  public static class StackFinder extends SecurityManager
>>>>>>>  {
>>>>>>> -    context = ctx;
>>>>>>> +    public Class<?>[] getClassContext()
>>>>>>> +    {
>>>>>>> +      return super.getClassContext();
>>>>>>> +    }
>>>>>>>  }
>>>>>>> -  -  /**
>>>>>>> -   * This class is used as the key into the cache. It holds
>>>>>>> information
>>>>>>> to identify -   * who performed the query, along with the className
>>>>>>> and
>>>>>>> filter used. The thread context
>>>>>>> -   * class loader is used in the key, so two different modules will
>>>>>>> potentially get different
>>>>>>> -   * services.
>>>>>>> -   */
>>>>>>> -  private static final class ServiceKey
>>>>>>> +
>>>>>>> +  private static class JNDIServiceDamper implements InvocationHandler
>>>>>>>  {
>>>>>>> -    /** The class loader of the invoking application */
>>>>>>> -    private ClassLoader classLoader;
>>>>>>> -    /** The name of the class being queried from the registry */
>>>>>>> -    private String className;
>>>>>>> -    /** the registry filter, this may be null */
>>>>>>> +    private BundleContext ctx;
>>>>>>> +    private ServicePair pair;
>>>>>>> +    private String interfaceName;
>>>>>>>    private String filter;
>>>>>>> -    /** The cached hashCode */
>>>>>>> -    private final int hashCode;
>>>>>>> -
>>>>>>> -    /**
>>>>>>> -     * Boring unimportant comment.
>>>>>>> -     * -     * @param cl
>>>>>>> -     * @param cn
>>>>>>> -     * @param f
>>>>>>> -     */
>>>>>>> -    public ServiceKey(ClassLoader cl, String cn, String f)
>>>>>>> +    private boolean dynamic;
>>>>>>> +    +    public JNDIServiceDamper(BundleContext context, String i,
>>>>>>> String
>>>>>>> f, ServicePair service, boolean d)
>>>>>>>    {
>>>>>>> -      classLoader = cl;
>>>>>>> -      className = cn;
>>>>>>> +      ctx = context;
>>>>>>> +      pair = service;
>>>>>>> +      interfaceName = i;
>>>>>>>      filter = f;
>>>>>>> -      -      int classNameHash = (className == null) ? 0 :
>>>>>>> className.hashCode();
>>>>>>> -      hashCode = System.identityHashCode(classLoader) * 1000003 +
>>>>>>> classNameHash;
>>>>>>> +      dynamic = d;
>>>>>>>    }
>>>>>>> -
>>>>>>> -    @Override
>>>>>>> -    public int hashCode()
>>>>>>> -    {
>>>>>>> -      return hashCode;
>>>>>>> -    }
>>>>>>> -
>>>>>>> -    @Override
>>>>>>> -    public boolean equals(Object other)
>>>>>>> +    +    public Object invoke(Object proxy, Method method, Object[]
>>>>>>> args)
>>>>>>> throws Throwable
>>>>>>>    {
>>>>>>> -      if (other == this) return true;
>>>>>>> -      if (other == null) return false;
>>>>>>> -
>>>>>>> -      if (other instanceof ServiceKey) {
>>>>>>> -        ServiceKey otherKey = (ServiceKey) other;
>>>>>>> -        if (hashCode != otherKey.hashCode) return false;
>>>>>>> -
>>>>>>> -        if (classLoader != otherKey.classLoader) return false;
>>>>>>> -        if (!!!comparePossiblyNullObjects(className,
>>>>>>> otherKey.className))
>>>>>>> return false;
>>>>>>> -        return comparePossiblyNullObjects(filter, otherKey.filter);
>>>>>>> -      }
>>>>>>> -
>>>>>>> -      return false;
>>>>>>> -    }
>>>>>>> -    -    /**
>>>>>>> -     * Compares two objects where one or other (or both) may be null.
>>>>>>> -     * -     * @param a the first object to compare.
>>>>>>> -     * @param b the second object to compare.
>>>>>>> -     * @return true if they are ==, both null or identity equals,
>>>>>>> false
>>>>>>> otherwise.
>>>>>>> -     */
>>>>>>> -    public boolean comparePossiblyNullObjects(Object a, Object b) {
>>>>>>> -      if (a == b) return true;
>>>>>>> -      else if (a == null) return false;
>>>>>>> -      else return a.equals(b);
>>>>>>> +      if (pair.ref.getBundle() == null) {
>>>>>>> +        if (dynamic) pair = findService(ctx, interfaceName, filter);
>>>>>>> +        else pair = null;
>>>>>>> +      }
>>>>>>> +      +      if (pair == null) {
>>>>>>> +        throw new ServiceException(interfaceName,
>>>>>>> ServiceException.UNREGISTERED);
>>>>>>> +      }
>>>>>>> +      +      return method.invoke(pair.service, args);
>>>>>>>    }
>>>>>>>  }
>>>>>>> -
>>>>>>> -  /**
>>>>>>> -   * This method is used to obtain a single instance of a desired
>>>>>>> service
>>>>>>> from the OSGi
>>>>>>> -   * service registry. If the filter and class name identify multiple
>>>>>>> services the first
>>>>>>> -   * one is returned. If no service is found null will be returned.
>>>>>>> -   * -   * @param className The class name used to register the
>>>>>>> desired
>>>>>>> service. If null is provided
>>>>>>> -   *                  then all services are eligible to be returned.
>>>>>>> -   * @param filter    An RFC 1960 query into the properties of the
>>>>>>> registered services. e.g.
>>>>>>> -   *                  (service.description=really useful)
>>>>>>> -   * @return          The desired service
>>>>>>> -   * -   * @throws IllegalArgumentException If the filter is not
>>>>>>> valid.
>>>>>>> See RFC 1960 to work out what -   *
>>>>>>>  it
>>>>>>> should be.
>>>>>>> -   */
>>>>>>> -  public static Object getService(String className, String filter)
>>>>>>> throws
>>>>>>> IllegalArgumentException
>>>>>>> +  +  private static class ServicePair
>>>>>>>  {
>>>>>>> -    Object service = null;
>>>>>>> -    try {
>>>>>>> -      BundleContext callerCtx = getBundleContext();
>>>>>>> -      ServiceReference[] refs =
>>>>>>> callerCtx.getServiceReferences(className,
>>>>>>> filter);
>>>>>>> -      -      if (refs != null) {
>>>>>>> -        // we need to sort the references returned in case they are
>>>>>>> out
>>>>>>> of order
>>>>>>> -        // we need to sort in the reverse natural order, services
>>>>>>> with
>>>>>>> higher -        // ranking or lower id should be processed first so
>>>>>>> should
>>>>>>> be earlier in the array.
>>>>>>> -        Arrays.sort(refs, new Comparator<ServiceReference>() {
>>>>>>> -          public int compare(ServiceReference o1, ServiceReference
>>>>>>> o2)
>>>>>>> -          {
>>>>>>> -            return o2.compareTo(o1);
>>>>>>> -          }
>>>>>>> -        });
>>>>>>> -        -        for (ServiceReference ref : refs) {
>>>>>>> -          List<Object> services = getServices(callerCtx, className,
>>>>>>> filter, ref);
>>>>>>> -          if (!!!services.isEmpty()) {
>>>>>>> -            service = services.get(0);
>>>>>>> -            break;
>>>>>>> -          }
>>>>>>> -        }
>>>>>>> -      }      -    } catch (InvalidSyntaxException e) {
>>>>>>> -      throw new IllegalArgumentException(e.getMessage(), e);
>>>>>>> -    }
>>>>>>> -    -    return service;
>>>>>>> +    private ServiceReference ref;
>>>>>>> +    private Object service;
>>>>>>>  }
>>>>>>>     /**
>>>>>>> -   * This method is used to obtain a list of service instances from
>>>>>>> the
>>>>>>> OSGi
>>>>>>> -   * service registry. If no service is found an empty list will be
>>>>>>> returned.
>>>>>>> -   * -   * @param className The class name used to register the
>>>>>>> desired
>>>>>>> service. If null is provided
>>>>>>> -   *                  then all services are eligible to be returned.
>>>>>>> -   * @param filter    An RFC 1960 query into the properties of the
>>>>>>> registered services. e.g.
>>>>>>> -   *                  (service.description=really useful)
>>>>>>> -   * @return          A list of matching services.
>>>>>>> -   * -   * @throws IllegalArgumentException If the filter is not
>>>>>>> valid.
>>>>>>> See RFC 1960 to work out what -   *
>>>>>>>  it
>>>>>>> should be.
>>>>>>> +   * @param env +   * @return the bundle context for the caller.
>>>>>>> +   * @throws NamingException     */
>>>>>>> -  public static List<?> getServices(String className, String filter)
>>>>>>> -      throws IllegalArgumentException
>>>>>>> +  public static BundleContext getBundleContext(Map<String, Object>
>>>>>>> env)
>>>>>>> throws NamingException
>>>>>>>  {
>>>>>>> -    List<Object> services;
>>>>>>> -    try {
>>>>>>> -      BundleContext callerCtx = getBundleContext();
>>>>>>> -      ServiceReference[] refs =
>>>>>>> callerCtx.getAllServiceReferences(className, filter);
>>>>>>> +    BundleContext result = null;
>>>>>>> +    +    Object bc = env.get("osgi.service.jndi.bundleContext");
>>>>>>> +    +    if (bc != null && bc instanceof BundleContext) result =
>>>>>>> (BundleContext) bc;
>>>>>>> +    else {
>>>>>>> +      ClassLoader cl = AccessController.doPrivileged(new
>>>>>>> PrivilegedAction<ClassLoader>() {
>>>>>>> +        public ClassLoader run()
>>>>>>> +        {
>>>>>>> +          return Thread.currentThread().getContextClassLoader();
>>>>>>> +        }
>>>>>>> +      });
>>>>>>>      -      services = getServices(callerCtx, className, filter,
>>>>>>> refs);
>>>>>>> -    } catch (InvalidSyntaxException e) {
>>>>>>> -      throw new IllegalArgumentException(e.getMessage(), e);
>>>>>>> +      result = getBundleContext(cl);
>>>>>>> +    }
>>>>>>> +    +    if (result == null) {
>>>>>>> +      StackTraceElement[] stackTrace =
>>>>>>> AccessController.doPrivileged(new
>>>>>>> PrivilegedAction<StackTraceElement[]>() {
>>>>>>> +        public StackTraceElement[] run()
>>>>>>> +        {
>>>>>>> +          return Thread.currentThread().getStackTrace();
>>>>>>> +        }
>>>>>>> +      });
>>>>>>> +      +      StackFinder finder = new StackFinder();
>>>>>>> +      Class<?>[] classStack = finder.getClassContext();
>>>>>>> +      +      boolean found = false;
>>>>>>> +      boolean foundLookup = false;
>>>>>>> +      int i = 0;
>>>>>>> +      for (; i < stackTrace.length && !!!found; i++) {
>>>>>>> +        if (!!!foundLookup &&
>>>>>>> "lookup".equals(stackTrace[i].getMethodName())) {
>>>>>>> +          foundLookup = true;
>>>>>>> +        } else if (foundLookup &&
>>>>>>> !!!(stackTrace[i].getClassName().startsWith("org.apache.aries.jndi")
>>>>>>> ||
>>>>>>> +
>>>>>>>  stackTrace[i].getClassName().startsWith("javax.naming"))) {
>>>>>>> +          found = true;
>>>>>>> +        }
>>>>>>> +      }
>>>>>>> +      +      if (found) {
>>>>>>> +        Set<Integer> classLoadersChecked = new HashSet<Integer>();
>>>>>>> +        for (; i < classStack.length && result == null; i++) {
>>>>>>> +          ClassLoader cl = classStack[i].getClassLoader();
>>>>>>> +          int hash = System.identityHashCode(cl);
>>>>>>> +          if (!!!classLoadersChecked.contains(hash)) {
>>>>>>> +            classLoadersChecked.add(hash);
>>>>>>> +            result = getBundleContext(cl);
>>>>>>> +          }
>>>>>>> +        }
>>>>>>> +        // Now we walk the stack looking for the BundleContext
>>>>>>> +      }
>>>>>>>    }
>>>>>>>    -    return services;
>>>>>>> +    if (result == null) throw new NamingException("Unable to find
>>>>>>> BundleContext");
>>>>>>> +    +    return result;
>>>>>>>  }
>>>>>>> -  -  /**
>>>>>>> -   * @return the bundle context for the caller.
>>>>>>> -   */
>>>>>>> -  private static BundleContext getBundleContext()
>>>>>>> +
>>>>>>> +  private static BundleContext getBundleContext(ClassLoader cl)
>>>>>>>  {
>>>>>>>    BundleContext result = null;
>>>>>>> -    ClassLoader cl = Thread.currentThread().getContextClassLoader();
>>>>>>>    while (result == null && cl != null) {
>>>>>>>      if (cl instanceof BundleReference) {
>>>>>>>        result = ((BundleReference)cl).getBundle().getBundleContext();
>>>>>>>      } else if (cl != null) {
>>>>>>>        cl = cl.getParent();
>>>>>>>      }
>>>>>>> -    } +    }
>>>>>>>    -    if (result == null) result = context;
>>>>>>>    return result;
>>>>>>>  }
>>>>>>>  -  /**
>>>>>>> -   * This worker method obtains the requested service(s) and if the
>>>>>>> service(s) -   * exist updates the cache and releases the previous
>>>>>>> service(s).
>>>>>>> -   * -   * @param callerCtx The caller context.
>>>>>>> -   * @param className The class name used to query for the service.
>>>>>>> -   * @param filter    The filter name used to query for the service.
>>>>>>> -   * @param refs      The references to get.
>>>>>>> -   * @return          The service, if one was found, or null.
>>>>>>> -   */
>>>>>>> -  private static List<Object> getServices(BundleContext callerCtx,
>>>>>>> String
>>>>>>> className, String filter, ServiceReference...refs)
>>>>>>> +  public static Object getService(String interface1, String filter,
>>>>>>> String serviceName, boolean dynamicRebind, Map<String, Object> env)
>>>>>>> throws
>>>>>>> NamingException
>>>>>>>  {
>>>>>>> -    List<Object> data = new LinkedList<Object>();
>>>>>>> +    Object result = null;
>>>>>>> +    +    BundleContext ctx = getBundleContext(env);
>>>>>>> +    +    ServicePair pair = findService(ctx, interface1, filter);
>>>>>>>    -    if (refs != null) {
>>>>>>> -      Set<ServiceReference> refSet = new HashSet<ServiceReference>();
>>>>>>> -      for (ServiceReference ref : refs) {
>>>>>>> -        Object service = callerCtx.getService(ref);
>>>>>>> -        if (service != null) {
>>>>>>> -          data.add(service);
>>>>>>> -          refSet.add(ref);
>>>>>>> +    if (pair == null) {
>>>>>>> +      interface1 = null;
>>>>>>> +      filter = "(osgi.jndi.serviceName=" + serviceName + ")";
>>>>>>> +      pair = findService(ctx, interface1, filter);
>>>>>>> +    }
>>>>>>> +    +    if (pair != null) {
>>>>>>> +      String[] interfaces = (String[])
>>>>>>> pair.ref.getProperty("objectClass");
>>>>>>> +      +      List<Class<?>> clazz = new
>>>>>>> ArrayList<Class<?>>(interfaces.length);
>>>>>>> +      +      Bundle b = ctx.getBundle();
>>>>>>> +      +      for (String interfaceName : interfaces) {
>>>>>>> +        try {
>>>>>>> +          clazz.add(b.loadClass(interfaceName));
>>>>>>> +        } catch (ClassNotFoundException e) {
>>>>>>> +          // TODO Auto-generated catch block
>>>>>>> +          e.printStackTrace();
>>>>>>>        }
>>>>>>>      }
>>>>>>>      -      ClassLoader cl =
>>>>>>> Thread.currentThread().getContextClassLoader();
>>>>>>> -      ServiceKey key = new ServiceKey(cl, className, filter);
>>>>>>> +      if (clazz.isEmpty()) {
>>>>>>> +        throw new IllegalArgumentException();
>>>>>>> +      }
>>>>>>>      -      // we do not need any synchronization around this. The map
>>>>>>> is
>>>>>>> concurrent
>>>>>>> -      // and until here we do not touch any shared state.
>>>>>>> -      refSet = cache.put(key, refSet);
>>>>>>> +      InvocationHandler ih = new JNDIServiceDamper(ctx, interface1,
>>>>>>> filter, pair, dynamicRebind);
>>>>>>>      -      if (refSet != null) {
>>>>>>> -        for (ServiceReference ref : refSet) {
>>>>>>> -          callerCtx.ungetService(ref);
>>>>>>> +      result = Proxy.newProxyInstance(new
>>>>>>> BundleToClassLoaderAdapter(b),
>>>>>>> clazz.toArray(new Class<?>[clazz.size()]), ih);
>>>>>>> +    }
>>>>>>> +    +    return result;
>>>>>>> +  }
>>>>>>> +
>>>>>>> +  private static ServicePair findService(BundleContext ctx, String
>>>>>>> interface1, String filter)
>>>>>>> +  {
>>>>>>> +    ServicePair p = null;
>>>>>>> +    +    try {
>>>>>>> +      ServiceReference[] refs = ctx.getServiceReferences(interface1,
>>>>>>> filter);
>>>>>>> +      +      if (refs != null) {
>>>>>>> +        // natural order is the exact opposite of the order we
>>>>>>> desire.
>>>>>>> +        Arrays.sort(refs, new Comparator<ServiceReference>() {
>>>>>>> +          public int compare(ServiceReference o1, ServiceReference
>>>>>>> o2)
>>>>>>> +          {
>>>>>>> +            return o2.compareTo(o1);
>>>>>>> +          }
>>>>>>> +        });
>>>>>>> +        +        for (ServiceReference ref : refs) {
>>>>>>> +          Object service = ctx.getService(ref);
>>>>>>> +          +          if (service != null) {
>>>>>>> +            p = new ServicePair();
>>>>>>> +            p.ref = ref;
>>>>>>> +            p.service = service;
>>>>>>> +            break;
>>>>>>> +          }
>>>>>>>        }
>>>>>>>      }
>>>>>>> +      +    } catch (InvalidSyntaxException e) {
>>>>>>> +      // TODO Auto-generated catch block
>>>>>>> +      e.printStackTrace();
>>>>>>>    }
>>>>>>>    -    return data;
>>>>>>> +    return p;
>>>>>>>  }
>>>>>>>  }
>>>>>>>
>>>>>>> Modified:
>>>>>>>
>>>>>>> incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/Activator.java
>>>>>>> URL:
>>>>>>>
>>>>>>> http://svn.apache.org/viewvc/incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/Activator.java?rev=917809&r1=917808&r2=917809&view=diff
>>>>>>>
>>>>>>>
>>>>>>> ==============================================================================
>>>>>>> ---
>>>>>>>
>>>>>>> incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/Activator.java
>>>>>>> (original)
>>>>>>> +++
>>>>>>>
>>>>>>> incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/Activator.java
>>>>>>> Mon Mar  1 23:53:18 2010
>>>>>>> @@ -34,8 +34,6 @@
>>>>>>>
>>>>>>>  public void start(BundleContext context)
>>>>>>>  {
>>>>>>> -    ServiceHelper.setBundleContext(context);
>>>>>>> -         Hashtable<Object, Object> props = new Hashtable<Object,
>>>>>>> Object>();
>>>>>>>    props.put("osgi.jndi.urlScheme", new String[] {"osgi", "aries"} );
>>>>>>>    reg = context.registerService(ObjectFactory.class.getName(), new
>>>>>>> OsgiURLContextFactory(), props);
>>>>>>>
>>>>>>> Copied:
>>>>>>>
>>>>>>> incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/OsgiName.java
>>>>>>> (from r910238,
>>>>>>>
>>>>>>> incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/ServiceRegistryName.java)
>>>>>>> URL:
>>>>>>>
>>>>>>> http://svn.apache.org/viewvc/incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/OsgiName.java?p2=incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/OsgiName.java&p1=incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/ServiceRegistryName.java&r1=910238&r2=917809&rev=917809&view=diff
>>>>>>>
>>>>>>>
>>>>>>> ==============================================================================
>>>>>>> ---
>>>>>>>
>>>>>>> incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/ServiceRegistryName.java
>>>>>>> (original)
>>>>>>> +++
>>>>>>>
>>>>>>> incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/OsgiName.java
>>>>>>> Mon Mar  1 23:53:18 2010
>>>>>>> @@ -21,28 +21,104 @@
>>>>>>>  import java.util.Enumeration;
>>>>>>>  import javax.naming.CompositeName;
>>>>>>> +import javax.naming.InvalidNameException;
>>>>>>> +import javax.naming.Name;
>>>>>>>  /**
>>>>>>> - * A composite name for the aries namespace. We only have this so
>>>>>>> that we
>>>>>>> can
>>>>>>> - * provide a nicer toString()
>>>>>>> + * A composite name for the aries namespace. This provides useful
>>>>>>> utility
>>>>>>> methods
>>>>>>> + * for accessing the name.
>>>>>>> + * + * component 0: osgi:service, aries:services, osgi:servicelist
>>>>>>> + * component 1: interface
>>>>>>> + * component 2: filter
>>>>>>>  */
>>>>>>> -public final class ServiceRegistryName extends CompositeName
>>>>>>> +public final class OsgiName extends CompositeName
>>>>>>>  {
>>>>>>>  /** The serial version UID */
>>>>>>>  private static final long serialVersionUID = 6617580228852444656L;
>>>>>>> +  public static final String OSGI_SCHEME = "osgi";
>>>>>>> +  public static final String ARIES_SCHEME = "aries";
>>>>>>> +  public static final String SERVICE_PATH = "service";
>>>>>>> +  public static final String SERVICES_PATH = "services";
>>>>>>> +  public static final String SERVICE_LIST_PATH = "servicelist";
>>>>>>> +  public static final String FRAMEWORK_PATH = "framework";
>>>>>>>  -  @Override
>>>>>>> -  public String toString()
>>>>>>> +  public OsgiName(String name) throws InvalidNameException
>>>>>>>  {
>>>>>>> -    StringBuilder buffer = new StringBuilder();
>>>>>>> +    super(name);
>>>>>>> +  }
>>>>>>> +
>>>>>>> +  public OsgiName(Name name) throws InvalidNameException
>>>>>>> +  {
>>>>>>> +    this(name.toString());
>>>>>>> +  }
>>>>>>> +
>>>>>>> +  public boolean hasFilter()
>>>>>>> +  {
>>>>>>> +    return size() == 3;
>>>>>>> +  }
>>>>>>> +  +  public boolean isServiceNameBased()
>>>>>>> +  {
>>>>>>> +    return size() > 3;
>>>>>>> +  }
>>>>>>> +  +  public String getScheme()
>>>>>>> +  {
>>>>>>> +    String part0 = get(0);
>>>>>>> +    int index = part0.indexOf(':');
>>>>>>> +    +    String result;
>>>>>>> +    +    if (index > 0) {
>>>>>>> +      result = part0.substring(0, index);
>>>>>>> +    } else {
>>>>>>> +      result = null;
>>>>>>> +    }
>>>>>>> +    +    return result;
>>>>>>> +  }
>>>>>>> +  +  public String getSchemePath()
>>>>>>> +  {
>>>>>>> +    String part0 = get(0);
>>>>>>> +    int index = part0.indexOf(':');
>>>>>>> +    +    String result;
>>>>>>>    -    buffer.append("aries:services");
>>>>>>> -    Enumeration<String> components = getAll();
>>>>>>> -    while (components.hasMoreElements()) {
>>>>>>> -      buffer.append('/');
>>>>>>> -      buffer.append(components.nextElement());
>>>>>>> +    if (index > 0) {
>>>>>>> +      result = part0.substring(index + 1);
>>>>>>> +    } else {
>>>>>>> +      result = null;
>>>>>>>    }
>>>>>>>    -    return buffer.toString();
>>>>>>> +    return result;
>>>>>>> +  }
>>>>>>> +  +  public String getInterface()
>>>>>>> +  {
>>>>>>> +    return get(1);
>>>>>>> +  }
>>>>>>> +  +  public String getFilter()
>>>>>>> +  {
>>>>>>> +    return hasFilter() ? get(2) : null;
>>>>>>> +  }
>>>>>>> +  +  public String getServiceName()
>>>>>>> +  {
>>>>>>> +    Enumeration<String> parts = getAll();
>>>>>>> +    parts.nextElement();
>>>>>>> +    +    StringBuilder builder = new StringBuilder();
>>>>>>> +    +    while (parts.hasMoreElements()) {
>>>>>>> +      builder.append(parts.nextElement());
>>>>>>> +      builder.append('/');
>>>>>>> +    }
>>>>>>> +    +    builder.deleteCharAt(builder.length() - 1);
>>>>>>> +    +    return builder.toString();
>>>>>>>  }
>>>>>>>  }
>>>>>>> \ No newline at end of file
>>>>>>>
>>>>>>> Copied:
>>>>>>>
>>>>>>> incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/OsgiNameParser.java
>>>>>>> (from r910238,
>>>>>>>
>>>>>>> incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/ServiceRegistryNameParser.java)
>>>>>>> URL:
>>>>>>>
>>>>>>> http://svn.apache.org/viewvc/incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/OsgiNameParser.java?p2=incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/OsgiNameParser.java&p1=incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/ServiceRegistryNameParser.java&r1=910238&r2=917809&rev=917809&view=diff
>>>>>>>
>>>>>>>
>>>>>>> ==============================================================================
>>>>>>> ---
>>>>>>>
>>>>>>> incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/ServiceRegistryNameParser.java
>>>>>>> (original)
>>>>>>> +++
>>>>>>>
>>>>>>> incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/OsgiNameParser.java
>>>>>>> Mon Mar  1 23:53:18 2010
>>>>>>> @@ -26,31 +26,40 @@
>>>>>>>  /**
>>>>>>>  * A parser for the aries namespace
>>>>>>>  */
>>>>>>> -public final class ServiceRegistryNameParser implements NameParser
>>>>>>> +public final class OsgiNameParser implements NameParser
>>>>>>>  {
>>>>>>> -
>>>>>>> +  private static final String OSGI_SCHEME = "osgi";
>>>>>>> +  private static final String ARIES_SCHEME = "aries";
>>>>>>> +  private static final String SERVICE_PATH = "service";
>>>>>>> +  private static final String SERVICES_PATH = "services";
>>>>>>> +  private static final String SERVICE_LIST_PATH = "servicelist";
>>>>>>> +  private static final String FRAMEWORK_PATH = "framework";
>>>>>>> +     public Name parse(String name) throws NamingException
>>>>>>>  {
>>>>>>> -    if (!!!name.startsWith("aries:services/") &&
>>>>>>> -        !!!name.startsWith("osgi:services/")) throw new
>>>>>>> InvalidNameException("The JNDI name did not start with aries:, or
>>>>>>> osgi:");
>>>>>>> +    OsgiName result = new OsgiName(name);
>>>>>>> +    +    if (result.size() < 2) throw new InvalidNameException(name);
>>>>>>>    -    name = name.substring(name.indexOf('/') + 1);
>>>>>>> +    String urlScheme = result.getScheme();
>>>>>>> +    String schemePath = result.getSchemePath();
>>>>>>>    -    int slashIndex = name.indexOf('/');
>>>>>>> -    String interfaceName = name;
>>>>>>> -    String filter = null;
>>>>>>> -    -    if (slashIndex != -1) {
>>>>>>> -      interfaceName = name.substring(0, slashIndex);
>>>>>>> -      filter = name.substring(slashIndex + 1);
>>>>>>> +    if (!!!(OSGI_SCHEME.equals(urlScheme) ||
>>>>>>> ARIES_SCHEME.equals(urlScheme))) {
>>>>>>> +      throw new InvalidNameException(name);
>>>>>>>    }
>>>>>>>    -    if (interfaceName.length() == 0) throw new
>>>>>>> InvalidNameException("No interface name was specified");
>>>>>>> +    if (ARIES_SCHEME.equals(urlScheme) &&
>>>>>>> !!!SERVICES_PATH.equals(schemePath)) {
>>>>>>> +      throw new InvalidNameException(name);
>>>>>>> +    }
>>>>>>> +    +    if (OSGI_SCHEME.equals(urlScheme) && !!!(
>>>>>>> SERVICE_PATH.equals(schemePath) || +
>>>>>>>     SERVICE_LIST_PATH.equals(schemePath) || +
>>>>>>>               FRAMEWORK_PATH.equals(schemePath))) {
>>>>>>> +      throw new InvalidNameException(name);
>>>>>>> +    }
>>>>>>>    -    Name result = new ServiceRegistryName();
>>>>>>> -    result.add(interfaceName);
>>>>>>> -    if (filter != null) {
>>>>>>> -      result.add(filter);
>>>>>>> +    if (result.getInterface() == null ||
>>>>>>> result.getInterface().length()
>>>>>>> == 0) {
>>>>>>> +      throw new InvalidNameException(name);
>>>>>>>    }
>>>>>>>         return result;
>>>>>>> @@ -59,7 +68,7 @@
>>>>>>>  @Override
>>>>>>>  public boolean equals(Object other)
>>>>>>>  {
>>>>>>> -    return other instanceof ServiceRegistryNameParser;
>>>>>>> +    return other instanceof OsgiNameParser;
>>>>>>>  }
>>>>>>>     @Override
>>>>>>>
>>>>>>> Modified:
>>>>>>>
>>>>>>> incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/OsgiURLContextFactory.java
>>>>>>> URL:
>>>>>>>
>>>>>>> http://svn.apache.org/viewvc/incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/OsgiURLContextFactory.java?rev=917809&r1=917808&r2=917809&view=diff
>>>>>>>
>>>>>>>
>>>>>>> ==============================================================================
>>>>>>> ---
>>>>>>>
>>>>>>> incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/OsgiURLContextFactory.java
>>>>>>> (original)
>>>>>>> +++
>>>>>>>
>>>>>>> incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/OsgiURLContextFactory.java
>>>>>>> Mon Mar  1 23:53:18 2010
>>>>>>> @@ -49,7 +49,7 @@
>>>>>>>    } else if (obj instanceof String[]) {
>>>>>>>      // Try each URL until either lookup succeeds or they all fail
>>>>>>>      String[] urls = (String[])obj;
>>>>>>> -      if (urls.length == 0) throw new
>>>>>>> ConfigurationException("ariesURLContextFactory: empty URL array");
>>>>>>> +      if (urls.length == 0) throw new ConfigurationException("0");
>>>>>>>      Context context = new ServiceRegistryContext(environment);
>>>>>>>      try
>>>>>>>      {
>>>>>>>
>>>>>>> Modified:
>>>>>>>
>>>>>>> incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/ServiceRegistryContext.java
>>>>>>> URL:
>>>>>>>
>>>>>>> http://svn.apache.org/viewvc/incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/ServiceRegistryContext.java?rev=917809&r1=917808&r2=917809&view=diff
>>>>>>>
>>>>>>>
>>>>>>> ==============================================================================
>>>>>>> ---
>>>>>>>
>>>>>>> incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/ServiceRegistryContext.java
>>>>>>> (original)
>>>>>>> +++
>>>>>>>
>>>>>>> incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/ServiceRegistryContext.java
>>>>>>> Mon Mar  1 23:53:18 2010
>>>>>>> @@ -42,9 +42,9 @@
>>>>>>>  {
>>>>>>>  private static final String ARIES_SERVICES = "aries:services/";
>>>>>>>  /** The name parser for the service registry name space */
>>>>>>> -  private NameParser parser = new ServiceRegistryNameParser();
>>>>>>> +  private NameParser parser = new OsgiNameParser();
>>>>>>>  /** The environment for this context */
>>>>>>> -  private Map<Object, Object> env;
>>>>>>> +  private Map<String, Object> env;
>>>>>>>     /**
>>>>>>>   * Why Mr Java this class does indeed take a fine copy of the
>>>>>>> provided
>>>>>>> @@ -53,10 +53,11 @@
>>>>>>>   *     * @param environment
>>>>>>>   */
>>>>>>> +  @SuppressWarnings("unchecked")
>>>>>>>  public ServiceRegistryContext(Hashtable<?, ?> environment)
>>>>>>>  {
>>>>>>> -    env = new HashMap<Object, Object>();
>>>>>>> -    env.putAll(environment);
>>>>>>> +    env = new HashMap<String, Object>();
>>>>>>> +    env.putAll((Map<? extends String, ? extends Object>)
>>>>>>> environment);
>>>>>>>  }
>>>>>>>   public Object addToEnvironment(String propName, Object propVal)
>>>>>>> throws
>>>>>>> NamingException
>>>>>>> @@ -153,7 +154,7 @@
>>>>>>>   public NamingEnumeration<NameClassPair> list(final Name name) throws
>>>>>>> NamingException
>>>>>>>  {
>>>>>>> -    throw new NamingException("Not a Context");
>>>>>>> +    return new ServiceRegistryListContext(env,
>>>>>>> convert(name)).list("");
>>>>>>>  }
>>>>>>>   public NamingEnumeration<NameClassPair> list(String name) throws
>>>>>>> NamingException
>>>>>>> @@ -163,7 +164,7 @@
>>>>>>>   public NamingEnumeration<Binding> listBindings(final Name name)
>>>>>>> throws
>>>>>>> NamingException
>>>>>>>  {
>>>>>>> -    throw new NamingException("Not a Context");
>>>>>>> +    return new ServiceRegistryListContext(env,
>>>>>>> convert(name)).listBindings("");
>>>>>>>  }
>>>>>>>   public NamingEnumeration<Binding> listBindings(String name) throws
>>>>>>> NamingException
>>>>>>> @@ -173,28 +174,43 @@
>>>>>>>   public Object lookup(Name name) throws NamingException
>>>>>>>  {
>>>>>>> -    int nameSize = validateName(name);
>>>>>>> -    String className = name.get(0);
>>>>>>> -
>>>>>>> -    String filter = null;
>>>>>>> +    Object result;
>>>>>>> +    +    OsgiName validName = convert(name);
>>>>>>>    -    if (nameSize == 2) {
>>>>>>> -      filter = name.get(1);
>>>>>>> +    String pathFragment = validName.getSchemePath();
>>>>>>> +    String serviceName = validName.getServiceName();
>>>>>>> +    String schemeName = validName.getScheme();
>>>>>>> +    +    if (OsgiName.FRAMEWORK_PATH.equals(pathFragment) &&
>>>>>>> "bundleContext".equals(validName.getServiceName())) {
>>>>>>> +      result = ServiceHelper.getBundleContext(env);
>>>>>>> +    } else if ((OsgiName.SERVICE_PATH.equals(pathFragment) &&
>>>>>>> OsgiName.OSGI_SCHEME.equals(schemeName)) ||
>>>>>>> +               (OsgiName.SERVICES_PATH.equals(pathFragment) &&
>>>>>>> OsgiName.ARIES_SCHEME.equals(schemeName))) {
>>>>>>> +      result = ServiceHelper.getService(validName.getInterface(),
>>>>>>> validName.getFilter(), serviceName, true, env);
>>>>>>> +    } else if (OsgiName.SERVICE_LIST_PATH.equals(pathFragment)) {
>>>>>>> +      result = new ServiceRegistryListContext(env, validName);
>>>>>>> +    } else {
>>>>>>> +      result = null;
>>>>>>>    }
>>>>>>>    -    try {
>>>>>>> -      Object result = ServiceHelper.getService(className, filter);
>>>>>>> -      -      if (result == null) {
>>>>>>> -        throw new NameNotFoundException("We couldn't find an object
>>>>>>> in
>>>>>>> the registry matching the query " + name);
>>>>>>> -      }
>>>>>>> -      -      return result;
>>>>>>> -    } catch (IllegalArgumentException e) {
>>>>>>> -      NamingException ne = new NamingException(e.getMessage());
>>>>>>> -      ne.initCause(e);
>>>>>>> -      throw ne;
>>>>>>> +    if (result == null) {
>>>>>>> +      throw new NameNotFoundException(name.toString());
>>>>>>> +    }
>>>>>>> +    +    return result;
>>>>>>> +  }
>>>>>>> +
>>>>>>> +  private OsgiName convert(Name name) throws InvalidNameException
>>>>>>> +  {
>>>>>>> +    OsgiName result;
>>>>>>> +    +    if (name instanceof OsgiName) {
>>>>>>> +      result = (OsgiName) name;
>>>>>>> +    } else {
>>>>>>> +      result = new OsgiName(name);
>>>>>>>    }
>>>>>>> +    +    return result;
>>>>>>>  }
>>>>>>>   public Object lookup(String name) throws NamingException
>>>>>>> @@ -246,27 +262,4 @@
>>>>>>>  {
>>>>>>>    throw new OperationNotSupportedException();
>>>>>>>  }
>>>>>>> -  -  /**
>>>>>>> -   * Check that the name conforms to the expected format
>>>>>>> -   * @param name
>>>>>>> -   * @return the size of the name
>>>>>>> -   * @throws InvalidNameException
>>>>>>> -   */
>>>>>>> -  private int validateName(final Name name) throws
>>>>>>> InvalidNameException
>>>>>>> -  {
>>>>>>> -    int nameSize = name.size();
>>>>>>> -    if (nameSize == 0) {
>>>>>>> -      throw new InvalidNameException("The provided name does not have
>>>>>>> any
>>>>>>> components" + name);
>>>>>>> -    } -    -    if ("aries:services".equals(name.get(0))) {
>>>>>>> -      throw new InvalidNameException("The composite name should not
>>>>>>> start
>>>>>>> with aries:services");
>>>>>>> -    }
>>>>>>> -    -    if (nameSize > 2) {
>>>>>>> -      throw new InvalidNameException("This JNDI context only expects
>>>>>>> 2
>>>>>>> components, but it found " + nameSize);
>>>>>>> -    }
>>>>>>> -    return nameSize;
>>>>>>> -  }
>>>>>>>  }
>>>>>>> \ No newline at end of file
>>>>>>>
>>>>>>> Added:
>>>>>>>
>>>>>>> incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/ServiceRegistryListContext.java
>>>>>>> URL:
>>>>>>>
>>>>>>> http://svn.apache.org/viewvc/incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/ServiceRegistryListContext.java?rev=917809&view=auto
>>>>>>>
>>>>>>>
>>>>>>> ==============================================================================
>>>>>>> ---
>>>>>>>
>>>>>>> incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/ServiceRegistryListContext.java
>>>>>>> (added)
>>>>>>> +++
>>>>>>>
>>>>>>> incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/ServiceRegistryListContext.java
>>>>>>> Mon Mar  1 23:53:18 2010
>>>>>>> @@ -0,0 +1,197 @@
>>>>>>> +/*
>>>>>>> + * 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.aries.jndi.url;
>>>>>>> +
>>>>>>> +import java.util.HashMap;
>>>>>>> +import java.util.Hashtable;
>>>>>>> +import java.util.Map;
>>>>>>> +
>>>>>>> +import javax.naming.Binding;
>>>>>>> +import javax.naming.Context;
>>>>>>> +import javax.naming.Name;
>>>>>>> +import javax.naming.NameClassPair;
>>>>>>> +import javax.naming.NameParser;
>>>>>>> +import javax.naming.NamingEnumeration;
>>>>>>> +import javax.naming.NamingException;
>>>>>>> +import javax.naming.OperationNotSupportedException;
>>>>>>> +
>>>>>>> +public class ServiceRegistryListContext implements Context
>>>>>>> +{
>>>>>>> +  private Map<String, Object> env;
>>>>>>> +  /** The name parser for the service registry name space */
>>>>>>> +  private NameParser parser = new OsgiNameParser();
>>>>>>> +  +  public ServiceRegistryListContext(Map<String, Object> env,
>>>>>>> OsgiName
>>>>>>> validName)
>>>>>>> +  {
>>>>>>> +    this.env = new HashMap<String, Object>(env);
>>>>>>> +  }
>>>>>>> +
>>>>>>> +  public Object addToEnvironment(String propName, Object propVal)
>>>>>>> throws
>>>>>>> NamingException
>>>>>>> +  {
>>>>>>> +    return env.put(propName, propVal);
>>>>>>> +  }
>>>>>>> +
>>>>>>> +  public void bind(Name name, Object obj) throws NamingException
>>>>>>> +  {
>>>>>>> +    throw new OperationNotSupportedException();
>>>>>>> +  }
>>>>>>> +
>>>>>>> +  public void bind(String name, Object obj) throws NamingException
>>>>>>> +  {
>>>>>>> +    throw new OperationNotSupportedException();
>>>>>>> +  }
>>>>>>> +
>>>>>>> +  public void close() throws NamingException
>>>>>>> +  {
>>>>>>> +    env = null;
>>>>>>> +    parser = null;
>>>>>>> +  }
>>>>>>> +
>>>>>>> +  public Name composeName(Name name, Name prefix) throws
>>>>>>> NamingException
>>>>>>> +  {
>>>>>>> +    // TODO Auto-generated method stub
>>>>>>> +    return null;
>>>>>>> +  }
>>>>>>> +
>>>>>>> +  public String composeName(String name, String prefix) throws
>>>>>>> NamingException
>>>>>>> +  {
>>>>>>> +    // TODO Auto-generated method stub
>>>>>>> +    return null;
>>>>>>> +  }
>>>>>>> +
>>>>>>> +  public Context createSubcontext(Name name) throws NamingException
>>>>>>> +  {
>>>>>>> +    throw new OperationNotSupportedException();
>>>>>>> +  }
>>>>>>> +
>>>>>>> +  public Context createSubcontext(String name) throws NamingException
>>>>>>> +  {
>>>>>>> +    throw new OperationNotSupportedException();
>>>>>>> +  }
>>>>>>> +
>>>>>>> +  public void destroySubcontext(Name name) throws NamingException
>>>>>>> +  {
>>>>>>> +    //No-op we don't support sub-contexts in our context
>>>>>>> +  }
>>>>>>> +
>>>>>>> +  public void destroySubcontext(String name) throws NamingException
>>>>>>> +  {
>>>>>>> +    //No-op we don't support sub-contexts in our context
>>>>>>> +  }
>>>>>>> +
>>>>>>> +  public Hashtable<?, ?> getEnvironment() throws NamingException
>>>>>>> +  {
>>>>>>> +    Hashtable<Object, Object> environment = new Hashtable<Object,
>>>>>>> Object>();
>>>>>>> +    environment.putAll(env);
>>>>>>> +    return environment;
>>>>>>> +  }
>>>>>>> +
>>>>>>> +  public String getNameInNamespace() throws NamingException
>>>>>>> +  {
>>>>>>> +    // TODO Auto-generated method stub
>>>>>>> +    return null;
>>>>>>> +  }
>>>>>>> +
>>>>>>> +  public NameParser getNameParser(Name name) throws NamingException
>>>>>>> +  {
>>>>>>> +    return parser;
>>>>>>> +  }
>>>>>>> +
>>>>>>> +  public NameParser getNameParser(String name) throws NamingException
>>>>>>> +  {
>>>>>>> +    return parser;
>>>>>>> +  }
>>>>>>> +
>>>>>>> +  public NamingEnumeration<NameClassPair> list(Name name) throws
>>>>>>> NamingException
>>>>>>> +  {
>>>>>>> +    return list(name.toString());
>>>>>>> +  }
>>>>>>> +
>>>>>>> +  public NamingEnumeration<NameClassPair> list(String name) throws
>>>>>>> NamingException
>>>>>>> +  {
>>>>>>> +    // TODO Auto-generated method stub
>>>>>>> +    return null;
>>>>>>> +  }
>>>>>>> +
>>>>>>> +  public NamingEnumeration<Binding> listBindings(Name name) throws
>>>>>>> NamingException
>>>>>>> +  {
>>>>>>> +    return listBindings(name.toString());
>>>>>>> +  }
>>>>>>> +
>>>>>>> +  public NamingEnumeration<Binding> listBindings(String name) throws
>>>>>>> NamingException
>>>>>>> +  {
>>>>>>> +    // TODO Auto-generated method stub
>>>>>>> +    return null;
>>>>>>> +  }
>>>>>>> +
>>>>>>> +  public Object lookup(Name name) throws NamingException
>>>>>>> +  {
>>>>>>> +    return lookup(name.toString());
>>>>>>> +  }
>>>>>>> +
>>>>>>> +  public Object lookup(String name) throws NamingException
>>>>>>> +  {
>>>>>>> +    return null;
>>>>>>> +  }
>>>>>>> +
>>>>>>> +  public Object lookupLink(Name name) throws NamingException
>>>>>>> +  {
>>>>>>> +    throw new OperationNotSupportedException();
>>>>>>> +  }
>>>>>>> +
>>>>>>> +  public Object lookupLink(String name) throws NamingException
>>>>>>> +  {
>>>>>>> +    throw new OperationNotSupportedException();
>>>>>>> +  }
>>>>>>> +
>>>>>>> +  public void rebind(Name name, Object obj) throws NamingException
>>>>>>> +  {
>>>>>>> +    throw new OperationNotSupportedException();
>>>>>>> +  }
>>>>>>> +
>>>>>>> +  public void rebind(String name, Object obj) throws NamingException
>>>>>>> +  {
>>>>>>> +    throw new OperationNotSupportedException();
>>>>>>> +  }
>>>>>>> +
>>>>>>> +  public Object removeFromEnvironment(String propName) throws
>>>>>>> NamingException
>>>>>>> +  {
>>>>>>> +    return env.remove(propName);
>>>>>>> +  }
>>>>>>> +
>>>>>>> +  public void rename(Name oldName, Name newName) throws
>>>>>>> NamingException
>>>>>>> +  {
>>>>>>> +    throw new OperationNotSupportedException();
>>>>>>> +  }
>>>>>>> +
>>>>>>> +  public void rename(String oldName, String newName) throws
>>>>>>> NamingException
>>>>>>> +  {
>>>>>>> +    throw new OperationNotSupportedException();
>>>>>>> +  }
>>>>>>> +
>>>>>>> +  public void unbind(Name name) throws NamingException
>>>>>>> +  {
>>>>>>> +    throw new OperationNotSupportedException();
>>>>>>> +  }
>>>>>>> +
>>>>>>> +  public void unbind(String name) throws NamingException
>>>>>>> +  {
>>>>>>> +    throw new OperationNotSupportedException();
>>>>>>> +  }
>>>>>>> +}
>>>>>>> \ No newline at end of file
>>>>>>>
>>>>>>> Copied:
>>>>>>>
>>>>>>> incubator/aries/trunk/jndi/jndi-url/src/test/java/org/apache/aries/jndi/url/OsgiNameParserTest.java
>>>>>>> (from r917002,
>>>>>>>
>>>>>>> incubator/aries/trunk/jndi/jndi-url/src/test/java/org/apache/aries/jndi/url/ServiceRegistryNameParserTest.java)
>>>>>>> URL:
>>>>>>>
>>>>>>> http://svn.apache.org/viewvc/incubator/aries/trunk/jndi/jndi-url/src/test/java/org/apache/aries/jndi/url/OsgiNameParserTest.java?p2=incubator/aries/trunk/jndi/jndi-url/src/test/java/org/apache/aries/jndi/url/OsgiNameParserTest.java&p1=incubator/aries/trunk/jndi/jndi-url/src/test/java/org/apache/aries/jndi/url/ServiceRegistryNameParserTest.java&r1=917002&r2=917809&rev=917809&view=diff
>>>>>>>
>>>>>>>
>>>>>>> ==============================================================================
>>>>>>> ---
>>>>>>>
>>>>>>> incubator/aries/trunk/jndi/jndi-url/src/test/java/org/apache/aries/jndi/url/ServiceRegistryNameParserTest.java
>>>>>>> (original)
>>>>>>> +++
>>>>>>>
>>>>>>> incubator/aries/trunk/jndi/jndi-url/src/test/java/org/apache/aries/jndi/url/OsgiNameParserTest.java
>>>>>>> Mon Mar  1 23:53:18 2010
>>>>>>> @@ -18,11 +18,11 @@
>>>>>>>  */
>>>>>>>  package org.apache.aries.jndi.url;
>>>>>>>  -import static org.junit.Assert.assertNotNull;
>>>>>>>  import static org.junit.Assert.assertEquals;
>>>>>>> +import static org.junit.Assert.assertFalse;
>>>>>>> +import static org.junit.Assert.assertTrue;
>>>>>>>  import javax.naming.InvalidNameException;
>>>>>>> -import javax.naming.Name;
>>>>>>>  import javax.naming.NameParser;
>>>>>>>  import javax.naming.NamingException;
>>>>>>>  @@ -31,10 +31,10 @@
>>>>>>>  /**
>>>>>>>  * This is where we test the service registry name parser.
>>>>>>>  */
>>>>>>> -public class ServiceRegistryNameParserTest
>>>>>>> +public class OsgiNameParserTest
>>>>>>>  {
>>>>>>>  /** The parser we are going to use for testing */
>>>>>>> -  private NameParser parser = new ServiceRegistryNameParser();
>>>>>>> +  private NameParser parser = new OsgiNameParser();
>>>>>>>   /**
>>>>>>>   * OK, so we check that we can call checkNames multiple times.
>>>>>>> @@ -43,8 +43,14 @@
>>>>>>>  @Test
>>>>>>>  public void checkValidNames() throws NamingException
>>>>>>>  {
>>>>>>> -    checkName("aries:services/java.lang.Runnable/(a=b)");
>>>>>>> -    checkName("aries:services/java.lang.Runnable");
>>>>>>> +    checkName("aries","services","java.lang.Runnable","(a=b)");
>>>>>>> +    checkName("aries","services","java.lang.Runnable");
>>>>>>> +    checkName("osgi","service","java.lang.Runnable");
>>>>>>> +    checkName("osgi","service","java.lang.Runnable", "(a=b)");
>>>>>>> +    checkName("osgi","servicelist","java.lang.Runnable");
>>>>>>> +    checkName("osgi","servicelist","java.lang.Runnable", "(a=b)");
>>>>>>> +    checkName("osgi","servicelist","jdbc", "grok", "DataSource");
>>>>>>> +    checkName("osgi", "framework", "bundleContext");
>>>>>>>  }
>>>>>>>     /**
>>>>>>> @@ -54,7 +60,7 @@
>>>>>>>  @Test(expected=InvalidNameException.class)
>>>>>>>  public void checkOutsideNamespace() throws NamingException
>>>>>>>  {
>>>>>>> -    checkName("java:comp/env/jms/cf");
>>>>>>> +    checkName("java","comp","env","jms","cf");
>>>>>>>  }
>>>>>>>     /**
>>>>>>> @@ -64,7 +70,7 @@
>>>>>>>  @Test(expected=InvalidNameException.class)
>>>>>>>  public void checkMissingInterface() throws NamingException
>>>>>>>  {
>>>>>>> -    checkName("aries:services");
>>>>>>> +    checkName("aries","services");
>>>>>>>  }
>>>>>>>     /**
>>>>>>> @@ -75,20 +81,64 @@
>>>>>>>  @Test(expected=InvalidNameException.class)
>>>>>>>  public void checkMissingInterface2() throws NamingException
>>>>>>>  {
>>>>>>> -    checkName("aries:services/");
>>>>>>> +    checkName("aries","services", "");
>>>>>>>  }
>>>>>>> -
>>>>>>> -  /**
>>>>>>> -   * This method parses the name and then makes sure what was parsed
>>>>>>> was
>>>>>>> parsed
>>>>>>> -   * correctly.
>>>>>>> -   * -   * @param name
>>>>>>> -   * @throws NamingException
>>>>>>> -   */
>>>>>>> -  private void checkName(String name) throws NamingException
>>>>>>> +  +  @Test(expected=InvalidNameException.class)
>>>>>>> +  public void checkIncorrectPath() throws NamingException
>>>>>>> +  {
>>>>>>> +    checkName("osgi", "services", "java.lang.Runnable"); +  }
>>>>>>> +  +  @Test(expected=InvalidNameException.class)
>>>>>>> +  public void checkIllegalPath() throws NamingException
>>>>>>>  {
>>>>>>> -    Name n = parser.parse(name);
>>>>>>> -    assertNotNull("We got a null name back, which is not allowed.",
>>>>>>> n);
>>>>>>> -    assertEquals("The name's toString does not produce the original
>>>>>>> value", name, n.toString());
>>>>>>> +    checkName("osgi", "wibble", "java.lang.Runnable"); +  }
>>>>>>> +  +  private void checkName(String scheme, String path, String ...
>>>>>>> elements)
>>>>>>> +    throws NamingException
>>>>>>> +  {
>>>>>>> +    StringBuilder builder = new StringBuilder();
>>>>>>> +    StringBuilder serviceName = new StringBuilder();
>>>>>>> +    +    builder.append(scheme);
>>>>>>> +    builder.append(':');
>>>>>>> +    builder.append(path);
>>>>>>> +
>>>>>>> +    if (elements.length > 0) {
>>>>>>> +      builder.append('/');
>>>>>>> +      +      for (String element : elements) {
>>>>>>> +        serviceName.append(element);
>>>>>>> +        serviceName.append('/');
>>>>>>> +      }
>>>>>>> +  +      serviceName.deleteCharAt(serviceName.length() - 1);
>>>>>>> +      +      builder.append(serviceName);
>>>>>>> +    }
>>>>>>> +    +    OsgiName n = (OsgiName) parser.parse(builder.toString());
>>>>>>> +    +    assertEquals(scheme, n.getScheme());
>>>>>>> +    assertEquals(path, n.getSchemePath());
>>>>>>> +    +    if (elements.length > 1) {
>>>>>>> +      assertEquals(elements[0], n.getInterface());
>>>>>>> +    }
>>>>>>> +    +    if (elements.length == 1) {
>>>>>>> +      assertFalse(n.hasFilter());
>>>>>>> +    }
>>>>>>> +    +    if (elements.length > 2) {
>>>>>>> +      if (elements.length == 2) {
>>>>>>> +        assertTrue(n.hasFilter());
>>>>>>> +        assertEquals(elements[1], n.getFilter());
>>>>>>> +      } else assertFalse(n.hasFilter());
>>>>>>> +    }
>>>>>>> +    +    assertEquals(serviceName.toString(), n.getServiceName());
>>>>>>>  }
>>>>>>>  }
>>>>>>> \ No newline at end of file
>>>>>>>
>>>>>>> Modified:
>>>>>>>
>>>>>>> incubator/aries/trunk/jndi/jndi-url/src/test/java/org/apache/aries/jndi/url/ServiceRegistryContextTest.java
>>>>>>> URL:
>>>>>>>
>>>>>>> http://svn.apache.org/viewvc/incubator/aries/trunk/jndi/jndi-url/src/test/java/org/apache/aries/jndi/url/ServiceRegistryContextTest.java?rev=917809&r1=917808&r2=917809&view=diff
>>>>>>>
>>>>>>>
>>>>>>> ==============================================================================
>>>>>>> ---
>>>>>>>
>>>>>>> incubator/aries/trunk/jndi/jndi-url/src/test/java/org/apache/aries/jndi/url/ServiceRegistryContextTest.java
>>>>>>> (original)
>>>>>>> +++
>>>>>>>
>>>>>>> incubator/aries/trunk/jndi/jndi-url/src/test/java/org/apache/aries/jndi/url/ServiceRegistryContextTest.java
>>>>>>> Mon Mar  1 23:53:18 2010
>>>>>>> @@ -21,7 +21,6 @@
>>>>>>>  import static org.junit.Assert.assertEquals;
>>>>>>>  import static org.junit.Assert.assertFalse;
>>>>>>>  import static org.junit.Assert.assertNotNull;
>>>>>>> -import static org.junit.Assert.assertSame;
>>>>>>>  import static org.junit.Assert.assertTrue;
>>>>>>>  import java.lang.reflect.Field;
>>>>>>> @@ -37,6 +36,12 @@
>>>>>>>  import javax.naming.NamingException;
>>>>>>>  import javax.naming.spi.ObjectFactory;
>>>>>>>  +import org.apache.aries.jndi.ContextHelper;
>>>>>>> +import org.apache.aries.jndi.OSGiObjectFactoryBuilder;
>>>>>>> +import org.apache.aries.mocks.BundleContextMock;
>>>>>>> +import org.apache.aries.mocks.BundleMock;
>>>>>>> +import org.apache.aries.unittest.mocks.MethodCall;
>>>>>>> +import org.apache.aries.unittest.mocks.Skeleton;
>>>>>>>  import org.junit.After;
>>>>>>>  import org.junit.Before;
>>>>>>>  import org.junit.Test;
>>>>>>> @@ -47,22 +52,13 @@
>>>>>>>  import org.osgi.framework.ServiceReference;
>>>>>>>  import org.osgi.framework.ServiceRegistration;
>>>>>>>  -import org.apache.aries.unittest.mocks.MethodCall;
>>>>>>> -import org.apache.aries.unittest.mocks.Skeleton;
>>>>>>> -import org.apache.aries.jndi.ContextHelper;
>>>>>>> -import org.apache.aries.jndi.OSGiObjectFactoryBuilder;
>>>>>>> -import org.apache.aries.jndi.services.ServiceHelper;
>>>>>>> -import org.apache.aries.jndi.url.Activator;
>>>>>>> -import org.apache.aries.mocks.BundleContextMock;
>>>>>>> -import org.apache.aries.mocks.BundleMock;
>>>>>>> -
>>>>>>>  /**
>>>>>>>  * Tests for our JNDI implementation for the service registry.
>>>>>>>  */
>>>>>>>  public class ServiceRegistryContextTest
>>>>>>>  {
>>>>>>>  /** The service we register by default */
>>>>>>> -  private Thread service;
>>>>>>> +  private Runnable service;
>>>>>>>  /** The bundle context for the test */
>>>>>>>  private BundleContext bc;
>>>>>>>  /** The service registration for the service */
>>>>>>> @@ -83,10 +79,7 @@
>>>>>>>    new Activator().start(bc);
>>>>>>>    new org.apache.aries.jndi.startup.Activator().start(bc);
>>>>>>>    -    Field f = ServiceHelper.class.getDeclaredField("context");
>>>>>>> -    f.setAccessible(true);
>>>>>>> -    f.set(null, bc);
>>>>>>> -    f = ContextHelper.class.getDeclaredField("context");
>>>>>>> +    Field f = ContextHelper.class.getDeclaredField("context");
>>>>>>>    f.setAccessible(true);
>>>>>>>    f.set(null, bc);
>>>>>>>    f = OSGiObjectFactoryBuilder.class.getDeclaredField("context");
>>>>>>> @@ -94,7 +87,7 @@
>>>>>>>    f.set(null, bc);
>>>>>>>  -    service = new Thread();
>>>>>>> +    service = Skeleton.newMock(Runnable.class);
>>>>>>>         registerService(service);
>>>>>>>  }
>>>>>>> @@ -104,7 +97,7 @@
>>>>>>>   *     * @param service2 The service to register.
>>>>>>>   */
>>>>>>> -  private void registerService(Thread service2)
>>>>>>> +  private void registerService(Runnable service2)
>>>>>>>  {
>>>>>>>    ServiceFactory factory = Skeleton.newMock(ServiceFactory.class);
>>>>>>>    Skeleton skel = Skeleton.getSkeleton(factory);
>>>>>>> @@ -159,11 +152,13 @@
>>>>>>>
>>>>>>>  Thread.currentThread().setContextClassLoader(mock.getClassLoader());
>>>>>>>    -    Object s = ctx.lookup("aries:services/java.lang.Runnable");
>>>>>>> +    Runnable s = (Runnable)
>>>>>>> ctx.lookup("aries:services/java.lang.Runnable");
>>>>>>>         assertNotNull("We didn't get a service back from our lookup
>>>>>>> :(",
>>>>>>> s);
>>>>>>>    -    assertEquals("The SR did not return the object we expected",
>>>>>>> service, s);
>>>>>>> +    s.run();
>>>>>>> +    +
>>>>>>>  Skeleton.getSkeleton(service).assertCalledExactNumberOfTimes(new
>>>>>>> MethodCall(Runnable.class, "run"), 1);
>>>>>>>         Skeleton skel = Skeleton.getSkeleton(mock.getBundleContext());
>>>>>>>    @@ -173,7 +168,7 @@
>>>>>>>
>>>>>>>  Thread.currentThread().setContextClassLoader(mock.getClassLoader());
>>>>>>>  -    s = ctx.lookup("osgi:services/java.lang.Runnable");
>>>>>>> +    s = (Runnable) ctx.lookup("osgi:service/java.lang.Runnable");
>>>>>>>         // Check we have the packages set correctly
>>>>>>>    @@ -181,10 +176,11 @@
>>>>>>>         assertTrue(ctx.getEnvironment().containsValue(packages));
>>>>>>>  -         assertNotNull("We didn't get a service back from our lookup
>>>>>>> :(", s);
>>>>>>> +
>>>>>>> +    s.run();
>>>>>>>    -    assertEquals("The SR did not return the object we expected",
>>>>>>> service, s);
>>>>>>> +    Skeleton.getSkeleton(service).assertCalledExactNumberOfTimes(new
>>>>>>> MethodCall(Runnable.class, "run"), 2);
>>>>>>>     skel = Skeleton.getSkeleton(mock.getBundleContext());
>>>>>>>    skel.assertCalled(new MethodCall(BundleContext.class,
>>>>>>> "getServiceReferences", "java.lang.Runnable", null));
>>>>>>> @@ -201,15 +197,21 @@
>>>>>>>  @Test
>>>>>>>  public void jndiLookupWithFilter() throws NamingException
>>>>>>>  {
>>>>>>> +    BundleMock mock = new BundleMock("scooby.doo", new Properties());
>>>>>>> +    +
>>>>>>>  Thread.currentThread().setContextClassLoader(mock.getClassLoader());
>>>>>>> +
>>>>>>>    InitialContext ctx = new InitialContext();
>>>>>>>         Object s =
>>>>>>> ctx.lookup("aries:services/java.lang.Runnable/(rubbish=smelly)");
>>>>>>>         assertNotNull("We didn't get a service back from our lookup
>>>>>>> :(",
>>>>>>> s);
>>>>>>>    -    assertEquals("The SR did not return the object we expected",
>>>>>>> service, s);
>>>>>>> +    service.run();
>>>>>>>    -    Skeleton.getSkeleton(bc).assertCalled(new
>>>>>>> MethodCall(BundleContext.class, "getServiceReferences",
>>>>>>> "java.lang.Runnable", "(rubbish=smelly)"));
>>>>>>> +    Skeleton.getSkeleton(service).assertCalledExactNumberOfTimes(new
>>>>>>> MethodCall(Runnable.class, "run"), 1);
>>>>>>> +
>>>>>>> +    Skeleton.getSkeleton(mock.getBundleContext()).assertCalled(new
>>>>>>> MethodCall(BundleContext.class, "getServiceReferences",
>>>>>>> "java.lang.Runnable", "(rubbish=smelly)"));
>>>>>>>  }
>>>>>>>     /**
>>>>>>> @@ -222,6 +224,11 @@
>>>>>>>  public void testLookupWhenServiceHasBeenRemoved() throws
>>>>>>> NamingException
>>>>>>>  {
>>>>>>>    reg.unregister();
>>>>>>> +
>>>>>>> +    BundleMock mock = new BundleMock("scooby.doo", new Properties());
>>>>>>> +    +
>>>>>>>  Thread.currentThread().setContextClassLoader(mock.getClassLoader());
>>>>>>> +
>>>>>>>    InitialContext ctx = new InitialContext();
>>>>>>>         ctx.lookup("aries:services/java.lang.Runnable");
>>>>>>> @@ -236,6 +243,10 @@
>>>>>>>  @Test(expected=NameNotFoundException.class)
>>>>>>>  public void testLookupForServiceWeNeverHad() throws NamingException
>>>>>>>  {
>>>>>>> +    BundleMock mock = new BundleMock("scooby.doo", new Properties());
>>>>>>> +    +
>>>>>>>  Thread.currentThread().setContextClassLoader(mock.getClassLoader());
>>>>>>> +
>>>>>>>    InitialContext ctx = new InitialContext();
>>>>>>>         ctx.lookup("aries:services/java.lang.Integer");
>>>>>>> @@ -271,14 +282,53 @@
>>>>>>>  }
>>>>>>>   @Test
>>>>>>> +  public void checkProxyDynamism() throws NamingException
>>>>>>> +  {
>>>>>>> +    BundleMock mock = new BundleMock("scooby.doo", new Properties());
>>>>>>> +    +
>>>>>>>  Thread.currentThread().setContextClassLoader(mock.getClassLoader());
>>>>>>> +
>>>>>>> +    InitialContext ctx = new InitialContext();
>>>>>>> +    +    String className = Runnable.class.getName();
>>>>>>> +    +    Runnable t = Skeleton.newMock(Runnable.class);
>>>>>>> +    Runnable t2 = Skeleton.newMock(Runnable.class);
>>>>>>> +    +    // we don't want the default service
>>>>>>> +    reg.unregister();
>>>>>>> +    +    ServiceRegistration reg = bc.registerService(className, t,
>>>>>>> null);
>>>>>>> +    bc.registerService(className, t2, null);
>>>>>>> +    +    Runnable r = (Runnable)
>>>>>>> ctx.lookup("osgi:service/java.lang.Runnable");
>>>>>>> +    +    r.run();
>>>>>>> +    +    Skeleton.getSkeleton(t).assertCalledExactNumberOfTimes(new
>>>>>>> MethodCall(Runnable.class, "run"), 1);
>>>>>>> +    Skeleton.getSkeleton(t2).assertNotCalled(new
>>>>>>> MethodCall(Runnable.class, "run"));
>>>>>>> +    +    reg.unregister();
>>>>>>> +    +    r.run();
>>>>>>> +    +    Skeleton.getSkeleton(t).assertCalledExactNumberOfTimes(new
>>>>>>> MethodCall(Runnable.class, "run"), 1);
>>>>>>> +    Skeleton.getSkeleton(t2).assertCalledExactNumberOfTimes(new
>>>>>>> MethodCall(Runnable.class, "run"), 1);
>>>>>>> +  }  +
>>>>>>> +  @Test
>>>>>>>  public void checkServiceOrderObserved() throws NamingException
>>>>>>>  {
>>>>>>> +    BundleMock mock = new BundleMock("scooby.doo", new Properties());
>>>>>>> +    +
>>>>>>>  Thread.currentThread().setContextClassLoader(mock.getClassLoader());
>>>>>>> +
>>>>>>>    InitialContext ctx = new InitialContext();
>>>>>>>         String className = Runnable.class.getName();
>>>>>>>    -    Thread t = new Thread();
>>>>>>> -    Thread t2 = new Thread();
>>>>>>> +    Runnable t = Skeleton.newMock(Runnable.class);
>>>>>>> +    Runnable t2 = Skeleton.newMock(Runnable.class);
>>>>>>>         // we don't want the default service
>>>>>>>    reg.unregister();
>>>>>>> @@ -286,9 +336,12 @@
>>>>>>>    ServiceRegistration reg = bc.registerService(className, t, null);
>>>>>>>    ServiceRegistration reg2 = bc.registerService(className, t2, null);
>>>>>>>    -    Runnable r = (Runnable)
>>>>>>> ctx.lookup("osgi:services/java.lang.Runnable");
>>>>>>> +    Runnable r = (Runnable)
>>>>>>> ctx.lookup("osgi:service/java.lang.Runnable");
>>>>>>>    -    assertSame("The wrong runnable was returned", t, r);
>>>>>>> +    r.run();
>>>>>>> +    +    Skeleton.getSkeleton(t).assertCalledExactNumberOfTimes(new
>>>>>>> MethodCall(Runnable.class, "run"), 1);
>>>>>>> +    Skeleton.getSkeleton(t2).assertNotCalled(new
>>>>>>> MethodCall(Runnable.class, "run"));
>>>>>>>         reg.unregister();
>>>>>>>    reg2.unregister();
>>>>>>> @@ -296,12 +349,18 @@
>>>>>>>    Hashtable<String, Object> props = new Hashtable<String, Object>();
>>>>>>>    props.put(Constants.SERVICE_RANKING, 55);
>>>>>>>    +    t = Skeleton.newMock(Runnable.class);
>>>>>>> +    t2 = Skeleton.newMock(Runnable.class);
>>>>>>> +
>>>>>>>    reg = bc.registerService(className, t, null);
>>>>>>>    reg2 = bc.registerService(className, t2, props);
>>>>>>>    -    r = (Runnable) ctx.lookup("osgi:services/java.lang.Runnable");
>>>>>>> +    r = (Runnable) ctx.lookup("osgi:service/java.lang.Runnable");
>>>>>>> +    +    r.run();
>>>>>>>    -    assertSame("The wrong runnable was returned", t2, r);
>>>>>>> +    Skeleton.getSkeleton(t).assertNotCalled(new
>>>>>>> MethodCall(Runnable.class, "run"));
>>>>>>> +    Skeleton.getSkeleton(t2).assertCalledExactNumberOfTimes(new
>>>>>>> MethodCall(Runnable.class, "run"), 1);
>>>>>>>  }
>>>>>>>     /**
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>> --
>>>>>> Joe
>>>>>>
>>>>>
>>>>>
>>>>
>>>
>>
>> --
>> Joe
>>
> 
> 
> 


-- 
Joe

Re: svn commit: r917809 - in /incubator/aries/trunk/jndi/jndi-url: ./ src/main/java/org/apache/aries/jndi/services/ src/main/java/org/apache/aries/jndi/url/ src/test/java/org/apache/aries/jndi/url/

Posted by Alasdair Nottingham <no...@apache.org>.
Hi,

I just committed a fix. On a related note I see that the pax web guy's
put a Thread context classloader on the thread, but it doesn't
implement BundleReference. Does anyone know how we can raise this with
them?

Thanks
Alasdair

On 3 March 2010 14:16, Joe Bohn <jo...@gmail.com> wrote:
> It looks like Blog-Sample is having the same issue and it doesn't use JSPs.
>   Here's a similar stack trace from blog-sample:
>
> [1643210767@qtp-2131869628-0 -
> /org.apache.aries.samples.blog-servlet/ViewBlog] DEBUG
> org.apache.aries.blueprint.container.ServiceRecipe - Retrieving service for
> bundle org.ops4j.pax.web.pax-web-jetty-bundle_0.7.2 [6] and service
> registration
> {org.apache.aries.samples.blog.api.BloggingService}={osgi.service.blueprint.compname=bloggingServiceComponent,
> service.id=52}
> java.lang.ClassNotFoundException:
> org.apache.aries.samples.blog.api.BloggingService
>        at
> org.eclipse.osgi.internal.loader.BundleLoader.findClassInternal(BundleLoader.java:489)
>        at
> org.eclipse.osgi.internal.loader.BundleLoader.findClass(BundleLoader.java:405)
>        at
> org.eclipse.osgi.internal.loader.BundleLoader.findClass(BundleLoader.java:393)
>        at
> org.eclipse.osgi.internal.baseadaptor.DefaultClassLoader.loadClass(DefaultClassLoader.java:105)
>        at java.lang.ClassLoader.loadClass(ClassLoader.java:250)
>        at
> org.eclipse.osgi.internal.loader.BundleLoader.loadClass(BundleLoader.java:321)
>        at
> org.eclipse.osgi.framework.internal.core.BundleHost.loadClass(BundleHost.java:231)
>        at
> org.eclipse.osgi.framework.internal.core.AbstractBundle.loadClass(AbstractBundle.java:1193)
>        at
> org.apache.aries.jndi.services.ServiceHelper.getService(ServiceHelper.java:210)
>        at
> org.apache.aries.jndi.url.ServiceRegistryContext.lookup(ServiceRegistryContext.java:189)
>        at
> org.apache.aries.jndi.url.ServiceRegistryContext.lookup(ServiceRegistryContext.java:218)
>        at
> org.apache.aries.jndi.DelegateContext.lookup(DelegateContext.java:160)
>        at javax.naming.InitialContext.lookup(InitialContext.java:392)
>        at
> org.apache.aries.samples.blog.web.util.JNDIHelper.getBloggingService(JNDIHelper.java:33)
>        at org.apache.aries.samples.blog.web.ViewBlog.doGet(ViewBlog.java:53)
>        at javax.servlet.http.HttpServlet.service(HttpServlet.java:707)
>        at javax.servlet.http.HttpServlet.service(HttpServlet.java:820)
>        at
> org.mortbay.jetty.servlet.ServletHolder.handle(ServletHolder.java:502)
>        at
> org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)
>        at
> org.ops4j.pax.web.service.internal.WelcomeFilesFilter.doFilter(WelcomeFilesFilter.java:169)
>        at
> org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1148)
>        at
> org.mortbay.jetty.servlet.ServletHandler.handle(ServletHandler.java:387)
>        at
> org.ops4j.pax.web.service.jetty.internal.HttpServiceServletHandler.handle(HttpServiceServletHandler.java:64)
>        at
> org.mortbay.jetty.servlet.SessionHandler.handle(SessionHandler.java:181)
>        at
> org.mortbay.jetty.handler.ContextHandler.handle(ContextHandler.java:765)
>        at
> org.ops4j.pax.web.service.jetty.internal.HttpServiceContext.handle(HttpServiceContext.java:111)
>        at
> org.ops4j.pax.web.service.jetty.internal.JettyServerHandlerCollection.handle(JettyServerHandlerCollection.java:64)
>        at
> org.mortbay.jetty.handler.HandlerWrapper.handle(HandlerWrapper.java:152)
>        at org.mortbay.jetty.Server.handle(Server.java:322)
>        at
> org.mortbay.jetty.HttpConnection.handleRequest(HttpConnection.java:534)
>        at
> org.mortbay.jetty.HttpConnection$RequestHandler.headerComplete(HttpConnection.java:864)
>        at org.mortbay.jetty.HttpParser.parseNext(HttpParser.java:539)
>        at org.mortbay.jetty.HttpParser.parseAvailable(HttpParser.java:212)
>        at org.mortbay.jetty.HttpConnection.handle(HttpConnection.java:404)
>        at
> org.mortbay.io.nio.SelectChannelEndPoint.run(SelectChannelEndPoint.java:409)
>        at
> org.mortbay.thread.QueuedThreadPool$PoolThread.run(QueuedThreadPool.java:520)
>
>
> Joe Bohn wrote:
>>
>> And here's the thread context classloader before the lookup ...
>>
>>
>> JasperClassLoader{bundleClassLoader=BundleClassLoader{bundle=org.apache.aries.ariestrader.modules.ariestrader-web_1.0.0.incubating-SNAPSHOT
>> [35],parent=org.eclipse.osgi.internal.baseadaptor.DefaultClassLoader@78ecf608}}
>>
>>
>> Joe
>>
>> Joe Bohn wrote:
>>>
>>> Here's the stack trace for the CNFE.  I'll have to work on getting the
>>> thread context classloader.
>>>
>>> [112793090@qtp-2020456228-2 -
>>> /org.apache.aries.ariestrader.modules.ariestrader-web/config] DEBUG
>>> org.apache.aries.blueprint.container.ServiceRecipe - Calling listeners for
>>> initial service registration
>>> java.lang.ClassNotFoundException:
>>> org.apache.aries.samples.ariestrader.api.TradeServicesManager
>>>        at
>>> org.eclipse.osgi.internal.loader.BundleLoader.findClassInternal(BundleLoader.java:489)
>>>        at
>>> org.eclipse.osgi.internal.loader.BundleLoader.findClass(BundleLoader.java:405)
>>>        at
>>> org.eclipse.osgi.internal.loader.BundleLoader.findClass(BundleLoader.java:393)
>>>        at
>>> org.eclipse.osgi.internal.baseadaptor.DefaultClassLoader.loadClass(DefaultClassLoader.java:105)
>>>        at java.lang.ClassLoader.loadClass(ClassLoader.java:250)
>>>        at
>>> org.eclipse.osgi.internal.loader.BundleLoader.loadClass(BundleLoader.java:321)
>>>        at
>>> org.eclipse.osgi.framework.internal.core.BundleHost.loadClass(BundleHost.java:231)
>>>        at
>>> org.eclipse.osgi.framework.internal.core.AbstractBundle.loadClass(AbstractBundle.java:1193)
>>>        at
>>> org.apache.aries.jndi.services.ServiceHelper.getService(ServiceHelper.java:210)
>>>        at
>>> org.apache.aries.jndi.url.ServiceRegistryContext.lookup(ServiceRegistryContext.java:189)
>>>        at
>>> org.apache.aries.jndi.url.ServiceRegistryContext.lookup(ServiceRegistryContext.java:218)
>>>        at
>>> org.apache.aries.jndi.DelegateContext.lookup(DelegateContext.java:160)
>>>        at javax.naming.InitialContext.lookup(InitialContext.java:392)
>>>        at
>>> org.apache.aries.samples.ariestrader.util.ServiceUtilities.getOSGIService(ServiceUtilities.java:60)
>>>        at
>>> org.apache.aries.samples.ariestrader.util.ServiceUtilities.getOSGIService(ServiceUtilities.java:41)
>>>        at
>>> org.apache.aries.samples.ariestrader.api.TradeServiceUtilities.getTradeServicesManager(TradeServiceUtilities.java:63)
>>>        at org.apache.jsp.config_jsp._jspService(config_jsp.java:86)
>>>        at
>>> org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:70)
>>>        at javax.servlet.http.HttpServlet.service(HttpServlet.java:820)
>>>        at
>>> org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:374)
>>>        at
>>> org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:342)
>>>        at
>>> org.apache.jasper.servlet.JspServlet.service(JspServlet.java:267)
>>>        at javax.servlet.http.HttpServlet.service(HttpServlet.java:820)
>>>        at
>>> org.ops4j.pax.web.jsp.JspServletWrapper$2.call(JspServletWrapper.java:132)
>>>        at
>>> org.ops4j.pax.web.jsp.JspServletWrapper$2.call(JspServletWrapper.java:127)
>>>        at
>>> org.ops4j.pax.swissbox.core.ContextClassLoaderUtils.doWithClassLoader(ContextClassLoaderUtils.java:60)
>>>        at
>>> org.ops4j.pax.web.jsp.JspServletWrapper.service(JspServletWrapper.java:124)
>>>        at
>>> org.mortbay.jetty.servlet.ServletHolder.handle(ServletHolder.java:502)
>>>        at
>>> org.mortbay.jetty.servlet.ServletHandler.handle(ServletHandler.java:389)
>>>        at
>>> org.ops4j.pax.web.service.jetty.internal.HttpServiceServletHandler.handle(HttpServiceServletHandler.java:64)
>>>        at
>>> org.mortbay.jetty.servlet.SessionHandler.handle(SessionHandler.java:181)
>>>        at
>>> org.mortbay.jetty.handler.ContextHandler.handle(ContextHandler.java:765)
>>>        at
>>> org.ops4j.pax.web.service.jetty.internal.HttpServiceContext.handle(HttpServiceContext.java:111)
>>>        at
>>> org.mortbay.jetty.servlet.Dispatcher.include(Dispatcher.java:192)
>>>        at
>>> org.apache.aries.samples.ariestrader.web.TradeConfigServlet.doConfigDisplay(TradeConfigServlet.java:62)
>>>        at
>>> org.apache.aries.samples.ariestrader.web.TradeConfigServlet.service(TradeConfigServlet.java:403)
>>>        at javax.servlet.http.HttpServlet.service(HttpServlet.java:820)
>>>        at
>>> org.mortbay.jetty.servlet.ServletHolder.handle(ServletHolder.java:502)
>>>        at
>>> org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)
>>>        at
>>> org.ops4j.pax.web.service.internal.WelcomeFilesFilter.doFilter(WelcomeFilesFilter.java:169)
>>>        at
>>> org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1148)
>>>        at
>>> org.mortbay.jetty.servlet.ServletHandler.handle(ServletHandler.java:387)
>>>        at
>>> org.ops4j.pax.web.service.jetty.internal.HttpServiceServletHandler.handle(HttpServiceServletHandler.java:64)
>>>        at
>>> org.mortbay.jetty.servlet.SessionHandler.handle(SessionHandler.java:181)
>>>        at
>>> org.mortbay.jetty.handler.ContextHandler.handle(ContextHandler.java:765)
>>>        at
>>> org.ops4j.pax.web.service.jetty.internal.HttpServiceContext.handle(HttpServiceContext.java:111)
>>>        at
>>> org.ops4j.pax.web.service.jetty.internal.JettyServerHandlerCollection.handle(JettyServerHandlerCollection.java:64)
>>>        at
>>> org.mortbay.jetty.handler.HandlerWrapper.handle(HandlerWrapper.java:152)
>>>        at org.mortbay.jetty.Server.handle(Server.java:322)
>>>        at
>>> org.mortbay.jetty.HttpConnection.handleRequest(HttpConnection.java:534)
>>>        at
>>> org.mortbay.jetty.HttpConnection$RequestHandler.headerComplete(HttpConnection.java:864)
>>>        at org.mortbay.jetty.HttpParser.parseNext(HttpParser.java:539)
>>>        at
>>> org.mortbay.jetty.HttpParser.parseAvailable(HttpParser.java:212)
>>>        at
>>> org.mortbay.jetty.HttpConnection.handle(HttpConnection.java:404)
>>>        at
>>> org.mortbay.io.nio.SelectChannelEndPoint.run(SelectChannelEndPoint.java:409)
>>>        at
>>> org.mortbay.thread.QueuedThreadPool$PoolThread.run(QueuedThreadPool.java:520)
>>>
>>> Alasdair Nottingham wrote:
>>>>
>>>> Hi,
>>>>
>>>> Hmm, I suspect I am not correctly finding the appropriate
>>>> BundleContext to use. That would explain the CNFE because we now proxy
>>>> the services rather than returning the raw service. If it is being
>>>> listed as being used by the pax-web jsp bundle that would explain
>>>> things.
>>>>
>>>> Do you have a stack trace for the ClassNotFoundException? That might
>>>> help to work out what went wrong.
>>>>
>>>> Also can you check the thread context classloader before the lookup?
>>>>
>>>> Thanks
>>>> Alasdair
>>>>
>>>> On 2 March 2010 23:21, Joe Bohn <jo...@gmail.com> wrote:
>>>>>
>>>>> I think there are some issues with this change.   I'll have to dig some
>>>>> more
>>>>> and post more details later (don't have time right now) ... but in
>>>>> short I'm
>>>>> seeing the following:
>>>>>
>>>>> - AriesTrader is behaving very badly after this change.
>>>>> - From within a jsp we use jndi lookup to find an osgi service.
>>>>> - After this change I get a failure in my jsp with a CNFE.   This
>>>>> despite
>>>>> the fact that I can see the package is imported on the web bundle and
>>>>> appears to be wired correctly.
>>>>> - Even more strange: I notice that the application service I was
>>>>> looking for
>>>>> is listed as being used by the pax-web jsp bundle.  So it seems like we
>>>>> might be using the wrong bundle context at some point.
>>>>>
>>>>>
>>>>> Joe
>>>>>
>>>>>
>>>>>
>>>>> not@apache.org wrote:
>>>>>>
>>>>>> Author: not
>>>>>> Date: Mon Mar  1 23:53:18 2010
>>>>>> New Revision: 917809
>>>>>>
>>>>>> URL: http://svn.apache.org/viewvc?rev=917809&view=rev
>>>>>> Log:
>>>>>> ARIES-128 Implement OSGi spec url lookup scheme
>>>>>>
>>>>>> Added:
>>>>>>
>>>>>>
>>>>>>  incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/OsgiName.java
>>>>>>     - copied, changed from r910238,
>>>>>>
>>>>>> incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/ServiceRegistryName.java
>>>>>>
>>>>>>
>>>>>>  incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/OsgiNameParser.java
>>>>>>     - copied, changed from r910238,
>>>>>>
>>>>>> incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/ServiceRegistryNameParser.java
>>>>>>
>>>>>>
>>>>>>  incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/ServiceRegistryListContext.java
>>>>>>
>>>>>>
>>>>>>  incubator/aries/trunk/jndi/jndi-url/src/test/java/org/apache/aries/jndi/url/OsgiNameParserTest.java
>>>>>>     - copied, changed from r917002,
>>>>>>
>>>>>> incubator/aries/trunk/jndi/jndi-url/src/test/java/org/apache/aries/jndi/url/ServiceRegistryNameParserTest.java
>>>>>> Removed:
>>>>>>
>>>>>>
>>>>>>  incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/ServiceRegistryName.java
>>>>>>
>>>>>>
>>>>>>  incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/ServiceRegistryNameParser.java
>>>>>>
>>>>>>
>>>>>>  incubator/aries/trunk/jndi/jndi-url/src/test/java/org/apache/aries/jndi/url/ServiceHelperTest.java
>>>>>>
>>>>>>
>>>>>>  incubator/aries/trunk/jndi/jndi-url/src/test/java/org/apache/aries/jndi/url/ServiceRegistryNameParserTest.java
>>>>>> Modified:
>>>>>>   incubator/aries/trunk/jndi/jndi-url/pom.xml
>>>>>>
>>>>>>
>>>>>>  incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/services/ServiceHelper.java
>>>>>>
>>>>>>
>>>>>>  incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/Activator.java
>>>>>>
>>>>>>
>>>>>>  incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/OsgiURLContextFactory.java
>>>>>>
>>>>>>
>>>>>>  incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/ServiceRegistryContext.java
>>>>>>
>>>>>>
>>>>>>  incubator/aries/trunk/jndi/jndi-url/src/test/java/org/apache/aries/jndi/url/ServiceRegistryContextTest.java
>>>>>>
>>>>>> Modified: incubator/aries/trunk/jndi/jndi-url/pom.xml
>>>>>> URL:
>>>>>>
>>>>>> http://svn.apache.org/viewvc/incubator/aries/trunk/jndi/jndi-url/pom.xml?rev=917809&r1=917808&r2=917809&view=diff
>>>>>>
>>>>>>
>>>>>> ==============================================================================
>>>>>> --- incubator/aries/trunk/jndi/jndi-url/pom.xml (original)
>>>>>> +++ incubator/aries/trunk/jndi/jndi-url/pom.xml Mon Mar  1 23:53:18
>>>>>> 2010
>>>>>> @@ -33,6 +33,10 @@
>>>>>>     <dependencies>
>>>>>>      <dependency>
>>>>>> +       <groupId>org.apache.aries</groupId>
>>>>>> +       <artifactId>org.apache.aries.util</artifactId>
>>>>>> +      </dependency>
>>>>>> +      <dependency>
>>>>>>          <groupId>org.osgi</groupId>
>>>>>>          <artifactId>org.osgi.core</artifactId>
>>>>>>          <scope>provided</scope>
>>>>>>
>>>>>> Modified:
>>>>>>
>>>>>> incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/services/ServiceHelper.java
>>>>>> URL:
>>>>>>
>>>>>> http://svn.apache.org/viewvc/incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/services/ServiceHelper.java?rev=917809&r1=917808&r2=917809&view=diff
>>>>>>
>>>>>>
>>>>>> ==============================================================================
>>>>>> ---
>>>>>>
>>>>>> incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/services/ServiceHelper.java
>>>>>> (original)
>>>>>> +++
>>>>>>
>>>>>> incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/services/ServiceHelper.java
>>>>>> Mon Mar  1 23:53:18 2010
>>>>>> @@ -18,18 +18,30 @@
>>>>>>  */
>>>>>>  package org.apache.aries.jndi.services;
>>>>>>  +import java.lang.reflect.InvocationHandler;
>>>>>> +import java.lang.reflect.Method;
>>>>>> +import java.lang.reflect.Proxy;
>>>>>> +import java.security.AccessController;
>>>>>> +import java.security.PrivilegedAction;
>>>>>> +import java.util.ArrayList;
>>>>>>  import java.util.Arrays;
>>>>>>  import java.util.Comparator;
>>>>>>  import java.util.HashSet;
>>>>>>  import java.util.LinkedList;
>>>>>>  import java.util.List;
>>>>>> +import java.util.Map;
>>>>>>  import java.util.Set;
>>>>>>  import java.util.concurrent.ConcurrentHashMap;
>>>>>>  import java.util.concurrent.ConcurrentMap;
>>>>>>  +import javax.naming.NamingException;
>>>>>> +
>>>>>> +import org.apache.aries.util.BundleToClassLoaderAdapter;
>>>>>> +import org.osgi.framework.Bundle;
>>>>>>  import org.osgi.framework.BundleContext;
>>>>>>  import org.osgi.framework.BundleReference;
>>>>>>  import org.osgi.framework.InvalidSyntaxException;
>>>>>> +import org.osgi.framework.ServiceException;
>>>>>>  import org.osgi.framework.ServiceReference;
>>>>>>  /**
>>>>>> @@ -47,221 +59,206 @@
>>>>>>  */
>>>>>>  public final class ServiceHelper
>>>>>>  {
>>>>>> -  /** The bundle context used for service registry queries */
>>>>>> -  private static BundleContext context;
>>>>>> -  /** A cache of what service was returned last time the query was
>>>>>> performed */
>>>>>> -  private static ConcurrentMap<ServiceKey, Set<ServiceReference>>
>>>>>> cache =
>>>>>> new ConcurrentHashMap<ServiceKey, Set<ServiceReference>>();
>>>>>> -
>>>>>> -  public static void setBundleContext(BundleContext ctx)
>>>>>> +  public static class StackFinder extends SecurityManager
>>>>>>  {
>>>>>> -    context = ctx;
>>>>>> +    public Class<?>[] getClassContext()
>>>>>> +    {
>>>>>> +      return super.getClassContext();
>>>>>> +    }
>>>>>>  }
>>>>>> -  -  /**
>>>>>> -   * This class is used as the key into the cache. It holds
>>>>>> information
>>>>>> to identify -   * who performed the query, along with the className
>>>>>> and
>>>>>> filter used. The thread context
>>>>>> -   * class loader is used in the key, so two different modules will
>>>>>> potentially get different
>>>>>> -   * services.
>>>>>> -   */
>>>>>> -  private static final class ServiceKey
>>>>>> +
>>>>>> +  private static class JNDIServiceDamper implements InvocationHandler
>>>>>>  {
>>>>>> -    /** The class loader of the invoking application */
>>>>>> -    private ClassLoader classLoader;
>>>>>> -    /** The name of the class being queried from the registry */
>>>>>> -    private String className;
>>>>>> -    /** the registry filter, this may be null */
>>>>>> +    private BundleContext ctx;
>>>>>> +    private ServicePair pair;
>>>>>> +    private String interfaceName;
>>>>>>    private String filter;
>>>>>> -    /** The cached hashCode */
>>>>>> -    private final int hashCode;
>>>>>> -
>>>>>> -    /**
>>>>>> -     * Boring unimportant comment.
>>>>>> -     * -     * @param cl
>>>>>> -     * @param cn
>>>>>> -     * @param f
>>>>>> -     */
>>>>>> -    public ServiceKey(ClassLoader cl, String cn, String f)
>>>>>> +    private boolean dynamic;
>>>>>> +    +    public JNDIServiceDamper(BundleContext context, String i,
>>>>>> String
>>>>>> f, ServicePair service, boolean d)
>>>>>>    {
>>>>>> -      classLoader = cl;
>>>>>> -      className = cn;
>>>>>> +      ctx = context;
>>>>>> +      pair = service;
>>>>>> +      interfaceName = i;
>>>>>>      filter = f;
>>>>>> -      -      int classNameHash = (className == null) ? 0 :
>>>>>> className.hashCode();
>>>>>> -      hashCode = System.identityHashCode(classLoader) * 1000003 +
>>>>>> classNameHash;
>>>>>> +      dynamic = d;
>>>>>>    }
>>>>>> -
>>>>>> -    @Override
>>>>>> -    public int hashCode()
>>>>>> -    {
>>>>>> -      return hashCode;
>>>>>> -    }
>>>>>> -
>>>>>> -    @Override
>>>>>> -    public boolean equals(Object other)
>>>>>> +    +    public Object invoke(Object proxy, Method method, Object[]
>>>>>> args)
>>>>>> throws Throwable
>>>>>>    {
>>>>>> -      if (other == this) return true;
>>>>>> -      if (other == null) return false;
>>>>>> -
>>>>>> -      if (other instanceof ServiceKey) {
>>>>>> -        ServiceKey otherKey = (ServiceKey) other;
>>>>>> -        if (hashCode != otherKey.hashCode) return false;
>>>>>> -
>>>>>> -        if (classLoader != otherKey.classLoader) return false;
>>>>>> -        if (!!!comparePossiblyNullObjects(className,
>>>>>> otherKey.className))
>>>>>> return false;
>>>>>> -        return comparePossiblyNullObjects(filter, otherKey.filter);
>>>>>> -      }
>>>>>> -
>>>>>> -      return false;
>>>>>> -    }
>>>>>> -    -    /**
>>>>>> -     * Compares two objects where one or other (or both) may be null.
>>>>>> -     * -     * @param a the first object to compare.
>>>>>> -     * @param b the second object to compare.
>>>>>> -     * @return true if they are ==, both null or identity equals,
>>>>>> false
>>>>>> otherwise.
>>>>>> -     */
>>>>>> -    public boolean comparePossiblyNullObjects(Object a, Object b) {
>>>>>> -      if (a == b) return true;
>>>>>> -      else if (a == null) return false;
>>>>>> -      else return a.equals(b);
>>>>>> +      if (pair.ref.getBundle() == null) {
>>>>>> +        if (dynamic) pair = findService(ctx, interfaceName, filter);
>>>>>> +        else pair = null;
>>>>>> +      }
>>>>>> +      +      if (pair == null) {
>>>>>> +        throw new ServiceException(interfaceName,
>>>>>> ServiceException.UNREGISTERED);
>>>>>> +      }
>>>>>> +      +      return method.invoke(pair.service, args);
>>>>>>    }
>>>>>>  }
>>>>>> -
>>>>>> -  /**
>>>>>> -   * This method is used to obtain a single instance of a desired
>>>>>> service
>>>>>> from the OSGi
>>>>>> -   * service registry. If the filter and class name identify multiple
>>>>>> services the first
>>>>>> -   * one is returned. If no service is found null will be returned.
>>>>>> -   * -   * @param className The class name used to register the
>>>>>> desired
>>>>>> service. If null is provided
>>>>>> -   *                  then all services are eligible to be returned.
>>>>>> -   * @param filter    An RFC 1960 query into the properties of the
>>>>>> registered services. e.g.
>>>>>> -   *                  (service.description=really useful)
>>>>>> -   * @return          The desired service
>>>>>> -   * -   * @throws IllegalArgumentException If the filter is not
>>>>>> valid.
>>>>>> See RFC 1960 to work out what -   *
>>>>>>  it
>>>>>> should be.
>>>>>> -   */
>>>>>> -  public static Object getService(String className, String filter)
>>>>>> throws
>>>>>> IllegalArgumentException
>>>>>> +  +  private static class ServicePair
>>>>>>  {
>>>>>> -    Object service = null;
>>>>>> -    try {
>>>>>> -      BundleContext callerCtx = getBundleContext();
>>>>>> -      ServiceReference[] refs =
>>>>>> callerCtx.getServiceReferences(className,
>>>>>> filter);
>>>>>> -      -      if (refs != null) {
>>>>>> -        // we need to sort the references returned in case they are
>>>>>> out
>>>>>> of order
>>>>>> -        // we need to sort in the reverse natural order, services
>>>>>> with
>>>>>> higher -        // ranking or lower id should be processed first so
>>>>>> should
>>>>>> be earlier in the array.
>>>>>> -        Arrays.sort(refs, new Comparator<ServiceReference>() {
>>>>>> -          public int compare(ServiceReference o1, ServiceReference
>>>>>> o2)
>>>>>> -          {
>>>>>> -            return o2.compareTo(o1);
>>>>>> -          }
>>>>>> -        });
>>>>>> -        -        for (ServiceReference ref : refs) {
>>>>>> -          List<Object> services = getServices(callerCtx, className,
>>>>>> filter, ref);
>>>>>> -          if (!!!services.isEmpty()) {
>>>>>> -            service = services.get(0);
>>>>>> -            break;
>>>>>> -          }
>>>>>> -        }
>>>>>> -      }      -    } catch (InvalidSyntaxException e) {
>>>>>> -      throw new IllegalArgumentException(e.getMessage(), e);
>>>>>> -    }
>>>>>> -    -    return service;
>>>>>> +    private ServiceReference ref;
>>>>>> +    private Object service;
>>>>>>  }
>>>>>>     /**
>>>>>> -   * This method is used to obtain a list of service instances from
>>>>>> the
>>>>>> OSGi
>>>>>> -   * service registry. If no service is found an empty list will be
>>>>>> returned.
>>>>>> -   * -   * @param className The class name used to register the
>>>>>> desired
>>>>>> service. If null is provided
>>>>>> -   *                  then all services are eligible to be returned.
>>>>>> -   * @param filter    An RFC 1960 query into the properties of the
>>>>>> registered services. e.g.
>>>>>> -   *                  (service.description=really useful)
>>>>>> -   * @return          A list of matching services.
>>>>>> -   * -   * @throws IllegalArgumentException If the filter is not
>>>>>> valid.
>>>>>> See RFC 1960 to work out what -   *
>>>>>>  it
>>>>>> should be.
>>>>>> +   * @param env +   * @return the bundle context for the caller.
>>>>>> +   * @throws NamingException     */
>>>>>> -  public static List<?> getServices(String className, String filter)
>>>>>> -      throws IllegalArgumentException
>>>>>> +  public static BundleContext getBundleContext(Map<String, Object>
>>>>>> env)
>>>>>> throws NamingException
>>>>>>  {
>>>>>> -    List<Object> services;
>>>>>> -    try {
>>>>>> -      BundleContext callerCtx = getBundleContext();
>>>>>> -      ServiceReference[] refs =
>>>>>> callerCtx.getAllServiceReferences(className, filter);
>>>>>> +    BundleContext result = null;
>>>>>> +    +    Object bc = env.get("osgi.service.jndi.bundleContext");
>>>>>> +    +    if (bc != null && bc instanceof BundleContext) result =
>>>>>> (BundleContext) bc;
>>>>>> +    else {
>>>>>> +      ClassLoader cl = AccessController.doPrivileged(new
>>>>>> PrivilegedAction<ClassLoader>() {
>>>>>> +        public ClassLoader run()
>>>>>> +        {
>>>>>> +          return Thread.currentThread().getContextClassLoader();
>>>>>> +        }
>>>>>> +      });
>>>>>>      -      services = getServices(callerCtx, className, filter,
>>>>>> refs);
>>>>>> -    } catch (InvalidSyntaxException e) {
>>>>>> -      throw new IllegalArgumentException(e.getMessage(), e);
>>>>>> +      result = getBundleContext(cl);
>>>>>> +    }
>>>>>> +    +    if (result == null) {
>>>>>> +      StackTraceElement[] stackTrace =
>>>>>> AccessController.doPrivileged(new
>>>>>> PrivilegedAction<StackTraceElement[]>() {
>>>>>> +        public StackTraceElement[] run()
>>>>>> +        {
>>>>>> +          return Thread.currentThread().getStackTrace();
>>>>>> +        }
>>>>>> +      });
>>>>>> +      +      StackFinder finder = new StackFinder();
>>>>>> +      Class<?>[] classStack = finder.getClassContext();
>>>>>> +      +      boolean found = false;
>>>>>> +      boolean foundLookup = false;
>>>>>> +      int i = 0;
>>>>>> +      for (; i < stackTrace.length && !!!found; i++) {
>>>>>> +        if (!!!foundLookup &&
>>>>>> "lookup".equals(stackTrace[i].getMethodName())) {
>>>>>> +          foundLookup = true;
>>>>>> +        } else if (foundLookup &&
>>>>>> !!!(stackTrace[i].getClassName().startsWith("org.apache.aries.jndi")
>>>>>> ||
>>>>>> +
>>>>>>  stackTrace[i].getClassName().startsWith("javax.naming"))) {
>>>>>> +          found = true;
>>>>>> +        }
>>>>>> +      }
>>>>>> +      +      if (found) {
>>>>>> +        Set<Integer> classLoadersChecked = new HashSet<Integer>();
>>>>>> +        for (; i < classStack.length && result == null; i++) {
>>>>>> +          ClassLoader cl = classStack[i].getClassLoader();
>>>>>> +          int hash = System.identityHashCode(cl);
>>>>>> +          if (!!!classLoadersChecked.contains(hash)) {
>>>>>> +            classLoadersChecked.add(hash);
>>>>>> +            result = getBundleContext(cl);
>>>>>> +          }
>>>>>> +        }
>>>>>> +        // Now we walk the stack looking for the BundleContext
>>>>>> +      }
>>>>>>    }
>>>>>>    -    return services;
>>>>>> +    if (result == null) throw new NamingException("Unable to find
>>>>>> BundleContext");
>>>>>> +    +    return result;
>>>>>>  }
>>>>>> -  -  /**
>>>>>> -   * @return the bundle context for the caller.
>>>>>> -   */
>>>>>> -  private static BundleContext getBundleContext()
>>>>>> +
>>>>>> +  private static BundleContext getBundleContext(ClassLoader cl)
>>>>>>  {
>>>>>>    BundleContext result = null;
>>>>>> -    ClassLoader cl = Thread.currentThread().getContextClassLoader();
>>>>>>    while (result == null && cl != null) {
>>>>>>      if (cl instanceof BundleReference) {
>>>>>>        result = ((BundleReference)cl).getBundle().getBundleContext();
>>>>>>      } else if (cl != null) {
>>>>>>        cl = cl.getParent();
>>>>>>      }
>>>>>> -    } +    }
>>>>>>    -    if (result == null) result = context;
>>>>>>    return result;
>>>>>>  }
>>>>>>  -  /**
>>>>>> -   * This worker method obtains the requested service(s) and if the
>>>>>> service(s) -   * exist updates the cache and releases the previous
>>>>>> service(s).
>>>>>> -   * -   * @param callerCtx The caller context.
>>>>>> -   * @param className The class name used to query for the service.
>>>>>> -   * @param filter    The filter name used to query for the service.
>>>>>> -   * @param refs      The references to get.
>>>>>> -   * @return          The service, if one was found, or null.
>>>>>> -   */
>>>>>> -  private static List<Object> getServices(BundleContext callerCtx,
>>>>>> String
>>>>>> className, String filter, ServiceReference...refs)
>>>>>> +  public static Object getService(String interface1, String filter,
>>>>>> String serviceName, boolean dynamicRebind, Map<String, Object> env)
>>>>>> throws
>>>>>> NamingException
>>>>>>  {
>>>>>> -    List<Object> data = new LinkedList<Object>();
>>>>>> +    Object result = null;
>>>>>> +    +    BundleContext ctx = getBundleContext(env);
>>>>>> +    +    ServicePair pair = findService(ctx, interface1, filter);
>>>>>>    -    if (refs != null) {
>>>>>> -      Set<ServiceReference> refSet = new HashSet<ServiceReference>();
>>>>>> -      for (ServiceReference ref : refs) {
>>>>>> -        Object service = callerCtx.getService(ref);
>>>>>> -        if (service != null) {
>>>>>> -          data.add(service);
>>>>>> -          refSet.add(ref);
>>>>>> +    if (pair == null) {
>>>>>> +      interface1 = null;
>>>>>> +      filter = "(osgi.jndi.serviceName=" + serviceName + ")";
>>>>>> +      pair = findService(ctx, interface1, filter);
>>>>>> +    }
>>>>>> +    +    if (pair != null) {
>>>>>> +      String[] interfaces = (String[])
>>>>>> pair.ref.getProperty("objectClass");
>>>>>> +      +      List<Class<?>> clazz = new
>>>>>> ArrayList<Class<?>>(interfaces.length);
>>>>>> +      +      Bundle b = ctx.getBundle();
>>>>>> +      +      for (String interfaceName : interfaces) {
>>>>>> +        try {
>>>>>> +          clazz.add(b.loadClass(interfaceName));
>>>>>> +        } catch (ClassNotFoundException e) {
>>>>>> +          // TODO Auto-generated catch block
>>>>>> +          e.printStackTrace();
>>>>>>        }
>>>>>>      }
>>>>>>      -      ClassLoader cl =
>>>>>> Thread.currentThread().getContextClassLoader();
>>>>>> -      ServiceKey key = new ServiceKey(cl, className, filter);
>>>>>> +      if (clazz.isEmpty()) {
>>>>>> +        throw new IllegalArgumentException();
>>>>>> +      }
>>>>>>      -      // we do not need any synchronization around this. The map
>>>>>> is
>>>>>> concurrent
>>>>>> -      // and until here we do not touch any shared state.
>>>>>> -      refSet = cache.put(key, refSet);
>>>>>> +      InvocationHandler ih = new JNDIServiceDamper(ctx, interface1,
>>>>>> filter, pair, dynamicRebind);
>>>>>>      -      if (refSet != null) {
>>>>>> -        for (ServiceReference ref : refSet) {
>>>>>> -          callerCtx.ungetService(ref);
>>>>>> +      result = Proxy.newProxyInstance(new
>>>>>> BundleToClassLoaderAdapter(b),
>>>>>> clazz.toArray(new Class<?>[clazz.size()]), ih);
>>>>>> +    }
>>>>>> +    +    return result;
>>>>>> +  }
>>>>>> +
>>>>>> +  private static ServicePair findService(BundleContext ctx, String
>>>>>> interface1, String filter)
>>>>>> +  {
>>>>>> +    ServicePair p = null;
>>>>>> +    +    try {
>>>>>> +      ServiceReference[] refs = ctx.getServiceReferences(interface1,
>>>>>> filter);
>>>>>> +      +      if (refs != null) {
>>>>>> +        // natural order is the exact opposite of the order we
>>>>>> desire.
>>>>>> +        Arrays.sort(refs, new Comparator<ServiceReference>() {
>>>>>> +          public int compare(ServiceReference o1, ServiceReference
>>>>>> o2)
>>>>>> +          {
>>>>>> +            return o2.compareTo(o1);
>>>>>> +          }
>>>>>> +        });
>>>>>> +        +        for (ServiceReference ref : refs) {
>>>>>> +          Object service = ctx.getService(ref);
>>>>>> +          +          if (service != null) {
>>>>>> +            p = new ServicePair();
>>>>>> +            p.ref = ref;
>>>>>> +            p.service = service;
>>>>>> +            break;
>>>>>> +          }
>>>>>>        }
>>>>>>      }
>>>>>> +      +    } catch (InvalidSyntaxException e) {
>>>>>> +      // TODO Auto-generated catch block
>>>>>> +      e.printStackTrace();
>>>>>>    }
>>>>>>    -    return data;
>>>>>> +    return p;
>>>>>>  }
>>>>>>  }
>>>>>>
>>>>>> Modified:
>>>>>>
>>>>>> incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/Activator.java
>>>>>> URL:
>>>>>>
>>>>>> http://svn.apache.org/viewvc/incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/Activator.java?rev=917809&r1=917808&r2=917809&view=diff
>>>>>>
>>>>>>
>>>>>> ==============================================================================
>>>>>> ---
>>>>>>
>>>>>> incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/Activator.java
>>>>>> (original)
>>>>>> +++
>>>>>>
>>>>>> incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/Activator.java
>>>>>> Mon Mar  1 23:53:18 2010
>>>>>> @@ -34,8 +34,6 @@
>>>>>>
>>>>>>  public void start(BundleContext context)
>>>>>>  {
>>>>>> -    ServiceHelper.setBundleContext(context);
>>>>>> -         Hashtable<Object, Object> props = new Hashtable<Object,
>>>>>> Object>();
>>>>>>    props.put("osgi.jndi.urlScheme", new String[] {"osgi", "aries"} );
>>>>>>    reg = context.registerService(ObjectFactory.class.getName(), new
>>>>>> OsgiURLContextFactory(), props);
>>>>>>
>>>>>> Copied:
>>>>>>
>>>>>> incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/OsgiName.java
>>>>>> (from r910238,
>>>>>>
>>>>>> incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/ServiceRegistryName.java)
>>>>>> URL:
>>>>>>
>>>>>> http://svn.apache.org/viewvc/incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/OsgiName.java?p2=incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/OsgiName.java&p1=incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/ServiceRegistryName.java&r1=910238&r2=917809&rev=917809&view=diff
>>>>>>
>>>>>>
>>>>>> ==============================================================================
>>>>>> ---
>>>>>>
>>>>>> incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/ServiceRegistryName.java
>>>>>> (original)
>>>>>> +++
>>>>>>
>>>>>> incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/OsgiName.java
>>>>>> Mon Mar  1 23:53:18 2010
>>>>>> @@ -21,28 +21,104 @@
>>>>>>  import java.util.Enumeration;
>>>>>>  import javax.naming.CompositeName;
>>>>>> +import javax.naming.InvalidNameException;
>>>>>> +import javax.naming.Name;
>>>>>>  /**
>>>>>> - * A composite name for the aries namespace. We only have this so
>>>>>> that we
>>>>>> can
>>>>>> - * provide a nicer toString()
>>>>>> + * A composite name for the aries namespace. This provides useful
>>>>>> utility
>>>>>> methods
>>>>>> + * for accessing the name.
>>>>>> + * + * component 0: osgi:service, aries:services, osgi:servicelist
>>>>>> + * component 1: interface
>>>>>> + * component 2: filter
>>>>>>  */
>>>>>> -public final class ServiceRegistryName extends CompositeName
>>>>>> +public final class OsgiName extends CompositeName
>>>>>>  {
>>>>>>  /** The serial version UID */
>>>>>>  private static final long serialVersionUID = 6617580228852444656L;
>>>>>> +  public static final String OSGI_SCHEME = "osgi";
>>>>>> +  public static final String ARIES_SCHEME = "aries";
>>>>>> +  public static final String SERVICE_PATH = "service";
>>>>>> +  public static final String SERVICES_PATH = "services";
>>>>>> +  public static final String SERVICE_LIST_PATH = "servicelist";
>>>>>> +  public static final String FRAMEWORK_PATH = "framework";
>>>>>>  -  @Override
>>>>>> -  public String toString()
>>>>>> +  public OsgiName(String name) throws InvalidNameException
>>>>>>  {
>>>>>> -    StringBuilder buffer = new StringBuilder();
>>>>>> +    super(name);
>>>>>> +  }
>>>>>> +
>>>>>> +  public OsgiName(Name name) throws InvalidNameException
>>>>>> +  {
>>>>>> +    this(name.toString());
>>>>>> +  }
>>>>>> +
>>>>>> +  public boolean hasFilter()
>>>>>> +  {
>>>>>> +    return size() == 3;
>>>>>> +  }
>>>>>> +  +  public boolean isServiceNameBased()
>>>>>> +  {
>>>>>> +    return size() > 3;
>>>>>> +  }
>>>>>> +  +  public String getScheme()
>>>>>> +  {
>>>>>> +    String part0 = get(0);
>>>>>> +    int index = part0.indexOf(':');
>>>>>> +    +    String result;
>>>>>> +    +    if (index > 0) {
>>>>>> +      result = part0.substring(0, index);
>>>>>> +    } else {
>>>>>> +      result = null;
>>>>>> +    }
>>>>>> +    +    return result;
>>>>>> +  }
>>>>>> +  +  public String getSchemePath()
>>>>>> +  {
>>>>>> +    String part0 = get(0);
>>>>>> +    int index = part0.indexOf(':');
>>>>>> +    +    String result;
>>>>>>    -    buffer.append("aries:services");
>>>>>> -    Enumeration<String> components = getAll();
>>>>>> -    while (components.hasMoreElements()) {
>>>>>> -      buffer.append('/');
>>>>>> -      buffer.append(components.nextElement());
>>>>>> +    if (index > 0) {
>>>>>> +      result = part0.substring(index + 1);
>>>>>> +    } else {
>>>>>> +      result = null;
>>>>>>    }
>>>>>>    -    return buffer.toString();
>>>>>> +    return result;
>>>>>> +  }
>>>>>> +  +  public String getInterface()
>>>>>> +  {
>>>>>> +    return get(1);
>>>>>> +  }
>>>>>> +  +  public String getFilter()
>>>>>> +  {
>>>>>> +    return hasFilter() ? get(2) : null;
>>>>>> +  }
>>>>>> +  +  public String getServiceName()
>>>>>> +  {
>>>>>> +    Enumeration<String> parts = getAll();
>>>>>> +    parts.nextElement();
>>>>>> +    +    StringBuilder builder = new StringBuilder();
>>>>>> +    +    while (parts.hasMoreElements()) {
>>>>>> +      builder.append(parts.nextElement());
>>>>>> +      builder.append('/');
>>>>>> +    }
>>>>>> +    +    builder.deleteCharAt(builder.length() - 1);
>>>>>> +    +    return builder.toString();
>>>>>>  }
>>>>>>  }
>>>>>> \ No newline at end of file
>>>>>>
>>>>>> Copied:
>>>>>>
>>>>>> incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/OsgiNameParser.java
>>>>>> (from r910238,
>>>>>>
>>>>>> incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/ServiceRegistryNameParser.java)
>>>>>> URL:
>>>>>>
>>>>>> http://svn.apache.org/viewvc/incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/OsgiNameParser.java?p2=incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/OsgiNameParser.java&p1=incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/ServiceRegistryNameParser.java&r1=910238&r2=917809&rev=917809&view=diff
>>>>>>
>>>>>>
>>>>>> ==============================================================================
>>>>>> ---
>>>>>>
>>>>>> incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/ServiceRegistryNameParser.java
>>>>>> (original)
>>>>>> +++
>>>>>>
>>>>>> incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/OsgiNameParser.java
>>>>>> Mon Mar  1 23:53:18 2010
>>>>>> @@ -26,31 +26,40 @@
>>>>>>  /**
>>>>>>  * A parser for the aries namespace
>>>>>>  */
>>>>>> -public final class ServiceRegistryNameParser implements NameParser
>>>>>> +public final class OsgiNameParser implements NameParser
>>>>>>  {
>>>>>> -
>>>>>> +  private static final String OSGI_SCHEME = "osgi";
>>>>>> +  private static final String ARIES_SCHEME = "aries";
>>>>>> +  private static final String SERVICE_PATH = "service";
>>>>>> +  private static final String SERVICES_PATH = "services";
>>>>>> +  private static final String SERVICE_LIST_PATH = "servicelist";
>>>>>> +  private static final String FRAMEWORK_PATH = "framework";
>>>>>> +     public Name parse(String name) throws NamingException
>>>>>>  {
>>>>>> -    if (!!!name.startsWith("aries:services/") &&
>>>>>> -        !!!name.startsWith("osgi:services/")) throw new
>>>>>> InvalidNameException("The JNDI name did not start with aries:, or
>>>>>> osgi:");
>>>>>> +    OsgiName result = new OsgiName(name);
>>>>>> +    +    if (result.size() < 2) throw new InvalidNameException(name);
>>>>>>    -    name = name.substring(name.indexOf('/') + 1);
>>>>>> +    String urlScheme = result.getScheme();
>>>>>> +    String schemePath = result.getSchemePath();
>>>>>>    -    int slashIndex = name.indexOf('/');
>>>>>> -    String interfaceName = name;
>>>>>> -    String filter = null;
>>>>>> -    -    if (slashIndex != -1) {
>>>>>> -      interfaceName = name.substring(0, slashIndex);
>>>>>> -      filter = name.substring(slashIndex + 1);
>>>>>> +    if (!!!(OSGI_SCHEME.equals(urlScheme) ||
>>>>>> ARIES_SCHEME.equals(urlScheme))) {
>>>>>> +      throw new InvalidNameException(name);
>>>>>>    }
>>>>>>    -    if (interfaceName.length() == 0) throw new
>>>>>> InvalidNameException("No interface name was specified");
>>>>>> +    if (ARIES_SCHEME.equals(urlScheme) &&
>>>>>> !!!SERVICES_PATH.equals(schemePath)) {
>>>>>> +      throw new InvalidNameException(name);
>>>>>> +    }
>>>>>> +    +    if (OSGI_SCHEME.equals(urlScheme) && !!!(
>>>>>> SERVICE_PATH.equals(schemePath) || +
>>>>>>     SERVICE_LIST_PATH.equals(schemePath) || +
>>>>>>               FRAMEWORK_PATH.equals(schemePath))) {
>>>>>> +      throw new InvalidNameException(name);
>>>>>> +    }
>>>>>>    -    Name result = new ServiceRegistryName();
>>>>>> -    result.add(interfaceName);
>>>>>> -    if (filter != null) {
>>>>>> -      result.add(filter);
>>>>>> +    if (result.getInterface() == null ||
>>>>>> result.getInterface().length()
>>>>>> == 0) {
>>>>>> +      throw new InvalidNameException(name);
>>>>>>    }
>>>>>>         return result;
>>>>>> @@ -59,7 +68,7 @@
>>>>>>  @Override
>>>>>>  public boolean equals(Object other)
>>>>>>  {
>>>>>> -    return other instanceof ServiceRegistryNameParser;
>>>>>> +    return other instanceof OsgiNameParser;
>>>>>>  }
>>>>>>     @Override
>>>>>>
>>>>>> Modified:
>>>>>>
>>>>>> incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/OsgiURLContextFactory.java
>>>>>> URL:
>>>>>>
>>>>>> http://svn.apache.org/viewvc/incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/OsgiURLContextFactory.java?rev=917809&r1=917808&r2=917809&view=diff
>>>>>>
>>>>>>
>>>>>> ==============================================================================
>>>>>> ---
>>>>>>
>>>>>> incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/OsgiURLContextFactory.java
>>>>>> (original)
>>>>>> +++
>>>>>>
>>>>>> incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/OsgiURLContextFactory.java
>>>>>> Mon Mar  1 23:53:18 2010
>>>>>> @@ -49,7 +49,7 @@
>>>>>>    } else if (obj instanceof String[]) {
>>>>>>      // Try each URL until either lookup succeeds or they all fail
>>>>>>      String[] urls = (String[])obj;
>>>>>> -      if (urls.length == 0) throw new
>>>>>> ConfigurationException("ariesURLContextFactory: empty URL array");
>>>>>> +      if (urls.length == 0) throw new ConfigurationException("0");
>>>>>>      Context context = new ServiceRegistryContext(environment);
>>>>>>      try
>>>>>>      {
>>>>>>
>>>>>> Modified:
>>>>>>
>>>>>> incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/ServiceRegistryContext.java
>>>>>> URL:
>>>>>>
>>>>>> http://svn.apache.org/viewvc/incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/ServiceRegistryContext.java?rev=917809&r1=917808&r2=917809&view=diff
>>>>>>
>>>>>>
>>>>>> ==============================================================================
>>>>>> ---
>>>>>>
>>>>>> incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/ServiceRegistryContext.java
>>>>>> (original)
>>>>>> +++
>>>>>>
>>>>>> incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/ServiceRegistryContext.java
>>>>>> Mon Mar  1 23:53:18 2010
>>>>>> @@ -42,9 +42,9 @@
>>>>>>  {
>>>>>>  private static final String ARIES_SERVICES = "aries:services/";
>>>>>>  /** The name parser for the service registry name space */
>>>>>> -  private NameParser parser = new ServiceRegistryNameParser();
>>>>>> +  private NameParser parser = new OsgiNameParser();
>>>>>>  /** The environment for this context */
>>>>>> -  private Map<Object, Object> env;
>>>>>> +  private Map<String, Object> env;
>>>>>>     /**
>>>>>>   * Why Mr Java this class does indeed take a fine copy of the
>>>>>> provided
>>>>>> @@ -53,10 +53,11 @@
>>>>>>   *     * @param environment
>>>>>>   */
>>>>>> +  @SuppressWarnings("unchecked")
>>>>>>  public ServiceRegistryContext(Hashtable<?, ?> environment)
>>>>>>  {
>>>>>> -    env = new HashMap<Object, Object>();
>>>>>> -    env.putAll(environment);
>>>>>> +    env = new HashMap<String, Object>();
>>>>>> +    env.putAll((Map<? extends String, ? extends Object>)
>>>>>> environment);
>>>>>>  }
>>>>>>   public Object addToEnvironment(String propName, Object propVal)
>>>>>> throws
>>>>>> NamingException
>>>>>> @@ -153,7 +154,7 @@
>>>>>>   public NamingEnumeration<NameClassPair> list(final Name name) throws
>>>>>> NamingException
>>>>>>  {
>>>>>> -    throw new NamingException("Not a Context");
>>>>>> +    return new ServiceRegistryListContext(env,
>>>>>> convert(name)).list("");
>>>>>>  }
>>>>>>   public NamingEnumeration<NameClassPair> list(String name) throws
>>>>>> NamingException
>>>>>> @@ -163,7 +164,7 @@
>>>>>>   public NamingEnumeration<Binding> listBindings(final Name name)
>>>>>> throws
>>>>>> NamingException
>>>>>>  {
>>>>>> -    throw new NamingException("Not a Context");
>>>>>> +    return new ServiceRegistryListContext(env,
>>>>>> convert(name)).listBindings("");
>>>>>>  }
>>>>>>   public NamingEnumeration<Binding> listBindings(String name) throws
>>>>>> NamingException
>>>>>> @@ -173,28 +174,43 @@
>>>>>>   public Object lookup(Name name) throws NamingException
>>>>>>  {
>>>>>> -    int nameSize = validateName(name);
>>>>>> -    String className = name.get(0);
>>>>>> -
>>>>>> -    String filter = null;
>>>>>> +    Object result;
>>>>>> +    +    OsgiName validName = convert(name);
>>>>>>    -    if (nameSize == 2) {
>>>>>> -      filter = name.get(1);
>>>>>> +    String pathFragment = validName.getSchemePath();
>>>>>> +    String serviceName = validName.getServiceName();
>>>>>> +    String schemeName = validName.getScheme();
>>>>>> +    +    if (OsgiName.FRAMEWORK_PATH.equals(pathFragment) &&
>>>>>> "bundleContext".equals(validName.getServiceName())) {
>>>>>> +      result = ServiceHelper.getBundleContext(env);
>>>>>> +    } else if ((OsgiName.SERVICE_PATH.equals(pathFragment) &&
>>>>>> OsgiName.OSGI_SCHEME.equals(schemeName)) ||
>>>>>> +               (OsgiName.SERVICES_PATH.equals(pathFragment) &&
>>>>>> OsgiName.ARIES_SCHEME.equals(schemeName))) {
>>>>>> +      result = ServiceHelper.getService(validName.getInterface(),
>>>>>> validName.getFilter(), serviceName, true, env);
>>>>>> +    } else if (OsgiName.SERVICE_LIST_PATH.equals(pathFragment)) {
>>>>>> +      result = new ServiceRegistryListContext(env, validName);
>>>>>> +    } else {
>>>>>> +      result = null;
>>>>>>    }
>>>>>>    -    try {
>>>>>> -      Object result = ServiceHelper.getService(className, filter);
>>>>>> -      -      if (result == null) {
>>>>>> -        throw new NameNotFoundException("We couldn't find an object
>>>>>> in
>>>>>> the registry matching the query " + name);
>>>>>> -      }
>>>>>> -      -      return result;
>>>>>> -    } catch (IllegalArgumentException e) {
>>>>>> -      NamingException ne = new NamingException(e.getMessage());
>>>>>> -      ne.initCause(e);
>>>>>> -      throw ne;
>>>>>> +    if (result == null) {
>>>>>> +      throw new NameNotFoundException(name.toString());
>>>>>> +    }
>>>>>> +    +    return result;
>>>>>> +  }
>>>>>> +
>>>>>> +  private OsgiName convert(Name name) throws InvalidNameException
>>>>>> +  {
>>>>>> +    OsgiName result;
>>>>>> +    +    if (name instanceof OsgiName) {
>>>>>> +      result = (OsgiName) name;
>>>>>> +    } else {
>>>>>> +      result = new OsgiName(name);
>>>>>>    }
>>>>>> +    +    return result;
>>>>>>  }
>>>>>>   public Object lookup(String name) throws NamingException
>>>>>> @@ -246,27 +262,4 @@
>>>>>>  {
>>>>>>    throw new OperationNotSupportedException();
>>>>>>  }
>>>>>> -  -  /**
>>>>>> -   * Check that the name conforms to the expected format
>>>>>> -   * @param name
>>>>>> -   * @return the size of the name
>>>>>> -   * @throws InvalidNameException
>>>>>> -   */
>>>>>> -  private int validateName(final Name name) throws
>>>>>> InvalidNameException
>>>>>> -  {
>>>>>> -    int nameSize = name.size();
>>>>>> -    if (nameSize == 0) {
>>>>>> -      throw new InvalidNameException("The provided name does not have
>>>>>> any
>>>>>> components" + name);
>>>>>> -    } -    -    if ("aries:services".equals(name.get(0))) {
>>>>>> -      throw new InvalidNameException("The composite name should not
>>>>>> start
>>>>>> with aries:services");
>>>>>> -    }
>>>>>> -    -    if (nameSize > 2) {
>>>>>> -      throw new InvalidNameException("This JNDI context only expects
>>>>>> 2
>>>>>> components, but it found " + nameSize);
>>>>>> -    }
>>>>>> -    return nameSize;
>>>>>> -  }
>>>>>>  }
>>>>>> \ No newline at end of file
>>>>>>
>>>>>> Added:
>>>>>>
>>>>>> incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/ServiceRegistryListContext.java
>>>>>> URL:
>>>>>>
>>>>>> http://svn.apache.org/viewvc/incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/ServiceRegistryListContext.java?rev=917809&view=auto
>>>>>>
>>>>>>
>>>>>> ==============================================================================
>>>>>> ---
>>>>>>
>>>>>> incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/ServiceRegistryListContext.java
>>>>>> (added)
>>>>>> +++
>>>>>>
>>>>>> incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/ServiceRegistryListContext.java
>>>>>> Mon Mar  1 23:53:18 2010
>>>>>> @@ -0,0 +1,197 @@
>>>>>> +/*
>>>>>> + * 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.aries.jndi.url;
>>>>>> +
>>>>>> +import java.util.HashMap;
>>>>>> +import java.util.Hashtable;
>>>>>> +import java.util.Map;
>>>>>> +
>>>>>> +import javax.naming.Binding;
>>>>>> +import javax.naming.Context;
>>>>>> +import javax.naming.Name;
>>>>>> +import javax.naming.NameClassPair;
>>>>>> +import javax.naming.NameParser;
>>>>>> +import javax.naming.NamingEnumeration;
>>>>>> +import javax.naming.NamingException;
>>>>>> +import javax.naming.OperationNotSupportedException;
>>>>>> +
>>>>>> +public class ServiceRegistryListContext implements Context
>>>>>> +{
>>>>>> +  private Map<String, Object> env;
>>>>>> +  /** The name parser for the service registry name space */
>>>>>> +  private NameParser parser = new OsgiNameParser();
>>>>>> +  +  public ServiceRegistryListContext(Map<String, Object> env,
>>>>>> OsgiName
>>>>>> validName)
>>>>>> +  {
>>>>>> +    this.env = new HashMap<String, Object>(env);
>>>>>> +  }
>>>>>> +
>>>>>> +  public Object addToEnvironment(String propName, Object propVal)
>>>>>> throws
>>>>>> NamingException
>>>>>> +  {
>>>>>> +    return env.put(propName, propVal);
>>>>>> +  }
>>>>>> +
>>>>>> +  public void bind(Name name, Object obj) throws NamingException
>>>>>> +  {
>>>>>> +    throw new OperationNotSupportedException();
>>>>>> +  }
>>>>>> +
>>>>>> +  public void bind(String name, Object obj) throws NamingException
>>>>>> +  {
>>>>>> +    throw new OperationNotSupportedException();
>>>>>> +  }
>>>>>> +
>>>>>> +  public void close() throws NamingException
>>>>>> +  {
>>>>>> +    env = null;
>>>>>> +    parser = null;
>>>>>> +  }
>>>>>> +
>>>>>> +  public Name composeName(Name name, Name prefix) throws
>>>>>> NamingException
>>>>>> +  {
>>>>>> +    // TODO Auto-generated method stub
>>>>>> +    return null;
>>>>>> +  }
>>>>>> +
>>>>>> +  public String composeName(String name, String prefix) throws
>>>>>> NamingException
>>>>>> +  {
>>>>>> +    // TODO Auto-generated method stub
>>>>>> +    return null;
>>>>>> +  }
>>>>>> +
>>>>>> +  public Context createSubcontext(Name name) throws NamingException
>>>>>> +  {
>>>>>> +    throw new OperationNotSupportedException();
>>>>>> +  }
>>>>>> +
>>>>>> +  public Context createSubcontext(String name) throws NamingException
>>>>>> +  {
>>>>>> +    throw new OperationNotSupportedException();
>>>>>> +  }
>>>>>> +
>>>>>> +  public void destroySubcontext(Name name) throws NamingException
>>>>>> +  {
>>>>>> +    //No-op we don't support sub-contexts in our context
>>>>>> +  }
>>>>>> +
>>>>>> +  public void destroySubcontext(String name) throws NamingException
>>>>>> +  {
>>>>>> +    //No-op we don't support sub-contexts in our context
>>>>>> +  }
>>>>>> +
>>>>>> +  public Hashtable<?, ?> getEnvironment() throws NamingException
>>>>>> +  {
>>>>>> +    Hashtable<Object, Object> environment = new Hashtable<Object,
>>>>>> Object>();
>>>>>> +    environment.putAll(env);
>>>>>> +    return environment;
>>>>>> +  }
>>>>>> +
>>>>>> +  public String getNameInNamespace() throws NamingException
>>>>>> +  {
>>>>>> +    // TODO Auto-generated method stub
>>>>>> +    return null;
>>>>>> +  }
>>>>>> +
>>>>>> +  public NameParser getNameParser(Name name) throws NamingException
>>>>>> +  {
>>>>>> +    return parser;
>>>>>> +  }
>>>>>> +
>>>>>> +  public NameParser getNameParser(String name) throws NamingException
>>>>>> +  {
>>>>>> +    return parser;
>>>>>> +  }
>>>>>> +
>>>>>> +  public NamingEnumeration<NameClassPair> list(Name name) throws
>>>>>> NamingException
>>>>>> +  {
>>>>>> +    return list(name.toString());
>>>>>> +  }
>>>>>> +
>>>>>> +  public NamingEnumeration<NameClassPair> list(String name) throws
>>>>>> NamingException
>>>>>> +  {
>>>>>> +    // TODO Auto-generated method stub
>>>>>> +    return null;
>>>>>> +  }
>>>>>> +
>>>>>> +  public NamingEnumeration<Binding> listBindings(Name name) throws
>>>>>> NamingException
>>>>>> +  {
>>>>>> +    return listBindings(name.toString());
>>>>>> +  }
>>>>>> +
>>>>>> +  public NamingEnumeration<Binding> listBindings(String name) throws
>>>>>> NamingException
>>>>>> +  {
>>>>>> +    // TODO Auto-generated method stub
>>>>>> +    return null;
>>>>>> +  }
>>>>>> +
>>>>>> +  public Object lookup(Name name) throws NamingException
>>>>>> +  {
>>>>>> +    return lookup(name.toString());
>>>>>> +  }
>>>>>> +
>>>>>> +  public Object lookup(String name) throws NamingException
>>>>>> +  {
>>>>>> +    return null;
>>>>>> +  }
>>>>>> +
>>>>>> +  public Object lookupLink(Name name) throws NamingException
>>>>>> +  {
>>>>>> +    throw new OperationNotSupportedException();
>>>>>> +  }
>>>>>> +
>>>>>> +  public Object lookupLink(String name) throws NamingException
>>>>>> +  {
>>>>>> +    throw new OperationNotSupportedException();
>>>>>> +  }
>>>>>> +
>>>>>> +  public void rebind(Name name, Object obj) throws NamingException
>>>>>> +  {
>>>>>> +    throw new OperationNotSupportedException();
>>>>>> +  }
>>>>>> +
>>>>>> +  public void rebind(String name, Object obj) throws NamingException
>>>>>> +  {
>>>>>> +    throw new OperationNotSupportedException();
>>>>>> +  }
>>>>>> +
>>>>>> +  public Object removeFromEnvironment(String propName) throws
>>>>>> NamingException
>>>>>> +  {
>>>>>> +    return env.remove(propName);
>>>>>> +  }
>>>>>> +
>>>>>> +  public void rename(Name oldName, Name newName) throws
>>>>>> NamingException
>>>>>> +  {
>>>>>> +    throw new OperationNotSupportedException();
>>>>>> +  }
>>>>>> +
>>>>>> +  public void rename(String oldName, String newName) throws
>>>>>> NamingException
>>>>>> +  {
>>>>>> +    throw new OperationNotSupportedException();
>>>>>> +  }
>>>>>> +
>>>>>> +  public void unbind(Name name) throws NamingException
>>>>>> +  {
>>>>>> +    throw new OperationNotSupportedException();
>>>>>> +  }
>>>>>> +
>>>>>> +  public void unbind(String name) throws NamingException
>>>>>> +  {
>>>>>> +    throw new OperationNotSupportedException();
>>>>>> +  }
>>>>>> +}
>>>>>> \ No newline at end of file
>>>>>>
>>>>>> Copied:
>>>>>>
>>>>>> incubator/aries/trunk/jndi/jndi-url/src/test/java/org/apache/aries/jndi/url/OsgiNameParserTest.java
>>>>>> (from r917002,
>>>>>>
>>>>>> incubator/aries/trunk/jndi/jndi-url/src/test/java/org/apache/aries/jndi/url/ServiceRegistryNameParserTest.java)
>>>>>> URL:
>>>>>>
>>>>>> http://svn.apache.org/viewvc/incubator/aries/trunk/jndi/jndi-url/src/test/java/org/apache/aries/jndi/url/OsgiNameParserTest.java?p2=incubator/aries/trunk/jndi/jndi-url/src/test/java/org/apache/aries/jndi/url/OsgiNameParserTest.java&p1=incubator/aries/trunk/jndi/jndi-url/src/test/java/org/apache/aries/jndi/url/ServiceRegistryNameParserTest.java&r1=917002&r2=917809&rev=917809&view=diff
>>>>>>
>>>>>>
>>>>>> ==============================================================================
>>>>>> ---
>>>>>>
>>>>>> incubator/aries/trunk/jndi/jndi-url/src/test/java/org/apache/aries/jndi/url/ServiceRegistryNameParserTest.java
>>>>>> (original)
>>>>>> +++
>>>>>>
>>>>>> incubator/aries/trunk/jndi/jndi-url/src/test/java/org/apache/aries/jndi/url/OsgiNameParserTest.java
>>>>>> Mon Mar  1 23:53:18 2010
>>>>>> @@ -18,11 +18,11 @@
>>>>>>  */
>>>>>>  package org.apache.aries.jndi.url;
>>>>>>  -import static org.junit.Assert.assertNotNull;
>>>>>>  import static org.junit.Assert.assertEquals;
>>>>>> +import static org.junit.Assert.assertFalse;
>>>>>> +import static org.junit.Assert.assertTrue;
>>>>>>  import javax.naming.InvalidNameException;
>>>>>> -import javax.naming.Name;
>>>>>>  import javax.naming.NameParser;
>>>>>>  import javax.naming.NamingException;
>>>>>>  @@ -31,10 +31,10 @@
>>>>>>  /**
>>>>>>  * This is where we test the service registry name parser.
>>>>>>  */
>>>>>> -public class ServiceRegistryNameParserTest
>>>>>> +public class OsgiNameParserTest
>>>>>>  {
>>>>>>  /** The parser we are going to use for testing */
>>>>>> -  private NameParser parser = new ServiceRegistryNameParser();
>>>>>> +  private NameParser parser = new OsgiNameParser();
>>>>>>   /**
>>>>>>   * OK, so we check that we can call checkNames multiple times.
>>>>>> @@ -43,8 +43,14 @@
>>>>>>  @Test
>>>>>>  public void checkValidNames() throws NamingException
>>>>>>  {
>>>>>> -    checkName("aries:services/java.lang.Runnable/(a=b)");
>>>>>> -    checkName("aries:services/java.lang.Runnable");
>>>>>> +    checkName("aries","services","java.lang.Runnable","(a=b)");
>>>>>> +    checkName("aries","services","java.lang.Runnable");
>>>>>> +    checkName("osgi","service","java.lang.Runnable");
>>>>>> +    checkName("osgi","service","java.lang.Runnable", "(a=b)");
>>>>>> +    checkName("osgi","servicelist","java.lang.Runnable");
>>>>>> +    checkName("osgi","servicelist","java.lang.Runnable", "(a=b)");
>>>>>> +    checkName("osgi","servicelist","jdbc", "grok", "DataSource");
>>>>>> +    checkName("osgi", "framework", "bundleContext");
>>>>>>  }
>>>>>>     /**
>>>>>> @@ -54,7 +60,7 @@
>>>>>>  @Test(expected=InvalidNameException.class)
>>>>>>  public void checkOutsideNamespace() throws NamingException
>>>>>>  {
>>>>>> -    checkName("java:comp/env/jms/cf");
>>>>>> +    checkName("java","comp","env","jms","cf");
>>>>>>  }
>>>>>>     /**
>>>>>> @@ -64,7 +70,7 @@
>>>>>>  @Test(expected=InvalidNameException.class)
>>>>>>  public void checkMissingInterface() throws NamingException
>>>>>>  {
>>>>>> -    checkName("aries:services");
>>>>>> +    checkName("aries","services");
>>>>>>  }
>>>>>>     /**
>>>>>> @@ -75,20 +81,64 @@
>>>>>>  @Test(expected=InvalidNameException.class)
>>>>>>  public void checkMissingInterface2() throws NamingException
>>>>>>  {
>>>>>> -    checkName("aries:services/");
>>>>>> +    checkName("aries","services", "");
>>>>>>  }
>>>>>> -
>>>>>> -  /**
>>>>>> -   * This method parses the name and then makes sure what was parsed
>>>>>> was
>>>>>> parsed
>>>>>> -   * correctly.
>>>>>> -   * -   * @param name
>>>>>> -   * @throws NamingException
>>>>>> -   */
>>>>>> -  private void checkName(String name) throws NamingException
>>>>>> +  +  @Test(expected=InvalidNameException.class)
>>>>>> +  public void checkIncorrectPath() throws NamingException
>>>>>> +  {
>>>>>> +    checkName("osgi", "services", "java.lang.Runnable"); +  }
>>>>>> +  +  @Test(expected=InvalidNameException.class)
>>>>>> +  public void checkIllegalPath() throws NamingException
>>>>>>  {
>>>>>> -    Name n = parser.parse(name);
>>>>>> -    assertNotNull("We got a null name back, which is not allowed.",
>>>>>> n);
>>>>>> -    assertEquals("The name's toString does not produce the original
>>>>>> value", name, n.toString());
>>>>>> +    checkName("osgi", "wibble", "java.lang.Runnable"); +  }
>>>>>> +  +  private void checkName(String scheme, String path, String ...
>>>>>> elements)
>>>>>> +    throws NamingException
>>>>>> +  {
>>>>>> +    StringBuilder builder = new StringBuilder();
>>>>>> +    StringBuilder serviceName = new StringBuilder();
>>>>>> +    +    builder.append(scheme);
>>>>>> +    builder.append(':');
>>>>>> +    builder.append(path);
>>>>>> +
>>>>>> +    if (elements.length > 0) {
>>>>>> +      builder.append('/');
>>>>>> +      +      for (String element : elements) {
>>>>>> +        serviceName.append(element);
>>>>>> +        serviceName.append('/');
>>>>>> +      }
>>>>>> +  +      serviceName.deleteCharAt(serviceName.length() - 1);
>>>>>> +      +      builder.append(serviceName);
>>>>>> +    }
>>>>>> +    +    OsgiName n = (OsgiName) parser.parse(builder.toString());
>>>>>> +    +    assertEquals(scheme, n.getScheme());
>>>>>> +    assertEquals(path, n.getSchemePath());
>>>>>> +    +    if (elements.length > 1) {
>>>>>> +      assertEquals(elements[0], n.getInterface());
>>>>>> +    }
>>>>>> +    +    if (elements.length == 1) {
>>>>>> +      assertFalse(n.hasFilter());
>>>>>> +    }
>>>>>> +    +    if (elements.length > 2) {
>>>>>> +      if (elements.length == 2) {
>>>>>> +        assertTrue(n.hasFilter());
>>>>>> +        assertEquals(elements[1], n.getFilter());
>>>>>> +      } else assertFalse(n.hasFilter());
>>>>>> +    }
>>>>>> +    +    assertEquals(serviceName.toString(), n.getServiceName());
>>>>>>  }
>>>>>>  }
>>>>>> \ No newline at end of file
>>>>>>
>>>>>> Modified:
>>>>>>
>>>>>> incubator/aries/trunk/jndi/jndi-url/src/test/java/org/apache/aries/jndi/url/ServiceRegistryContextTest.java
>>>>>> URL:
>>>>>>
>>>>>> http://svn.apache.org/viewvc/incubator/aries/trunk/jndi/jndi-url/src/test/java/org/apache/aries/jndi/url/ServiceRegistryContextTest.java?rev=917809&r1=917808&r2=917809&view=diff
>>>>>>
>>>>>>
>>>>>> ==============================================================================
>>>>>> ---
>>>>>>
>>>>>> incubator/aries/trunk/jndi/jndi-url/src/test/java/org/apache/aries/jndi/url/ServiceRegistryContextTest.java
>>>>>> (original)
>>>>>> +++
>>>>>>
>>>>>> incubator/aries/trunk/jndi/jndi-url/src/test/java/org/apache/aries/jndi/url/ServiceRegistryContextTest.java
>>>>>> Mon Mar  1 23:53:18 2010
>>>>>> @@ -21,7 +21,6 @@
>>>>>>  import static org.junit.Assert.assertEquals;
>>>>>>  import static org.junit.Assert.assertFalse;
>>>>>>  import static org.junit.Assert.assertNotNull;
>>>>>> -import static org.junit.Assert.assertSame;
>>>>>>  import static org.junit.Assert.assertTrue;
>>>>>>  import java.lang.reflect.Field;
>>>>>> @@ -37,6 +36,12 @@
>>>>>>  import javax.naming.NamingException;
>>>>>>  import javax.naming.spi.ObjectFactory;
>>>>>>  +import org.apache.aries.jndi.ContextHelper;
>>>>>> +import org.apache.aries.jndi.OSGiObjectFactoryBuilder;
>>>>>> +import org.apache.aries.mocks.BundleContextMock;
>>>>>> +import org.apache.aries.mocks.BundleMock;
>>>>>> +import org.apache.aries.unittest.mocks.MethodCall;
>>>>>> +import org.apache.aries.unittest.mocks.Skeleton;
>>>>>>  import org.junit.After;
>>>>>>  import org.junit.Before;
>>>>>>  import org.junit.Test;
>>>>>> @@ -47,22 +52,13 @@
>>>>>>  import org.osgi.framework.ServiceReference;
>>>>>>  import org.osgi.framework.ServiceRegistration;
>>>>>>  -import org.apache.aries.unittest.mocks.MethodCall;
>>>>>> -import org.apache.aries.unittest.mocks.Skeleton;
>>>>>> -import org.apache.aries.jndi.ContextHelper;
>>>>>> -import org.apache.aries.jndi.OSGiObjectFactoryBuilder;
>>>>>> -import org.apache.aries.jndi.services.ServiceHelper;
>>>>>> -import org.apache.aries.jndi.url.Activator;
>>>>>> -import org.apache.aries.mocks.BundleContextMock;
>>>>>> -import org.apache.aries.mocks.BundleMock;
>>>>>> -
>>>>>>  /**
>>>>>>  * Tests for our JNDI implementation for the service registry.
>>>>>>  */
>>>>>>  public class ServiceRegistryContextTest
>>>>>>  {
>>>>>>  /** The service we register by default */
>>>>>> -  private Thread service;
>>>>>> +  private Runnable service;
>>>>>>  /** The bundle context for the test */
>>>>>>  private BundleContext bc;
>>>>>>  /** The service registration for the service */
>>>>>> @@ -83,10 +79,7 @@
>>>>>>    new Activator().start(bc);
>>>>>>    new org.apache.aries.jndi.startup.Activator().start(bc);
>>>>>>    -    Field f = ServiceHelper.class.getDeclaredField("context");
>>>>>> -    f.setAccessible(true);
>>>>>> -    f.set(null, bc);
>>>>>> -    f = ContextHelper.class.getDeclaredField("context");
>>>>>> +    Field f = ContextHelper.class.getDeclaredField("context");
>>>>>>    f.setAccessible(true);
>>>>>>    f.set(null, bc);
>>>>>>    f = OSGiObjectFactoryBuilder.class.getDeclaredField("context");
>>>>>> @@ -94,7 +87,7 @@
>>>>>>    f.set(null, bc);
>>>>>>  -    service = new Thread();
>>>>>> +    service = Skeleton.newMock(Runnable.class);
>>>>>>         registerService(service);
>>>>>>  }
>>>>>> @@ -104,7 +97,7 @@
>>>>>>   *     * @param service2 The service to register.
>>>>>>   */
>>>>>> -  private void registerService(Thread service2)
>>>>>> +  private void registerService(Runnable service2)
>>>>>>  {
>>>>>>    ServiceFactory factory = Skeleton.newMock(ServiceFactory.class);
>>>>>>    Skeleton skel = Skeleton.getSkeleton(factory);
>>>>>> @@ -159,11 +152,13 @@
>>>>>>
>>>>>>  Thread.currentThread().setContextClassLoader(mock.getClassLoader());
>>>>>>    -    Object s = ctx.lookup("aries:services/java.lang.Runnable");
>>>>>> +    Runnable s = (Runnable)
>>>>>> ctx.lookup("aries:services/java.lang.Runnable");
>>>>>>         assertNotNull("We didn't get a service back from our lookup
>>>>>> :(",
>>>>>> s);
>>>>>>    -    assertEquals("The SR did not return the object we expected",
>>>>>> service, s);
>>>>>> +    s.run();
>>>>>> +    +
>>>>>>  Skeleton.getSkeleton(service).assertCalledExactNumberOfTimes(new
>>>>>> MethodCall(Runnable.class, "run"), 1);
>>>>>>         Skeleton skel = Skeleton.getSkeleton(mock.getBundleContext());
>>>>>>    @@ -173,7 +168,7 @@
>>>>>>
>>>>>>  Thread.currentThread().setContextClassLoader(mock.getClassLoader());
>>>>>>  -    s = ctx.lookup("osgi:services/java.lang.Runnable");
>>>>>> +    s = (Runnable) ctx.lookup("osgi:service/java.lang.Runnable");
>>>>>>         // Check we have the packages set correctly
>>>>>>    @@ -181,10 +176,11 @@
>>>>>>         assertTrue(ctx.getEnvironment().containsValue(packages));
>>>>>>  -         assertNotNull("We didn't get a service back from our lookup
>>>>>> :(", s);
>>>>>> +
>>>>>> +    s.run();
>>>>>>    -    assertEquals("The SR did not return the object we expected",
>>>>>> service, s);
>>>>>> +    Skeleton.getSkeleton(service).assertCalledExactNumberOfTimes(new
>>>>>> MethodCall(Runnable.class, "run"), 2);
>>>>>>     skel = Skeleton.getSkeleton(mock.getBundleContext());
>>>>>>    skel.assertCalled(new MethodCall(BundleContext.class,
>>>>>> "getServiceReferences", "java.lang.Runnable", null));
>>>>>> @@ -201,15 +197,21 @@
>>>>>>  @Test
>>>>>>  public void jndiLookupWithFilter() throws NamingException
>>>>>>  {
>>>>>> +    BundleMock mock = new BundleMock("scooby.doo", new Properties());
>>>>>> +    +
>>>>>>  Thread.currentThread().setContextClassLoader(mock.getClassLoader());
>>>>>> +
>>>>>>    InitialContext ctx = new InitialContext();
>>>>>>         Object s =
>>>>>> ctx.lookup("aries:services/java.lang.Runnable/(rubbish=smelly)");
>>>>>>         assertNotNull("We didn't get a service back from our lookup
>>>>>> :(",
>>>>>> s);
>>>>>>    -    assertEquals("The SR did not return the object we expected",
>>>>>> service, s);
>>>>>> +    service.run();
>>>>>>    -    Skeleton.getSkeleton(bc).assertCalled(new
>>>>>> MethodCall(BundleContext.class, "getServiceReferences",
>>>>>> "java.lang.Runnable", "(rubbish=smelly)"));
>>>>>> +    Skeleton.getSkeleton(service).assertCalledExactNumberOfTimes(new
>>>>>> MethodCall(Runnable.class, "run"), 1);
>>>>>> +
>>>>>> +    Skeleton.getSkeleton(mock.getBundleContext()).assertCalled(new
>>>>>> MethodCall(BundleContext.class, "getServiceReferences",
>>>>>> "java.lang.Runnable", "(rubbish=smelly)"));
>>>>>>  }
>>>>>>     /**
>>>>>> @@ -222,6 +224,11 @@
>>>>>>  public void testLookupWhenServiceHasBeenRemoved() throws
>>>>>> NamingException
>>>>>>  {
>>>>>>    reg.unregister();
>>>>>> +
>>>>>> +    BundleMock mock = new BundleMock("scooby.doo", new Properties());
>>>>>> +    +
>>>>>>  Thread.currentThread().setContextClassLoader(mock.getClassLoader());
>>>>>> +
>>>>>>    InitialContext ctx = new InitialContext();
>>>>>>         ctx.lookup("aries:services/java.lang.Runnable");
>>>>>> @@ -236,6 +243,10 @@
>>>>>>  @Test(expected=NameNotFoundException.class)
>>>>>>  public void testLookupForServiceWeNeverHad() throws NamingException
>>>>>>  {
>>>>>> +    BundleMock mock = new BundleMock("scooby.doo", new Properties());
>>>>>> +    +
>>>>>>  Thread.currentThread().setContextClassLoader(mock.getClassLoader());
>>>>>> +
>>>>>>    InitialContext ctx = new InitialContext();
>>>>>>         ctx.lookup("aries:services/java.lang.Integer");
>>>>>> @@ -271,14 +282,53 @@
>>>>>>  }
>>>>>>   @Test
>>>>>> +  public void checkProxyDynamism() throws NamingException
>>>>>> +  {
>>>>>> +    BundleMock mock = new BundleMock("scooby.doo", new Properties());
>>>>>> +    +
>>>>>>  Thread.currentThread().setContextClassLoader(mock.getClassLoader());
>>>>>> +
>>>>>> +    InitialContext ctx = new InitialContext();
>>>>>> +    +    String className = Runnable.class.getName();
>>>>>> +    +    Runnable t = Skeleton.newMock(Runnable.class);
>>>>>> +    Runnable t2 = Skeleton.newMock(Runnable.class);
>>>>>> +    +    // we don't want the default service
>>>>>> +    reg.unregister();
>>>>>> +    +    ServiceRegistration reg = bc.registerService(className, t,
>>>>>> null);
>>>>>> +    bc.registerService(className, t2, null);
>>>>>> +    +    Runnable r = (Runnable)
>>>>>> ctx.lookup("osgi:service/java.lang.Runnable");
>>>>>> +    +    r.run();
>>>>>> +    +    Skeleton.getSkeleton(t).assertCalledExactNumberOfTimes(new
>>>>>> MethodCall(Runnable.class, "run"), 1);
>>>>>> +    Skeleton.getSkeleton(t2).assertNotCalled(new
>>>>>> MethodCall(Runnable.class, "run"));
>>>>>> +    +    reg.unregister();
>>>>>> +    +    r.run();
>>>>>> +    +    Skeleton.getSkeleton(t).assertCalledExactNumberOfTimes(new
>>>>>> MethodCall(Runnable.class, "run"), 1);
>>>>>> +    Skeleton.getSkeleton(t2).assertCalledExactNumberOfTimes(new
>>>>>> MethodCall(Runnable.class, "run"), 1);
>>>>>> +  }  +
>>>>>> +  @Test
>>>>>>  public void checkServiceOrderObserved() throws NamingException
>>>>>>  {
>>>>>> +    BundleMock mock = new BundleMock("scooby.doo", new Properties());
>>>>>> +    +
>>>>>>  Thread.currentThread().setContextClassLoader(mock.getClassLoader());
>>>>>> +
>>>>>>    InitialContext ctx = new InitialContext();
>>>>>>         String className = Runnable.class.getName();
>>>>>>    -    Thread t = new Thread();
>>>>>> -    Thread t2 = new Thread();
>>>>>> +    Runnable t = Skeleton.newMock(Runnable.class);
>>>>>> +    Runnable t2 = Skeleton.newMock(Runnable.class);
>>>>>>         // we don't want the default service
>>>>>>    reg.unregister();
>>>>>> @@ -286,9 +336,12 @@
>>>>>>    ServiceRegistration reg = bc.registerService(className, t, null);
>>>>>>    ServiceRegistration reg2 = bc.registerService(className, t2, null);
>>>>>>    -    Runnable r = (Runnable)
>>>>>> ctx.lookup("osgi:services/java.lang.Runnable");
>>>>>> +    Runnable r = (Runnable)
>>>>>> ctx.lookup("osgi:service/java.lang.Runnable");
>>>>>>    -    assertSame("The wrong runnable was returned", t, r);
>>>>>> +    r.run();
>>>>>> +    +    Skeleton.getSkeleton(t).assertCalledExactNumberOfTimes(new
>>>>>> MethodCall(Runnable.class, "run"), 1);
>>>>>> +    Skeleton.getSkeleton(t2).assertNotCalled(new
>>>>>> MethodCall(Runnable.class, "run"));
>>>>>>         reg.unregister();
>>>>>>    reg2.unregister();
>>>>>> @@ -296,12 +349,18 @@
>>>>>>    Hashtable<String, Object> props = new Hashtable<String, Object>();
>>>>>>    props.put(Constants.SERVICE_RANKING, 55);
>>>>>>    +    t = Skeleton.newMock(Runnable.class);
>>>>>> +    t2 = Skeleton.newMock(Runnable.class);
>>>>>> +
>>>>>>    reg = bc.registerService(className, t, null);
>>>>>>    reg2 = bc.registerService(className, t2, props);
>>>>>>    -    r = (Runnable) ctx.lookup("osgi:services/java.lang.Runnable");
>>>>>> +    r = (Runnable) ctx.lookup("osgi:service/java.lang.Runnable");
>>>>>> +    +    r.run();
>>>>>>    -    assertSame("The wrong runnable was returned", t2, r);
>>>>>> +    Skeleton.getSkeleton(t).assertNotCalled(new
>>>>>> MethodCall(Runnable.class, "run"));
>>>>>> +    Skeleton.getSkeleton(t2).assertCalledExactNumberOfTimes(new
>>>>>> MethodCall(Runnable.class, "run"), 1);
>>>>>>  }
>>>>>>     /**
>>>>>>
>>>>>>
>>>>>>
>>>>>
>>>>> --
>>>>> Joe
>>>>>
>>>>
>>>>
>>>>
>>>
>>>
>>
>>
>
>
> --
> Joe
>



-- 
Alasdair Nottingham
not@apache.org

Re: svn commit: r917809 - in /incubator/aries/trunk/jndi/jndi-url: ./ src/main/java/org/apache/aries/jndi/services/ src/main/java/org/apache/aries/jndi/url/ src/test/java/org/apache/aries/jndi/url/

Posted by Joe Bohn <jo...@gmail.com>.
It looks like Blog-Sample is having the same issue and it doesn't use 
JSPs.   Here's a similar stack trace from blog-sample:

[1643210767@qtp-2131869628-0 - 
/org.apache.aries.samples.blog-servlet/ViewBlog] DEBUG 
org.apache.aries.blueprint.container.ServiceRecipe - Retrieving service 
for bundle org.ops4j.pax.web.pax-web-jetty-bundle_0.7.2 [6] and service 
registration 
{org.apache.aries.samples.blog.api.BloggingService}={osgi.service.blueprint.compname=bloggingServiceComponent, 
service.id=52}
java.lang.ClassNotFoundException: 
org.apache.aries.samples.blog.api.BloggingService
         at 
org.eclipse.osgi.internal.loader.BundleLoader.findClassInternal(BundleLoader.java:489)
         at 
org.eclipse.osgi.internal.loader.BundleLoader.findClass(BundleLoader.java:405)
         at 
org.eclipse.osgi.internal.loader.BundleLoader.findClass(BundleLoader.java:393)
         at 
org.eclipse.osgi.internal.baseadaptor.DefaultClassLoader.loadClass(DefaultClassLoader.java:105)
         at java.lang.ClassLoader.loadClass(ClassLoader.java:250)
         at 
org.eclipse.osgi.internal.loader.BundleLoader.loadClass(BundleLoader.java:321)
         at 
org.eclipse.osgi.framework.internal.core.BundleHost.loadClass(BundleHost.java:231)
         at 
org.eclipse.osgi.framework.internal.core.AbstractBundle.loadClass(AbstractBundle.java:1193)
         at 
org.apache.aries.jndi.services.ServiceHelper.getService(ServiceHelper.java:210)
         at 
org.apache.aries.jndi.url.ServiceRegistryContext.lookup(ServiceRegistryContext.java:189)
         at 
org.apache.aries.jndi.url.ServiceRegistryContext.lookup(ServiceRegistryContext.java:218)
         at 
org.apache.aries.jndi.DelegateContext.lookup(DelegateContext.java:160)
         at javax.naming.InitialContext.lookup(InitialContext.java:392)
         at 
org.apache.aries.samples.blog.web.util.JNDIHelper.getBloggingService(JNDIHelper.java:33)
         at 
org.apache.aries.samples.blog.web.ViewBlog.doGet(ViewBlog.java:53)
         at javax.servlet.http.HttpServlet.service(HttpServlet.java:707)
         at javax.servlet.http.HttpServlet.service(HttpServlet.java:820)
         at 
org.mortbay.jetty.servlet.ServletHolder.handle(ServletHolder.java:502)
         at 
org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)
         at 
org.ops4j.pax.web.service.internal.WelcomeFilesFilter.doFilter(WelcomeFilesFilter.java:169)
         at 
org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1148)
         at 
org.mortbay.jetty.servlet.ServletHandler.handle(ServletHandler.java:387)
         at 
org.ops4j.pax.web.service.jetty.internal.HttpServiceServletHandler.handle(HttpServiceServletHandler.java:64)
         at 
org.mortbay.jetty.servlet.SessionHandler.handle(SessionHandler.java:181)
         at 
org.mortbay.jetty.handler.ContextHandler.handle(ContextHandler.java:765)
         at 
org.ops4j.pax.web.service.jetty.internal.HttpServiceContext.handle(HttpServiceContext.java:111)
         at 
org.ops4j.pax.web.service.jetty.internal.JettyServerHandlerCollection.handle(JettyServerHandlerCollection.java:64)
         at 
org.mortbay.jetty.handler.HandlerWrapper.handle(HandlerWrapper.java:152)
         at org.mortbay.jetty.Server.handle(Server.java:322)
         at 
org.mortbay.jetty.HttpConnection.handleRequest(HttpConnection.java:534)
         at 
org.mortbay.jetty.HttpConnection$RequestHandler.headerComplete(HttpConnection.java:864)
         at org.mortbay.jetty.HttpParser.parseNext(HttpParser.java:539)
         at org.mortbay.jetty.HttpParser.parseAvailable(HttpParser.java:212)
         at org.mortbay.jetty.HttpConnection.handle(HttpConnection.java:404)
         at 
org.mortbay.io.nio.SelectChannelEndPoint.run(SelectChannelEndPoint.java:409)
         at 
org.mortbay.thread.QueuedThreadPool$PoolThread.run(QueuedThreadPool.java:520)


Joe Bohn wrote:
> 
> And here's the thread context classloader before the lookup ...
> 
> JasperClassLoader{bundleClassLoader=BundleClassLoader{bundle=org.apache.aries.ariestrader.modules.ariestrader-web_1.0.0.incubating-SNAPSHOT 
> [35],parent=org.eclipse.osgi.internal.baseadaptor.DefaultClassLoader@78ecf608}} 
> 
> 
> 
> Joe
> 
> Joe Bohn wrote:
>>
>> Here's the stack trace for the CNFE.  I'll have to work on getting the 
>> thread context classloader.
>>
>> [112793090@qtp-2020456228-2 - 
>> /org.apache.aries.ariestrader.modules.ariestrader-web/config] DEBUG 
>> org.apache.aries.blueprint.container.ServiceRecipe - Calling listeners 
>> for initial service registration
>> java.lang.ClassNotFoundException: 
>> org.apache.aries.samples.ariestrader.api.TradeServicesManager
>>         at 
>> org.eclipse.osgi.internal.loader.BundleLoader.findClassInternal(BundleLoader.java:489) 
>>
>>         at 
>> org.eclipse.osgi.internal.loader.BundleLoader.findClass(BundleLoader.java:405) 
>>
>>         at 
>> org.eclipse.osgi.internal.loader.BundleLoader.findClass(BundleLoader.java:393) 
>>
>>         at 
>> org.eclipse.osgi.internal.baseadaptor.DefaultClassLoader.loadClass(DefaultClassLoader.java:105) 
>>
>>         at java.lang.ClassLoader.loadClass(ClassLoader.java:250)
>>         at 
>> org.eclipse.osgi.internal.loader.BundleLoader.loadClass(BundleLoader.java:321) 
>>
>>         at 
>> org.eclipse.osgi.framework.internal.core.BundleHost.loadClass(BundleHost.java:231) 
>>
>>         at 
>> org.eclipse.osgi.framework.internal.core.AbstractBundle.loadClass(AbstractBundle.java:1193) 
>>
>>         at 
>> org.apache.aries.jndi.services.ServiceHelper.getService(ServiceHelper.java:210) 
>>
>>         at 
>> org.apache.aries.jndi.url.ServiceRegistryContext.lookup(ServiceRegistryContext.java:189) 
>>
>>         at 
>> org.apache.aries.jndi.url.ServiceRegistryContext.lookup(ServiceRegistryContext.java:218) 
>>
>>         at 
>> org.apache.aries.jndi.DelegateContext.lookup(DelegateContext.java:160)
>>         at javax.naming.InitialContext.lookup(InitialContext.java:392)
>>         at 
>> org.apache.aries.samples.ariestrader.util.ServiceUtilities.getOSGIService(ServiceUtilities.java:60) 
>>
>>         at 
>> org.apache.aries.samples.ariestrader.util.ServiceUtilities.getOSGIService(ServiceUtilities.java:41) 
>>
>>         at 
>> org.apache.aries.samples.ariestrader.api.TradeServiceUtilities.getTradeServicesManager(TradeServiceUtilities.java:63) 
>>
>>         at org.apache.jsp.config_jsp._jspService(config_jsp.java:86)
>>         at 
>> org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:70)
>>         at javax.servlet.http.HttpServlet.service(HttpServlet.java:820)
>>         at 
>> org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:374) 
>>
>>         at 
>> org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:342)
>>         at 
>> org.apache.jasper.servlet.JspServlet.service(JspServlet.java:267)
>>         at javax.servlet.http.HttpServlet.service(HttpServlet.java:820)
>>         at 
>> org.ops4j.pax.web.jsp.JspServletWrapper$2.call(JspServletWrapper.java:132) 
>>
>>         at 
>> org.ops4j.pax.web.jsp.JspServletWrapper$2.call(JspServletWrapper.java:127) 
>>
>>         at 
>> org.ops4j.pax.swissbox.core.ContextClassLoaderUtils.doWithClassLoader(ContextClassLoaderUtils.java:60) 
>>
>>         at 
>> org.ops4j.pax.web.jsp.JspServletWrapper.service(JspServletWrapper.java:124) 
>>
>>         at 
>> org.mortbay.jetty.servlet.ServletHolder.handle(ServletHolder.java:502)
>>         at 
>> org.mortbay.jetty.servlet.ServletHandler.handle(ServletHandler.java:389)
>>         at 
>> org.ops4j.pax.web.service.jetty.internal.HttpServiceServletHandler.handle(HttpServiceServletHandler.java:64) 
>>
>>         at 
>> org.mortbay.jetty.servlet.SessionHandler.handle(SessionHandler.java:181)
>>         at 
>> org.mortbay.jetty.handler.ContextHandler.handle(ContextHandler.java:765)
>>         at 
>> org.ops4j.pax.web.service.jetty.internal.HttpServiceContext.handle(HttpServiceContext.java:111) 
>>
>>         at 
>> org.mortbay.jetty.servlet.Dispatcher.include(Dispatcher.java:192)
>>         at 
>> org.apache.aries.samples.ariestrader.web.TradeConfigServlet.doConfigDisplay(TradeConfigServlet.java:62) 
>>
>>         at 
>> org.apache.aries.samples.ariestrader.web.TradeConfigServlet.service(TradeConfigServlet.java:403) 
>>
>>         at javax.servlet.http.HttpServlet.service(HttpServlet.java:820)
>>         at 
>> org.mortbay.jetty.servlet.ServletHolder.handle(ServletHolder.java:502)
>>         at 
>> org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157) 
>>
>>         at 
>> org.ops4j.pax.web.service.internal.WelcomeFilesFilter.doFilter(WelcomeFilesFilter.java:169) 
>>
>>         at 
>> org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1148) 
>>
>>         at 
>> org.mortbay.jetty.servlet.ServletHandler.handle(ServletHandler.java:387)
>>         at 
>> org.ops4j.pax.web.service.jetty.internal.HttpServiceServletHandler.handle(HttpServiceServletHandler.java:64) 
>>
>>         at 
>> org.mortbay.jetty.servlet.SessionHandler.handle(SessionHandler.java:181)
>>         at 
>> org.mortbay.jetty.handler.ContextHandler.handle(ContextHandler.java:765)
>>         at 
>> org.ops4j.pax.web.service.jetty.internal.HttpServiceContext.handle(HttpServiceContext.java:111) 
>>
>>         at 
>> org.ops4j.pax.web.service.jetty.internal.JettyServerHandlerCollection.handle(JettyServerHandlerCollection.java:64) 
>>
>>         at 
>> org.mortbay.jetty.handler.HandlerWrapper.handle(HandlerWrapper.java:152)
>>         at org.mortbay.jetty.Server.handle(Server.java:322)
>>         at 
>> org.mortbay.jetty.HttpConnection.handleRequest(HttpConnection.java:534)
>>         at 
>> org.mortbay.jetty.HttpConnection$RequestHandler.headerComplete(HttpConnection.java:864) 
>>
>>         at org.mortbay.jetty.HttpParser.parseNext(HttpParser.java:539)
>>         at 
>> org.mortbay.jetty.HttpParser.parseAvailable(HttpParser.java:212)
>>         at 
>> org.mortbay.jetty.HttpConnection.handle(HttpConnection.java:404)
>>         at 
>> org.mortbay.io.nio.SelectChannelEndPoint.run(SelectChannelEndPoint.java:409) 
>>
>>         at 
>> org.mortbay.thread.QueuedThreadPool$PoolThread.run(QueuedThreadPool.java:520) 
>>
>>
>> Alasdair Nottingham wrote:
>>> Hi,
>>>
>>> Hmm, I suspect I am not correctly finding the appropriate
>>> BundleContext to use. That would explain the CNFE because we now proxy
>>> the services rather than returning the raw service. If it is being
>>> listed as being used by the pax-web jsp bundle that would explain
>>> things.
>>>
>>> Do you have a stack trace for the ClassNotFoundException? That might
>>> help to work out what went wrong.
>>>
>>> Also can you check the thread context classloader before the lookup?
>>>
>>> Thanks
>>> Alasdair
>>>
>>> On 2 March 2010 23:21, Joe Bohn <jo...@gmail.com> wrote:
>>>> I think there are some issues with this change.   I'll have to dig 
>>>> some more
>>>> and post more details later (don't have time right now) ... but in 
>>>> short I'm
>>>> seeing the following:
>>>>
>>>> - AriesTrader is behaving very badly after this change.
>>>> - From within a jsp we use jndi lookup to find an osgi service.
>>>> - After this change I get a failure in my jsp with a CNFE.   This 
>>>> despite
>>>> the fact that I can see the package is imported on the web bundle and
>>>> appears to be wired correctly.
>>>> - Even more strange: I notice that the application service I was 
>>>> looking for
>>>> is listed as being used by the pax-web jsp bundle.  So it seems like we
>>>> might be using the wrong bundle context at some point.
>>>>
>>>>
>>>> Joe
>>>>
>>>>
>>>>
>>>> not@apache.org wrote:
>>>>> Author: not
>>>>> Date: Mon Mar  1 23:53:18 2010
>>>>> New Revision: 917809
>>>>>
>>>>> URL: http://svn.apache.org/viewvc?rev=917809&view=rev
>>>>> Log:
>>>>> ARIES-128 Implement OSGi spec url lookup scheme
>>>>>
>>>>> Added:
>>>>>
>>>>>  incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/OsgiName.java 
>>>>>
>>>>>      - copied, changed from r910238,
>>>>> incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/ServiceRegistryName.java 
>>>>>
>>>>>
>>>>>  incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/OsgiNameParser.java 
>>>>>
>>>>>      - copied, changed from r910238,
>>>>> incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/ServiceRegistryNameParser.java 
>>>>>
>>>>>
>>>>>  incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/ServiceRegistryListContext.java 
>>>>>
>>>>>
>>>>>  incubator/aries/trunk/jndi/jndi-url/src/test/java/org/apache/aries/jndi/url/OsgiNameParserTest.java 
>>>>>
>>>>>      - copied, changed from r917002,
>>>>> incubator/aries/trunk/jndi/jndi-url/src/test/java/org/apache/aries/jndi/url/ServiceRegistryNameParserTest.java 
>>>>>
>>>>> Removed:
>>>>>
>>>>>  incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/ServiceRegistryName.java 
>>>>>
>>>>>
>>>>>  incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/ServiceRegistryNameParser.java 
>>>>>
>>>>>
>>>>>  incubator/aries/trunk/jndi/jndi-url/src/test/java/org/apache/aries/jndi/url/ServiceHelperTest.java 
>>>>>
>>>>>
>>>>>  incubator/aries/trunk/jndi/jndi-url/src/test/java/org/apache/aries/jndi/url/ServiceRegistryNameParserTest.java 
>>>>>
>>>>> Modified:
>>>>>    incubator/aries/trunk/jndi/jndi-url/pom.xml
>>>>>
>>>>>  incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/services/ServiceHelper.java 
>>>>>
>>>>>
>>>>>  incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/Activator.java 
>>>>>
>>>>>
>>>>>  incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/OsgiURLContextFactory.java 
>>>>>
>>>>>
>>>>>  incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/ServiceRegistryContext.java 
>>>>>
>>>>>
>>>>>  incubator/aries/trunk/jndi/jndi-url/src/test/java/org/apache/aries/jndi/url/ServiceRegistryContextTest.java 
>>>>>
>>>>>
>>>>> Modified: incubator/aries/trunk/jndi/jndi-url/pom.xml
>>>>> URL:
>>>>> http://svn.apache.org/viewvc/incubator/aries/trunk/jndi/jndi-url/pom.xml?rev=917809&r1=917808&r2=917809&view=diff 
>>>>>
>>>>>
>>>>> ============================================================================== 
>>>>>
>>>>> --- incubator/aries/trunk/jndi/jndi-url/pom.xml (original)
>>>>> +++ incubator/aries/trunk/jndi/jndi-url/pom.xml Mon Mar  1 23:53:18 
>>>>> 2010
>>>>> @@ -33,6 +33,10 @@
>>>>>      <dependencies>
>>>>>       <dependency>
>>>>> +       <groupId>org.apache.aries</groupId>
>>>>> +       <artifactId>org.apache.aries.util</artifactId>
>>>>> +      </dependency>
>>>>> +      <dependency>
>>>>>           <groupId>org.osgi</groupId>
>>>>>           <artifactId>org.osgi.core</artifactId>
>>>>>           <scope>provided</scope>
>>>>>
>>>>> Modified:
>>>>> incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/services/ServiceHelper.java 
>>>>>
>>>>> URL:
>>>>> http://svn.apache.org/viewvc/incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/services/ServiceHelper.java?rev=917809&r1=917808&r2=917809&view=diff 
>>>>>
>>>>>
>>>>> ============================================================================== 
>>>>>
>>>>> ---
>>>>> incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/services/ServiceHelper.java 
>>>>>
>>>>> (original)
>>>>> +++
>>>>> incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/services/ServiceHelper.java 
>>>>>
>>>>> Mon Mar  1 23:53:18 2010
>>>>> @@ -18,18 +18,30 @@
>>>>>  */
>>>>>  package org.apache.aries.jndi.services;
>>>>>  +import java.lang.reflect.InvocationHandler;
>>>>> +import java.lang.reflect.Method;
>>>>> +import java.lang.reflect.Proxy;
>>>>> +import java.security.AccessController;
>>>>> +import java.security.PrivilegedAction;
>>>>> +import java.util.ArrayList;
>>>>>  import java.util.Arrays;
>>>>>  import java.util.Comparator;
>>>>>  import java.util.HashSet;
>>>>>  import java.util.LinkedList;
>>>>>  import java.util.List;
>>>>> +import java.util.Map;
>>>>>  import java.util.Set;
>>>>>  import java.util.concurrent.ConcurrentHashMap;
>>>>>  import java.util.concurrent.ConcurrentMap;
>>>>>  +import javax.naming.NamingException;
>>>>> +
>>>>> +import org.apache.aries.util.BundleToClassLoaderAdapter;
>>>>> +import org.osgi.framework.Bundle;
>>>>>  import org.osgi.framework.BundleContext;
>>>>>  import org.osgi.framework.BundleReference;
>>>>>  import org.osgi.framework.InvalidSyntaxException;
>>>>> +import org.osgi.framework.ServiceException;
>>>>>  import org.osgi.framework.ServiceReference;
>>>>>  /**
>>>>> @@ -47,221 +59,206 @@
>>>>>  */
>>>>>  public final class ServiceHelper
>>>>>  {
>>>>> -  /** The bundle context used for service registry queries */
>>>>> -  private static BundleContext context;
>>>>> -  /** A cache of what service was returned last time the query was
>>>>> performed */
>>>>> -  private static ConcurrentMap<ServiceKey, Set<ServiceReference>> 
>>>>> cache =
>>>>> new ConcurrentHashMap<ServiceKey, Set<ServiceReference>>();
>>>>> -
>>>>> -  public static void setBundleContext(BundleContext ctx)
>>>>> +  public static class StackFinder extends SecurityManager
>>>>>   {
>>>>> -    context = ctx;
>>>>> +    public Class<?>[] getClassContext()
>>>>> +    {
>>>>> +      return super.getClassContext();
>>>>> +    }
>>>>>   }
>>>>> -  -  /**
>>>>> -   * This class is used as the key into the cache. It holds 
>>>>> information
>>>>> to identify -   * who performed the query, along with the className 
>>>>> and
>>>>> filter used. The thread context
>>>>> -   * class loader is used in the key, so two different modules will
>>>>> potentially get different
>>>>> -   * services.
>>>>> -   */
>>>>> -  private static final class ServiceKey
>>>>> +
>>>>> +  private static class JNDIServiceDamper implements InvocationHandler
>>>>>   {
>>>>> -    /** The class loader of the invoking application */
>>>>> -    private ClassLoader classLoader;
>>>>> -    /** The name of the class being queried from the registry */
>>>>> -    private String className;
>>>>> -    /** the registry filter, this may be null */
>>>>> +    private BundleContext ctx;
>>>>> +    private ServicePair pair;
>>>>> +    private String interfaceName;
>>>>>     private String filter;
>>>>> -    /** The cached hashCode */
>>>>> -    private final int hashCode;
>>>>> -
>>>>> -    /**
>>>>> -     * Boring unimportant comment.
>>>>> -     * -     * @param cl
>>>>> -     * @param cn
>>>>> -     * @param f
>>>>> -     */
>>>>> -    public ServiceKey(ClassLoader cl, String cn, String f)
>>>>> +    private boolean dynamic;
>>>>> +    +    public JNDIServiceDamper(BundleContext context, String i, 
>>>>> String
>>>>> f, ServicePair service, boolean d)
>>>>>     {
>>>>> -      classLoader = cl;
>>>>> -      className = cn;
>>>>> +      ctx = context;
>>>>> +      pair = service;
>>>>> +      interfaceName = i;
>>>>>       filter = f;
>>>>> -      -      int classNameHash = (className == null) ? 0 :
>>>>> className.hashCode();
>>>>> -      hashCode = System.identityHashCode(classLoader) * 1000003 +
>>>>> classNameHash;
>>>>> +      dynamic = d;
>>>>>     }
>>>>> -
>>>>> -    @Override
>>>>> -    public int hashCode()
>>>>> -    {
>>>>> -      return hashCode;
>>>>> -    }
>>>>> -
>>>>> -    @Override
>>>>> -    public boolean equals(Object other)
>>>>> +    +    public Object invoke(Object proxy, Method method, 
>>>>> Object[] args)
>>>>> throws Throwable
>>>>>     {
>>>>> -      if (other == this) return true;
>>>>> -      if (other == null) return false;
>>>>> -
>>>>> -      if (other instanceof ServiceKey) {
>>>>> -        ServiceKey otherKey = (ServiceKey) other;
>>>>> -        if (hashCode != otherKey.hashCode) return false;
>>>>> -
>>>>> -        if (classLoader != otherKey.classLoader) return false;
>>>>> -        if (!!!comparePossiblyNullObjects(className, 
>>>>> otherKey.className))
>>>>> return false;
>>>>> -        return comparePossiblyNullObjects(filter, otherKey.filter);
>>>>> -      }
>>>>> -
>>>>> -      return false;
>>>>> -    }
>>>>> -    -    /**
>>>>> -     * Compares two objects where one or other (or both) may be null.
>>>>> -     * -     * @param a the first object to compare.
>>>>> -     * @param b the second object to compare.
>>>>> -     * @return true if they are ==, both null or identity equals, 
>>>>> false
>>>>> otherwise.
>>>>> -     */
>>>>> -    public boolean comparePossiblyNullObjects(Object a, Object b) {
>>>>> -      if (a == b) return true;
>>>>> -      else if (a == null) return false;
>>>>> -      else return a.equals(b);
>>>>> +      if (pair.ref.getBundle() == null) {
>>>>> +        if (dynamic) pair = findService(ctx, interfaceName, filter);
>>>>> +        else pair = null;
>>>>> +      }
>>>>> +      +      if (pair == null) {
>>>>> +        throw new ServiceException(interfaceName,
>>>>> ServiceException.UNREGISTERED);
>>>>> +      }
>>>>> +      +      return method.invoke(pair.service, args);
>>>>>     }
>>>>>   }
>>>>> -
>>>>> -  /**
>>>>> -   * This method is used to obtain a single instance of a desired 
>>>>> service
>>>>> from the OSGi
>>>>> -   * service registry. If the filter and class name identify multiple
>>>>> services the first
>>>>> -   * one is returned. If no service is found null will be returned.
>>>>> -   * -   * @param className The class name used to register the 
>>>>> desired
>>>>> service. If null is provided
>>>>> -   *                  then all services are eligible to be returned.
>>>>> -   * @param filter    An RFC 1960 query into the properties of the
>>>>> registered services. e.g.
>>>>> -   *                  (service.description=really useful)
>>>>> -   * @return          The desired service
>>>>> -   * -   * @throws IllegalArgumentException If the filter is not 
>>>>> valid.
>>>>> See RFC 1960 to work out what -   
>>>>> *                                  it
>>>>> should be.
>>>>> -   */
>>>>> -  public static Object getService(String className, String filter) 
>>>>> throws
>>>>> IllegalArgumentException
>>>>> +  +  private static class ServicePair
>>>>>   {
>>>>> -    Object service = null;
>>>>> -    try {
>>>>> -      BundleContext callerCtx = getBundleContext();
>>>>> -      ServiceReference[] refs = 
>>>>> callerCtx.getServiceReferences(className,
>>>>> filter);
>>>>> -      -      if (refs != null) {
>>>>> -        // we need to sort the references returned in case they 
>>>>> are out
>>>>> of order
>>>>> -        // we need to sort in the reverse natural order, services 
>>>>> with
>>>>> higher -        // ranking or lower id should be processed first so 
>>>>> should
>>>>> be earlier in the array.
>>>>> -        Arrays.sort(refs, new Comparator<ServiceReference>() {
>>>>> -          public int compare(ServiceReference o1, ServiceReference 
>>>>> o2)
>>>>> -          {
>>>>> -            return o2.compareTo(o1);
>>>>> -          }
>>>>> -        });
>>>>> -        -        for (ServiceReference ref : refs) {
>>>>> -          List<Object> services = getServices(callerCtx, className,
>>>>> filter, ref);
>>>>> -          if (!!!services.isEmpty()) {
>>>>> -            service = services.get(0);
>>>>> -            break;
>>>>> -          }
>>>>> -        }
>>>>> -      }      -    } catch (InvalidSyntaxException e) {
>>>>> -      throw new IllegalArgumentException(e.getMessage(), e);
>>>>> -    }
>>>>> -    -    return service;
>>>>> +    private ServiceReference ref;
>>>>> +    private Object service;
>>>>>   }
>>>>>      /**
>>>>> -   * This method is used to obtain a list of service instances 
>>>>> from the
>>>>> OSGi
>>>>> -   * service registry. If no service is found an empty list will be
>>>>> returned.
>>>>> -   * -   * @param className The class name used to register the 
>>>>> desired
>>>>> service. If null is provided
>>>>> -   *                  then all services are eligible to be returned.
>>>>> -   * @param filter    An RFC 1960 query into the properties of the
>>>>> registered services. e.g.
>>>>> -   *                  (service.description=really useful)
>>>>> -   * @return          A list of matching services.
>>>>> -   * -   * @throws IllegalArgumentException If the filter is not 
>>>>> valid.
>>>>> See RFC 1960 to work out what -   
>>>>> *                                  it
>>>>> should be.
>>>>> +   * @param env +   * @return the bundle context for the caller.
>>>>> +   * @throws NamingException     */
>>>>> -  public static List<?> getServices(String className, String filter)
>>>>> -      throws IllegalArgumentException
>>>>> +  public static BundleContext getBundleContext(Map<String, Object> 
>>>>> env)
>>>>> throws NamingException
>>>>>   {
>>>>> -    List<Object> services;
>>>>> -    try {
>>>>> -      BundleContext callerCtx = getBundleContext();
>>>>> -      ServiceReference[] refs =
>>>>> callerCtx.getAllServiceReferences(className, filter);
>>>>> +    BundleContext result = null;
>>>>> +    +    Object bc = env.get("osgi.service.jndi.bundleContext");
>>>>> +    +    if (bc != null && bc instanceof BundleContext) result =
>>>>> (BundleContext) bc;
>>>>> +    else {
>>>>> +      ClassLoader cl = AccessController.doPrivileged(new
>>>>> PrivilegedAction<ClassLoader>() {
>>>>> +        public ClassLoader run()
>>>>> +        {
>>>>> +          return Thread.currentThread().getContextClassLoader();
>>>>> +        }
>>>>> +      });
>>>>>       -      services = getServices(callerCtx, className, filter, 
>>>>> refs);
>>>>> -    } catch (InvalidSyntaxException e) {
>>>>> -      throw new IllegalArgumentException(e.getMessage(), e);
>>>>> +      result = getBundleContext(cl);
>>>>> +    }
>>>>> +    +    if (result == null) {
>>>>> +      StackTraceElement[] stackTrace = 
>>>>> AccessController.doPrivileged(new
>>>>> PrivilegedAction<StackTraceElement[]>() {
>>>>> +        public StackTraceElement[] run()
>>>>> +        {
>>>>> +          return Thread.currentThread().getStackTrace();
>>>>> +        }
>>>>> +      });
>>>>> +      +      StackFinder finder = new StackFinder();
>>>>> +      Class<?>[] classStack = finder.getClassContext();
>>>>> +      +      boolean found = false;
>>>>> +      boolean foundLookup = false;
>>>>> +      int i = 0;
>>>>> +      for (; i < stackTrace.length && !!!found; i++) {
>>>>> +        if (!!!foundLookup &&
>>>>> "lookup".equals(stackTrace[i].getMethodName())) {
>>>>> +          foundLookup = true;
>>>>> +        } else if (foundLookup &&
>>>>> !!!(stackTrace[i].getClassName().startsWith("org.apache.aries.jndi") 
>>>>> ||
>>>>> +
>>>>>  stackTrace[i].getClassName().startsWith("javax.naming"))) {
>>>>> +          found = true;
>>>>> +        }
>>>>> +      }
>>>>> +      +      if (found) {
>>>>> +        Set<Integer> classLoadersChecked = new HashSet<Integer>();
>>>>> +        for (; i < classStack.length && result == null; i++) {
>>>>> +          ClassLoader cl = classStack[i].getClassLoader();
>>>>> +          int hash = System.identityHashCode(cl);
>>>>> +          if (!!!classLoadersChecked.contains(hash)) {
>>>>> +            classLoadersChecked.add(hash);
>>>>> +            result = getBundleContext(cl);
>>>>> +          }
>>>>> +        }
>>>>> +        // Now we walk the stack looking for the BundleContext
>>>>> +      }
>>>>>     }
>>>>>     -    return services;
>>>>> +    if (result == null) throw new NamingException("Unable to find
>>>>> BundleContext");
>>>>> +    +    return result;
>>>>>   }
>>>>> -  -  /**
>>>>> -   * @return the bundle context for the caller.
>>>>> -   */
>>>>> -  private static BundleContext getBundleContext()
>>>>> +
>>>>> +  private static BundleContext getBundleContext(ClassLoader cl)
>>>>>   {
>>>>>     BundleContext result = null;
>>>>> -    ClassLoader cl = Thread.currentThread().getContextClassLoader();
>>>>>     while (result == null && cl != null) {
>>>>>       if (cl instanceof BundleReference) {
>>>>>         result = ((BundleReference)cl).getBundle().getBundleContext();
>>>>>       } else if (cl != null) {
>>>>>         cl = cl.getParent();
>>>>>       }
>>>>> -    } +    }
>>>>>     -    if (result == null) result = context;
>>>>>     return result;
>>>>>   }
>>>>>  -  /**
>>>>> -   * This worker method obtains the requested service(s) and if the
>>>>> service(s) -   * exist updates the cache and releases the previous
>>>>> service(s).
>>>>> -   * -   * @param callerCtx The caller context.
>>>>> -   * @param className The class name used to query for the service.
>>>>> -   * @param filter    The filter name used to query for the service.
>>>>> -   * @param refs      The references to get.
>>>>> -   * @return          The service, if one was found, or null.
>>>>> -   */
>>>>> -  private static List<Object> getServices(BundleContext callerCtx, 
>>>>> String
>>>>> className, String filter, ServiceReference...refs)
>>>>> +  public static Object getService(String interface1, String filter,
>>>>> String serviceName, boolean dynamicRebind, Map<String, Object> env) 
>>>>> throws
>>>>> NamingException
>>>>>   {
>>>>> -    List<Object> data = new LinkedList<Object>();
>>>>> +    Object result = null;
>>>>> +    +    BundleContext ctx = getBundleContext(env);
>>>>> +    +    ServicePair pair = findService(ctx, interface1, filter);
>>>>>     -    if (refs != null) {
>>>>> -      Set<ServiceReference> refSet = new HashSet<ServiceReference>();
>>>>> -      for (ServiceReference ref : refs) {
>>>>> -        Object service = callerCtx.getService(ref);
>>>>> -        if (service != null) {
>>>>> -          data.add(service);
>>>>> -          refSet.add(ref);
>>>>> +    if (pair == null) {
>>>>> +      interface1 = null;
>>>>> +      filter = "(osgi.jndi.serviceName=" + serviceName + ")";
>>>>> +      pair = findService(ctx, interface1, filter);
>>>>> +    }
>>>>> +    +    if (pair != null) {
>>>>> +      String[] interfaces = (String[])
>>>>> pair.ref.getProperty("objectClass");
>>>>> +      +      List<Class<?>> clazz = new
>>>>> ArrayList<Class<?>>(interfaces.length);
>>>>> +      +      Bundle b = ctx.getBundle();
>>>>> +      +      for (String interfaceName : interfaces) {
>>>>> +        try {
>>>>> +          clazz.add(b.loadClass(interfaceName));
>>>>> +        } catch (ClassNotFoundException e) {
>>>>> +          // TODO Auto-generated catch block
>>>>> +          e.printStackTrace();
>>>>>         }
>>>>>       }
>>>>>       -      ClassLoader cl =
>>>>> Thread.currentThread().getContextClassLoader();
>>>>> -      ServiceKey key = new ServiceKey(cl, className, filter);
>>>>> +      if (clazz.isEmpty()) {
>>>>> +        throw new IllegalArgumentException();
>>>>> +      }
>>>>>       -      // we do not need any synchronization around this. The 
>>>>> map is
>>>>> concurrent
>>>>> -      // and until here we do not touch any shared state.
>>>>> -      refSet = cache.put(key, refSet);
>>>>> +      InvocationHandler ih = new JNDIServiceDamper(ctx, interface1,
>>>>> filter, pair, dynamicRebind);
>>>>>       -      if (refSet != null) {
>>>>> -        for (ServiceReference ref : refSet) {
>>>>> -          callerCtx.ungetService(ref);
>>>>> +      result = Proxy.newProxyInstance(new 
>>>>> BundleToClassLoaderAdapter(b),
>>>>> clazz.toArray(new Class<?>[clazz.size()]), ih);
>>>>> +    }
>>>>> +    +    return result;
>>>>> +  }
>>>>> +
>>>>> +  private static ServicePair findService(BundleContext ctx, String
>>>>> interface1, String filter)
>>>>> +  {
>>>>> +    ServicePair p = null;
>>>>> +    +    try {
>>>>> +      ServiceReference[] refs = ctx.getServiceReferences(interface1,
>>>>> filter);
>>>>> +      +      if (refs != null) {
>>>>> +        // natural order is the exact opposite of the order we 
>>>>> desire.
>>>>> +        Arrays.sort(refs, new Comparator<ServiceReference>() {
>>>>> +          public int compare(ServiceReference o1, ServiceReference 
>>>>> o2)
>>>>> +          {
>>>>> +            return o2.compareTo(o1);
>>>>> +          }
>>>>> +        });
>>>>> +        +        for (ServiceReference ref : refs) {
>>>>> +          Object service = ctx.getService(ref);
>>>>> +          +          if (service != null) {
>>>>> +            p = new ServicePair();
>>>>> +            p.ref = ref;
>>>>> +            p.service = service;
>>>>> +            break;
>>>>> +          }
>>>>>         }
>>>>>       }
>>>>> +      +    } catch (InvalidSyntaxException e) {
>>>>> +      // TODO Auto-generated catch block
>>>>> +      e.printStackTrace();
>>>>>     }
>>>>>     -    return data;
>>>>> +    return p;
>>>>>   }
>>>>>  }
>>>>>
>>>>> Modified:
>>>>> incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/Activator.java 
>>>>>
>>>>> URL:
>>>>> http://svn.apache.org/viewvc/incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/Activator.java?rev=917809&r1=917808&r2=917809&view=diff 
>>>>>
>>>>>
>>>>> ============================================================================== 
>>>>>
>>>>> ---
>>>>> incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/Activator.java 
>>>>>
>>>>> (original)
>>>>> +++
>>>>> incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/Activator.java 
>>>>>
>>>>> Mon Mar  1 23:53:18 2010
>>>>> @@ -34,8 +34,6 @@
>>>>>
>>>>>   public void start(BundleContext context)
>>>>>   {
>>>>> -    ServiceHelper.setBundleContext(context);
>>>>> -         Hashtable<Object, Object> props = new Hashtable<Object,
>>>>> Object>();
>>>>>     props.put("osgi.jndi.urlScheme", new String[] {"osgi", "aries"} );
>>>>>     reg = context.registerService(ObjectFactory.class.getName(), new
>>>>> OsgiURLContextFactory(), props);
>>>>>
>>>>> Copied:
>>>>> incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/OsgiName.java 
>>>>>
>>>>> (from r910238,
>>>>> incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/ServiceRegistryName.java) 
>>>>>
>>>>> URL:
>>>>> http://svn.apache.org/viewvc/incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/OsgiName.java?p2=incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/OsgiName.java&p1=incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/ServiceRegistryName.java&r1=910238&r2=917809&rev=917809&view=diff 
>>>>>
>>>>>
>>>>> ============================================================================== 
>>>>>
>>>>> ---
>>>>> incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/ServiceRegistryName.java 
>>>>>
>>>>> (original)
>>>>> +++
>>>>> incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/OsgiName.java 
>>>>>
>>>>> Mon Mar  1 23:53:18 2010
>>>>> @@ -21,28 +21,104 @@
>>>>>  import java.util.Enumeration;
>>>>>  import javax.naming.CompositeName;
>>>>> +import javax.naming.InvalidNameException;
>>>>> +import javax.naming.Name;
>>>>>  /**
>>>>> - * A composite name for the aries namespace. We only have this so 
>>>>> that we
>>>>> can
>>>>> - * provide a nicer toString()
>>>>> + * A composite name for the aries namespace. This provides useful 
>>>>> utility
>>>>> methods
>>>>> + * for accessing the name.
>>>>> + * + * component 0: osgi:service, aries:services, osgi:servicelist
>>>>> + * component 1: interface
>>>>> + * component 2: filter
>>>>>  */
>>>>> -public final class ServiceRegistryName extends CompositeName
>>>>> +public final class OsgiName extends CompositeName
>>>>>  {
>>>>>   /** The serial version UID */
>>>>>   private static final long serialVersionUID = 6617580228852444656L;
>>>>> +  public static final String OSGI_SCHEME = "osgi";
>>>>> +  public static final String ARIES_SCHEME = "aries";
>>>>> +  public static final String SERVICE_PATH = "service";
>>>>> +  public static final String SERVICES_PATH = "services";
>>>>> +  public static final String SERVICE_LIST_PATH = "servicelist";
>>>>> +  public static final String FRAMEWORK_PATH = "framework";
>>>>>   -  @Override
>>>>> -  public String toString()
>>>>> +  public OsgiName(String name) throws InvalidNameException
>>>>>   {
>>>>> -    StringBuilder buffer = new StringBuilder();
>>>>> +    super(name);
>>>>> +  }
>>>>> +
>>>>> +  public OsgiName(Name name) throws InvalidNameException
>>>>> +  {
>>>>> +    this(name.toString());
>>>>> +  }
>>>>> +
>>>>> +  public boolean hasFilter()
>>>>> +  {
>>>>> +    return size() == 3;
>>>>> +  }
>>>>> +  +  public boolean isServiceNameBased()
>>>>> +  {
>>>>> +    return size() > 3;
>>>>> +  }
>>>>> +  +  public String getScheme()
>>>>> +  {
>>>>> +    String part0 = get(0);
>>>>> +    int index = part0.indexOf(':');
>>>>> +    +    String result;
>>>>> +    +    if (index > 0) {
>>>>> +      result = part0.substring(0, index);
>>>>> +    } else {
>>>>> +      result = null;
>>>>> +    }
>>>>> +    +    return result;
>>>>> +  }
>>>>> +  +  public String getSchemePath()
>>>>> +  {
>>>>> +    String part0 = get(0);
>>>>> +    int index = part0.indexOf(':');
>>>>> +    +    String result;
>>>>>     -    buffer.append("aries:services");
>>>>> -    Enumeration<String> components = getAll();
>>>>> -    while (components.hasMoreElements()) {
>>>>> -      buffer.append('/');
>>>>> -      buffer.append(components.nextElement());
>>>>> +    if (index > 0) {
>>>>> +      result = part0.substring(index + 1);
>>>>> +    } else {
>>>>> +      result = null;
>>>>>     }
>>>>>     -    return buffer.toString();
>>>>> +    return result;
>>>>> +  }
>>>>> +  +  public String getInterface()
>>>>> +  {
>>>>> +    return get(1);
>>>>> +  }
>>>>> +  +  public String getFilter()
>>>>> +  {
>>>>> +    return hasFilter() ? get(2) : null;
>>>>> +  }
>>>>> +  +  public String getServiceName()
>>>>> +  {
>>>>> +    Enumeration<String> parts = getAll();
>>>>> +    parts.nextElement();
>>>>> +    +    StringBuilder builder = new StringBuilder();
>>>>> +    +    while (parts.hasMoreElements()) {
>>>>> +      builder.append(parts.nextElement());
>>>>> +      builder.append('/');
>>>>> +    }
>>>>> +    +    builder.deleteCharAt(builder.length() - 1);
>>>>> +    +    return builder.toString();
>>>>>   }
>>>>>  }
>>>>> \ No newline at end of file
>>>>>
>>>>> Copied:
>>>>> incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/OsgiNameParser.java 
>>>>>
>>>>> (from r910238,
>>>>> incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/ServiceRegistryNameParser.java) 
>>>>>
>>>>> URL:
>>>>> http://svn.apache.org/viewvc/incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/OsgiNameParser.java?p2=incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/OsgiNameParser.java&p1=incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/ServiceRegistryNameParser.java&r1=910238&r2=917809&rev=917809&view=diff 
>>>>>
>>>>>
>>>>> ============================================================================== 
>>>>>
>>>>> ---
>>>>> incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/ServiceRegistryNameParser.java 
>>>>>
>>>>> (original)
>>>>> +++
>>>>> incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/OsgiNameParser.java 
>>>>>
>>>>> Mon Mar  1 23:53:18 2010
>>>>> @@ -26,31 +26,40 @@
>>>>>  /**
>>>>>  * A parser for the aries namespace
>>>>>  */
>>>>> -public final class ServiceRegistryNameParser implements NameParser
>>>>> +public final class OsgiNameParser implements NameParser
>>>>>  {
>>>>> -
>>>>> +  private static final String OSGI_SCHEME = "osgi";
>>>>> +  private static final String ARIES_SCHEME = "aries";
>>>>> +  private static final String SERVICE_PATH = "service";
>>>>> +  private static final String SERVICES_PATH = "services";
>>>>> +  private static final String SERVICE_LIST_PATH = "servicelist";
>>>>> +  private static final String FRAMEWORK_PATH = "framework";
>>>>> +     public Name parse(String name) throws NamingException
>>>>>   {
>>>>> -    if (!!!name.startsWith("aries:services/") &&
>>>>> -        !!!name.startsWith("osgi:services/")) throw new
>>>>> InvalidNameException("The JNDI name did not start with aries:, or 
>>>>> osgi:");
>>>>> +    OsgiName result = new OsgiName(name);
>>>>> +    +    if (result.size() < 2) throw new InvalidNameException(name);
>>>>>     -    name = name.substring(name.indexOf('/') + 1);
>>>>> +    String urlScheme = result.getScheme();
>>>>> +    String schemePath = result.getSchemePath();
>>>>>     -    int slashIndex = name.indexOf('/');
>>>>> -    String interfaceName = name;
>>>>> -    String filter = null;
>>>>> -    -    if (slashIndex != -1) {
>>>>> -      interfaceName = name.substring(0, slashIndex);
>>>>> -      filter = name.substring(slashIndex + 1);
>>>>> +    if (!!!(OSGI_SCHEME.equals(urlScheme) ||
>>>>> ARIES_SCHEME.equals(urlScheme))) {
>>>>> +      throw new InvalidNameException(name);
>>>>>     }
>>>>>     -    if (interfaceName.length() == 0) throw new
>>>>> InvalidNameException("No interface name was specified");
>>>>> +    if (ARIES_SCHEME.equals(urlScheme) &&
>>>>> !!!SERVICES_PATH.equals(schemePath)) {
>>>>> +      throw new InvalidNameException(name);
>>>>> +    }
>>>>> +    +    if (OSGI_SCHEME.equals(urlScheme) && !!!(
>>>>> SERVICE_PATH.equals(schemePath) || +
>>>>>      SERVICE_LIST_PATH.equals(schemePath) || +
>>>>>                FRAMEWORK_PATH.equals(schemePath))) {
>>>>> +      throw new InvalidNameException(name);
>>>>> +    }
>>>>>     -    Name result = new ServiceRegistryName();
>>>>> -    result.add(interfaceName);
>>>>> -    if (filter != null) {
>>>>> -      result.add(filter);
>>>>> +    if (result.getInterface() == null || 
>>>>> result.getInterface().length()
>>>>> == 0) {
>>>>> +      throw new InvalidNameException(name);
>>>>>     }
>>>>>          return result;
>>>>> @@ -59,7 +68,7 @@
>>>>>   @Override
>>>>>   public boolean equals(Object other)
>>>>>   {
>>>>> -    return other instanceof ServiceRegistryNameParser;
>>>>> +    return other instanceof OsgiNameParser;
>>>>>   }
>>>>>      @Override
>>>>>
>>>>> Modified:
>>>>> incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/OsgiURLContextFactory.java 
>>>>>
>>>>> URL:
>>>>> http://svn.apache.org/viewvc/incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/OsgiURLContextFactory.java?rev=917809&r1=917808&r2=917809&view=diff 
>>>>>
>>>>>
>>>>> ============================================================================== 
>>>>>
>>>>> ---
>>>>> incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/OsgiURLContextFactory.java 
>>>>>
>>>>> (original)
>>>>> +++
>>>>> incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/OsgiURLContextFactory.java 
>>>>>
>>>>> Mon Mar  1 23:53:18 2010
>>>>> @@ -49,7 +49,7 @@
>>>>>     } else if (obj instanceof String[]) {
>>>>>       // Try each URL until either lookup succeeds or they all fail
>>>>>       String[] urls = (String[])obj;
>>>>> -      if (urls.length == 0) throw new
>>>>> ConfigurationException("ariesURLContextFactory: empty URL array");
>>>>> +      if (urls.length == 0) throw new ConfigurationException("0");
>>>>>       Context context = new ServiceRegistryContext(environment);
>>>>>       try
>>>>>       {
>>>>>
>>>>> Modified:
>>>>> incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/ServiceRegistryContext.java 
>>>>>
>>>>> URL:
>>>>> http://svn.apache.org/viewvc/incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/ServiceRegistryContext.java?rev=917809&r1=917808&r2=917809&view=diff 
>>>>>
>>>>>
>>>>> ============================================================================== 
>>>>>
>>>>> ---
>>>>> incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/ServiceRegistryContext.java 
>>>>>
>>>>> (original)
>>>>> +++
>>>>> incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/ServiceRegistryContext.java 
>>>>>
>>>>> Mon Mar  1 23:53:18 2010
>>>>> @@ -42,9 +42,9 @@
>>>>>  {
>>>>>   private static final String ARIES_SERVICES = "aries:services/";
>>>>>   /** The name parser for the service registry name space */
>>>>> -  private NameParser parser = new ServiceRegistryNameParser();
>>>>> +  private NameParser parser = new OsgiNameParser();
>>>>>   /** The environment for this context */
>>>>> -  private Map<Object, Object> env;
>>>>> +  private Map<String, Object> env;
>>>>>      /**
>>>>>    * Why Mr Java this class does indeed take a fine copy of the 
>>>>> provided
>>>>> @@ -53,10 +53,11 @@
>>>>>    *     * @param environment
>>>>>    */
>>>>> +  @SuppressWarnings("unchecked")
>>>>>   public ServiceRegistryContext(Hashtable<?, ?> environment)
>>>>>   {
>>>>> -    env = new HashMap<Object, Object>();
>>>>> -    env.putAll(environment);
>>>>> +    env = new HashMap<String, Object>();
>>>>> +    env.putAll((Map<? extends String, ? extends Object>) 
>>>>> environment);
>>>>>   }
>>>>>    public Object addToEnvironment(String propName, Object propVal) 
>>>>> throws
>>>>> NamingException
>>>>> @@ -153,7 +154,7 @@
>>>>>    public NamingEnumeration<NameClassPair> list(final Name name) 
>>>>> throws
>>>>> NamingException
>>>>>   {
>>>>> -    throw new NamingException("Not a Context");
>>>>> +    return new ServiceRegistryListContext(env, 
>>>>> convert(name)).list("");
>>>>>   }
>>>>>    public NamingEnumeration<NameClassPair> list(String name) throws
>>>>> NamingException
>>>>> @@ -163,7 +164,7 @@
>>>>>    public NamingEnumeration<Binding> listBindings(final Name name) 
>>>>> throws
>>>>> NamingException
>>>>>   {
>>>>> -    throw new NamingException("Not a Context");
>>>>> +    return new ServiceRegistryListContext(env,
>>>>> convert(name)).listBindings("");
>>>>>   }
>>>>>    public NamingEnumeration<Binding> listBindings(String name) throws
>>>>> NamingException
>>>>> @@ -173,28 +174,43 @@
>>>>>    public Object lookup(Name name) throws NamingException
>>>>>   {
>>>>> -    int nameSize = validateName(name);
>>>>> -    String className = name.get(0);
>>>>> -
>>>>> -    String filter = null;
>>>>> +    Object result;
>>>>> +    +    OsgiName validName = convert(name);
>>>>>     -    if (nameSize == 2) {
>>>>> -      filter = name.get(1);
>>>>> +    String pathFragment = validName.getSchemePath();
>>>>> +    String serviceName = validName.getServiceName();
>>>>> +    String schemeName = validName.getScheme();
>>>>> +    +    if (OsgiName.FRAMEWORK_PATH.equals(pathFragment) &&
>>>>> "bundleContext".equals(validName.getServiceName())) {
>>>>> +      result = ServiceHelper.getBundleContext(env);
>>>>> +    } else if ((OsgiName.SERVICE_PATH.equals(pathFragment) &&
>>>>> OsgiName.OSGI_SCHEME.equals(schemeName)) ||
>>>>> +               (OsgiName.SERVICES_PATH.equals(pathFragment) &&
>>>>> OsgiName.ARIES_SCHEME.equals(schemeName))) {
>>>>> +      result = ServiceHelper.getService(validName.getInterface(),
>>>>> validName.getFilter(), serviceName, true, env);
>>>>> +    } else if (OsgiName.SERVICE_LIST_PATH.equals(pathFragment)) {
>>>>> +      result = new ServiceRegistryListContext(env, validName);
>>>>> +    } else {
>>>>> +      result = null;
>>>>>     }
>>>>>     -    try {
>>>>> -      Object result = ServiceHelper.getService(className, filter);
>>>>> -      -      if (result == null) {
>>>>> -        throw new NameNotFoundException("We couldn't find an 
>>>>> object in
>>>>> the registry matching the query " + name);
>>>>> -      }
>>>>> -      -      return result;
>>>>> -    } catch (IllegalArgumentException e) {
>>>>> -      NamingException ne = new NamingException(e.getMessage());
>>>>> -      ne.initCause(e);
>>>>> -      throw ne;
>>>>> +    if (result == null) {
>>>>> +      throw new NameNotFoundException(name.toString());
>>>>> +    }
>>>>> +    +    return result;
>>>>> +  }
>>>>> +
>>>>> +  private OsgiName convert(Name name) throws InvalidNameException
>>>>> +  {
>>>>> +    OsgiName result;
>>>>> +    +    if (name instanceof OsgiName) {
>>>>> +      result = (OsgiName) name;
>>>>> +    } else {
>>>>> +      result = new OsgiName(name);
>>>>>     }
>>>>> +    +    return result;
>>>>>   }
>>>>>    public Object lookup(String name) throws NamingException
>>>>> @@ -246,27 +262,4 @@
>>>>>   {
>>>>>     throw new OperationNotSupportedException();
>>>>>   }
>>>>> -  -  /**
>>>>> -   * Check that the name conforms to the expected format
>>>>> -   * @param name
>>>>> -   * @return the size of the name
>>>>> -   * @throws InvalidNameException
>>>>> -   */
>>>>> -  private int validateName(final Name name) throws 
>>>>> InvalidNameException
>>>>> -  {
>>>>> -    int nameSize = name.size();
>>>>> -    if (nameSize == 0) {
>>>>> -      throw new InvalidNameException("The provided name does not 
>>>>> have any
>>>>> components" + name);
>>>>> -    } -    -    if ("aries:services".equals(name.get(0))) {
>>>>> -      throw new InvalidNameException("The composite name should 
>>>>> not start
>>>>> with aries:services");
>>>>> -    }
>>>>> -    -    if (nameSize > 2) {
>>>>> -      throw new InvalidNameException("This JNDI context only 
>>>>> expects 2
>>>>> components, but it found " + nameSize);
>>>>> -    }
>>>>> -    return nameSize;
>>>>> -  }
>>>>>  }
>>>>> \ No newline at end of file
>>>>>
>>>>> Added:
>>>>> incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/ServiceRegistryListContext.java 
>>>>>
>>>>> URL:
>>>>> http://svn.apache.org/viewvc/incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/ServiceRegistryListContext.java?rev=917809&view=auto 
>>>>>
>>>>>
>>>>> ============================================================================== 
>>>>>
>>>>> ---
>>>>> incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/ServiceRegistryListContext.java 
>>>>>
>>>>> (added)
>>>>> +++
>>>>> incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/ServiceRegistryListContext.java 
>>>>>
>>>>> Mon Mar  1 23:53:18 2010
>>>>> @@ -0,0 +1,197 @@
>>>>> +/*
>>>>> + * 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.aries.jndi.url;
>>>>> +
>>>>> +import java.util.HashMap;
>>>>> +import java.util.Hashtable;
>>>>> +import java.util.Map;
>>>>> +
>>>>> +import javax.naming.Binding;
>>>>> +import javax.naming.Context;
>>>>> +import javax.naming.Name;
>>>>> +import javax.naming.NameClassPair;
>>>>> +import javax.naming.NameParser;
>>>>> +import javax.naming.NamingEnumeration;
>>>>> +import javax.naming.NamingException;
>>>>> +import javax.naming.OperationNotSupportedException;
>>>>> +
>>>>> +public class ServiceRegistryListContext implements Context
>>>>> +{
>>>>> +  private Map<String, Object> env;
>>>>> +  /** The name parser for the service registry name space */
>>>>> +  private NameParser parser = new OsgiNameParser();
>>>>> +  +  public ServiceRegistryListContext(Map<String, Object> env, 
>>>>> OsgiName
>>>>> validName)
>>>>> +  {
>>>>> +    this.env = new HashMap<String, Object>(env);
>>>>> +  }
>>>>> +
>>>>> +  public Object addToEnvironment(String propName, Object propVal) 
>>>>> throws
>>>>> NamingException
>>>>> +  {
>>>>> +    return env.put(propName, propVal);
>>>>> +  }
>>>>> +
>>>>> +  public void bind(Name name, Object obj) throws NamingException
>>>>> +  {
>>>>> +    throw new OperationNotSupportedException();
>>>>> +  }
>>>>> +
>>>>> +  public void bind(String name, Object obj) throws NamingException
>>>>> +  {
>>>>> +    throw new OperationNotSupportedException();
>>>>> +  }
>>>>> +
>>>>> +  public void close() throws NamingException
>>>>> +  {
>>>>> +    env = null;
>>>>> +    parser = null;
>>>>> +  }
>>>>> +
>>>>> +  public Name composeName(Name name, Name prefix) throws 
>>>>> NamingException
>>>>> +  {
>>>>> +    // TODO Auto-generated method stub
>>>>> +    return null;
>>>>> +  }
>>>>> +
>>>>> +  public String composeName(String name, String prefix) throws
>>>>> NamingException
>>>>> +  {
>>>>> +    // TODO Auto-generated method stub
>>>>> +    return null;
>>>>> +  }
>>>>> +
>>>>> +  public Context createSubcontext(Name name) throws NamingException
>>>>> +  {
>>>>> +    throw new OperationNotSupportedException();
>>>>> +  }
>>>>> +
>>>>> +  public Context createSubcontext(String name) throws NamingException
>>>>> +  {
>>>>> +    throw new OperationNotSupportedException();
>>>>> +  }
>>>>> +
>>>>> +  public void destroySubcontext(Name name) throws NamingException
>>>>> +  {
>>>>> +    //No-op we don't support sub-contexts in our context
>>>>> +  }
>>>>> +
>>>>> +  public void destroySubcontext(String name) throws NamingException
>>>>> +  {
>>>>> +    //No-op we don't support sub-contexts in our context
>>>>> +  }
>>>>> +
>>>>> +  public Hashtable<?, ?> getEnvironment() throws NamingException
>>>>> +  {
>>>>> +    Hashtable<Object, Object> environment = new Hashtable<Object,
>>>>> Object>();
>>>>> +    environment.putAll(env);
>>>>> +    return environment;
>>>>> +  }
>>>>> +
>>>>> +  public String getNameInNamespace() throws NamingException
>>>>> +  {
>>>>> +    // TODO Auto-generated method stub
>>>>> +    return null;
>>>>> +  }
>>>>> +
>>>>> +  public NameParser getNameParser(Name name) throws NamingException
>>>>> +  {
>>>>> +    return parser;
>>>>> +  }
>>>>> +
>>>>> +  public NameParser getNameParser(String name) throws NamingException
>>>>> +  {
>>>>> +    return parser;
>>>>> +  }
>>>>> +
>>>>> +  public NamingEnumeration<NameClassPair> list(Name name) throws
>>>>> NamingException
>>>>> +  {
>>>>> +    return list(name.toString());
>>>>> +  }
>>>>> +
>>>>> +  public NamingEnumeration<NameClassPair> list(String name) throws
>>>>> NamingException
>>>>> +  {
>>>>> +    // TODO Auto-generated method stub
>>>>> +    return null;
>>>>> +  }
>>>>> +
>>>>> +  public NamingEnumeration<Binding> listBindings(Name name) throws
>>>>> NamingException
>>>>> +  {
>>>>> +    return listBindings(name.toString());
>>>>> +  }
>>>>> +
>>>>> +  public NamingEnumeration<Binding> listBindings(String name) throws
>>>>> NamingException
>>>>> +  {
>>>>> +    // TODO Auto-generated method stub
>>>>> +    return null;
>>>>> +  }
>>>>> +
>>>>> +  public Object lookup(Name name) throws NamingException
>>>>> +  {
>>>>> +    return lookup(name.toString());
>>>>> +  }
>>>>> +
>>>>> +  public Object lookup(String name) throws NamingException
>>>>> +  {
>>>>> +    return null;
>>>>> +  }
>>>>> +
>>>>> +  public Object lookupLink(Name name) throws NamingException
>>>>> +  {
>>>>> +    throw new OperationNotSupportedException();
>>>>> +  }
>>>>> +
>>>>> +  public Object lookupLink(String name) throws NamingException
>>>>> +  {
>>>>> +    throw new OperationNotSupportedException();
>>>>> +  }
>>>>> +
>>>>> +  public void rebind(Name name, Object obj) throws NamingException
>>>>> +  {
>>>>> +    throw new OperationNotSupportedException();
>>>>> +  }
>>>>> +
>>>>> +  public void rebind(String name, Object obj) throws NamingException
>>>>> +  {
>>>>> +    throw new OperationNotSupportedException();
>>>>> +  }
>>>>> +
>>>>> +  public Object removeFromEnvironment(String propName) throws
>>>>> NamingException
>>>>> +  {
>>>>> +    return env.remove(propName);
>>>>> +  }
>>>>> +
>>>>> +  public void rename(Name oldName, Name newName) throws 
>>>>> NamingException
>>>>> +  {
>>>>> +    throw new OperationNotSupportedException();
>>>>> +  }
>>>>> +
>>>>> +  public void rename(String oldName, String newName) throws
>>>>> NamingException
>>>>> +  {
>>>>> +    throw new OperationNotSupportedException();
>>>>> +  }
>>>>> +
>>>>> +  public void unbind(Name name) throws NamingException
>>>>> +  {
>>>>> +    throw new OperationNotSupportedException();
>>>>> +  }
>>>>> +
>>>>> +  public void unbind(String name) throws NamingException
>>>>> +  {
>>>>> +    throw new OperationNotSupportedException();
>>>>> +  }
>>>>> +}
>>>>> \ No newline at end of file
>>>>>
>>>>> Copied:
>>>>> incubator/aries/trunk/jndi/jndi-url/src/test/java/org/apache/aries/jndi/url/OsgiNameParserTest.java 
>>>>>
>>>>> (from r917002,
>>>>> incubator/aries/trunk/jndi/jndi-url/src/test/java/org/apache/aries/jndi/url/ServiceRegistryNameParserTest.java) 
>>>>>
>>>>> URL:
>>>>> http://svn.apache.org/viewvc/incubator/aries/trunk/jndi/jndi-url/src/test/java/org/apache/aries/jndi/url/OsgiNameParserTest.java?p2=incubator/aries/trunk/jndi/jndi-url/src/test/java/org/apache/aries/jndi/url/OsgiNameParserTest.java&p1=incubator/aries/trunk/jndi/jndi-url/src/test/java/org/apache/aries/jndi/url/ServiceRegistryNameParserTest.java&r1=917002&r2=917809&rev=917809&view=diff 
>>>>>
>>>>>
>>>>> ============================================================================== 
>>>>>
>>>>> ---
>>>>> incubator/aries/trunk/jndi/jndi-url/src/test/java/org/apache/aries/jndi/url/ServiceRegistryNameParserTest.java 
>>>>>
>>>>> (original)
>>>>> +++
>>>>> incubator/aries/trunk/jndi/jndi-url/src/test/java/org/apache/aries/jndi/url/OsgiNameParserTest.java 
>>>>>
>>>>> Mon Mar  1 23:53:18 2010
>>>>> @@ -18,11 +18,11 @@
>>>>>  */
>>>>>  package org.apache.aries.jndi.url;
>>>>>  -import static org.junit.Assert.assertNotNull;
>>>>>  import static org.junit.Assert.assertEquals;
>>>>> +import static org.junit.Assert.assertFalse;
>>>>> +import static org.junit.Assert.assertTrue;
>>>>>  import javax.naming.InvalidNameException;
>>>>> -import javax.naming.Name;
>>>>>  import javax.naming.NameParser;
>>>>>  import javax.naming.NamingException;
>>>>>  @@ -31,10 +31,10 @@
>>>>>  /**
>>>>>  * This is where we test the service registry name parser.
>>>>>  */
>>>>> -public class ServiceRegistryNameParserTest
>>>>> +public class OsgiNameParserTest
>>>>>  {
>>>>>   /** The parser we are going to use for testing */
>>>>> -  private NameParser parser = new ServiceRegistryNameParser();
>>>>> +  private NameParser parser = new OsgiNameParser();
>>>>>    /**
>>>>>    * OK, so we check that we can call checkNames multiple times.
>>>>> @@ -43,8 +43,14 @@
>>>>>   @Test
>>>>>   public void checkValidNames() throws NamingException
>>>>>   {
>>>>> -    checkName("aries:services/java.lang.Runnable/(a=b)");
>>>>> -    checkName("aries:services/java.lang.Runnable");
>>>>> +    checkName("aries","services","java.lang.Runnable","(a=b)");
>>>>> +    checkName("aries","services","java.lang.Runnable");
>>>>> +    checkName("osgi","service","java.lang.Runnable");
>>>>> +    checkName("osgi","service","java.lang.Runnable", "(a=b)");
>>>>> +    checkName("osgi","servicelist","java.lang.Runnable");
>>>>> +    checkName("osgi","servicelist","java.lang.Runnable", "(a=b)");
>>>>> +    checkName("osgi","servicelist","jdbc", "grok", "DataSource");
>>>>> +    checkName("osgi", "framework", "bundleContext");
>>>>>   }
>>>>>      /**
>>>>> @@ -54,7 +60,7 @@
>>>>>   @Test(expected=InvalidNameException.class)
>>>>>   public void checkOutsideNamespace() throws NamingException
>>>>>   {
>>>>> -    checkName("java:comp/env/jms/cf");
>>>>> +    checkName("java","comp","env","jms","cf");
>>>>>   }
>>>>>      /**
>>>>> @@ -64,7 +70,7 @@
>>>>>   @Test(expected=InvalidNameException.class)
>>>>>   public void checkMissingInterface() throws NamingException
>>>>>   {
>>>>> -    checkName("aries:services");
>>>>> +    checkName("aries","services");
>>>>>   }
>>>>>      /**
>>>>> @@ -75,20 +81,64 @@
>>>>>   @Test(expected=InvalidNameException.class)
>>>>>   public void checkMissingInterface2() throws NamingException
>>>>>   {
>>>>> -    checkName("aries:services/");
>>>>> +    checkName("aries","services", "");
>>>>>   }
>>>>> -
>>>>> -  /**
>>>>> -   * This method parses the name and then makes sure what was 
>>>>> parsed was
>>>>> parsed
>>>>> -   * correctly.
>>>>> -   * -   * @param name
>>>>> -   * @throws NamingException
>>>>> -   */
>>>>> -  private void checkName(String name) throws NamingException
>>>>> +  +  @Test(expected=InvalidNameException.class)
>>>>> +  public void checkIncorrectPath() throws NamingException
>>>>> +  {
>>>>> +    checkName("osgi", "services", "java.lang.Runnable"); +  }
>>>>> +  +  @Test(expected=InvalidNameException.class)
>>>>> +  public void checkIllegalPath() throws NamingException
>>>>>   {
>>>>> -    Name n = parser.parse(name);
>>>>> -    assertNotNull("We got a null name back, which is not 
>>>>> allowed.", n);
>>>>> -    assertEquals("The name's toString does not produce the original
>>>>> value", name, n.toString());
>>>>> +    checkName("osgi", "wibble", "java.lang.Runnable"); +  }
>>>>> +  +  private void checkName(String scheme, String path, String ...
>>>>> elements)
>>>>> +    throws NamingException
>>>>> +  {
>>>>> +    StringBuilder builder = new StringBuilder();
>>>>> +    StringBuilder serviceName = new StringBuilder();
>>>>> +    +    builder.append(scheme);
>>>>> +    builder.append(':');
>>>>> +    builder.append(path);
>>>>> +
>>>>> +    if (elements.length > 0) {
>>>>> +      builder.append('/');
>>>>> +      +      for (String element : elements) {
>>>>> +        serviceName.append(element);
>>>>> +        serviceName.append('/');
>>>>> +      }
>>>>> +  +      serviceName.deleteCharAt(serviceName.length() - 1);
>>>>> +      +      builder.append(serviceName);
>>>>> +    }
>>>>> +    +    OsgiName n = (OsgiName) parser.parse(builder.toString());
>>>>> +    +    assertEquals(scheme, n.getScheme());
>>>>> +    assertEquals(path, n.getSchemePath());
>>>>> +    +    if (elements.length > 1) {
>>>>> +      assertEquals(elements[0], n.getInterface());
>>>>> +    }
>>>>> +    +    if (elements.length == 1) {
>>>>> +      assertFalse(n.hasFilter());
>>>>> +    }
>>>>> +    +    if (elements.length > 2) {
>>>>> +      if (elements.length == 2) {
>>>>> +        assertTrue(n.hasFilter());
>>>>> +        assertEquals(elements[1], n.getFilter());
>>>>> +      } else assertFalse(n.hasFilter());
>>>>> +    }
>>>>> +    +    assertEquals(serviceName.toString(), n.getServiceName());
>>>>>   }
>>>>>  }
>>>>> \ No newline at end of file
>>>>>
>>>>> Modified:
>>>>> incubator/aries/trunk/jndi/jndi-url/src/test/java/org/apache/aries/jndi/url/ServiceRegistryContextTest.java 
>>>>>
>>>>> URL:
>>>>> http://svn.apache.org/viewvc/incubator/aries/trunk/jndi/jndi-url/src/test/java/org/apache/aries/jndi/url/ServiceRegistryContextTest.java?rev=917809&r1=917808&r2=917809&view=diff 
>>>>>
>>>>>
>>>>> ============================================================================== 
>>>>>
>>>>> ---
>>>>> incubator/aries/trunk/jndi/jndi-url/src/test/java/org/apache/aries/jndi/url/ServiceRegistryContextTest.java 
>>>>>
>>>>> (original)
>>>>> +++
>>>>> incubator/aries/trunk/jndi/jndi-url/src/test/java/org/apache/aries/jndi/url/ServiceRegistryContextTest.java 
>>>>>
>>>>> Mon Mar  1 23:53:18 2010
>>>>> @@ -21,7 +21,6 @@
>>>>>  import static org.junit.Assert.assertEquals;
>>>>>  import static org.junit.Assert.assertFalse;
>>>>>  import static org.junit.Assert.assertNotNull;
>>>>> -import static org.junit.Assert.assertSame;
>>>>>  import static org.junit.Assert.assertTrue;
>>>>>  import java.lang.reflect.Field;
>>>>> @@ -37,6 +36,12 @@
>>>>>  import javax.naming.NamingException;
>>>>>  import javax.naming.spi.ObjectFactory;
>>>>>  +import org.apache.aries.jndi.ContextHelper;
>>>>> +import org.apache.aries.jndi.OSGiObjectFactoryBuilder;
>>>>> +import org.apache.aries.mocks.BundleContextMock;
>>>>> +import org.apache.aries.mocks.BundleMock;
>>>>> +import org.apache.aries.unittest.mocks.MethodCall;
>>>>> +import org.apache.aries.unittest.mocks.Skeleton;
>>>>>  import org.junit.After;
>>>>>  import org.junit.Before;
>>>>>  import org.junit.Test;
>>>>> @@ -47,22 +52,13 @@
>>>>>  import org.osgi.framework.ServiceReference;
>>>>>  import org.osgi.framework.ServiceRegistration;
>>>>>  -import org.apache.aries.unittest.mocks.MethodCall;
>>>>> -import org.apache.aries.unittest.mocks.Skeleton;
>>>>> -import org.apache.aries.jndi.ContextHelper;
>>>>> -import org.apache.aries.jndi.OSGiObjectFactoryBuilder;
>>>>> -import org.apache.aries.jndi.services.ServiceHelper;
>>>>> -import org.apache.aries.jndi.url.Activator;
>>>>> -import org.apache.aries.mocks.BundleContextMock;
>>>>> -import org.apache.aries.mocks.BundleMock;
>>>>> -
>>>>>  /**
>>>>>  * Tests for our JNDI implementation for the service registry.
>>>>>  */
>>>>>  public class ServiceRegistryContextTest
>>>>>  {
>>>>>   /** The service we register by default */
>>>>> -  private Thread service;
>>>>> +  private Runnable service;
>>>>>   /** The bundle context for the test */
>>>>>   private BundleContext bc;
>>>>>   /** The service registration for the service */
>>>>> @@ -83,10 +79,7 @@
>>>>>     new Activator().start(bc);
>>>>>     new org.apache.aries.jndi.startup.Activator().start(bc);
>>>>>     -    Field f = ServiceHelper.class.getDeclaredField("context");
>>>>> -    f.setAccessible(true);
>>>>> -    f.set(null, bc);
>>>>> -    f = ContextHelper.class.getDeclaredField("context");
>>>>> +    Field f = ContextHelper.class.getDeclaredField("context");
>>>>>     f.setAccessible(true);
>>>>>     f.set(null, bc);
>>>>>     f = OSGiObjectFactoryBuilder.class.getDeclaredField("context");
>>>>> @@ -94,7 +87,7 @@
>>>>>     f.set(null, bc);
>>>>>  -    service = new Thread();
>>>>> +    service = Skeleton.newMock(Runnable.class);
>>>>>          registerService(service);
>>>>>   }
>>>>> @@ -104,7 +97,7 @@
>>>>>    *     * @param service2 The service to register.
>>>>>    */
>>>>> -  private void registerService(Thread service2)
>>>>> +  private void registerService(Runnable service2)
>>>>>   {
>>>>>     ServiceFactory factory = Skeleton.newMock(ServiceFactory.class);
>>>>>     Skeleton skel = Skeleton.getSkeleton(factory);
>>>>> @@ -159,11 +152,13 @@
>>>>>
>>>>>  Thread.currentThread().setContextClassLoader(mock.getClassLoader());
>>>>>     -    Object s = ctx.lookup("aries:services/java.lang.Runnable");
>>>>> +    Runnable s = (Runnable)
>>>>> ctx.lookup("aries:services/java.lang.Runnable");
>>>>>          assertNotNull("We didn't get a service back from our 
>>>>> lookup :(",
>>>>> s);
>>>>>     -    assertEquals("The SR did not return the object we expected",
>>>>> service, s);
>>>>> +    s.run();
>>>>> +    +    
>>>>> Skeleton.getSkeleton(service).assertCalledExactNumberOfTimes(new
>>>>> MethodCall(Runnable.class, "run"), 1);
>>>>>          Skeleton skel = 
>>>>> Skeleton.getSkeleton(mock.getBundleContext());
>>>>>     @@ -173,7 +168,7 @@
>>>>>
>>>>>  Thread.currentThread().setContextClassLoader(mock.getClassLoader());
>>>>>  -    s = ctx.lookup("osgi:services/java.lang.Runnable");
>>>>> +    s = (Runnable) ctx.lookup("osgi:service/java.lang.Runnable");
>>>>>          // Check we have the packages set correctly
>>>>>     @@ -181,10 +176,11 @@
>>>>>          assertTrue(ctx.getEnvironment().containsValue(packages));
>>>>>  -         assertNotNull("We didn't get a service back from our lookup
>>>>> :(", s);
>>>>> +
>>>>> +    s.run();
>>>>>     -    assertEquals("The SR did not return the object we expected",
>>>>> service, s);
>>>>> +    Skeleton.getSkeleton(service).assertCalledExactNumberOfTimes(new
>>>>> MethodCall(Runnable.class, "run"), 2);
>>>>>      skel = Skeleton.getSkeleton(mock.getBundleContext());
>>>>>     skel.assertCalled(new MethodCall(BundleContext.class,
>>>>> "getServiceReferences", "java.lang.Runnable", null));
>>>>> @@ -201,15 +197,21 @@
>>>>>   @Test
>>>>>   public void jndiLookupWithFilter() throws NamingException
>>>>>   {
>>>>> +    BundleMock mock = new BundleMock("scooby.doo", new Properties());
>>>>> +    +
>>>>>  Thread.currentThread().setContextClassLoader(mock.getClassLoader());
>>>>> +
>>>>>     InitialContext ctx = new InitialContext();
>>>>>          Object s =
>>>>> ctx.lookup("aries:services/java.lang.Runnable/(rubbish=smelly)");
>>>>>          assertNotNull("We didn't get a service back from our 
>>>>> lookup :(",
>>>>> s);
>>>>>     -    assertEquals("The SR did not return the object we expected",
>>>>> service, s);
>>>>> +    service.run();
>>>>>     -    Skeleton.getSkeleton(bc).assertCalled(new
>>>>> MethodCall(BundleContext.class, "getServiceReferences",
>>>>> "java.lang.Runnable", "(rubbish=smelly)"));
>>>>> +    Skeleton.getSkeleton(service).assertCalledExactNumberOfTimes(new
>>>>> MethodCall(Runnable.class, "run"), 1);
>>>>> +
>>>>> +    Skeleton.getSkeleton(mock.getBundleContext()).assertCalled(new
>>>>> MethodCall(BundleContext.class, "getServiceReferences",
>>>>> "java.lang.Runnable", "(rubbish=smelly)"));
>>>>>   }
>>>>>      /**
>>>>> @@ -222,6 +224,11 @@
>>>>>   public void testLookupWhenServiceHasBeenRemoved() throws 
>>>>> NamingException
>>>>>   {
>>>>>     reg.unregister();
>>>>> +
>>>>> +    BundleMock mock = new BundleMock("scooby.doo", new Properties());
>>>>> +    +
>>>>>  Thread.currentThread().setContextClassLoader(mock.getClassLoader());
>>>>> +
>>>>>     InitialContext ctx = new InitialContext();
>>>>>          ctx.lookup("aries:services/java.lang.Runnable");
>>>>> @@ -236,6 +243,10 @@
>>>>>   @Test(expected=NameNotFoundException.class)
>>>>>   public void testLookupForServiceWeNeverHad() throws NamingException
>>>>>   {
>>>>> +    BundleMock mock = new BundleMock("scooby.doo", new Properties());
>>>>> +    +
>>>>>  Thread.currentThread().setContextClassLoader(mock.getClassLoader());
>>>>> +
>>>>>     InitialContext ctx = new InitialContext();
>>>>>          ctx.lookup("aries:services/java.lang.Integer");
>>>>> @@ -271,14 +282,53 @@
>>>>>   }
>>>>>    @Test
>>>>> +  public void checkProxyDynamism() throws NamingException
>>>>> +  {
>>>>> +    BundleMock mock = new BundleMock("scooby.doo", new Properties());
>>>>> +    +
>>>>>  Thread.currentThread().setContextClassLoader(mock.getClassLoader());
>>>>> +
>>>>> +    InitialContext ctx = new InitialContext();
>>>>> +    +    String className = Runnable.class.getName();
>>>>> +    +    Runnable t = Skeleton.newMock(Runnable.class);
>>>>> +    Runnable t2 = Skeleton.newMock(Runnable.class);
>>>>> +    +    // we don't want the default service
>>>>> +    reg.unregister();
>>>>> +    +    ServiceRegistration reg = bc.registerService(className, t,
>>>>> null);
>>>>> +    bc.registerService(className, t2, null);
>>>>> +    +    Runnable r = (Runnable)
>>>>> ctx.lookup("osgi:service/java.lang.Runnable");
>>>>> +    +    r.run();
>>>>> +    +    Skeleton.getSkeleton(t).assertCalledExactNumberOfTimes(new
>>>>> MethodCall(Runnable.class, "run"), 1);
>>>>> +    Skeleton.getSkeleton(t2).assertNotCalled(new
>>>>> MethodCall(Runnable.class, "run"));
>>>>> +    +    reg.unregister();
>>>>> +    +    r.run();
>>>>> +    +    Skeleton.getSkeleton(t).assertCalledExactNumberOfTimes(new
>>>>> MethodCall(Runnable.class, "run"), 1);
>>>>> +    Skeleton.getSkeleton(t2).assertCalledExactNumberOfTimes(new
>>>>> MethodCall(Runnable.class, "run"), 1);
>>>>> +  }  +
>>>>> +  @Test
>>>>>   public void checkServiceOrderObserved() throws NamingException
>>>>>   {
>>>>> +    BundleMock mock = new BundleMock("scooby.doo", new Properties());
>>>>> +    +
>>>>>  Thread.currentThread().setContextClassLoader(mock.getClassLoader());
>>>>> +
>>>>>     InitialContext ctx = new InitialContext();
>>>>>          String className = Runnable.class.getName();
>>>>>     -    Thread t = new Thread();
>>>>> -    Thread t2 = new Thread();
>>>>> +    Runnable t = Skeleton.newMock(Runnable.class);
>>>>> +    Runnable t2 = Skeleton.newMock(Runnable.class);
>>>>>          // we don't want the default service
>>>>>     reg.unregister();
>>>>> @@ -286,9 +336,12 @@
>>>>>     ServiceRegistration reg = bc.registerService(className, t, null);
>>>>>     ServiceRegistration reg2 = bc.registerService(className, t2, 
>>>>> null);
>>>>>     -    Runnable r = (Runnable)
>>>>> ctx.lookup("osgi:services/java.lang.Runnable");
>>>>> +    Runnable r = (Runnable)
>>>>> ctx.lookup("osgi:service/java.lang.Runnable");
>>>>>     -    assertSame("The wrong runnable was returned", t, r);
>>>>> +    r.run();
>>>>> +    +    Skeleton.getSkeleton(t).assertCalledExactNumberOfTimes(new
>>>>> MethodCall(Runnable.class, "run"), 1);
>>>>> +    Skeleton.getSkeleton(t2).assertNotCalled(new
>>>>> MethodCall(Runnable.class, "run"));
>>>>>          reg.unregister();
>>>>>     reg2.unregister();
>>>>> @@ -296,12 +349,18 @@
>>>>>     Hashtable<String, Object> props = new Hashtable<String, Object>();
>>>>>     props.put(Constants.SERVICE_RANKING, 55);
>>>>>     +    t = Skeleton.newMock(Runnable.class);
>>>>> +    t2 = Skeleton.newMock(Runnable.class);
>>>>> +
>>>>>     reg = bc.registerService(className, t, null);
>>>>>     reg2 = bc.registerService(className, t2, props);
>>>>>     -    r = (Runnable) 
>>>>> ctx.lookup("osgi:services/java.lang.Runnable");
>>>>> +    r = (Runnable) ctx.lookup("osgi:service/java.lang.Runnable");
>>>>> +    +    r.run();
>>>>>     -    assertSame("The wrong runnable was returned", t2, r);
>>>>> +    Skeleton.getSkeleton(t).assertNotCalled(new
>>>>> MethodCall(Runnable.class, "run"));
>>>>> +    Skeleton.getSkeleton(t2).assertCalledExactNumberOfTimes(new
>>>>> MethodCall(Runnable.class, "run"), 1);
>>>>>   }
>>>>>      /**
>>>>>
>>>>>
>>>>>
>>>>
>>>> -- 
>>>> Joe
>>>>
>>>
>>>
>>>
>>
>>
> 
> 


-- 
Joe

Re: svn commit: r917809 - in /incubator/aries/trunk/jndi/jndi-url: ./ src/main/java/org/apache/aries/jndi/services/ src/main/java/org/apache/aries/jndi/url/ src/test/java/org/apache/aries/jndi/url/

Posted by Joe Bohn <jo...@gmail.com>.
And here's the thread context classloader before the lookup ...

JasperClassLoader{bundleClassLoader=BundleClassLoader{bundle=org.apache.aries.ariestrader.modules.ariestrader-web_1.0.0.incubating-SNAPSHOT 
[35],parent=org.eclipse.osgi.internal.baseadaptor.DefaultClassLoader@78ecf608}}


Joe

Joe Bohn wrote:
> 
> Here's the stack trace for the CNFE.  I'll have to work on getting the 
> thread context classloader.
> 
> [112793090@qtp-2020456228-2 - 
> /org.apache.aries.ariestrader.modules.ariestrader-web/config] DEBUG 
> org.apache.aries.blueprint.container.ServiceRecipe - Calling listeners 
> for initial service registration
> java.lang.ClassNotFoundException: 
> org.apache.aries.samples.ariestrader.api.TradeServicesManager
>         at 
> org.eclipse.osgi.internal.loader.BundleLoader.findClassInternal(BundleLoader.java:489) 
> 
>         at 
> org.eclipse.osgi.internal.loader.BundleLoader.findClass(BundleLoader.java:405) 
> 
>         at 
> org.eclipse.osgi.internal.loader.BundleLoader.findClass(BundleLoader.java:393) 
> 
>         at 
> org.eclipse.osgi.internal.baseadaptor.DefaultClassLoader.loadClass(DefaultClassLoader.java:105) 
> 
>         at java.lang.ClassLoader.loadClass(ClassLoader.java:250)
>         at 
> org.eclipse.osgi.internal.loader.BundleLoader.loadClass(BundleLoader.java:321) 
> 
>         at 
> org.eclipse.osgi.framework.internal.core.BundleHost.loadClass(BundleHost.java:231) 
> 
>         at 
> org.eclipse.osgi.framework.internal.core.AbstractBundle.loadClass(AbstractBundle.java:1193) 
> 
>         at 
> org.apache.aries.jndi.services.ServiceHelper.getService(ServiceHelper.java:210) 
> 
>         at 
> org.apache.aries.jndi.url.ServiceRegistryContext.lookup(ServiceRegistryContext.java:189) 
> 
>         at 
> org.apache.aries.jndi.url.ServiceRegistryContext.lookup(ServiceRegistryContext.java:218) 
> 
>         at 
> org.apache.aries.jndi.DelegateContext.lookup(DelegateContext.java:160)
>         at javax.naming.InitialContext.lookup(InitialContext.java:392)
>         at 
> org.apache.aries.samples.ariestrader.util.ServiceUtilities.getOSGIService(ServiceUtilities.java:60) 
> 
>         at 
> org.apache.aries.samples.ariestrader.util.ServiceUtilities.getOSGIService(ServiceUtilities.java:41) 
> 
>         at 
> org.apache.aries.samples.ariestrader.api.TradeServiceUtilities.getTradeServicesManager(TradeServiceUtilities.java:63) 
> 
>         at org.apache.jsp.config_jsp._jspService(config_jsp.java:86)
>         at 
> org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:70)
>         at javax.servlet.http.HttpServlet.service(HttpServlet.java:820)
>         at 
> org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:374) 
> 
>         at 
> org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:342)
>         at 
> org.apache.jasper.servlet.JspServlet.service(JspServlet.java:267)
>         at javax.servlet.http.HttpServlet.service(HttpServlet.java:820)
>         at 
> org.ops4j.pax.web.jsp.JspServletWrapper$2.call(JspServletWrapper.java:132)
>         at 
> org.ops4j.pax.web.jsp.JspServletWrapper$2.call(JspServletWrapper.java:127)
>         at 
> org.ops4j.pax.swissbox.core.ContextClassLoaderUtils.doWithClassLoader(ContextClassLoaderUtils.java:60) 
> 
>         at 
> org.ops4j.pax.web.jsp.JspServletWrapper.service(JspServletWrapper.java:124)
>         at 
> org.mortbay.jetty.servlet.ServletHolder.handle(ServletHolder.java:502)
>         at 
> org.mortbay.jetty.servlet.ServletHandler.handle(ServletHandler.java:389)
>         at 
> org.ops4j.pax.web.service.jetty.internal.HttpServiceServletHandler.handle(HttpServiceServletHandler.java:64) 
> 
>         at 
> org.mortbay.jetty.servlet.SessionHandler.handle(SessionHandler.java:181)
>         at 
> org.mortbay.jetty.handler.ContextHandler.handle(ContextHandler.java:765)
>         at 
> org.ops4j.pax.web.service.jetty.internal.HttpServiceContext.handle(HttpServiceContext.java:111) 
> 
>         at 
> org.mortbay.jetty.servlet.Dispatcher.include(Dispatcher.java:192)
>         at 
> org.apache.aries.samples.ariestrader.web.TradeConfigServlet.doConfigDisplay(TradeConfigServlet.java:62) 
> 
>         at 
> org.apache.aries.samples.ariestrader.web.TradeConfigServlet.service(TradeConfigServlet.java:403) 
> 
>         at javax.servlet.http.HttpServlet.service(HttpServlet.java:820)
>         at 
> org.mortbay.jetty.servlet.ServletHolder.handle(ServletHolder.java:502)
>         at 
> org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157) 
> 
>         at 
> org.ops4j.pax.web.service.internal.WelcomeFilesFilter.doFilter(WelcomeFilesFilter.java:169) 
> 
>         at 
> org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1148) 
> 
>         at 
> org.mortbay.jetty.servlet.ServletHandler.handle(ServletHandler.java:387)
>         at 
> org.ops4j.pax.web.service.jetty.internal.HttpServiceServletHandler.handle(HttpServiceServletHandler.java:64) 
> 
>         at 
> org.mortbay.jetty.servlet.SessionHandler.handle(SessionHandler.java:181)
>         at 
> org.mortbay.jetty.handler.ContextHandler.handle(ContextHandler.java:765)
>         at 
> org.ops4j.pax.web.service.jetty.internal.HttpServiceContext.handle(HttpServiceContext.java:111) 
> 
>         at 
> org.ops4j.pax.web.service.jetty.internal.JettyServerHandlerCollection.handle(JettyServerHandlerCollection.java:64) 
> 
>         at 
> org.mortbay.jetty.handler.HandlerWrapper.handle(HandlerWrapper.java:152)
>         at org.mortbay.jetty.Server.handle(Server.java:322)
>         at 
> org.mortbay.jetty.HttpConnection.handleRequest(HttpConnection.java:534)
>         at 
> org.mortbay.jetty.HttpConnection$RequestHandler.headerComplete(HttpConnection.java:864) 
> 
>         at org.mortbay.jetty.HttpParser.parseNext(HttpParser.java:539)
>         at org.mortbay.jetty.HttpParser.parseAvailable(HttpParser.java:212)
>         at org.mortbay.jetty.HttpConnection.handle(HttpConnection.java:404)
>         at 
> org.mortbay.io.nio.SelectChannelEndPoint.run(SelectChannelEndPoint.java:409) 
> 
>         at 
> org.mortbay.thread.QueuedThreadPool$PoolThread.run(QueuedThreadPool.java:520) 
> 
> 
> Alasdair Nottingham wrote:
>> Hi,
>>
>> Hmm, I suspect I am not correctly finding the appropriate
>> BundleContext to use. That would explain the CNFE because we now proxy
>> the services rather than returning the raw service. If it is being
>> listed as being used by the pax-web jsp bundle that would explain
>> things.
>>
>> Do you have a stack trace for the ClassNotFoundException? That might
>> help to work out what went wrong.
>>
>> Also can you check the thread context classloader before the lookup?
>>
>> Thanks
>> Alasdair
>>
>> On 2 March 2010 23:21, Joe Bohn <jo...@gmail.com> wrote:
>>> I think there are some issues with this change.   I'll have to dig 
>>> some more
>>> and post more details later (don't have time right now) ... but in 
>>> short I'm
>>> seeing the following:
>>>
>>> - AriesTrader is behaving very badly after this change.
>>> - From within a jsp we use jndi lookup to find an osgi service.
>>> - After this change I get a failure in my jsp with a CNFE.   This 
>>> despite
>>> the fact that I can see the package is imported on the web bundle and
>>> appears to be wired correctly.
>>> - Even more strange: I notice that the application service I was 
>>> looking for
>>> is listed as being used by the pax-web jsp bundle.  So it seems like we
>>> might be using the wrong bundle context at some point.
>>>
>>>
>>> Joe
>>>
>>>
>>>
>>> not@apache.org wrote:
>>>> Author: not
>>>> Date: Mon Mar  1 23:53:18 2010
>>>> New Revision: 917809
>>>>
>>>> URL: http://svn.apache.org/viewvc?rev=917809&view=rev
>>>> Log:
>>>> ARIES-128 Implement OSGi spec url lookup scheme
>>>>
>>>> Added:
>>>>
>>>>  incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/OsgiName.java 
>>>>
>>>>      - copied, changed from r910238,
>>>> incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/ServiceRegistryName.java 
>>>>
>>>>
>>>>  incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/OsgiNameParser.java 
>>>>
>>>>      - copied, changed from r910238,
>>>> incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/ServiceRegistryNameParser.java 
>>>>
>>>>
>>>>  incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/ServiceRegistryListContext.java 
>>>>
>>>>
>>>>  incubator/aries/trunk/jndi/jndi-url/src/test/java/org/apache/aries/jndi/url/OsgiNameParserTest.java 
>>>>
>>>>      - copied, changed from r917002,
>>>> incubator/aries/trunk/jndi/jndi-url/src/test/java/org/apache/aries/jndi/url/ServiceRegistryNameParserTest.java 
>>>>
>>>> Removed:
>>>>
>>>>  incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/ServiceRegistryName.java 
>>>>
>>>>
>>>>  incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/ServiceRegistryNameParser.java 
>>>>
>>>>
>>>>  incubator/aries/trunk/jndi/jndi-url/src/test/java/org/apache/aries/jndi/url/ServiceHelperTest.java 
>>>>
>>>>
>>>>  incubator/aries/trunk/jndi/jndi-url/src/test/java/org/apache/aries/jndi/url/ServiceRegistryNameParserTest.java 
>>>>
>>>> Modified:
>>>>    incubator/aries/trunk/jndi/jndi-url/pom.xml
>>>>
>>>>  incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/services/ServiceHelper.java 
>>>>
>>>>
>>>>  incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/Activator.java 
>>>>
>>>>
>>>>  incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/OsgiURLContextFactory.java 
>>>>
>>>>
>>>>  incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/ServiceRegistryContext.java 
>>>>
>>>>
>>>>  incubator/aries/trunk/jndi/jndi-url/src/test/java/org/apache/aries/jndi/url/ServiceRegistryContextTest.java 
>>>>
>>>>
>>>> Modified: incubator/aries/trunk/jndi/jndi-url/pom.xml
>>>> URL:
>>>> http://svn.apache.org/viewvc/incubator/aries/trunk/jndi/jndi-url/pom.xml?rev=917809&r1=917808&r2=917809&view=diff 
>>>>
>>>>
>>>> ============================================================================== 
>>>>
>>>> --- incubator/aries/trunk/jndi/jndi-url/pom.xml (original)
>>>> +++ incubator/aries/trunk/jndi/jndi-url/pom.xml Mon Mar  1 23:53:18 
>>>> 2010
>>>> @@ -33,6 +33,10 @@
>>>>      <dependencies>
>>>>       <dependency>
>>>> +       <groupId>org.apache.aries</groupId>
>>>> +       <artifactId>org.apache.aries.util</artifactId>
>>>> +      </dependency>
>>>> +      <dependency>
>>>>           <groupId>org.osgi</groupId>
>>>>           <artifactId>org.osgi.core</artifactId>
>>>>           <scope>provided</scope>
>>>>
>>>> Modified:
>>>> incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/services/ServiceHelper.java 
>>>>
>>>> URL:
>>>> http://svn.apache.org/viewvc/incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/services/ServiceHelper.java?rev=917809&r1=917808&r2=917809&view=diff 
>>>>
>>>>
>>>> ============================================================================== 
>>>>
>>>> ---
>>>> incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/services/ServiceHelper.java 
>>>>
>>>> (original)
>>>> +++
>>>> incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/services/ServiceHelper.java 
>>>>
>>>> Mon Mar  1 23:53:18 2010
>>>> @@ -18,18 +18,30 @@
>>>>  */
>>>>  package org.apache.aries.jndi.services;
>>>>  +import java.lang.reflect.InvocationHandler;
>>>> +import java.lang.reflect.Method;
>>>> +import java.lang.reflect.Proxy;
>>>> +import java.security.AccessController;
>>>> +import java.security.PrivilegedAction;
>>>> +import java.util.ArrayList;
>>>>  import java.util.Arrays;
>>>>  import java.util.Comparator;
>>>>  import java.util.HashSet;
>>>>  import java.util.LinkedList;
>>>>  import java.util.List;
>>>> +import java.util.Map;
>>>>  import java.util.Set;
>>>>  import java.util.concurrent.ConcurrentHashMap;
>>>>  import java.util.concurrent.ConcurrentMap;
>>>>  +import javax.naming.NamingException;
>>>> +
>>>> +import org.apache.aries.util.BundleToClassLoaderAdapter;
>>>> +import org.osgi.framework.Bundle;
>>>>  import org.osgi.framework.BundleContext;
>>>>  import org.osgi.framework.BundleReference;
>>>>  import org.osgi.framework.InvalidSyntaxException;
>>>> +import org.osgi.framework.ServiceException;
>>>>  import org.osgi.framework.ServiceReference;
>>>>  /**
>>>> @@ -47,221 +59,206 @@
>>>>  */
>>>>  public final class ServiceHelper
>>>>  {
>>>> -  /** The bundle context used for service registry queries */
>>>> -  private static BundleContext context;
>>>> -  /** A cache of what service was returned last time the query was
>>>> performed */
>>>> -  private static ConcurrentMap<ServiceKey, Set<ServiceReference>> 
>>>> cache =
>>>> new ConcurrentHashMap<ServiceKey, Set<ServiceReference>>();
>>>> -
>>>> -  public static void setBundleContext(BundleContext ctx)
>>>> +  public static class StackFinder extends SecurityManager
>>>>   {
>>>> -    context = ctx;
>>>> +    public Class<?>[] getClassContext()
>>>> +    {
>>>> +      return super.getClassContext();
>>>> +    }
>>>>   }
>>>> -  -  /**
>>>> -   * This class is used as the key into the cache. It holds 
>>>> information
>>>> to identify -   * who performed the query, along with the className and
>>>> filter used. The thread context
>>>> -   * class loader is used in the key, so two different modules will
>>>> potentially get different
>>>> -   * services.
>>>> -   */
>>>> -  private static final class ServiceKey
>>>> +
>>>> +  private static class JNDIServiceDamper implements InvocationHandler
>>>>   {
>>>> -    /** The class loader of the invoking application */
>>>> -    private ClassLoader classLoader;
>>>> -    /** The name of the class being queried from the registry */
>>>> -    private String className;
>>>> -    /** the registry filter, this may be null */
>>>> +    private BundleContext ctx;
>>>> +    private ServicePair pair;
>>>> +    private String interfaceName;
>>>>     private String filter;
>>>> -    /** The cached hashCode */
>>>> -    private final int hashCode;
>>>> -
>>>> -    /**
>>>> -     * Boring unimportant comment.
>>>> -     * -     * @param cl
>>>> -     * @param cn
>>>> -     * @param f
>>>> -     */
>>>> -    public ServiceKey(ClassLoader cl, String cn, String f)
>>>> +    private boolean dynamic;
>>>> +    +    public JNDIServiceDamper(BundleContext context, String i, 
>>>> String
>>>> f, ServicePair service, boolean d)
>>>>     {
>>>> -      classLoader = cl;
>>>> -      className = cn;
>>>> +      ctx = context;
>>>> +      pair = service;
>>>> +      interfaceName = i;
>>>>       filter = f;
>>>> -      -      int classNameHash = (className == null) ? 0 :
>>>> className.hashCode();
>>>> -      hashCode = System.identityHashCode(classLoader) * 1000003 +
>>>> classNameHash;
>>>> +      dynamic = d;
>>>>     }
>>>> -
>>>> -    @Override
>>>> -    public int hashCode()
>>>> -    {
>>>> -      return hashCode;
>>>> -    }
>>>> -
>>>> -    @Override
>>>> -    public boolean equals(Object other)
>>>> +    +    public Object invoke(Object proxy, Method method, Object[] 
>>>> args)
>>>> throws Throwable
>>>>     {
>>>> -      if (other == this) return true;
>>>> -      if (other == null) return false;
>>>> -
>>>> -      if (other instanceof ServiceKey) {
>>>> -        ServiceKey otherKey = (ServiceKey) other;
>>>> -        if (hashCode != otherKey.hashCode) return false;
>>>> -
>>>> -        if (classLoader != otherKey.classLoader) return false;
>>>> -        if (!!!comparePossiblyNullObjects(className, 
>>>> otherKey.className))
>>>> return false;
>>>> -        return comparePossiblyNullObjects(filter, otherKey.filter);
>>>> -      }
>>>> -
>>>> -      return false;
>>>> -    }
>>>> -    -    /**
>>>> -     * Compares two objects where one or other (or both) may be null.
>>>> -     * -     * @param a the first object to compare.
>>>> -     * @param b the second object to compare.
>>>> -     * @return true if they are ==, both null or identity equals, 
>>>> false
>>>> otherwise.
>>>> -     */
>>>> -    public boolean comparePossiblyNullObjects(Object a, Object b) {
>>>> -      if (a == b) return true;
>>>> -      else if (a == null) return false;
>>>> -      else return a.equals(b);
>>>> +      if (pair.ref.getBundle() == null) {
>>>> +        if (dynamic) pair = findService(ctx, interfaceName, filter);
>>>> +        else pair = null;
>>>> +      }
>>>> +      +      if (pair == null) {
>>>> +        throw new ServiceException(interfaceName,
>>>> ServiceException.UNREGISTERED);
>>>> +      }
>>>> +      +      return method.invoke(pair.service, args);
>>>>     }
>>>>   }
>>>> -
>>>> -  /**
>>>> -   * This method is used to obtain a single instance of a desired 
>>>> service
>>>> from the OSGi
>>>> -   * service registry. If the filter and class name identify multiple
>>>> services the first
>>>> -   * one is returned. If no service is found null will be returned.
>>>> -   * -   * @param className The class name used to register the 
>>>> desired
>>>> service. If null is provided
>>>> -   *                  then all services are eligible to be returned.
>>>> -   * @param filter    An RFC 1960 query into the properties of the
>>>> registered services. e.g.
>>>> -   *                  (service.description=really useful)
>>>> -   * @return          The desired service
>>>> -   * -   * @throws IllegalArgumentException If the filter is not 
>>>> valid.
>>>> See RFC 1960 to work out what -   *                                  it
>>>> should be.
>>>> -   */
>>>> -  public static Object getService(String className, String filter) 
>>>> throws
>>>> IllegalArgumentException
>>>> +  +  private static class ServicePair
>>>>   {
>>>> -    Object service = null;
>>>> -    try {
>>>> -      BundleContext callerCtx = getBundleContext();
>>>> -      ServiceReference[] refs = 
>>>> callerCtx.getServiceReferences(className,
>>>> filter);
>>>> -      -      if (refs != null) {
>>>> -        // we need to sort the references returned in case they are 
>>>> out
>>>> of order
>>>> -        // we need to sort in the reverse natural order, services with
>>>> higher -        // ranking or lower id should be processed first so 
>>>> should
>>>> be earlier in the array.
>>>> -        Arrays.sort(refs, new Comparator<ServiceReference>() {
>>>> -          public int compare(ServiceReference o1, ServiceReference o2)
>>>> -          {
>>>> -            return o2.compareTo(o1);
>>>> -          }
>>>> -        });
>>>> -        -        for (ServiceReference ref : refs) {
>>>> -          List<Object> services = getServices(callerCtx, className,
>>>> filter, ref);
>>>> -          if (!!!services.isEmpty()) {
>>>> -            service = services.get(0);
>>>> -            break;
>>>> -          }
>>>> -        }
>>>> -      }      -    } catch (InvalidSyntaxException e) {
>>>> -      throw new IllegalArgumentException(e.getMessage(), e);
>>>> -    }
>>>> -    -    return service;
>>>> +    private ServiceReference ref;
>>>> +    private Object service;
>>>>   }
>>>>      /**
>>>> -   * This method is used to obtain a list of service instances from 
>>>> the
>>>> OSGi
>>>> -   * service registry. If no service is found an empty list will be
>>>> returned.
>>>> -   * -   * @param className The class name used to register the 
>>>> desired
>>>> service. If null is provided
>>>> -   *                  then all services are eligible to be returned.
>>>> -   * @param filter    An RFC 1960 query into the properties of the
>>>> registered services. e.g.
>>>> -   *                  (service.description=really useful)
>>>> -   * @return          A list of matching services.
>>>> -   * -   * @throws IllegalArgumentException If the filter is not 
>>>> valid.
>>>> See RFC 1960 to work out what -   *                                  it
>>>> should be.
>>>> +   * @param env +   * @return the bundle context for the caller.
>>>> +   * @throws NamingException     */
>>>> -  public static List<?> getServices(String className, String filter)
>>>> -      throws IllegalArgumentException
>>>> +  public static BundleContext getBundleContext(Map<String, Object> 
>>>> env)
>>>> throws NamingException
>>>>   {
>>>> -    List<Object> services;
>>>> -    try {
>>>> -      BundleContext callerCtx = getBundleContext();
>>>> -      ServiceReference[] refs =
>>>> callerCtx.getAllServiceReferences(className, filter);
>>>> +    BundleContext result = null;
>>>> +    +    Object bc = env.get("osgi.service.jndi.bundleContext");
>>>> +    +    if (bc != null && bc instanceof BundleContext) result =
>>>> (BundleContext) bc;
>>>> +    else {
>>>> +      ClassLoader cl = AccessController.doPrivileged(new
>>>> PrivilegedAction<ClassLoader>() {
>>>> +        public ClassLoader run()
>>>> +        {
>>>> +          return Thread.currentThread().getContextClassLoader();
>>>> +        }
>>>> +      });
>>>>       -      services = getServices(callerCtx, className, filter, 
>>>> refs);
>>>> -    } catch (InvalidSyntaxException e) {
>>>> -      throw new IllegalArgumentException(e.getMessage(), e);
>>>> +      result = getBundleContext(cl);
>>>> +    }
>>>> +    +    if (result == null) {
>>>> +      StackTraceElement[] stackTrace = 
>>>> AccessController.doPrivileged(new
>>>> PrivilegedAction<StackTraceElement[]>() {
>>>> +        public StackTraceElement[] run()
>>>> +        {
>>>> +          return Thread.currentThread().getStackTrace();
>>>> +        }
>>>> +      });
>>>> +      +      StackFinder finder = new StackFinder();
>>>> +      Class<?>[] classStack = finder.getClassContext();
>>>> +      +      boolean found = false;
>>>> +      boolean foundLookup = false;
>>>> +      int i = 0;
>>>> +      for (; i < stackTrace.length && !!!found; i++) {
>>>> +        if (!!!foundLookup &&
>>>> "lookup".equals(stackTrace[i].getMethodName())) {
>>>> +          foundLookup = true;
>>>> +        } else if (foundLookup &&
>>>> !!!(stackTrace[i].getClassName().startsWith("org.apache.aries.jndi") ||
>>>> +
>>>>  stackTrace[i].getClassName().startsWith("javax.naming"))) {
>>>> +          found = true;
>>>> +        }
>>>> +      }
>>>> +      +      if (found) {
>>>> +        Set<Integer> classLoadersChecked = new HashSet<Integer>();
>>>> +        for (; i < classStack.length && result == null; i++) {
>>>> +          ClassLoader cl = classStack[i].getClassLoader();
>>>> +          int hash = System.identityHashCode(cl);
>>>> +          if (!!!classLoadersChecked.contains(hash)) {
>>>> +            classLoadersChecked.add(hash);
>>>> +            result = getBundleContext(cl);
>>>> +          }
>>>> +        }
>>>> +        // Now we walk the stack looking for the BundleContext
>>>> +      }
>>>>     }
>>>>     -    return services;
>>>> +    if (result == null) throw new NamingException("Unable to find
>>>> BundleContext");
>>>> +    +    return result;
>>>>   }
>>>> -  -  /**
>>>> -   * @return the bundle context for the caller.
>>>> -   */
>>>> -  private static BundleContext getBundleContext()
>>>> +
>>>> +  private static BundleContext getBundleContext(ClassLoader cl)
>>>>   {
>>>>     BundleContext result = null;
>>>> -    ClassLoader cl = Thread.currentThread().getContextClassLoader();
>>>>     while (result == null && cl != null) {
>>>>       if (cl instanceof BundleReference) {
>>>>         result = ((BundleReference)cl).getBundle().getBundleContext();
>>>>       } else if (cl != null) {
>>>>         cl = cl.getParent();
>>>>       }
>>>> -    } +    }
>>>>     -    if (result == null) result = context;
>>>>     return result;
>>>>   }
>>>>  -  /**
>>>> -   * This worker method obtains the requested service(s) and if the
>>>> service(s) -   * exist updates the cache and releases the previous
>>>> service(s).
>>>> -   * -   * @param callerCtx The caller context.
>>>> -   * @param className The class name used to query for the service.
>>>> -   * @param filter    The filter name used to query for the service.
>>>> -   * @param refs      The references to get.
>>>> -   * @return          The service, if one was found, or null.
>>>> -   */
>>>> -  private static List<Object> getServices(BundleContext callerCtx, 
>>>> String
>>>> className, String filter, ServiceReference...refs)
>>>> +  public static Object getService(String interface1, String filter,
>>>> String serviceName, boolean dynamicRebind, Map<String, Object> env) 
>>>> throws
>>>> NamingException
>>>>   {
>>>> -    List<Object> data = new LinkedList<Object>();
>>>> +    Object result = null;
>>>> +    +    BundleContext ctx = getBundleContext(env);
>>>> +    +    ServicePair pair = findService(ctx, interface1, filter);
>>>>     -    if (refs != null) {
>>>> -      Set<ServiceReference> refSet = new HashSet<ServiceReference>();
>>>> -      for (ServiceReference ref : refs) {
>>>> -        Object service = callerCtx.getService(ref);
>>>> -        if (service != null) {
>>>> -          data.add(service);
>>>> -          refSet.add(ref);
>>>> +    if (pair == null) {
>>>> +      interface1 = null;
>>>> +      filter = "(osgi.jndi.serviceName=" + serviceName + ")";
>>>> +      pair = findService(ctx, interface1, filter);
>>>> +    }
>>>> +    +    if (pair != null) {
>>>> +      String[] interfaces = (String[])
>>>> pair.ref.getProperty("objectClass");
>>>> +      +      List<Class<?>> clazz = new
>>>> ArrayList<Class<?>>(interfaces.length);
>>>> +      +      Bundle b = ctx.getBundle();
>>>> +      +      for (String interfaceName : interfaces) {
>>>> +        try {
>>>> +          clazz.add(b.loadClass(interfaceName));
>>>> +        } catch (ClassNotFoundException e) {
>>>> +          // TODO Auto-generated catch block
>>>> +          e.printStackTrace();
>>>>         }
>>>>       }
>>>>       -      ClassLoader cl =
>>>> Thread.currentThread().getContextClassLoader();
>>>> -      ServiceKey key = new ServiceKey(cl, className, filter);
>>>> +      if (clazz.isEmpty()) {
>>>> +        throw new IllegalArgumentException();
>>>> +      }
>>>>       -      // we do not need any synchronization around this. The 
>>>> map is
>>>> concurrent
>>>> -      // and until here we do not touch any shared state.
>>>> -      refSet = cache.put(key, refSet);
>>>> +      InvocationHandler ih = new JNDIServiceDamper(ctx, interface1,
>>>> filter, pair, dynamicRebind);
>>>>       -      if (refSet != null) {
>>>> -        for (ServiceReference ref : refSet) {
>>>> -          callerCtx.ungetService(ref);
>>>> +      result = Proxy.newProxyInstance(new 
>>>> BundleToClassLoaderAdapter(b),
>>>> clazz.toArray(new Class<?>[clazz.size()]), ih);
>>>> +    }
>>>> +    +    return result;
>>>> +  }
>>>> +
>>>> +  private static ServicePair findService(BundleContext ctx, String
>>>> interface1, String filter)
>>>> +  {
>>>> +    ServicePair p = null;
>>>> +    +    try {
>>>> +      ServiceReference[] refs = ctx.getServiceReferences(interface1,
>>>> filter);
>>>> +      +      if (refs != null) {
>>>> +        // natural order is the exact opposite of the order we desire.
>>>> +        Arrays.sort(refs, new Comparator<ServiceReference>() {
>>>> +          public int compare(ServiceReference o1, ServiceReference o2)
>>>> +          {
>>>> +            return o2.compareTo(o1);
>>>> +          }
>>>> +        });
>>>> +        +        for (ServiceReference ref : refs) {
>>>> +          Object service = ctx.getService(ref);
>>>> +          +          if (service != null) {
>>>> +            p = new ServicePair();
>>>> +            p.ref = ref;
>>>> +            p.service = service;
>>>> +            break;
>>>> +          }
>>>>         }
>>>>       }
>>>> +      +    } catch (InvalidSyntaxException e) {
>>>> +      // TODO Auto-generated catch block
>>>> +      e.printStackTrace();
>>>>     }
>>>>     -    return data;
>>>> +    return p;
>>>>   }
>>>>  }
>>>>
>>>> Modified:
>>>> incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/Activator.java 
>>>>
>>>> URL:
>>>> http://svn.apache.org/viewvc/incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/Activator.java?rev=917809&r1=917808&r2=917809&view=diff 
>>>>
>>>>
>>>> ============================================================================== 
>>>>
>>>> ---
>>>> incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/Activator.java 
>>>>
>>>> (original)
>>>> +++
>>>> incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/Activator.java 
>>>>
>>>> Mon Mar  1 23:53:18 2010
>>>> @@ -34,8 +34,6 @@
>>>>
>>>>   public void start(BundleContext context)
>>>>   {
>>>> -    ServiceHelper.setBundleContext(context);
>>>> -         Hashtable<Object, Object> props = new Hashtable<Object,
>>>> Object>();
>>>>     props.put("osgi.jndi.urlScheme", new String[] {"osgi", "aries"} );
>>>>     reg = context.registerService(ObjectFactory.class.getName(), new
>>>> OsgiURLContextFactory(), props);
>>>>
>>>> Copied:
>>>> incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/OsgiName.java 
>>>>
>>>> (from r910238,
>>>> incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/ServiceRegistryName.java) 
>>>>
>>>> URL:
>>>> http://svn.apache.org/viewvc/incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/OsgiName.java?p2=incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/OsgiName.java&p1=incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/ServiceRegistryName.java&r1=910238&r2=917809&rev=917809&view=diff 
>>>>
>>>>
>>>> ============================================================================== 
>>>>
>>>> ---
>>>> incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/ServiceRegistryName.java 
>>>>
>>>> (original)
>>>> +++
>>>> incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/OsgiName.java 
>>>>
>>>> Mon Mar  1 23:53:18 2010
>>>> @@ -21,28 +21,104 @@
>>>>  import java.util.Enumeration;
>>>>  import javax.naming.CompositeName;
>>>> +import javax.naming.InvalidNameException;
>>>> +import javax.naming.Name;
>>>>  /**
>>>> - * A composite name for the aries namespace. We only have this so 
>>>> that we
>>>> can
>>>> - * provide a nicer toString()
>>>> + * A composite name for the aries namespace. This provides useful 
>>>> utility
>>>> methods
>>>> + * for accessing the name.
>>>> + * + * component 0: osgi:service, aries:services, osgi:servicelist
>>>> + * component 1: interface
>>>> + * component 2: filter
>>>>  */
>>>> -public final class ServiceRegistryName extends CompositeName
>>>> +public final class OsgiName extends CompositeName
>>>>  {
>>>>   /** The serial version UID */
>>>>   private static final long serialVersionUID = 6617580228852444656L;
>>>> +  public static final String OSGI_SCHEME = "osgi";
>>>> +  public static final String ARIES_SCHEME = "aries";
>>>> +  public static final String SERVICE_PATH = "service";
>>>> +  public static final String SERVICES_PATH = "services";
>>>> +  public static final String SERVICE_LIST_PATH = "servicelist";
>>>> +  public static final String FRAMEWORK_PATH = "framework";
>>>>   -  @Override
>>>> -  public String toString()
>>>> +  public OsgiName(String name) throws InvalidNameException
>>>>   {
>>>> -    StringBuilder buffer = new StringBuilder();
>>>> +    super(name);
>>>> +  }
>>>> +
>>>> +  public OsgiName(Name name) throws InvalidNameException
>>>> +  {
>>>> +    this(name.toString());
>>>> +  }
>>>> +
>>>> +  public boolean hasFilter()
>>>> +  {
>>>> +    return size() == 3;
>>>> +  }
>>>> +  +  public boolean isServiceNameBased()
>>>> +  {
>>>> +    return size() > 3;
>>>> +  }
>>>> +  +  public String getScheme()
>>>> +  {
>>>> +    String part0 = get(0);
>>>> +    int index = part0.indexOf(':');
>>>> +    +    String result;
>>>> +    +    if (index > 0) {
>>>> +      result = part0.substring(0, index);
>>>> +    } else {
>>>> +      result = null;
>>>> +    }
>>>> +    +    return result;
>>>> +  }
>>>> +  +  public String getSchemePath()
>>>> +  {
>>>> +    String part0 = get(0);
>>>> +    int index = part0.indexOf(':');
>>>> +    +    String result;
>>>>     -    buffer.append("aries:services");
>>>> -    Enumeration<String> components = getAll();
>>>> -    while (components.hasMoreElements()) {
>>>> -      buffer.append('/');
>>>> -      buffer.append(components.nextElement());
>>>> +    if (index > 0) {
>>>> +      result = part0.substring(index + 1);
>>>> +    } else {
>>>> +      result = null;
>>>>     }
>>>>     -    return buffer.toString();
>>>> +    return result;
>>>> +  }
>>>> +  +  public String getInterface()
>>>> +  {
>>>> +    return get(1);
>>>> +  }
>>>> +  +  public String getFilter()
>>>> +  {
>>>> +    return hasFilter() ? get(2) : null;
>>>> +  }
>>>> +  +  public String getServiceName()
>>>> +  {
>>>> +    Enumeration<String> parts = getAll();
>>>> +    parts.nextElement();
>>>> +    +    StringBuilder builder = new StringBuilder();
>>>> +    +    while (parts.hasMoreElements()) {
>>>> +      builder.append(parts.nextElement());
>>>> +      builder.append('/');
>>>> +    }
>>>> +    +    builder.deleteCharAt(builder.length() - 1);
>>>> +    +    return builder.toString();
>>>>   }
>>>>  }
>>>> \ No newline at end of file
>>>>
>>>> Copied:
>>>> incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/OsgiNameParser.java 
>>>>
>>>> (from r910238,
>>>> incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/ServiceRegistryNameParser.java) 
>>>>
>>>> URL:
>>>> http://svn.apache.org/viewvc/incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/OsgiNameParser.java?p2=incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/OsgiNameParser.java&p1=incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/ServiceRegistryNameParser.java&r1=910238&r2=917809&rev=917809&view=diff 
>>>>
>>>>
>>>> ============================================================================== 
>>>>
>>>> ---
>>>> incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/ServiceRegistryNameParser.java 
>>>>
>>>> (original)
>>>> +++
>>>> incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/OsgiNameParser.java 
>>>>
>>>> Mon Mar  1 23:53:18 2010
>>>> @@ -26,31 +26,40 @@
>>>>  /**
>>>>  * A parser for the aries namespace
>>>>  */
>>>> -public final class ServiceRegistryNameParser implements NameParser
>>>> +public final class OsgiNameParser implements NameParser
>>>>  {
>>>> -
>>>> +  private static final String OSGI_SCHEME = "osgi";
>>>> +  private static final String ARIES_SCHEME = "aries";
>>>> +  private static final String SERVICE_PATH = "service";
>>>> +  private static final String SERVICES_PATH = "services";
>>>> +  private static final String SERVICE_LIST_PATH = "servicelist";
>>>> +  private static final String FRAMEWORK_PATH = "framework";
>>>> +     public Name parse(String name) throws NamingException
>>>>   {
>>>> -    if (!!!name.startsWith("aries:services/") &&
>>>> -        !!!name.startsWith("osgi:services/")) throw new
>>>> InvalidNameException("The JNDI name did not start with aries:, or 
>>>> osgi:");
>>>> +    OsgiName result = new OsgiName(name);
>>>> +    +    if (result.size() < 2) throw new InvalidNameException(name);
>>>>     -    name = name.substring(name.indexOf('/') + 1);
>>>> +    String urlScheme = result.getScheme();
>>>> +    String schemePath = result.getSchemePath();
>>>>     -    int slashIndex = name.indexOf('/');
>>>> -    String interfaceName = name;
>>>> -    String filter = null;
>>>> -    -    if (slashIndex != -1) {
>>>> -      interfaceName = name.substring(0, slashIndex);
>>>> -      filter = name.substring(slashIndex + 1);
>>>> +    if (!!!(OSGI_SCHEME.equals(urlScheme) ||
>>>> ARIES_SCHEME.equals(urlScheme))) {
>>>> +      throw new InvalidNameException(name);
>>>>     }
>>>>     -    if (interfaceName.length() == 0) throw new
>>>> InvalidNameException("No interface name was specified");
>>>> +    if (ARIES_SCHEME.equals(urlScheme) &&
>>>> !!!SERVICES_PATH.equals(schemePath)) {
>>>> +      throw new InvalidNameException(name);
>>>> +    }
>>>> +    +    if (OSGI_SCHEME.equals(urlScheme) && !!!(
>>>> SERVICE_PATH.equals(schemePath) || +
>>>>      SERVICE_LIST_PATH.equals(schemePath) || +
>>>>                FRAMEWORK_PATH.equals(schemePath))) {
>>>> +      throw new InvalidNameException(name);
>>>> +    }
>>>>     -    Name result = new ServiceRegistryName();
>>>> -    result.add(interfaceName);
>>>> -    if (filter != null) {
>>>> -      result.add(filter);
>>>> +    if (result.getInterface() == null || 
>>>> result.getInterface().length()
>>>> == 0) {
>>>> +      throw new InvalidNameException(name);
>>>>     }
>>>>          return result;
>>>> @@ -59,7 +68,7 @@
>>>>   @Override
>>>>   public boolean equals(Object other)
>>>>   {
>>>> -    return other instanceof ServiceRegistryNameParser;
>>>> +    return other instanceof OsgiNameParser;
>>>>   }
>>>>      @Override
>>>>
>>>> Modified:
>>>> incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/OsgiURLContextFactory.java 
>>>>
>>>> URL:
>>>> http://svn.apache.org/viewvc/incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/OsgiURLContextFactory.java?rev=917809&r1=917808&r2=917809&view=diff 
>>>>
>>>>
>>>> ============================================================================== 
>>>>
>>>> ---
>>>> incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/OsgiURLContextFactory.java 
>>>>
>>>> (original)
>>>> +++
>>>> incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/OsgiURLContextFactory.java 
>>>>
>>>> Mon Mar  1 23:53:18 2010
>>>> @@ -49,7 +49,7 @@
>>>>     } else if (obj instanceof String[]) {
>>>>       // Try each URL until either lookup succeeds or they all fail
>>>>       String[] urls = (String[])obj;
>>>> -      if (urls.length == 0) throw new
>>>> ConfigurationException("ariesURLContextFactory: empty URL array");
>>>> +      if (urls.length == 0) throw new ConfigurationException("0");
>>>>       Context context = new ServiceRegistryContext(environment);
>>>>       try
>>>>       {
>>>>
>>>> Modified:
>>>> incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/ServiceRegistryContext.java 
>>>>
>>>> URL:
>>>> http://svn.apache.org/viewvc/incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/ServiceRegistryContext.java?rev=917809&r1=917808&r2=917809&view=diff 
>>>>
>>>>
>>>> ============================================================================== 
>>>>
>>>> ---
>>>> incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/ServiceRegistryContext.java 
>>>>
>>>> (original)
>>>> +++
>>>> incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/ServiceRegistryContext.java 
>>>>
>>>> Mon Mar  1 23:53:18 2010
>>>> @@ -42,9 +42,9 @@
>>>>  {
>>>>   private static final String ARIES_SERVICES = "aries:services/";
>>>>   /** The name parser for the service registry name space */
>>>> -  private NameParser parser = new ServiceRegistryNameParser();
>>>> +  private NameParser parser = new OsgiNameParser();
>>>>   /** The environment for this context */
>>>> -  private Map<Object, Object> env;
>>>> +  private Map<String, Object> env;
>>>>      /**
>>>>    * Why Mr Java this class does indeed take a fine copy of the 
>>>> provided
>>>> @@ -53,10 +53,11 @@
>>>>    *     * @param environment
>>>>    */
>>>> +  @SuppressWarnings("unchecked")
>>>>   public ServiceRegistryContext(Hashtable<?, ?> environment)
>>>>   {
>>>> -    env = new HashMap<Object, Object>();
>>>> -    env.putAll(environment);
>>>> +    env = new HashMap<String, Object>();
>>>> +    env.putAll((Map<? extends String, ? extends Object>) environment);
>>>>   }
>>>>    public Object addToEnvironment(String propName, Object propVal) 
>>>> throws
>>>> NamingException
>>>> @@ -153,7 +154,7 @@
>>>>    public NamingEnumeration<NameClassPair> list(final Name name) throws
>>>> NamingException
>>>>   {
>>>> -    throw new NamingException("Not a Context");
>>>> +    return new ServiceRegistryListContext(env, 
>>>> convert(name)).list("");
>>>>   }
>>>>    public NamingEnumeration<NameClassPair> list(String name) throws
>>>> NamingException
>>>> @@ -163,7 +164,7 @@
>>>>    public NamingEnumeration<Binding> listBindings(final Name name) 
>>>> throws
>>>> NamingException
>>>>   {
>>>> -    throw new NamingException("Not a Context");
>>>> +    return new ServiceRegistryListContext(env,
>>>> convert(name)).listBindings("");
>>>>   }
>>>>    public NamingEnumeration<Binding> listBindings(String name) throws
>>>> NamingException
>>>> @@ -173,28 +174,43 @@
>>>>    public Object lookup(Name name) throws NamingException
>>>>   {
>>>> -    int nameSize = validateName(name);
>>>> -    String className = name.get(0);
>>>> -
>>>> -    String filter = null;
>>>> +    Object result;
>>>> +    +    OsgiName validName = convert(name);
>>>>     -    if (nameSize == 2) {
>>>> -      filter = name.get(1);
>>>> +    String pathFragment = validName.getSchemePath();
>>>> +    String serviceName = validName.getServiceName();
>>>> +    String schemeName = validName.getScheme();
>>>> +    +    if (OsgiName.FRAMEWORK_PATH.equals(pathFragment) &&
>>>> "bundleContext".equals(validName.getServiceName())) {
>>>> +      result = ServiceHelper.getBundleContext(env);
>>>> +    } else if ((OsgiName.SERVICE_PATH.equals(pathFragment) &&
>>>> OsgiName.OSGI_SCHEME.equals(schemeName)) ||
>>>> +               (OsgiName.SERVICES_PATH.equals(pathFragment) &&
>>>> OsgiName.ARIES_SCHEME.equals(schemeName))) {
>>>> +      result = ServiceHelper.getService(validName.getInterface(),
>>>> validName.getFilter(), serviceName, true, env);
>>>> +    } else if (OsgiName.SERVICE_LIST_PATH.equals(pathFragment)) {
>>>> +      result = new ServiceRegistryListContext(env, validName);
>>>> +    } else {
>>>> +      result = null;
>>>>     }
>>>>     -    try {
>>>> -      Object result = ServiceHelper.getService(className, filter);
>>>> -      -      if (result == null) {
>>>> -        throw new NameNotFoundException("We couldn't find an object in
>>>> the registry matching the query " + name);
>>>> -      }
>>>> -      -      return result;
>>>> -    } catch (IllegalArgumentException e) {
>>>> -      NamingException ne = new NamingException(e.getMessage());
>>>> -      ne.initCause(e);
>>>> -      throw ne;
>>>> +    if (result == null) {
>>>> +      throw new NameNotFoundException(name.toString());
>>>> +    }
>>>> +    +    return result;
>>>> +  }
>>>> +
>>>> +  private OsgiName convert(Name name) throws InvalidNameException
>>>> +  {
>>>> +    OsgiName result;
>>>> +    +    if (name instanceof OsgiName) {
>>>> +      result = (OsgiName) name;
>>>> +    } else {
>>>> +      result = new OsgiName(name);
>>>>     }
>>>> +    +    return result;
>>>>   }
>>>>    public Object lookup(String name) throws NamingException
>>>> @@ -246,27 +262,4 @@
>>>>   {
>>>>     throw new OperationNotSupportedException();
>>>>   }
>>>> -  -  /**
>>>> -   * Check that the name conforms to the expected format
>>>> -   * @param name
>>>> -   * @return the size of the name
>>>> -   * @throws InvalidNameException
>>>> -   */
>>>> -  private int validateName(final Name name) throws 
>>>> InvalidNameException
>>>> -  {
>>>> -    int nameSize = name.size();
>>>> -    if (nameSize == 0) {
>>>> -      throw new InvalidNameException("The provided name does not 
>>>> have any
>>>> components" + name);
>>>> -    } -    -    if ("aries:services".equals(name.get(0))) {
>>>> -      throw new InvalidNameException("The composite name should not 
>>>> start
>>>> with aries:services");
>>>> -    }
>>>> -    -    if (nameSize > 2) {
>>>> -      throw new InvalidNameException("This JNDI context only expects 2
>>>> components, but it found " + nameSize);
>>>> -    }
>>>> -    return nameSize;
>>>> -  }
>>>>  }
>>>> \ No newline at end of file
>>>>
>>>> Added:
>>>> incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/ServiceRegistryListContext.java 
>>>>
>>>> URL:
>>>> http://svn.apache.org/viewvc/incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/ServiceRegistryListContext.java?rev=917809&view=auto 
>>>>
>>>>
>>>> ============================================================================== 
>>>>
>>>> ---
>>>> incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/ServiceRegistryListContext.java 
>>>>
>>>> (added)
>>>> +++
>>>> incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/ServiceRegistryListContext.java 
>>>>
>>>> Mon Mar  1 23:53:18 2010
>>>> @@ -0,0 +1,197 @@
>>>> +/*
>>>> + * 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.aries.jndi.url;
>>>> +
>>>> +import java.util.HashMap;
>>>> +import java.util.Hashtable;
>>>> +import java.util.Map;
>>>> +
>>>> +import javax.naming.Binding;
>>>> +import javax.naming.Context;
>>>> +import javax.naming.Name;
>>>> +import javax.naming.NameClassPair;
>>>> +import javax.naming.NameParser;
>>>> +import javax.naming.NamingEnumeration;
>>>> +import javax.naming.NamingException;
>>>> +import javax.naming.OperationNotSupportedException;
>>>> +
>>>> +public class ServiceRegistryListContext implements Context
>>>> +{
>>>> +  private Map<String, Object> env;
>>>> +  /** The name parser for the service registry name space */
>>>> +  private NameParser parser = new OsgiNameParser();
>>>> +  +  public ServiceRegistryListContext(Map<String, Object> env, 
>>>> OsgiName
>>>> validName)
>>>> +  {
>>>> +    this.env = new HashMap<String, Object>(env);
>>>> +  }
>>>> +
>>>> +  public Object addToEnvironment(String propName, Object propVal) 
>>>> throws
>>>> NamingException
>>>> +  {
>>>> +    return env.put(propName, propVal);
>>>> +  }
>>>> +
>>>> +  public void bind(Name name, Object obj) throws NamingException
>>>> +  {
>>>> +    throw new OperationNotSupportedException();
>>>> +  }
>>>> +
>>>> +  public void bind(String name, Object obj) throws NamingException
>>>> +  {
>>>> +    throw new OperationNotSupportedException();
>>>> +  }
>>>> +
>>>> +  public void close() throws NamingException
>>>> +  {
>>>> +    env = null;
>>>> +    parser = null;
>>>> +  }
>>>> +
>>>> +  public Name composeName(Name name, Name prefix) throws 
>>>> NamingException
>>>> +  {
>>>> +    // TODO Auto-generated method stub
>>>> +    return null;
>>>> +  }
>>>> +
>>>> +  public String composeName(String name, String prefix) throws
>>>> NamingException
>>>> +  {
>>>> +    // TODO Auto-generated method stub
>>>> +    return null;
>>>> +  }
>>>> +
>>>> +  public Context createSubcontext(Name name) throws NamingException
>>>> +  {
>>>> +    throw new OperationNotSupportedException();
>>>> +  }
>>>> +
>>>> +  public Context createSubcontext(String name) throws NamingException
>>>> +  {
>>>> +    throw new OperationNotSupportedException();
>>>> +  }
>>>> +
>>>> +  public void destroySubcontext(Name name) throws NamingException
>>>> +  {
>>>> +    //No-op we don't support sub-contexts in our context
>>>> +  }
>>>> +
>>>> +  public void destroySubcontext(String name) throws NamingException
>>>> +  {
>>>> +    //No-op we don't support sub-contexts in our context
>>>> +  }
>>>> +
>>>> +  public Hashtable<?, ?> getEnvironment() throws NamingException
>>>> +  {
>>>> +    Hashtable<Object, Object> environment = new Hashtable<Object,
>>>> Object>();
>>>> +    environment.putAll(env);
>>>> +    return environment;
>>>> +  }
>>>> +
>>>> +  public String getNameInNamespace() throws NamingException
>>>> +  {
>>>> +    // TODO Auto-generated method stub
>>>> +    return null;
>>>> +  }
>>>> +
>>>> +  public NameParser getNameParser(Name name) throws NamingException
>>>> +  {
>>>> +    return parser;
>>>> +  }
>>>> +
>>>> +  public NameParser getNameParser(String name) throws NamingException
>>>> +  {
>>>> +    return parser;
>>>> +  }
>>>> +
>>>> +  public NamingEnumeration<NameClassPair> list(Name name) throws
>>>> NamingException
>>>> +  {
>>>> +    return list(name.toString());
>>>> +  }
>>>> +
>>>> +  public NamingEnumeration<NameClassPair> list(String name) throws
>>>> NamingException
>>>> +  {
>>>> +    // TODO Auto-generated method stub
>>>> +    return null;
>>>> +  }
>>>> +
>>>> +  public NamingEnumeration<Binding> listBindings(Name name) throws
>>>> NamingException
>>>> +  {
>>>> +    return listBindings(name.toString());
>>>> +  }
>>>> +
>>>> +  public NamingEnumeration<Binding> listBindings(String name) throws
>>>> NamingException
>>>> +  {
>>>> +    // TODO Auto-generated method stub
>>>> +    return null;
>>>> +  }
>>>> +
>>>> +  public Object lookup(Name name) throws NamingException
>>>> +  {
>>>> +    return lookup(name.toString());
>>>> +  }
>>>> +
>>>> +  public Object lookup(String name) throws NamingException
>>>> +  {
>>>> +    return null;
>>>> +  }
>>>> +
>>>> +  public Object lookupLink(Name name) throws NamingException
>>>> +  {
>>>> +    throw new OperationNotSupportedException();
>>>> +  }
>>>> +
>>>> +  public Object lookupLink(String name) throws NamingException
>>>> +  {
>>>> +    throw new OperationNotSupportedException();
>>>> +  }
>>>> +
>>>> +  public void rebind(Name name, Object obj) throws NamingException
>>>> +  {
>>>> +    throw new OperationNotSupportedException();
>>>> +  }
>>>> +
>>>> +  public void rebind(String name, Object obj) throws NamingException
>>>> +  {
>>>> +    throw new OperationNotSupportedException();
>>>> +  }
>>>> +
>>>> +  public Object removeFromEnvironment(String propName) throws
>>>> NamingException
>>>> +  {
>>>> +    return env.remove(propName);
>>>> +  }
>>>> +
>>>> +  public void rename(Name oldName, Name newName) throws 
>>>> NamingException
>>>> +  {
>>>> +    throw new OperationNotSupportedException();
>>>> +  }
>>>> +
>>>> +  public void rename(String oldName, String newName) throws
>>>> NamingException
>>>> +  {
>>>> +    throw new OperationNotSupportedException();
>>>> +  }
>>>> +
>>>> +  public void unbind(Name name) throws NamingException
>>>> +  {
>>>> +    throw new OperationNotSupportedException();
>>>> +  }
>>>> +
>>>> +  public void unbind(String name) throws NamingException
>>>> +  {
>>>> +    throw new OperationNotSupportedException();
>>>> +  }
>>>> +}
>>>> \ No newline at end of file
>>>>
>>>> Copied:
>>>> incubator/aries/trunk/jndi/jndi-url/src/test/java/org/apache/aries/jndi/url/OsgiNameParserTest.java 
>>>>
>>>> (from r917002,
>>>> incubator/aries/trunk/jndi/jndi-url/src/test/java/org/apache/aries/jndi/url/ServiceRegistryNameParserTest.java) 
>>>>
>>>> URL:
>>>> http://svn.apache.org/viewvc/incubator/aries/trunk/jndi/jndi-url/src/test/java/org/apache/aries/jndi/url/OsgiNameParserTest.java?p2=incubator/aries/trunk/jndi/jndi-url/src/test/java/org/apache/aries/jndi/url/OsgiNameParserTest.java&p1=incubator/aries/trunk/jndi/jndi-url/src/test/java/org/apache/aries/jndi/url/ServiceRegistryNameParserTest.java&r1=917002&r2=917809&rev=917809&view=diff 
>>>>
>>>>
>>>> ============================================================================== 
>>>>
>>>> ---
>>>> incubator/aries/trunk/jndi/jndi-url/src/test/java/org/apache/aries/jndi/url/ServiceRegistryNameParserTest.java 
>>>>
>>>> (original)
>>>> +++
>>>> incubator/aries/trunk/jndi/jndi-url/src/test/java/org/apache/aries/jndi/url/OsgiNameParserTest.java 
>>>>
>>>> Mon Mar  1 23:53:18 2010
>>>> @@ -18,11 +18,11 @@
>>>>  */
>>>>  package org.apache.aries.jndi.url;
>>>>  -import static org.junit.Assert.assertNotNull;
>>>>  import static org.junit.Assert.assertEquals;
>>>> +import static org.junit.Assert.assertFalse;
>>>> +import static org.junit.Assert.assertTrue;
>>>>  import javax.naming.InvalidNameException;
>>>> -import javax.naming.Name;
>>>>  import javax.naming.NameParser;
>>>>  import javax.naming.NamingException;
>>>>  @@ -31,10 +31,10 @@
>>>>  /**
>>>>  * This is where we test the service registry name parser.
>>>>  */
>>>> -public class ServiceRegistryNameParserTest
>>>> +public class OsgiNameParserTest
>>>>  {
>>>>   /** The parser we are going to use for testing */
>>>> -  private NameParser parser = new ServiceRegistryNameParser();
>>>> +  private NameParser parser = new OsgiNameParser();
>>>>    /**
>>>>    * OK, so we check that we can call checkNames multiple times.
>>>> @@ -43,8 +43,14 @@
>>>>   @Test
>>>>   public void checkValidNames() throws NamingException
>>>>   {
>>>> -    checkName("aries:services/java.lang.Runnable/(a=b)");
>>>> -    checkName("aries:services/java.lang.Runnable");
>>>> +    checkName("aries","services","java.lang.Runnable","(a=b)");
>>>> +    checkName("aries","services","java.lang.Runnable");
>>>> +    checkName("osgi","service","java.lang.Runnable");
>>>> +    checkName("osgi","service","java.lang.Runnable", "(a=b)");
>>>> +    checkName("osgi","servicelist","java.lang.Runnable");
>>>> +    checkName("osgi","servicelist","java.lang.Runnable", "(a=b)");
>>>> +    checkName("osgi","servicelist","jdbc", "grok", "DataSource");
>>>> +    checkName("osgi", "framework", "bundleContext");
>>>>   }
>>>>      /**
>>>> @@ -54,7 +60,7 @@
>>>>   @Test(expected=InvalidNameException.class)
>>>>   public void checkOutsideNamespace() throws NamingException
>>>>   {
>>>> -    checkName("java:comp/env/jms/cf");
>>>> +    checkName("java","comp","env","jms","cf");
>>>>   }
>>>>      /**
>>>> @@ -64,7 +70,7 @@
>>>>   @Test(expected=InvalidNameException.class)
>>>>   public void checkMissingInterface() throws NamingException
>>>>   {
>>>> -    checkName("aries:services");
>>>> +    checkName("aries","services");
>>>>   }
>>>>      /**
>>>> @@ -75,20 +81,64 @@
>>>>   @Test(expected=InvalidNameException.class)
>>>>   public void checkMissingInterface2() throws NamingException
>>>>   {
>>>> -    checkName("aries:services/");
>>>> +    checkName("aries","services", "");
>>>>   }
>>>> -
>>>> -  /**
>>>> -   * This method parses the name and then makes sure what was 
>>>> parsed was
>>>> parsed
>>>> -   * correctly.
>>>> -   * -   * @param name
>>>> -   * @throws NamingException
>>>> -   */
>>>> -  private void checkName(String name) throws NamingException
>>>> +  +  @Test(expected=InvalidNameException.class)
>>>> +  public void checkIncorrectPath() throws NamingException
>>>> +  {
>>>> +    checkName("osgi", "services", "java.lang.Runnable"); +  }
>>>> +  +  @Test(expected=InvalidNameException.class)
>>>> +  public void checkIllegalPath() throws NamingException
>>>>   {
>>>> -    Name n = parser.parse(name);
>>>> -    assertNotNull("We got a null name back, which is not allowed.", 
>>>> n);
>>>> -    assertEquals("The name's toString does not produce the original
>>>> value", name, n.toString());
>>>> +    checkName("osgi", "wibble", "java.lang.Runnable"); +  }
>>>> +  +  private void checkName(String scheme, String path, String ...
>>>> elements)
>>>> +    throws NamingException
>>>> +  {
>>>> +    StringBuilder builder = new StringBuilder();
>>>> +    StringBuilder serviceName = new StringBuilder();
>>>> +    +    builder.append(scheme);
>>>> +    builder.append(':');
>>>> +    builder.append(path);
>>>> +
>>>> +    if (elements.length > 0) {
>>>> +      builder.append('/');
>>>> +      +      for (String element : elements) {
>>>> +        serviceName.append(element);
>>>> +        serviceName.append('/');
>>>> +      }
>>>> +  +      serviceName.deleteCharAt(serviceName.length() - 1);
>>>> +      +      builder.append(serviceName);
>>>> +    }
>>>> +    +    OsgiName n = (OsgiName) parser.parse(builder.toString());
>>>> +    +    assertEquals(scheme, n.getScheme());
>>>> +    assertEquals(path, n.getSchemePath());
>>>> +    +    if (elements.length > 1) {
>>>> +      assertEquals(elements[0], n.getInterface());
>>>> +    }
>>>> +    +    if (elements.length == 1) {
>>>> +      assertFalse(n.hasFilter());
>>>> +    }
>>>> +    +    if (elements.length > 2) {
>>>> +      if (elements.length == 2) {
>>>> +        assertTrue(n.hasFilter());
>>>> +        assertEquals(elements[1], n.getFilter());
>>>> +      } else assertFalse(n.hasFilter());
>>>> +    }
>>>> +    +    assertEquals(serviceName.toString(), n.getServiceName());
>>>>   }
>>>>  }
>>>> \ No newline at end of file
>>>>
>>>> Modified:
>>>> incubator/aries/trunk/jndi/jndi-url/src/test/java/org/apache/aries/jndi/url/ServiceRegistryContextTest.java 
>>>>
>>>> URL:
>>>> http://svn.apache.org/viewvc/incubator/aries/trunk/jndi/jndi-url/src/test/java/org/apache/aries/jndi/url/ServiceRegistryContextTest.java?rev=917809&r1=917808&r2=917809&view=diff 
>>>>
>>>>
>>>> ============================================================================== 
>>>>
>>>> ---
>>>> incubator/aries/trunk/jndi/jndi-url/src/test/java/org/apache/aries/jndi/url/ServiceRegistryContextTest.java 
>>>>
>>>> (original)
>>>> +++
>>>> incubator/aries/trunk/jndi/jndi-url/src/test/java/org/apache/aries/jndi/url/ServiceRegistryContextTest.java 
>>>>
>>>> Mon Mar  1 23:53:18 2010
>>>> @@ -21,7 +21,6 @@
>>>>  import static org.junit.Assert.assertEquals;
>>>>  import static org.junit.Assert.assertFalse;
>>>>  import static org.junit.Assert.assertNotNull;
>>>> -import static org.junit.Assert.assertSame;
>>>>  import static org.junit.Assert.assertTrue;
>>>>  import java.lang.reflect.Field;
>>>> @@ -37,6 +36,12 @@
>>>>  import javax.naming.NamingException;
>>>>  import javax.naming.spi.ObjectFactory;
>>>>  +import org.apache.aries.jndi.ContextHelper;
>>>> +import org.apache.aries.jndi.OSGiObjectFactoryBuilder;
>>>> +import org.apache.aries.mocks.BundleContextMock;
>>>> +import org.apache.aries.mocks.BundleMock;
>>>> +import org.apache.aries.unittest.mocks.MethodCall;
>>>> +import org.apache.aries.unittest.mocks.Skeleton;
>>>>  import org.junit.After;
>>>>  import org.junit.Before;
>>>>  import org.junit.Test;
>>>> @@ -47,22 +52,13 @@
>>>>  import org.osgi.framework.ServiceReference;
>>>>  import org.osgi.framework.ServiceRegistration;
>>>>  -import org.apache.aries.unittest.mocks.MethodCall;
>>>> -import org.apache.aries.unittest.mocks.Skeleton;
>>>> -import org.apache.aries.jndi.ContextHelper;
>>>> -import org.apache.aries.jndi.OSGiObjectFactoryBuilder;
>>>> -import org.apache.aries.jndi.services.ServiceHelper;
>>>> -import org.apache.aries.jndi.url.Activator;
>>>> -import org.apache.aries.mocks.BundleContextMock;
>>>> -import org.apache.aries.mocks.BundleMock;
>>>> -
>>>>  /**
>>>>  * Tests for our JNDI implementation for the service registry.
>>>>  */
>>>>  public class ServiceRegistryContextTest
>>>>  {
>>>>   /** The service we register by default */
>>>> -  private Thread service;
>>>> +  private Runnable service;
>>>>   /** The bundle context for the test */
>>>>   private BundleContext bc;
>>>>   /** The service registration for the service */
>>>> @@ -83,10 +79,7 @@
>>>>     new Activator().start(bc);
>>>>     new org.apache.aries.jndi.startup.Activator().start(bc);
>>>>     -    Field f = ServiceHelper.class.getDeclaredField("context");
>>>> -    f.setAccessible(true);
>>>> -    f.set(null, bc);
>>>> -    f = ContextHelper.class.getDeclaredField("context");
>>>> +    Field f = ContextHelper.class.getDeclaredField("context");
>>>>     f.setAccessible(true);
>>>>     f.set(null, bc);
>>>>     f = OSGiObjectFactoryBuilder.class.getDeclaredField("context");
>>>> @@ -94,7 +87,7 @@
>>>>     f.set(null, bc);
>>>>  -    service = new Thread();
>>>> +    service = Skeleton.newMock(Runnable.class);
>>>>          registerService(service);
>>>>   }
>>>> @@ -104,7 +97,7 @@
>>>>    *     * @param service2 The service to register.
>>>>    */
>>>> -  private void registerService(Thread service2)
>>>> +  private void registerService(Runnable service2)
>>>>   {
>>>>     ServiceFactory factory = Skeleton.newMock(ServiceFactory.class);
>>>>     Skeleton skel = Skeleton.getSkeleton(factory);
>>>> @@ -159,11 +152,13 @@
>>>>
>>>>  Thread.currentThread().setContextClassLoader(mock.getClassLoader());
>>>>     -    Object s = ctx.lookup("aries:services/java.lang.Runnable");
>>>> +    Runnable s = (Runnable)
>>>> ctx.lookup("aries:services/java.lang.Runnable");
>>>>          assertNotNull("We didn't get a service back from our lookup 
>>>> :(",
>>>> s);
>>>>     -    assertEquals("The SR did not return the object we expected",
>>>> service, s);
>>>> +    s.run();
>>>> +    +    
>>>> Skeleton.getSkeleton(service).assertCalledExactNumberOfTimes(new
>>>> MethodCall(Runnable.class, "run"), 1);
>>>>          Skeleton skel = Skeleton.getSkeleton(mock.getBundleContext());
>>>>     @@ -173,7 +168,7 @@
>>>>
>>>>  Thread.currentThread().setContextClassLoader(mock.getClassLoader());
>>>>  -    s = ctx.lookup("osgi:services/java.lang.Runnable");
>>>> +    s = (Runnable) ctx.lookup("osgi:service/java.lang.Runnable");
>>>>          // Check we have the packages set correctly
>>>>     @@ -181,10 +176,11 @@
>>>>          assertTrue(ctx.getEnvironment().containsValue(packages));
>>>>  -         assertNotNull("We didn't get a service back from our lookup
>>>> :(", s);
>>>> +
>>>> +    s.run();
>>>>     -    assertEquals("The SR did not return the object we expected",
>>>> service, s);
>>>> +    Skeleton.getSkeleton(service).assertCalledExactNumberOfTimes(new
>>>> MethodCall(Runnable.class, "run"), 2);
>>>>      skel = Skeleton.getSkeleton(mock.getBundleContext());
>>>>     skel.assertCalled(new MethodCall(BundleContext.class,
>>>> "getServiceReferences", "java.lang.Runnable", null));
>>>> @@ -201,15 +197,21 @@
>>>>   @Test
>>>>   public void jndiLookupWithFilter() throws NamingException
>>>>   {
>>>> +    BundleMock mock = new BundleMock("scooby.doo", new Properties());
>>>> +    +
>>>>  Thread.currentThread().setContextClassLoader(mock.getClassLoader());
>>>> +
>>>>     InitialContext ctx = new InitialContext();
>>>>          Object s =
>>>> ctx.lookup("aries:services/java.lang.Runnable/(rubbish=smelly)");
>>>>          assertNotNull("We didn't get a service back from our lookup 
>>>> :(",
>>>> s);
>>>>     -    assertEquals("The SR did not return the object we expected",
>>>> service, s);
>>>> +    service.run();
>>>>     -    Skeleton.getSkeleton(bc).assertCalled(new
>>>> MethodCall(BundleContext.class, "getServiceReferences",
>>>> "java.lang.Runnable", "(rubbish=smelly)"));
>>>> +    Skeleton.getSkeleton(service).assertCalledExactNumberOfTimes(new
>>>> MethodCall(Runnable.class, "run"), 1);
>>>> +
>>>> +    Skeleton.getSkeleton(mock.getBundleContext()).assertCalled(new
>>>> MethodCall(BundleContext.class, "getServiceReferences",
>>>> "java.lang.Runnable", "(rubbish=smelly)"));
>>>>   }
>>>>      /**
>>>> @@ -222,6 +224,11 @@
>>>>   public void testLookupWhenServiceHasBeenRemoved() throws 
>>>> NamingException
>>>>   {
>>>>     reg.unregister();
>>>> +
>>>> +    BundleMock mock = new BundleMock("scooby.doo", new Properties());
>>>> +    +
>>>>  Thread.currentThread().setContextClassLoader(mock.getClassLoader());
>>>> +
>>>>     InitialContext ctx = new InitialContext();
>>>>          ctx.lookup("aries:services/java.lang.Runnable");
>>>> @@ -236,6 +243,10 @@
>>>>   @Test(expected=NameNotFoundException.class)
>>>>   public void testLookupForServiceWeNeverHad() throws NamingException
>>>>   {
>>>> +    BundleMock mock = new BundleMock("scooby.doo", new Properties());
>>>> +    +
>>>>  Thread.currentThread().setContextClassLoader(mock.getClassLoader());
>>>> +
>>>>     InitialContext ctx = new InitialContext();
>>>>          ctx.lookup("aries:services/java.lang.Integer");
>>>> @@ -271,14 +282,53 @@
>>>>   }
>>>>    @Test
>>>> +  public void checkProxyDynamism() throws NamingException
>>>> +  {
>>>> +    BundleMock mock = new BundleMock("scooby.doo", new Properties());
>>>> +    +
>>>>  Thread.currentThread().setContextClassLoader(mock.getClassLoader());
>>>> +
>>>> +    InitialContext ctx = new InitialContext();
>>>> +    +    String className = Runnable.class.getName();
>>>> +    +    Runnable t = Skeleton.newMock(Runnable.class);
>>>> +    Runnable t2 = Skeleton.newMock(Runnable.class);
>>>> +    +    // we don't want the default service
>>>> +    reg.unregister();
>>>> +    +    ServiceRegistration reg = bc.registerService(className, t,
>>>> null);
>>>> +    bc.registerService(className, t2, null);
>>>> +    +    Runnable r = (Runnable)
>>>> ctx.lookup("osgi:service/java.lang.Runnable");
>>>> +    +    r.run();
>>>> +    +    Skeleton.getSkeleton(t).assertCalledExactNumberOfTimes(new
>>>> MethodCall(Runnable.class, "run"), 1);
>>>> +    Skeleton.getSkeleton(t2).assertNotCalled(new
>>>> MethodCall(Runnable.class, "run"));
>>>> +    +    reg.unregister();
>>>> +    +    r.run();
>>>> +    +    Skeleton.getSkeleton(t).assertCalledExactNumberOfTimes(new
>>>> MethodCall(Runnable.class, "run"), 1);
>>>> +    Skeleton.getSkeleton(t2).assertCalledExactNumberOfTimes(new
>>>> MethodCall(Runnable.class, "run"), 1);
>>>> +  }  +
>>>> +  @Test
>>>>   public void checkServiceOrderObserved() throws NamingException
>>>>   {
>>>> +    BundleMock mock = new BundleMock("scooby.doo", new Properties());
>>>> +    +
>>>>  Thread.currentThread().setContextClassLoader(mock.getClassLoader());
>>>> +
>>>>     InitialContext ctx = new InitialContext();
>>>>          String className = Runnable.class.getName();
>>>>     -    Thread t = new Thread();
>>>> -    Thread t2 = new Thread();
>>>> +    Runnable t = Skeleton.newMock(Runnable.class);
>>>> +    Runnable t2 = Skeleton.newMock(Runnable.class);
>>>>          // we don't want the default service
>>>>     reg.unregister();
>>>> @@ -286,9 +336,12 @@
>>>>     ServiceRegistration reg = bc.registerService(className, t, null);
>>>>     ServiceRegistration reg2 = bc.registerService(className, t2, null);
>>>>     -    Runnable r = (Runnable)
>>>> ctx.lookup("osgi:services/java.lang.Runnable");
>>>> +    Runnable r = (Runnable)
>>>> ctx.lookup("osgi:service/java.lang.Runnable");
>>>>     -    assertSame("The wrong runnable was returned", t, r);
>>>> +    r.run();
>>>> +    +    Skeleton.getSkeleton(t).assertCalledExactNumberOfTimes(new
>>>> MethodCall(Runnable.class, "run"), 1);
>>>> +    Skeleton.getSkeleton(t2).assertNotCalled(new
>>>> MethodCall(Runnable.class, "run"));
>>>>          reg.unregister();
>>>>     reg2.unregister();
>>>> @@ -296,12 +349,18 @@
>>>>     Hashtable<String, Object> props = new Hashtable<String, Object>();
>>>>     props.put(Constants.SERVICE_RANKING, 55);
>>>>     +    t = Skeleton.newMock(Runnable.class);
>>>> +    t2 = Skeleton.newMock(Runnable.class);
>>>> +
>>>>     reg = bc.registerService(className, t, null);
>>>>     reg2 = bc.registerService(className, t2, props);
>>>>     -    r = (Runnable) ctx.lookup("osgi:services/java.lang.Runnable");
>>>> +    r = (Runnable) ctx.lookup("osgi:service/java.lang.Runnable");
>>>> +    +    r.run();
>>>>     -    assertSame("The wrong runnable was returned", t2, r);
>>>> +    Skeleton.getSkeleton(t).assertNotCalled(new
>>>> MethodCall(Runnable.class, "run"));
>>>> +    Skeleton.getSkeleton(t2).assertCalledExactNumberOfTimes(new
>>>> MethodCall(Runnable.class, "run"), 1);
>>>>   }
>>>>      /**
>>>>
>>>>
>>>>
>>>
>>> -- 
>>> Joe
>>>
>>
>>
>>
> 
> 


-- 
Joe

Re: svn commit: r917809 - in /incubator/aries/trunk/jndi/jndi-url: ./ src/main/java/org/apache/aries/jndi/services/ src/main/java/org/apache/aries/jndi/url/ src/test/java/org/apache/aries/jndi/url/

Posted by Joe Bohn <jo...@gmail.com>.
Here's the stack trace for the CNFE.  I'll have to work on getting the 
thread context classloader.

[112793090@qtp-2020456228-2 - 
/org.apache.aries.ariestrader.modules.ariestrader-web/config] DEBUG 
org.apache.aries.blueprint.container.ServiceRecipe - Calling listeners 
for initial service registration
java.lang.ClassNotFoundException: 
org.apache.aries.samples.ariestrader.api.TradeServicesManager
         at 
org.eclipse.osgi.internal.loader.BundleLoader.findClassInternal(BundleLoader.java:489)
         at 
org.eclipse.osgi.internal.loader.BundleLoader.findClass(BundleLoader.java:405)
         at 
org.eclipse.osgi.internal.loader.BundleLoader.findClass(BundleLoader.java:393)
         at 
org.eclipse.osgi.internal.baseadaptor.DefaultClassLoader.loadClass(DefaultClassLoader.java:105)
         at java.lang.ClassLoader.loadClass(ClassLoader.java:250)
         at 
org.eclipse.osgi.internal.loader.BundleLoader.loadClass(BundleLoader.java:321)
         at 
org.eclipse.osgi.framework.internal.core.BundleHost.loadClass(BundleHost.java:231)
         at 
org.eclipse.osgi.framework.internal.core.AbstractBundle.loadClass(AbstractBundle.java:1193)
         at 
org.apache.aries.jndi.services.ServiceHelper.getService(ServiceHelper.java:210)
         at 
org.apache.aries.jndi.url.ServiceRegistryContext.lookup(ServiceRegistryContext.java:189)
         at 
org.apache.aries.jndi.url.ServiceRegistryContext.lookup(ServiceRegistryContext.java:218)
         at 
org.apache.aries.jndi.DelegateContext.lookup(DelegateContext.java:160)
         at javax.naming.InitialContext.lookup(InitialContext.java:392)
         at 
org.apache.aries.samples.ariestrader.util.ServiceUtilities.getOSGIService(ServiceUtilities.java:60)
         at 
org.apache.aries.samples.ariestrader.util.ServiceUtilities.getOSGIService(ServiceUtilities.java:41)
         at 
org.apache.aries.samples.ariestrader.api.TradeServiceUtilities.getTradeServicesManager(TradeServiceUtilities.java:63)
         at org.apache.jsp.config_jsp._jspService(config_jsp.java:86)
         at 
org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:70)
         at javax.servlet.http.HttpServlet.service(HttpServlet.java:820)
         at 
org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:374)
         at 
org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:342)
         at 
org.apache.jasper.servlet.JspServlet.service(JspServlet.java:267)
         at javax.servlet.http.HttpServlet.service(HttpServlet.java:820)
         at 
org.ops4j.pax.web.jsp.JspServletWrapper$2.call(JspServletWrapper.java:132)
         at 
org.ops4j.pax.web.jsp.JspServletWrapper$2.call(JspServletWrapper.java:127)
         at 
org.ops4j.pax.swissbox.core.ContextClassLoaderUtils.doWithClassLoader(ContextClassLoaderUtils.java:60)
         at 
org.ops4j.pax.web.jsp.JspServletWrapper.service(JspServletWrapper.java:124)
         at 
org.mortbay.jetty.servlet.ServletHolder.handle(ServletHolder.java:502)
         at 
org.mortbay.jetty.servlet.ServletHandler.handle(ServletHandler.java:389)
         at 
org.ops4j.pax.web.service.jetty.internal.HttpServiceServletHandler.handle(HttpServiceServletHandler.java:64)
         at 
org.mortbay.jetty.servlet.SessionHandler.handle(SessionHandler.java:181)
         at 
org.mortbay.jetty.handler.ContextHandler.handle(ContextHandler.java:765)
         at 
org.ops4j.pax.web.service.jetty.internal.HttpServiceContext.handle(HttpServiceContext.java:111)
         at 
org.mortbay.jetty.servlet.Dispatcher.include(Dispatcher.java:192)
         at 
org.apache.aries.samples.ariestrader.web.TradeConfigServlet.doConfigDisplay(TradeConfigServlet.java:62)
         at 
org.apache.aries.samples.ariestrader.web.TradeConfigServlet.service(TradeConfigServlet.java:403)
         at javax.servlet.http.HttpServlet.service(HttpServlet.java:820)
         at 
org.mortbay.jetty.servlet.ServletHolder.handle(ServletHolder.java:502)
         at 
org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)
         at 
org.ops4j.pax.web.service.internal.WelcomeFilesFilter.doFilter(WelcomeFilesFilter.java:169)
         at 
org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1148)
         at 
org.mortbay.jetty.servlet.ServletHandler.handle(ServletHandler.java:387)
         at 
org.ops4j.pax.web.service.jetty.internal.HttpServiceServletHandler.handle(HttpServiceServletHandler.java:64)
         at 
org.mortbay.jetty.servlet.SessionHandler.handle(SessionHandler.java:181)
         at 
org.mortbay.jetty.handler.ContextHandler.handle(ContextHandler.java:765)
         at 
org.ops4j.pax.web.service.jetty.internal.HttpServiceContext.handle(HttpServiceContext.java:111)
         at 
org.ops4j.pax.web.service.jetty.internal.JettyServerHandlerCollection.handle(JettyServerHandlerCollection.java:64)
         at 
org.mortbay.jetty.handler.HandlerWrapper.handle(HandlerWrapper.java:152)
         at org.mortbay.jetty.Server.handle(Server.java:322)
         at 
org.mortbay.jetty.HttpConnection.handleRequest(HttpConnection.java:534)
         at 
org.mortbay.jetty.HttpConnection$RequestHandler.headerComplete(HttpConnection.java:864)
         at org.mortbay.jetty.HttpParser.parseNext(HttpParser.java:539)
         at org.mortbay.jetty.HttpParser.parseAvailable(HttpParser.java:212)
         at org.mortbay.jetty.HttpConnection.handle(HttpConnection.java:404)
         at 
org.mortbay.io.nio.SelectChannelEndPoint.run(SelectChannelEndPoint.java:409)
         at 
org.mortbay.thread.QueuedThreadPool$PoolThread.run(QueuedThreadPool.java:520)

Alasdair Nottingham wrote:
> Hi,
> 
> Hmm, I suspect I am not correctly finding the appropriate
> BundleContext to use. That would explain the CNFE because we now proxy
> the services rather than returning the raw service. If it is being
> listed as being used by the pax-web jsp bundle that would explain
> things.
> 
> Do you have a stack trace for the ClassNotFoundException? That might
> help to work out what went wrong.
> 
> Also can you check the thread context classloader before the lookup?
> 
> Thanks
> Alasdair
> 
> On 2 March 2010 23:21, Joe Bohn <jo...@gmail.com> wrote:
>> I think there are some issues with this change.   I'll have to dig some more
>> and post more details later (don't have time right now) ... but in short I'm
>> seeing the following:
>>
>> - AriesTrader is behaving very badly after this change.
>> - From within a jsp we use jndi lookup to find an osgi service.
>> - After this change I get a failure in my jsp with a CNFE.   This despite
>> the fact that I can see the package is imported on the web bundle and
>> appears to be wired correctly.
>> - Even more strange: I notice that the application service I was looking for
>> is listed as being used by the pax-web jsp bundle.  So it seems like we
>> might be using the wrong bundle context at some point.
>>
>>
>> Joe
>>
>>
>>
>> not@apache.org wrote:
>>> Author: not
>>> Date: Mon Mar  1 23:53:18 2010
>>> New Revision: 917809
>>>
>>> URL: http://svn.apache.org/viewvc?rev=917809&view=rev
>>> Log:
>>> ARIES-128 Implement OSGi spec url lookup scheme
>>>
>>> Added:
>>>
>>>  incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/OsgiName.java
>>>      - copied, changed from r910238,
>>> incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/ServiceRegistryName.java
>>>
>>>  incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/OsgiNameParser.java
>>>      - copied, changed from r910238,
>>> incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/ServiceRegistryNameParser.java
>>>
>>>  incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/ServiceRegistryListContext.java
>>>
>>>  incubator/aries/trunk/jndi/jndi-url/src/test/java/org/apache/aries/jndi/url/OsgiNameParserTest.java
>>>      - copied, changed from r917002,
>>> incubator/aries/trunk/jndi/jndi-url/src/test/java/org/apache/aries/jndi/url/ServiceRegistryNameParserTest.java
>>> Removed:
>>>
>>>  incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/ServiceRegistryName.java
>>>
>>>  incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/ServiceRegistryNameParser.java
>>>
>>>  incubator/aries/trunk/jndi/jndi-url/src/test/java/org/apache/aries/jndi/url/ServiceHelperTest.java
>>>
>>>  incubator/aries/trunk/jndi/jndi-url/src/test/java/org/apache/aries/jndi/url/ServiceRegistryNameParserTest.java
>>> Modified:
>>>    incubator/aries/trunk/jndi/jndi-url/pom.xml
>>>
>>>  incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/services/ServiceHelper.java
>>>
>>>  incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/Activator.java
>>>
>>>  incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/OsgiURLContextFactory.java
>>>
>>>  incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/ServiceRegistryContext.java
>>>
>>>  incubator/aries/trunk/jndi/jndi-url/src/test/java/org/apache/aries/jndi/url/ServiceRegistryContextTest.java
>>>
>>> Modified: incubator/aries/trunk/jndi/jndi-url/pom.xml
>>> URL:
>>> http://svn.apache.org/viewvc/incubator/aries/trunk/jndi/jndi-url/pom.xml?rev=917809&r1=917808&r2=917809&view=diff
>>>
>>> ==============================================================================
>>> --- incubator/aries/trunk/jndi/jndi-url/pom.xml (original)
>>> +++ incubator/aries/trunk/jndi/jndi-url/pom.xml Mon Mar  1 23:53:18 2010
>>> @@ -33,6 +33,10 @@
>>>      <dependencies>
>>>       <dependency>
>>> +       <groupId>org.apache.aries</groupId>
>>> +       <artifactId>org.apache.aries.util</artifactId>
>>> +      </dependency>
>>> +      <dependency>
>>>           <groupId>org.osgi</groupId>
>>>           <artifactId>org.osgi.core</artifactId>
>>>           <scope>provided</scope>
>>>
>>> Modified:
>>> incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/services/ServiceHelper.java
>>> URL:
>>> http://svn.apache.org/viewvc/incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/services/ServiceHelper.java?rev=917809&r1=917808&r2=917809&view=diff
>>>
>>> ==============================================================================
>>> ---
>>> incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/services/ServiceHelper.java
>>> (original)
>>> +++
>>> incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/services/ServiceHelper.java
>>> Mon Mar  1 23:53:18 2010
>>> @@ -18,18 +18,30 @@
>>>  */
>>>  package org.apache.aries.jndi.services;
>>>  +import java.lang.reflect.InvocationHandler;
>>> +import java.lang.reflect.Method;
>>> +import java.lang.reflect.Proxy;
>>> +import java.security.AccessController;
>>> +import java.security.PrivilegedAction;
>>> +import java.util.ArrayList;
>>>  import java.util.Arrays;
>>>  import java.util.Comparator;
>>>  import java.util.HashSet;
>>>  import java.util.LinkedList;
>>>  import java.util.List;
>>> +import java.util.Map;
>>>  import java.util.Set;
>>>  import java.util.concurrent.ConcurrentHashMap;
>>>  import java.util.concurrent.ConcurrentMap;
>>>  +import javax.naming.NamingException;
>>> +
>>> +import org.apache.aries.util.BundleToClassLoaderAdapter;
>>> +import org.osgi.framework.Bundle;
>>>  import org.osgi.framework.BundleContext;
>>>  import org.osgi.framework.BundleReference;
>>>  import org.osgi.framework.InvalidSyntaxException;
>>> +import org.osgi.framework.ServiceException;
>>>  import org.osgi.framework.ServiceReference;
>>>  /**
>>> @@ -47,221 +59,206 @@
>>>  */
>>>  public final class ServiceHelper
>>>  {
>>> -  /** The bundle context used for service registry queries */
>>> -  private static BundleContext context;
>>> -  /** A cache of what service was returned last time the query was
>>> performed */
>>> -  private static ConcurrentMap<ServiceKey, Set<ServiceReference>> cache =
>>> new ConcurrentHashMap<ServiceKey, Set<ServiceReference>>();
>>> -
>>> -  public static void setBundleContext(BundleContext ctx)
>>> +  public static class StackFinder extends SecurityManager
>>>   {
>>> -    context = ctx;
>>> +    public Class<?>[] getClassContext()
>>> +    {
>>> +      return super.getClassContext();
>>> +    }
>>>   }
>>> -  -  /**
>>> -   * This class is used as the key into the cache. It holds information
>>> to identify -   * who performed the query, along with the className and
>>> filter used. The thread context
>>> -   * class loader is used in the key, so two different modules will
>>> potentially get different
>>> -   * services.
>>> -   */
>>> -  private static final class ServiceKey
>>> +
>>> +  private static class JNDIServiceDamper implements InvocationHandler
>>>   {
>>> -    /** The class loader of the invoking application */
>>> -    private ClassLoader classLoader;
>>> -    /** The name of the class being queried from the registry */
>>> -    private String className;
>>> -    /** the registry filter, this may be null */
>>> +    private BundleContext ctx;
>>> +    private ServicePair pair;
>>> +    private String interfaceName;
>>>     private String filter;
>>> -    /** The cached hashCode */
>>> -    private final int hashCode;
>>> -
>>> -    /**
>>> -     * Boring unimportant comment.
>>> -     * -     * @param cl
>>> -     * @param cn
>>> -     * @param f
>>> -     */
>>> -    public ServiceKey(ClassLoader cl, String cn, String f)
>>> +    private boolean dynamic;
>>> +    +    public JNDIServiceDamper(BundleContext context, String i, String
>>> f, ServicePair service, boolean d)
>>>     {
>>> -      classLoader = cl;
>>> -      className = cn;
>>> +      ctx = context;
>>> +      pair = service;
>>> +      interfaceName = i;
>>>       filter = f;
>>> -      -      int classNameHash = (className == null) ? 0 :
>>> className.hashCode();
>>> -      hashCode = System.identityHashCode(classLoader) * 1000003 +
>>> classNameHash;
>>> +      dynamic = d;
>>>     }
>>> -
>>> -    @Override
>>> -    public int hashCode()
>>> -    {
>>> -      return hashCode;
>>> -    }
>>> -
>>> -    @Override
>>> -    public boolean equals(Object other)
>>> +    +    public Object invoke(Object proxy, Method method, Object[] args)
>>> throws Throwable
>>>     {
>>> -      if (other == this) return true;
>>> -      if (other == null) return false;
>>> -
>>> -      if (other instanceof ServiceKey) {
>>> -        ServiceKey otherKey = (ServiceKey) other;
>>> -        if (hashCode != otherKey.hashCode) return false;
>>> -
>>> -        if (classLoader != otherKey.classLoader) return false;
>>> -        if (!!!comparePossiblyNullObjects(className, otherKey.className))
>>> return false;
>>> -        return comparePossiblyNullObjects(filter, otherKey.filter);
>>> -      }
>>> -
>>> -      return false;
>>> -    }
>>> -    -    /**
>>> -     * Compares two objects where one or other (or both) may be null.
>>> -     * -     * @param a the first object to compare.
>>> -     * @param b the second object to compare.
>>> -     * @return true if they are ==, both null or identity equals, false
>>> otherwise.
>>> -     */
>>> -    public boolean comparePossiblyNullObjects(Object a, Object b) {
>>> -      if (a == b) return true;
>>> -      else if (a == null) return false;
>>> -      else return a.equals(b);
>>> +      if (pair.ref.getBundle() == null) {
>>> +        if (dynamic) pair = findService(ctx, interfaceName, filter);
>>> +        else pair = null;
>>> +      }
>>> +      +      if (pair == null) {
>>> +        throw new ServiceException(interfaceName,
>>> ServiceException.UNREGISTERED);
>>> +      }
>>> +      +      return method.invoke(pair.service, args);
>>>     }
>>>   }
>>> -
>>> -  /**
>>> -   * This method is used to obtain a single instance of a desired service
>>> from the OSGi
>>> -   * service registry. If the filter and class name identify multiple
>>> services the first
>>> -   * one is returned. If no service is found null will be returned.
>>> -   * -   * @param className The class name used to register the desired
>>> service. If null is provided
>>> -   *                  then all services are eligible to be returned.
>>> -   * @param filter    An RFC 1960 query into the properties of the
>>> registered services. e.g.
>>> -   *                  (service.description=really useful)
>>> -   * @return          The desired service
>>> -   * -   * @throws IllegalArgumentException If the filter is not valid.
>>> See RFC 1960 to work out what -   *                                  it
>>> should be.
>>> -   */
>>> -  public static Object getService(String className, String filter) throws
>>> IllegalArgumentException
>>> +  +  private static class ServicePair
>>>   {
>>> -    Object service = null;
>>> -    try {
>>> -      BundleContext callerCtx = getBundleContext();
>>> -      ServiceReference[] refs = callerCtx.getServiceReferences(className,
>>> filter);
>>> -      -      if (refs != null) {
>>> -        // we need to sort the references returned in case they are out
>>> of order
>>> -        // we need to sort in the reverse natural order, services with
>>> higher -        // ranking or lower id should be processed first so should
>>> be earlier in the array.
>>> -        Arrays.sort(refs, new Comparator<ServiceReference>() {
>>> -          public int compare(ServiceReference o1, ServiceReference o2)
>>> -          {
>>> -            return o2.compareTo(o1);
>>> -          }
>>> -        });
>>> -        -        for (ServiceReference ref : refs) {
>>> -          List<Object> services = getServices(callerCtx, className,
>>> filter, ref);
>>> -          if (!!!services.isEmpty()) {
>>> -            service = services.get(0);
>>> -            break;
>>> -          }
>>> -        }
>>> -      }      -    } catch (InvalidSyntaxException e) {
>>> -      throw new IllegalArgumentException(e.getMessage(), e);
>>> -    }
>>> -    -    return service;
>>> +    private ServiceReference ref;
>>> +    private Object service;
>>>   }
>>>      /**
>>> -   * This method is used to obtain a list of service instances from the
>>> OSGi
>>> -   * service registry. If no service is found an empty list will be
>>> returned.
>>> -   * -   * @param className The class name used to register the desired
>>> service. If null is provided
>>> -   *                  then all services are eligible to be returned.
>>> -   * @param filter    An RFC 1960 query into the properties of the
>>> registered services. e.g.
>>> -   *                  (service.description=really useful)
>>> -   * @return          A list of matching services.
>>> -   * -   * @throws IllegalArgumentException If the filter is not valid.
>>> See RFC 1960 to work out what -   *                                  it
>>> should be.
>>> +   * @param env +   * @return the bundle context for the caller.
>>> +   * @throws NamingException     */
>>> -  public static List<?> getServices(String className, String filter)
>>> -      throws IllegalArgumentException
>>> +  public static BundleContext getBundleContext(Map<String, Object> env)
>>> throws NamingException
>>>   {
>>> -    List<Object> services;
>>> -    try {
>>> -      BundleContext callerCtx = getBundleContext();
>>> -      ServiceReference[] refs =
>>> callerCtx.getAllServiceReferences(className, filter);
>>> +    BundleContext result = null;
>>> +    +    Object bc = env.get("osgi.service.jndi.bundleContext");
>>> +    +    if (bc != null && bc instanceof BundleContext) result =
>>> (BundleContext) bc;
>>> +    else {
>>> +      ClassLoader cl = AccessController.doPrivileged(new
>>> PrivilegedAction<ClassLoader>() {
>>> +        public ClassLoader run()
>>> +        {
>>> +          return Thread.currentThread().getContextClassLoader();
>>> +        }
>>> +      });
>>>       -      services = getServices(callerCtx, className, filter, refs);
>>> -    } catch (InvalidSyntaxException e) {
>>> -      throw new IllegalArgumentException(e.getMessage(), e);
>>> +      result = getBundleContext(cl);
>>> +    }
>>> +    +    if (result == null) {
>>> +      StackTraceElement[] stackTrace = AccessController.doPrivileged(new
>>> PrivilegedAction<StackTraceElement[]>() {
>>> +        public StackTraceElement[] run()
>>> +        {
>>> +          return Thread.currentThread().getStackTrace();
>>> +        }
>>> +      });
>>> +      +      StackFinder finder = new StackFinder();
>>> +      Class<?>[] classStack = finder.getClassContext();
>>> +      +      boolean found = false;
>>> +      boolean foundLookup = false;
>>> +      int i = 0;
>>> +      for (; i < stackTrace.length && !!!found; i++) {
>>> +        if (!!!foundLookup &&
>>> "lookup".equals(stackTrace[i].getMethodName())) {
>>> +          foundLookup = true;
>>> +        } else if (foundLookup &&
>>> !!!(stackTrace[i].getClassName().startsWith("org.apache.aries.jndi") ||
>>> +
>>>  stackTrace[i].getClassName().startsWith("javax.naming"))) {
>>> +          found = true;
>>> +        }
>>> +      }
>>> +      +      if (found) {
>>> +        Set<Integer> classLoadersChecked = new HashSet<Integer>();
>>> +        for (; i < classStack.length && result == null; i++) {
>>> +          ClassLoader cl = classStack[i].getClassLoader();
>>> +          int hash = System.identityHashCode(cl);
>>> +          if (!!!classLoadersChecked.contains(hash)) {
>>> +            classLoadersChecked.add(hash);
>>> +            result = getBundleContext(cl);
>>> +          }
>>> +        }
>>> +        // Now we walk the stack looking for the BundleContext
>>> +      }
>>>     }
>>>     -    return services;
>>> +    if (result == null) throw new NamingException("Unable to find
>>> BundleContext");
>>> +    +    return result;
>>>   }
>>> -  -  /**
>>> -   * @return the bundle context for the caller.
>>> -   */
>>> -  private static BundleContext getBundleContext()
>>> +
>>> +  private static BundleContext getBundleContext(ClassLoader cl)
>>>   {
>>>     BundleContext result = null;
>>> -    ClassLoader cl = Thread.currentThread().getContextClassLoader();
>>>     while (result == null && cl != null) {
>>>       if (cl instanceof BundleReference) {
>>>         result = ((BundleReference)cl).getBundle().getBundleContext();
>>>       } else if (cl != null) {
>>>         cl = cl.getParent();
>>>       }
>>> -    } +    }
>>>     -    if (result == null) result = context;
>>>     return result;
>>>   }
>>>  -  /**
>>> -   * This worker method obtains the requested service(s) and if the
>>> service(s) -   * exist updates the cache and releases the previous
>>> service(s).
>>> -   * -   * @param callerCtx The caller context.
>>> -   * @param className The class name used to query for the service.
>>> -   * @param filter    The filter name used to query for the service.
>>> -   * @param refs      The references to get.
>>> -   * @return          The service, if one was found, or null.
>>> -   */
>>> -  private static List<Object> getServices(BundleContext callerCtx, String
>>> className, String filter, ServiceReference...refs)
>>> +  public static Object getService(String interface1, String filter,
>>> String serviceName, boolean dynamicRebind, Map<String, Object> env) throws
>>> NamingException
>>>   {
>>> -    List<Object> data = new LinkedList<Object>();
>>> +    Object result = null;
>>> +    +    BundleContext ctx = getBundleContext(env);
>>> +    +    ServicePair pair = findService(ctx, interface1, filter);
>>>     -    if (refs != null) {
>>> -      Set<ServiceReference> refSet = new HashSet<ServiceReference>();
>>> -      for (ServiceReference ref : refs) {
>>> -        Object service = callerCtx.getService(ref);
>>> -        if (service != null) {
>>> -          data.add(service);
>>> -          refSet.add(ref);
>>> +    if (pair == null) {
>>> +      interface1 = null;
>>> +      filter = "(osgi.jndi.serviceName=" + serviceName + ")";
>>> +      pair = findService(ctx, interface1, filter);
>>> +    }
>>> +    +    if (pair != null) {
>>> +      String[] interfaces = (String[])
>>> pair.ref.getProperty("objectClass");
>>> +      +      List<Class<?>> clazz = new
>>> ArrayList<Class<?>>(interfaces.length);
>>> +      +      Bundle b = ctx.getBundle();
>>> +      +      for (String interfaceName : interfaces) {
>>> +        try {
>>> +          clazz.add(b.loadClass(interfaceName));
>>> +        } catch (ClassNotFoundException e) {
>>> +          // TODO Auto-generated catch block
>>> +          e.printStackTrace();
>>>         }
>>>       }
>>>       -      ClassLoader cl =
>>> Thread.currentThread().getContextClassLoader();
>>> -      ServiceKey key = new ServiceKey(cl, className, filter);
>>> +      if (clazz.isEmpty()) {
>>> +        throw new IllegalArgumentException();
>>> +      }
>>>       -      // we do not need any synchronization around this. The map is
>>> concurrent
>>> -      // and until here we do not touch any shared state.
>>> -      refSet = cache.put(key, refSet);
>>> +      InvocationHandler ih = new JNDIServiceDamper(ctx, interface1,
>>> filter, pair, dynamicRebind);
>>>       -      if (refSet != null) {
>>> -        for (ServiceReference ref : refSet) {
>>> -          callerCtx.ungetService(ref);
>>> +      result = Proxy.newProxyInstance(new BundleToClassLoaderAdapter(b),
>>> clazz.toArray(new Class<?>[clazz.size()]), ih);
>>> +    }
>>> +    +    return result;
>>> +  }
>>> +
>>> +  private static ServicePair findService(BundleContext ctx, String
>>> interface1, String filter)
>>> +  {
>>> +    ServicePair p = null;
>>> +    +    try {
>>> +      ServiceReference[] refs = ctx.getServiceReferences(interface1,
>>> filter);
>>> +      +      if (refs != null) {
>>> +        // natural order is the exact opposite of the order we desire.
>>> +        Arrays.sort(refs, new Comparator<ServiceReference>() {
>>> +          public int compare(ServiceReference o1, ServiceReference o2)
>>> +          {
>>> +            return o2.compareTo(o1);
>>> +          }
>>> +        });
>>> +        +        for (ServiceReference ref : refs) {
>>> +          Object service = ctx.getService(ref);
>>> +          +          if (service != null) {
>>> +            p = new ServicePair();
>>> +            p.ref = ref;
>>> +            p.service = service;
>>> +            break;
>>> +          }
>>>         }
>>>       }
>>> +      +    } catch (InvalidSyntaxException e) {
>>> +      // TODO Auto-generated catch block
>>> +      e.printStackTrace();
>>>     }
>>>     -    return data;
>>> +    return p;
>>>   }
>>>  }
>>>
>>> Modified:
>>> incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/Activator.java
>>> URL:
>>> http://svn.apache.org/viewvc/incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/Activator.java?rev=917809&r1=917808&r2=917809&view=diff
>>>
>>> ==============================================================================
>>> ---
>>> incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/Activator.java
>>> (original)
>>> +++
>>> incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/Activator.java
>>> Mon Mar  1 23:53:18 2010
>>> @@ -34,8 +34,6 @@
>>>
>>>   public void start(BundleContext context)
>>>   {
>>> -    ServiceHelper.setBundleContext(context);
>>> -         Hashtable<Object, Object> props = new Hashtable<Object,
>>> Object>();
>>>     props.put("osgi.jndi.urlScheme", new String[] {"osgi", "aries"} );
>>>     reg = context.registerService(ObjectFactory.class.getName(), new
>>> OsgiURLContextFactory(), props);
>>>
>>> Copied:
>>> incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/OsgiName.java
>>> (from r910238,
>>> incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/ServiceRegistryName.java)
>>> URL:
>>> http://svn.apache.org/viewvc/incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/OsgiName.java?p2=incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/OsgiName.java&p1=incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/ServiceRegistryName.java&r1=910238&r2=917809&rev=917809&view=diff
>>>
>>> ==============================================================================
>>> ---
>>> incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/ServiceRegistryName.java
>>> (original)
>>> +++
>>> incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/OsgiName.java
>>> Mon Mar  1 23:53:18 2010
>>> @@ -21,28 +21,104 @@
>>>  import java.util.Enumeration;
>>>  import javax.naming.CompositeName;
>>> +import javax.naming.InvalidNameException;
>>> +import javax.naming.Name;
>>>  /**
>>> - * A composite name for the aries namespace. We only have this so that we
>>> can
>>> - * provide a nicer toString()
>>> + * A composite name for the aries namespace. This provides useful utility
>>> methods
>>> + * for accessing the name.
>>> + * + * component 0: osgi:service, aries:services, osgi:servicelist
>>> + * component 1: interface
>>> + * component 2: filter
>>>  */
>>> -public final class ServiceRegistryName extends CompositeName
>>> +public final class OsgiName extends CompositeName
>>>  {
>>>   /** The serial version UID */
>>>   private static final long serialVersionUID = 6617580228852444656L;
>>> +  public static final String OSGI_SCHEME = "osgi";
>>> +  public static final String ARIES_SCHEME = "aries";
>>> +  public static final String SERVICE_PATH = "service";
>>> +  public static final String SERVICES_PATH = "services";
>>> +  public static final String SERVICE_LIST_PATH = "servicelist";
>>> +  public static final String FRAMEWORK_PATH = "framework";
>>>   -  @Override
>>> -  public String toString()
>>> +  public OsgiName(String name) throws InvalidNameException
>>>   {
>>> -    StringBuilder buffer = new StringBuilder();
>>> +    super(name);
>>> +  }
>>> +
>>> +  public OsgiName(Name name) throws InvalidNameException
>>> +  {
>>> +    this(name.toString());
>>> +  }
>>> +
>>> +  public boolean hasFilter()
>>> +  {
>>> +    return size() == 3;
>>> +  }
>>> +  +  public boolean isServiceNameBased()
>>> +  {
>>> +    return size() > 3;
>>> +  }
>>> +  +  public String getScheme()
>>> +  {
>>> +    String part0 = get(0);
>>> +    int index = part0.indexOf(':');
>>> +    +    String result;
>>> +    +    if (index > 0) {
>>> +      result = part0.substring(0, index);
>>> +    } else {
>>> +      result = null;
>>> +    }
>>> +    +    return result;
>>> +  }
>>> +  +  public String getSchemePath()
>>> +  {
>>> +    String part0 = get(0);
>>> +    int index = part0.indexOf(':');
>>> +    +    String result;
>>>     -    buffer.append("aries:services");
>>> -    Enumeration<String> components = getAll();
>>> -    while (components.hasMoreElements()) {
>>> -      buffer.append('/');
>>> -      buffer.append(components.nextElement());
>>> +    if (index > 0) {
>>> +      result = part0.substring(index + 1);
>>> +    } else {
>>> +      result = null;
>>>     }
>>>     -    return buffer.toString();
>>> +    return result;
>>> +  }
>>> +  +  public String getInterface()
>>> +  {
>>> +    return get(1);
>>> +  }
>>> +  +  public String getFilter()
>>> +  {
>>> +    return hasFilter() ? get(2) : null;
>>> +  }
>>> +  +  public String getServiceName()
>>> +  {
>>> +    Enumeration<String> parts = getAll();
>>> +    parts.nextElement();
>>> +    +    StringBuilder builder = new StringBuilder();
>>> +    +    while (parts.hasMoreElements()) {
>>> +      builder.append(parts.nextElement());
>>> +      builder.append('/');
>>> +    }
>>> +    +    builder.deleteCharAt(builder.length() - 1);
>>> +    +    return builder.toString();
>>>   }
>>>  }
>>> \ No newline at end of file
>>>
>>> Copied:
>>> incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/OsgiNameParser.java
>>> (from r910238,
>>> incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/ServiceRegistryNameParser.java)
>>> URL:
>>> http://svn.apache.org/viewvc/incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/OsgiNameParser.java?p2=incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/OsgiNameParser.java&p1=incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/ServiceRegistryNameParser.java&r1=910238&r2=917809&rev=917809&view=diff
>>>
>>> ==============================================================================
>>> ---
>>> incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/ServiceRegistryNameParser.java
>>> (original)
>>> +++
>>> incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/OsgiNameParser.java
>>> Mon Mar  1 23:53:18 2010
>>> @@ -26,31 +26,40 @@
>>>  /**
>>>  * A parser for the aries namespace
>>>  */
>>> -public final class ServiceRegistryNameParser implements NameParser
>>> +public final class OsgiNameParser implements NameParser
>>>  {
>>> -
>>> +  private static final String OSGI_SCHEME = "osgi";
>>> +  private static final String ARIES_SCHEME = "aries";
>>> +  private static final String SERVICE_PATH = "service";
>>> +  private static final String SERVICES_PATH = "services";
>>> +  private static final String SERVICE_LIST_PATH = "servicelist";
>>> +  private static final String FRAMEWORK_PATH = "framework";
>>> +     public Name parse(String name) throws NamingException
>>>   {
>>> -    if (!!!name.startsWith("aries:services/") &&
>>> -        !!!name.startsWith("osgi:services/")) throw new
>>> InvalidNameException("The JNDI name did not start with aries:, or osgi:");
>>> +    OsgiName result = new OsgiName(name);
>>> +    +    if (result.size() < 2) throw new InvalidNameException(name);
>>>     -    name = name.substring(name.indexOf('/') + 1);
>>> +    String urlScheme = result.getScheme();
>>> +    String schemePath = result.getSchemePath();
>>>     -    int slashIndex = name.indexOf('/');
>>> -    String interfaceName = name;
>>> -    String filter = null;
>>> -    -    if (slashIndex != -1) {
>>> -      interfaceName = name.substring(0, slashIndex);
>>> -      filter = name.substring(slashIndex + 1);
>>> +    if (!!!(OSGI_SCHEME.equals(urlScheme) ||
>>> ARIES_SCHEME.equals(urlScheme))) {
>>> +      throw new InvalidNameException(name);
>>>     }
>>>     -    if (interfaceName.length() == 0) throw new
>>> InvalidNameException("No interface name was specified");
>>> +    if (ARIES_SCHEME.equals(urlScheme) &&
>>> !!!SERVICES_PATH.equals(schemePath)) {
>>> +      throw new InvalidNameException(name);
>>> +    }
>>> +    +    if (OSGI_SCHEME.equals(urlScheme) && !!!(
>>> SERVICE_PATH.equals(schemePath) || +
>>>      SERVICE_LIST_PATH.equals(schemePath) || +
>>>                FRAMEWORK_PATH.equals(schemePath))) {
>>> +      throw new InvalidNameException(name);
>>> +    }
>>>     -    Name result = new ServiceRegistryName();
>>> -    result.add(interfaceName);
>>> -    if (filter != null) {
>>> -      result.add(filter);
>>> +    if (result.getInterface() == null || result.getInterface().length()
>>> == 0) {
>>> +      throw new InvalidNameException(name);
>>>     }
>>>          return result;
>>> @@ -59,7 +68,7 @@
>>>   @Override
>>>   public boolean equals(Object other)
>>>   {
>>> -    return other instanceof ServiceRegistryNameParser;
>>> +    return other instanceof OsgiNameParser;
>>>   }
>>>      @Override
>>>
>>> Modified:
>>> incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/OsgiURLContextFactory.java
>>> URL:
>>> http://svn.apache.org/viewvc/incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/OsgiURLContextFactory.java?rev=917809&r1=917808&r2=917809&view=diff
>>>
>>> ==============================================================================
>>> ---
>>> incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/OsgiURLContextFactory.java
>>> (original)
>>> +++
>>> incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/OsgiURLContextFactory.java
>>> Mon Mar  1 23:53:18 2010
>>> @@ -49,7 +49,7 @@
>>>     } else if (obj instanceof String[]) {
>>>       // Try each URL until either lookup succeeds or they all fail
>>>       String[] urls = (String[])obj;
>>> -      if (urls.length == 0) throw new
>>> ConfigurationException("ariesURLContextFactory: empty URL array");
>>> +      if (urls.length == 0) throw new ConfigurationException("0");
>>>       Context context = new ServiceRegistryContext(environment);
>>>       try
>>>       {
>>>
>>> Modified:
>>> incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/ServiceRegistryContext.java
>>> URL:
>>> http://svn.apache.org/viewvc/incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/ServiceRegistryContext.java?rev=917809&r1=917808&r2=917809&view=diff
>>>
>>> ==============================================================================
>>> ---
>>> incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/ServiceRegistryContext.java
>>> (original)
>>> +++
>>> incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/ServiceRegistryContext.java
>>> Mon Mar  1 23:53:18 2010
>>> @@ -42,9 +42,9 @@
>>>  {
>>>   private static final String ARIES_SERVICES = "aries:services/";
>>>   /** The name parser for the service registry name space */
>>> -  private NameParser parser = new ServiceRegistryNameParser();
>>> +  private NameParser parser = new OsgiNameParser();
>>>   /** The environment for this context */
>>> -  private Map<Object, Object> env;
>>> +  private Map<String, Object> env;
>>>      /**
>>>    * Why Mr Java this class does indeed take a fine copy of the provided
>>> @@ -53,10 +53,11 @@
>>>    *     * @param environment
>>>    */
>>> +  @SuppressWarnings("unchecked")
>>>   public ServiceRegistryContext(Hashtable<?, ?> environment)
>>>   {
>>> -    env = new HashMap<Object, Object>();
>>> -    env.putAll(environment);
>>> +    env = new HashMap<String, Object>();
>>> +    env.putAll((Map<? extends String, ? extends Object>) environment);
>>>   }
>>>    public Object addToEnvironment(String propName, Object propVal) throws
>>> NamingException
>>> @@ -153,7 +154,7 @@
>>>    public NamingEnumeration<NameClassPair> list(final Name name) throws
>>> NamingException
>>>   {
>>> -    throw new NamingException("Not a Context");
>>> +    return new ServiceRegistryListContext(env, convert(name)).list("");
>>>   }
>>>    public NamingEnumeration<NameClassPair> list(String name) throws
>>> NamingException
>>> @@ -163,7 +164,7 @@
>>>    public NamingEnumeration<Binding> listBindings(final Name name) throws
>>> NamingException
>>>   {
>>> -    throw new NamingException("Not a Context");
>>> +    return new ServiceRegistryListContext(env,
>>> convert(name)).listBindings("");
>>>   }
>>>    public NamingEnumeration<Binding> listBindings(String name) throws
>>> NamingException
>>> @@ -173,28 +174,43 @@
>>>    public Object lookup(Name name) throws NamingException
>>>   {
>>> -    int nameSize = validateName(name);
>>> -    String className = name.get(0);
>>> -
>>> -    String filter = null;
>>> +    Object result;
>>> +    +    OsgiName validName = convert(name);
>>>     -    if (nameSize == 2) {
>>> -      filter = name.get(1);
>>> +    String pathFragment = validName.getSchemePath();
>>> +    String serviceName = validName.getServiceName();
>>> +    String schemeName = validName.getScheme();
>>> +    +    if (OsgiName.FRAMEWORK_PATH.equals(pathFragment) &&
>>> "bundleContext".equals(validName.getServiceName())) {
>>> +      result = ServiceHelper.getBundleContext(env);
>>> +    } else if ((OsgiName.SERVICE_PATH.equals(pathFragment) &&
>>> OsgiName.OSGI_SCHEME.equals(schemeName)) ||
>>> +               (OsgiName.SERVICES_PATH.equals(pathFragment) &&
>>> OsgiName.ARIES_SCHEME.equals(schemeName))) {
>>> +      result = ServiceHelper.getService(validName.getInterface(),
>>> validName.getFilter(), serviceName, true, env);
>>> +    } else if (OsgiName.SERVICE_LIST_PATH.equals(pathFragment)) {
>>> +      result = new ServiceRegistryListContext(env, validName);
>>> +    } else {
>>> +      result = null;
>>>     }
>>>     -    try {
>>> -      Object result = ServiceHelper.getService(className, filter);
>>> -      -      if (result == null) {
>>> -        throw new NameNotFoundException("We couldn't find an object in
>>> the registry matching the query " + name);
>>> -      }
>>> -      -      return result;
>>> -    } catch (IllegalArgumentException e) {
>>> -      NamingException ne = new NamingException(e.getMessage());
>>> -      ne.initCause(e);
>>> -      throw ne;
>>> +    if (result == null) {
>>> +      throw new NameNotFoundException(name.toString());
>>> +    }
>>> +    +    return result;
>>> +  }
>>> +
>>> +  private OsgiName convert(Name name) throws InvalidNameException
>>> +  {
>>> +    OsgiName result;
>>> +    +    if (name instanceof OsgiName) {
>>> +      result = (OsgiName) name;
>>> +    } else {
>>> +      result = new OsgiName(name);
>>>     }
>>> +    +    return result;
>>>   }
>>>    public Object lookup(String name) throws NamingException
>>> @@ -246,27 +262,4 @@
>>>   {
>>>     throw new OperationNotSupportedException();
>>>   }
>>> -  -  /**
>>> -   * Check that the name conforms to the expected format
>>> -   * @param name
>>> -   * @return the size of the name
>>> -   * @throws InvalidNameException
>>> -   */
>>> -  private int validateName(final Name name) throws InvalidNameException
>>> -  {
>>> -    int nameSize = name.size();
>>> -    if (nameSize == 0) {
>>> -      throw new InvalidNameException("The provided name does not have any
>>> components" + name);
>>> -    } -    -    if ("aries:services".equals(name.get(0))) {
>>> -      throw new InvalidNameException("The composite name should not start
>>> with aries:services");
>>> -    }
>>> -    -    if (nameSize > 2) {
>>> -      throw new InvalidNameException("This JNDI context only expects 2
>>> components, but it found " + nameSize);
>>> -    }
>>> -    return nameSize;
>>> -  }
>>>  }
>>> \ No newline at end of file
>>>
>>> Added:
>>> incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/ServiceRegistryListContext.java
>>> URL:
>>> http://svn.apache.org/viewvc/incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/ServiceRegistryListContext.java?rev=917809&view=auto
>>>
>>> ==============================================================================
>>> ---
>>> incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/ServiceRegistryListContext.java
>>> (added)
>>> +++
>>> incubator/aries/trunk/jndi/jndi-url/src/main/java/org/apache/aries/jndi/url/ServiceRegistryListContext.java
>>> Mon Mar  1 23:53:18 2010
>>> @@ -0,0 +1,197 @@
>>> +/*
>>> + * 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.aries.jndi.url;
>>> +
>>> +import java.util.HashMap;
>>> +import java.util.Hashtable;
>>> +import java.util.Map;
>>> +
>>> +import javax.naming.Binding;
>>> +import javax.naming.Context;
>>> +import javax.naming.Name;
>>> +import javax.naming.NameClassPair;
>>> +import javax.naming.NameParser;
>>> +import javax.naming.NamingEnumeration;
>>> +import javax.naming.NamingException;
>>> +import javax.naming.OperationNotSupportedException;
>>> +
>>> +public class ServiceRegistryListContext implements Context
>>> +{
>>> +  private Map<String, Object> env;
>>> +  /** The name parser for the service registry name space */
>>> +  private NameParser parser = new OsgiNameParser();
>>> +  +  public ServiceRegistryListContext(Map<String, Object> env, OsgiName
>>> validName)
>>> +  {
>>> +    this.env = new HashMap<String, Object>(env);
>>> +  }
>>> +
>>> +  public Object addToEnvironment(String propName, Object propVal) throws
>>> NamingException
>>> +  {
>>> +    return env.put(propName, propVal);
>>> +  }
>>> +
>>> +  public void bind(Name name, Object obj) throws NamingException
>>> +  {
>>> +    throw new OperationNotSupportedException();
>>> +  }
>>> +
>>> +  public void bind(String name, Object obj) throws NamingException
>>> +  {
>>> +    throw new OperationNotSupportedException();
>>> +  }
>>> +
>>> +  public void close() throws NamingException
>>> +  {
>>> +    env = null;
>>> +    parser = null;
>>> +  }
>>> +
>>> +  public Name composeName(Name name, Name prefix) throws NamingException
>>> +  {
>>> +    // TODO Auto-generated method stub
>>> +    return null;
>>> +  }
>>> +
>>> +  public String composeName(String name, String prefix) throws
>>> NamingException
>>> +  {
>>> +    // TODO Auto-generated method stub
>>> +    return null;
>>> +  }
>>> +
>>> +  public Context createSubcontext(Name name) throws NamingException
>>> +  {
>>> +    throw new OperationNotSupportedException();
>>> +  }
>>> +
>>> +  public Context createSubcontext(String name) throws NamingException
>>> +  {
>>> +    throw new OperationNotSupportedException();
>>> +  }
>>> +
>>> +  public void destroySubcontext(Name name) throws NamingException
>>> +  {
>>> +    //No-op we don't support sub-contexts in our context
>>> +  }
>>> +
>>> +  public void destroySubcontext(String name) throws NamingException
>>> +  {
>>> +    //No-op we don't support sub-contexts in our context
>>> +  }
>>> +
>>> +  public Hashtable<?, ?> getEnvironment() throws NamingException
>>> +  {
>>> +    Hashtable<Object, Object> environment = new Hashtable<Object,
>>> Object>();
>>> +    environment.putAll(env);
>>> +    return environment;
>>> +  }
>>> +
>>> +  public String getNameInNamespace() throws NamingException
>>> +  {
>>> +    // TODO Auto-generated method stub
>>> +    return null;
>>> +  }
>>> +
>>> +  public NameParser getNameParser(Name name) throws NamingException
>>> +  {
>>> +    return parser;
>>> +  }
>>> +
>>> +  public NameParser getNameParser(String name) throws NamingException
>>> +  {
>>> +    return parser;
>>> +  }
>>> +
>>> +  public NamingEnumeration<NameClassPair> list(Name name) throws
>>> NamingException
>>> +  {
>>> +    return list(name.toString());
>>> +  }
>>> +
>>> +  public NamingEnumeration<NameClassPair> list(String name) throws
>>> NamingException
>>> +  {
>>> +    // TODO Auto-generated method stub
>>> +    return null;
>>> +  }
>>> +
>>> +  public NamingEnumeration<Binding> listBindings(Name name) throws
>>> NamingException
>>> +  {
>>> +    return listBindings(name.toString());
>>> +  }
>>> +
>>> +  public NamingEnumeration<Binding> listBindings(String name) throws
>>> NamingException
>>> +  {
>>> +    // TODO Auto-generated method stub
>>> +    return null;
>>> +  }
>>> +
>>> +  public Object lookup(Name name) throws NamingException
>>> +  {
>>> +    return lookup(name.toString());
>>> +  }
>>> +
>>> +  public Object lookup(String name) throws NamingException
>>> +  {
>>> +    return null;
>>> +  }
>>> +
>>> +  public Object lookupLink(Name name) throws NamingException
>>> +  {
>>> +    throw new OperationNotSupportedException();
>>> +  }
>>> +
>>> +  public Object lookupLink(String name) throws NamingException
>>> +  {
>>> +    throw new OperationNotSupportedException();
>>> +  }
>>> +
>>> +  public void rebind(Name name, Object obj) throws NamingException
>>> +  {
>>> +    throw new OperationNotSupportedException();
>>> +  }
>>> +
>>> +  public void rebind(String name, Object obj) throws NamingException
>>> +  {
>>> +    throw new OperationNotSupportedException();
>>> +  }
>>> +
>>> +  public Object removeFromEnvironment(String propName) throws
>>> NamingException
>>> +  {
>>> +    return env.remove(propName);
>>> +  }
>>> +
>>> +  public void rename(Name oldName, Name newName) throws NamingException
>>> +  {
>>> +    throw new OperationNotSupportedException();
>>> +  }
>>> +
>>> +  public void rename(String oldName, String newName) throws
>>> NamingException
>>> +  {
>>> +    throw new OperationNotSupportedException();
>>> +  }
>>> +
>>> +  public void unbind(Name name) throws NamingException
>>> +  {
>>> +    throw new OperationNotSupportedException();
>>> +  }
>>> +
>>> +  public void unbind(String name) throws NamingException
>>> +  {
>>> +    throw new OperationNotSupportedException();
>>> +  }
>>> +}
>>> \ No newline at end of file
>>>
>>> Copied:
>>> incubator/aries/trunk/jndi/jndi-url/src/test/java/org/apache/aries/jndi/url/OsgiNameParserTest.java
>>> (from r917002,
>>> incubator/aries/trunk/jndi/jndi-url/src/test/java/org/apache/aries/jndi/url/ServiceRegistryNameParserTest.java)
>>> URL:
>>> http://svn.apache.org/viewvc/incubator/aries/trunk/jndi/jndi-url/src/test/java/org/apache/aries/jndi/url/OsgiNameParserTest.java?p2=incubator/aries/trunk/jndi/jndi-url/src/test/java/org/apache/aries/jndi/url/OsgiNameParserTest.java&p1=incubator/aries/trunk/jndi/jndi-url/src/test/java/org/apache/aries/jndi/url/ServiceRegistryNameParserTest.java&r1=917002&r2=917809&rev=917809&view=diff
>>>
>>> ==============================================================================
>>> ---
>>> incubator/aries/trunk/jndi/jndi-url/src/test/java/org/apache/aries/jndi/url/ServiceRegistryNameParserTest.java
>>> (original)
>>> +++
>>> incubator/aries/trunk/jndi/jndi-url/src/test/java/org/apache/aries/jndi/url/OsgiNameParserTest.java
>>> Mon Mar  1 23:53:18 2010
>>> @@ -18,11 +18,11 @@
>>>  */
>>>  package org.apache.aries.jndi.url;
>>>  -import static org.junit.Assert.assertNotNull;
>>>  import static org.junit.Assert.assertEquals;
>>> +import static org.junit.Assert.assertFalse;
>>> +import static org.junit.Assert.assertTrue;
>>>  import javax.naming.InvalidNameException;
>>> -import javax.naming.Name;
>>>  import javax.naming.NameParser;
>>>  import javax.naming.NamingException;
>>>  @@ -31,10 +31,10 @@
>>>  /**
>>>  * This is where we test the service registry name parser.
>>>  */
>>> -public class ServiceRegistryNameParserTest
>>> +public class OsgiNameParserTest
>>>  {
>>>   /** The parser we are going to use for testing */
>>> -  private NameParser parser = new ServiceRegistryNameParser();
>>> +  private NameParser parser = new OsgiNameParser();
>>>    /**
>>>    * OK, so we check that we can call checkNames multiple times.
>>> @@ -43,8 +43,14 @@
>>>   @Test
>>>   public void checkValidNames() throws NamingException
>>>   {
>>> -    checkName("aries:services/java.lang.Runnable/(a=b)");
>>> -    checkName("aries:services/java.lang.Runnable");
>>> +    checkName("aries","services","java.lang.Runnable","(a=b)");
>>> +    checkName("aries","services","java.lang.Runnable");
>>> +    checkName("osgi","service","java.lang.Runnable");
>>> +    checkName("osgi","service","java.lang.Runnable", "(a=b)");
>>> +    checkName("osgi","servicelist","java.lang.Runnable");
>>> +    checkName("osgi","servicelist","java.lang.Runnable", "(a=b)");
>>> +    checkName("osgi","servicelist","jdbc", "grok", "DataSource");
>>> +    checkName("osgi", "framework", "bundleContext");
>>>   }
>>>      /**
>>> @@ -54,7 +60,7 @@
>>>   @Test(expected=InvalidNameException.class)
>>>   public void checkOutsideNamespace() throws NamingException
>>>   {
>>> -    checkName("java:comp/env/jms/cf");
>>> +    checkName("java","comp","env","jms","cf");
>>>   }
>>>      /**
>>> @@ -64,7 +70,7 @@
>>>   @Test(expected=InvalidNameException.class)
>>>   public void checkMissingInterface() throws NamingException
>>>   {
>>> -    checkName("aries:services");
>>> +    checkName("aries","services");
>>>   }
>>>      /**
>>> @@ -75,20 +81,64 @@
>>>   @Test(expected=InvalidNameException.class)
>>>   public void checkMissingInterface2() throws NamingException
>>>   {
>>> -    checkName("aries:services/");
>>> +    checkName("aries","services", "");
>>>   }
>>> -
>>> -  /**
>>> -   * This method parses the name and then makes sure what was parsed was
>>> parsed
>>> -   * correctly.
>>> -   * -   * @param name
>>> -   * @throws NamingException
>>> -   */
>>> -  private void checkName(String name) throws NamingException
>>> +  +  @Test(expected=InvalidNameException.class)
>>> +  public void checkIncorrectPath() throws NamingException
>>> +  {
>>> +    checkName("osgi", "services", "java.lang.Runnable"); +  }
>>> +  +  @Test(expected=InvalidNameException.class)
>>> +  public void checkIllegalPath() throws NamingException
>>>   {
>>> -    Name n = parser.parse(name);
>>> -    assertNotNull("We got a null name back, which is not allowed.", n);
>>> -    assertEquals("The name's toString does not produce the original
>>> value", name, n.toString());
>>> +    checkName("osgi", "wibble", "java.lang.Runnable"); +  }
>>> +  +  private void checkName(String scheme, String path, String ...
>>> elements)
>>> +    throws NamingException
>>> +  {
>>> +    StringBuilder builder = new StringBuilder();
>>> +    StringBuilder serviceName = new StringBuilder();
>>> +    +    builder.append(scheme);
>>> +    builder.append(':');
>>> +    builder.append(path);
>>> +
>>> +    if (elements.length > 0) {
>>> +      builder.append('/');
>>> +      +      for (String element : elements) {
>>> +        serviceName.append(element);
>>> +        serviceName.append('/');
>>> +      }
>>> +  +      serviceName.deleteCharAt(serviceName.length() - 1);
>>> +      +      builder.append(serviceName);
>>> +    }
>>> +    +    OsgiName n = (OsgiName) parser.parse(builder.toString());
>>> +    +    assertEquals(scheme, n.getScheme());
>>> +    assertEquals(path, n.getSchemePath());
>>> +    +    if (elements.length > 1) {
>>> +      assertEquals(elements[0], n.getInterface());
>>> +    }
>>> +    +    if (elements.length == 1) {
>>> +      assertFalse(n.hasFilter());
>>> +    }
>>> +    +    if (elements.length > 2) {
>>> +      if (elements.length == 2) {
>>> +        assertTrue(n.hasFilter());
>>> +        assertEquals(elements[1], n.getFilter());
>>> +      } else assertFalse(n.hasFilter());
>>> +    }
>>> +    +    assertEquals(serviceName.toString(), n.getServiceName());
>>>   }
>>>  }
>>> \ No newline at end of file
>>>
>>> Modified:
>>> incubator/aries/trunk/jndi/jndi-url/src/test/java/org/apache/aries/jndi/url/ServiceRegistryContextTest.java
>>> URL:
>>> http://svn.apache.org/viewvc/incubator/aries/trunk/jndi/jndi-url/src/test/java/org/apache/aries/jndi/url/ServiceRegistryContextTest.java?rev=917809&r1=917808&r2=917809&view=diff
>>>
>>> ==============================================================================
>>> ---
>>> incubator/aries/trunk/jndi/jndi-url/src/test/java/org/apache/aries/jndi/url/ServiceRegistryContextTest.java
>>> (original)
>>> +++
>>> incubator/aries/trunk/jndi/jndi-url/src/test/java/org/apache/aries/jndi/url/ServiceRegistryContextTest.java
>>> Mon Mar  1 23:53:18 2010
>>> @@ -21,7 +21,6 @@
>>>  import static org.junit.Assert.assertEquals;
>>>  import static org.junit.Assert.assertFalse;
>>>  import static org.junit.Assert.assertNotNull;
>>> -import static org.junit.Assert.assertSame;
>>>  import static org.junit.Assert.assertTrue;
>>>  import java.lang.reflect.Field;
>>> @@ -37,6 +36,12 @@
>>>  import javax.naming.NamingException;
>>>  import javax.naming.spi.ObjectFactory;
>>>  +import org.apache.aries.jndi.ContextHelper;
>>> +import org.apache.aries.jndi.OSGiObjectFactoryBuilder;
>>> +import org.apache.aries.mocks.BundleContextMock;
>>> +import org.apache.aries.mocks.BundleMock;
>>> +import org.apache.aries.unittest.mocks.MethodCall;
>>> +import org.apache.aries.unittest.mocks.Skeleton;
>>>  import org.junit.After;
>>>  import org.junit.Before;
>>>  import org.junit.Test;
>>> @@ -47,22 +52,13 @@
>>>  import org.osgi.framework.ServiceReference;
>>>  import org.osgi.framework.ServiceRegistration;
>>>  -import org.apache.aries.unittest.mocks.MethodCall;
>>> -import org.apache.aries.unittest.mocks.Skeleton;
>>> -import org.apache.aries.jndi.ContextHelper;
>>> -import org.apache.aries.jndi.OSGiObjectFactoryBuilder;
>>> -import org.apache.aries.jndi.services.ServiceHelper;
>>> -import org.apache.aries.jndi.url.Activator;
>>> -import org.apache.aries.mocks.BundleContextMock;
>>> -import org.apache.aries.mocks.BundleMock;
>>> -
>>>  /**
>>>  * Tests for our JNDI implementation for the service registry.
>>>  */
>>>  public class ServiceRegistryContextTest
>>>  {
>>>   /** The service we register by default */
>>> -  private Thread service;
>>> +  private Runnable service;
>>>   /** The bundle context for the test */
>>>   private BundleContext bc;
>>>   /** The service registration for the service */
>>> @@ -83,10 +79,7 @@
>>>     new Activator().start(bc);
>>>     new org.apache.aries.jndi.startup.Activator().start(bc);
>>>     -    Field f = ServiceHelper.class.getDeclaredField("context");
>>> -    f.setAccessible(true);
>>> -    f.set(null, bc);
>>> -    f = ContextHelper.class.getDeclaredField("context");
>>> +    Field f = ContextHelper.class.getDeclaredField("context");
>>>     f.setAccessible(true);
>>>     f.set(null, bc);
>>>     f = OSGiObjectFactoryBuilder.class.getDeclaredField("context");
>>> @@ -94,7 +87,7 @@
>>>     f.set(null, bc);
>>>  -    service = new Thread();
>>> +    service = Skeleton.newMock(Runnable.class);
>>>          registerService(service);
>>>   }
>>> @@ -104,7 +97,7 @@
>>>    *     * @param service2 The service to register.
>>>    */
>>> -  private void registerService(Thread service2)
>>> +  private void registerService(Runnable service2)
>>>   {
>>>     ServiceFactory factory = Skeleton.newMock(ServiceFactory.class);
>>>     Skeleton skel = Skeleton.getSkeleton(factory);
>>> @@ -159,11 +152,13 @@
>>>
>>>  Thread.currentThread().setContextClassLoader(mock.getClassLoader());
>>>     -    Object s = ctx.lookup("aries:services/java.lang.Runnable");
>>> +    Runnable s = (Runnable)
>>> ctx.lookup("aries:services/java.lang.Runnable");
>>>          assertNotNull("We didn't get a service back from our lookup :(",
>>> s);
>>>     -    assertEquals("The SR did not return the object we expected",
>>> service, s);
>>> +    s.run();
>>> +    +    Skeleton.getSkeleton(service).assertCalledExactNumberOfTimes(new
>>> MethodCall(Runnable.class, "run"), 1);
>>>          Skeleton skel = Skeleton.getSkeleton(mock.getBundleContext());
>>>     @@ -173,7 +168,7 @@
>>>
>>>  Thread.currentThread().setContextClassLoader(mock.getClassLoader());
>>>  -    s = ctx.lookup("osgi:services/java.lang.Runnable");
>>> +    s = (Runnable) ctx.lookup("osgi:service/java.lang.Runnable");
>>>          // Check we have the packages set correctly
>>>     @@ -181,10 +176,11 @@
>>>          assertTrue(ctx.getEnvironment().containsValue(packages));
>>>  -         assertNotNull("We didn't get a service back from our lookup
>>> :(", s);
>>> +
>>> +    s.run();
>>>     -    assertEquals("The SR did not return the object we expected",
>>> service, s);
>>> +    Skeleton.getSkeleton(service).assertCalledExactNumberOfTimes(new
>>> MethodCall(Runnable.class, "run"), 2);
>>>      skel = Skeleton.getSkeleton(mock.getBundleContext());
>>>     skel.assertCalled(new MethodCall(BundleContext.class,
>>> "getServiceReferences", "java.lang.Runnable", null));
>>> @@ -201,15 +197,21 @@
>>>   @Test
>>>   public void jndiLookupWithFilter() throws NamingException
>>>   {
>>> +    BundleMock mock = new BundleMock("scooby.doo", new Properties());
>>> +    +
>>>  Thread.currentThread().setContextClassLoader(mock.getClassLoader());
>>> +
>>>     InitialContext ctx = new InitialContext();
>>>          Object s =
>>> ctx.lookup("aries:services/java.lang.Runnable/(rubbish=smelly)");
>>>          assertNotNull("We didn't get a service back from our lookup :(",
>>> s);
>>>     -    assertEquals("The SR did not return the object we expected",
>>> service, s);
>>> +    service.run();
>>>     -    Skeleton.getSkeleton(bc).assertCalled(new
>>> MethodCall(BundleContext.class, "getServiceReferences",
>>> "java.lang.Runnable", "(rubbish=smelly)"));
>>> +    Skeleton.getSkeleton(service).assertCalledExactNumberOfTimes(new
>>> MethodCall(Runnable.class, "run"), 1);
>>> +
>>> +    Skeleton.getSkeleton(mock.getBundleContext()).assertCalled(new
>>> MethodCall(BundleContext.class, "getServiceReferences",
>>> "java.lang.Runnable", "(rubbish=smelly)"));
>>>   }
>>>      /**
>>> @@ -222,6 +224,11 @@
>>>   public void testLookupWhenServiceHasBeenRemoved() throws NamingException
>>>   {
>>>     reg.unregister();
>>> +
>>> +    BundleMock mock = new BundleMock("scooby.doo", new Properties());
>>> +    +
>>>  Thread.currentThread().setContextClassLoader(mock.getClassLoader());
>>> +
>>>     InitialContext ctx = new InitialContext();
>>>          ctx.lookup("aries:services/java.lang.Runnable");
>>> @@ -236,6 +243,10 @@
>>>   @Test(expected=NameNotFoundException.class)
>>>   public void testLookupForServiceWeNeverHad() throws NamingException
>>>   {
>>> +    BundleMock mock = new BundleMock("scooby.doo", new Properties());
>>> +    +
>>>  Thread.currentThread().setContextClassLoader(mock.getClassLoader());
>>> +
>>>     InitialContext ctx = new InitialContext();
>>>          ctx.lookup("aries:services/java.lang.Integer");
>>> @@ -271,14 +282,53 @@
>>>   }
>>>    @Test
>>> +  public void checkProxyDynamism() throws NamingException
>>> +  {
>>> +    BundleMock mock = new BundleMock("scooby.doo", new Properties());
>>> +    +
>>>  Thread.currentThread().setContextClassLoader(mock.getClassLoader());
>>> +
>>> +    InitialContext ctx = new InitialContext();
>>> +    +    String className = Runnable.class.getName();
>>> +    +    Runnable t = Skeleton.newMock(Runnable.class);
>>> +    Runnable t2 = Skeleton.newMock(Runnable.class);
>>> +    +    // we don't want the default service
>>> +    reg.unregister();
>>> +    +    ServiceRegistration reg = bc.registerService(className, t,
>>> null);
>>> +    bc.registerService(className, t2, null);
>>> +    +    Runnable r = (Runnable)
>>> ctx.lookup("osgi:service/java.lang.Runnable");
>>> +    +    r.run();
>>> +    +    Skeleton.getSkeleton(t).assertCalledExactNumberOfTimes(new
>>> MethodCall(Runnable.class, "run"), 1);
>>> +    Skeleton.getSkeleton(t2).assertNotCalled(new
>>> MethodCall(Runnable.class, "run"));
>>> +    +    reg.unregister();
>>> +    +    r.run();
>>> +    +    Skeleton.getSkeleton(t).assertCalledExactNumberOfTimes(new
>>> MethodCall(Runnable.class, "run"), 1);
>>> +    Skeleton.getSkeleton(t2).assertCalledExactNumberOfTimes(new
>>> MethodCall(Runnable.class, "run"), 1);
>>> +  }  +
>>> +  @Test
>>>   public void checkServiceOrderObserved() throws NamingException
>>>   {
>>> +    BundleMock mock = new BundleMock("scooby.doo", new Properties());
>>> +    +
>>>  Thread.currentThread().setContextClassLoader(mock.getClassLoader());
>>> +
>>>     InitialContext ctx = new InitialContext();
>>>          String className = Runnable.class.getName();
>>>     -    Thread t = new Thread();
>>> -    Thread t2 = new Thread();
>>> +    Runnable t = Skeleton.newMock(Runnable.class);
>>> +    Runnable t2 = Skeleton.newMock(Runnable.class);
>>>          // we don't want the default service
>>>     reg.unregister();
>>> @@ -286,9 +336,12 @@
>>>     ServiceRegistration reg = bc.registerService(className, t, null);
>>>     ServiceRegistration reg2 = bc.registerService(className, t2, null);
>>>     -    Runnable r = (Runnable)
>>> ctx.lookup("osgi:services/java.lang.Runnable");
>>> +    Runnable r = (Runnable)
>>> ctx.lookup("osgi:service/java.lang.Runnable");
>>>     -    assertSame("The wrong runnable was returned", t, r);
>>> +    r.run();
>>> +    +    Skeleton.getSkeleton(t).assertCalledExactNumberOfTimes(new
>>> MethodCall(Runnable.class, "run"), 1);
>>> +    Skeleton.getSkeleton(t2).assertNotCalled(new
>>> MethodCall(Runnable.class, "run"));
>>>          reg.unregister();
>>>     reg2.unregister();
>>> @@ -296,12 +349,18 @@
>>>     Hashtable<String, Object> props = new Hashtable<String, Object>();
>>>     props.put(Constants.SERVICE_RANKING, 55);
>>>     +    t = Skeleton.newMock(Runnable.class);
>>> +    t2 = Skeleton.newMock(Runnable.class);
>>> +
>>>     reg = bc.registerService(className, t, null);
>>>     reg2 = bc.registerService(className, t2, props);
>>>     -    r = (Runnable) ctx.lookup("osgi:services/java.lang.Runnable");
>>> +    r = (Runnable) ctx.lookup("osgi:service/java.lang.Runnable");
>>> +    +    r.run();
>>>     -    assertSame("The wrong runnable was returned", t2, r);
>>> +    Skeleton.getSkeleton(t).assertNotCalled(new
>>> MethodCall(Runnable.class, "run"));
>>> +    Skeleton.getSkeleton(t2).assertCalledExactNumberOfTimes(new
>>> MethodCall(Runnable.class, "run"), 1);
>>>   }
>>>      /**
>>>
>>>
>>>
>>
>> --
>> Joe
>>
> 
> 
> 


-- 
Joe