/** * Instantiate, configure and return a new component described by the supplied configuration. This * method does not manage the returned instance. * * @param config the configuration describing the component * @return the new component, or null if the component could not be successfully configured * @throws IllegalArgumentException if the component could not be configured properly */ @SuppressWarnings("unchecked") protected ComponentType newInstance(ConfigType config) { String[] classpath = config.getComponentClasspathArray(); final ClassLoader classLoader = this.getClassLoaderFactory().getClassLoader(classpath); assert classLoader != null; ComponentType newInstance = null; try { // Don't use ClassLoader.loadClass(String), as it doesn't properly initialize the class // (specifically static initializers may not be called) Class<?> componentClass = Class.forName(config.getComponentClassname(), true, classLoader); newInstance = doCreateInstance(componentClass); if (newInstance instanceof Component) { ((Component<ConfigType>) newInstance).setConfiguration(config); } if (config.getProperties() != null) { for (Map.Entry<String, Object> entry : config.getProperties().entrySet()) { // Set the JavaBean-style property on the RepositorySource instance ... Reflection reflection = new Reflection(newInstance.getClass()); reflection.invokeSetterMethodOnTarget(entry.getKey(), newInstance, entry.getValue()); } } configure(newInstance, config); } catch (Throwable e) { throw new SystemFailureException(e); } if (newInstance instanceof Component && ((Component<ConfigType>) newInstance).getConfiguration() == null) { throw new SystemFailureException(CommonI18n.componentNotConfigured.text(config.getName())); } return newInstance; }