View Javadoc

1   /**
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   *     http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing, software
13   * distributed under the License is distributed on an "AS IS" BASIS,
14   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15   * See the License for the specific language governing permissions and
16   * limitations under the License.
17   */
18  
19  package org.apache.hadoop.hbase;
20  
21  import org.apache.commons.logging.Log;
22  import org.apache.commons.logging.LogFactory;
23  
24  import java.util.Iterator;
25  import java.util.ServiceLoader;
26  
27  /**
28   * Class that will create many instances of classes provided by the hbase-hadoop{1|2}-compat jars.
29   */
30  public class CompatibilityFactory {
31  
32    private static final Log LOG = LogFactory.getLog(CompatibilitySingletonFactory.class);
33    public static final String EXCEPTION_START = "Could not create  ";
34    public static final String EXCEPTION_END = " Is the hadoop compatibility jar on the classpath?";
35  
36    /**
37     * This is a static only class don't let any instance be created.
38     */
39    protected CompatibilityFactory() {}
40  
41    public static synchronized <T> T getInstance(Class<T> klass) {
42      T instance = null;
43      try {
44        ServiceLoader<T> loader = ServiceLoader.load(klass);
45        Iterator<T> it = loader.iterator();
46        instance = it.next();
47        if (it.hasNext()) {
48          StringBuilder msg = new StringBuilder();
49          msg.append("ServiceLoader provided more than one implementation for class: ")
50             .append(klass)
51             .append(", using implementation: ").append(instance.getClass())
52             .append(", other implementations: {");
53          while (it.hasNext()) {
54            msg.append(it.next()).append(" ");
55          }
56          msg.append("}");
57          LOG.warn(msg);
58        }
59      } catch (Exception e) {
60        throw new RuntimeException(createExceptionString(klass), e);
61      } catch (Error e) {
62        throw new RuntimeException(createExceptionString(klass), e);
63      }
64  
65      // If there was nothing returned and no exception then throw an exception.
66      if (instance == null) {
67        throw new RuntimeException(createExceptionString(klass));
68      }
69      return instance;
70    }
71  
72    protected static String createExceptionString(Class klass) {
73      return EXCEPTION_START + klass.toString() + EXCEPTION_END;
74    }
75  }