Skip to content

Commit

Permalink
ARQ-117 Added more descriptive exception messages
Browse files Browse the repository at this point in the history
  • Loading branch information
aslakknutsen committed Apr 24, 2010
1 parent 26dcc30 commit 7d828f8
Show file tree
Hide file tree
Showing 5 changed files with 131 additions and 5 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
package org.jboss.arquillian.impl;

import java.util.Collection;
import java.util.logging.Logger;

import org.jboss.arquillian.spi.ServiceLoader;
import org.jboss.arquillian.spi.util.DefaultServiceLoader;
Expand All @@ -29,24 +30,81 @@
*/
public class DynamicServiceLoader implements ServiceLoader
{
private static Logger logger = Logger.getLogger(DynamicServiceLoader.class.getName());

/* (non-Javadoc)
* @see org.jboss.arquillian.spi.ServiceLoader#all(java.lang.Class)
*/
public <T> Collection<T> all(Class<T> serviceClass)
{
return DefaultServiceLoader.load(serviceClass).getProviders();
}

/* (non-Javadoc)
* @see org.jboss.arquillian.spi.ServiceLoader#onlyOne(java.lang.Class)
*/
public <T> T onlyOne(Class<T> serviceClass)
{
Collection<T> providers = DefaultServiceLoader.load(serviceClass).getProviders();
verifyOnlyOneOrSameImplementation(serviceClass, providers);

return providers.iterator().next();
}

private void verifyOnlyOneOrSameImplementation(Class<?> serviceClass, Collection<?> providers)
{
if(providers == null || providers.size() == 0)
{
throw new IllegalStateException("No implementation found for: " + serviceClass.getName() + ", check classpath");
throw new IllegalStateException(
"No implementation found for " +
serviceClass.getName() + ", please check your classpath");
}
if(providers.size() > 1)
{
throw new IllegalStateException("Mutiple implementations found for: " + serviceClass.getName() + ", check classpath");
// verify that they all point to the same implementation, if not throw exception
verifySameImplementation(serviceClass, providers);
}
return providers.iterator().next();
}


private void verifySameImplementation(Class<?> serviceClass, Collection<?> providers)
{
boolean providersAreTheSame = false;
Class<?> firstProvider = null;
for(Object provider : providers)
{
if(firstProvider == null)
{
// set the class to match
firstProvider = provider.getClass();
continue;
}
if(firstProvider == provider.getClass())
{
providersAreTheSame = true;
}
else
{
throw new IllegalStateException(
"More then one implementation found for "
+ serviceClass.getName() + ", " +
"please check your classpath. The found implementations are " + toClassString(providers));
}
}
if(providersAreTheSame)
{
logger.warning(
"More then one reference to the same implementation was found for " +
serviceClass.getName() + ", please verify you classpath");
}
}

private String toClassString(Collection<?> providers)
{
StringBuilder sb = new StringBuilder();
for(Object provider : providers)
{
sb.append(provider.getClass().getName()).append(", ");
}
return sb.subSequence(0, sb.length()-2).toString();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
/*
* JBoss, Home of Professional Open Source
* Copyright 2009, Red Hat Middleware LLC, and individual contributors
* by the @authors tag. See the copyright.txt in the distribution for a
* full listing of individual contributors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jboss.arquillian.impl;

import java.util.Collection;

import org.junit.Assert;
import org.junit.Test;

/**
* Verify the behavior of the Dynamic Service Loader
*
* @author <a href="mailto:aknutsen@redhat.com">Aslak Knutsen</a>
* @version $Revision: $
*/
public class DynamicServiceLoaderTestCase
{

@Test(expected = IllegalStateException.class)
public void shouldFailIfMultipleProvidersFound() throws Exception
{
new DynamicServiceLoader().onlyOne(Service.class);
}

@Test
public void shouldNotFailIfMultipleProvidersFoundPointingToSameImpl() throws Exception
{
Service2 service = new DynamicServiceLoader().onlyOne(Service2.class);

Assert.assertTrue(
"verify that a instance of Service2Impl was loaded",
service.getClass() == Service2Impl.class);
}

@Test
public void shouldLoadAllInstances() throws Exception {
Collection<Service> services = new DynamicServiceLoader().all(Service.class);

Assert.assertEquals(
"verify that all services where found and loaded",
2, services.size());
}

public interface Service {}
public static class ServiceImpl1 implements Service {}
public static class ServiceImpl2 implements Service {}

public interface Service2 {}
public static class Service2Impl implements Service2 {}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
org.jboss.arquillian.impl.DynamicServiceLoaderTestCase$ServiceImpl1
org.jboss.arquillian.impl.DynamicServiceLoaderTestCase$ServiceImpl2
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
org.jboss.arquillian.impl.DynamicServiceLoaderTestCase$Service2Impl
org.jboss.arquillian.impl.DynamicServiceLoaderTestCase$Service2Impl
Original file line number Diff line number Diff line change
Expand Up @@ -197,7 +197,7 @@ public void reload()
}
catch (ClassCastException e)
{
throw new IllegalStateException("Extension " + line + " does not implement Extension");
throw new IllegalStateException(line + " does not implement " + expectedType);
}
Constructor<? extends S> constructor = serviceClass.getConstructor();
if(!constructor.isAccessible()) {
Expand Down

0 comments on commit 7d828f8

Please sign in to comment.