/** * When using a BeanFactory. singletons are of course not pre-instantiated. * So rubbish class names in bean defs must now not be 'resolved' when the * bean def is being parsed, 'cos everything on a bean def is now lazy, but * must rather only be picked up when the bean is instantiated. */ @Test public void testClassNotFoundWithDefaultBeanClassLoader() { DefaultListableBeanFactory factory = new DefaultListableBeanFactory(); new XmlBeanDefinitionReader(factory).loadBeanDefinitions(CLASS_NOT_FOUND_CONTEXT); // cool, no errors, so the rubbish class name in the bean def was not resolved try { // let's resolve the bean definition; must blow up factory.getBean("classNotFound"); fail("Must have thrown a CannotLoadBeanClassException"); } catch (CannotLoadBeanClassException ex) { assertTrue(ex.getResourceDescription().indexOf("classNotFound.xml") != -1); assertTrue(ex.getCause() instanceof ClassNotFoundException); } }
/** * Performs the actual autodetection process, delegating to an * {@code AutodetectCallback} instance to vote on the inclusion of a * given bean. * @param callback the {@code AutodetectCallback} to use when deciding * whether to include a bean or not */ private void autodetect(AutodetectCallback callback) { Set<String> beanNames = new LinkedHashSet<String>(this.beanFactory.getBeanDefinitionCount()); beanNames.addAll(Arrays.asList(this.beanFactory.getBeanDefinitionNames())); if (this.beanFactory instanceof ConfigurableBeanFactory) { beanNames.addAll(Arrays.asList(((ConfigurableBeanFactory) this.beanFactory).getSingletonNames())); } for (String beanName : beanNames) { if (!isExcluded(beanName) && !isBeanDefinitionAbstract(this.beanFactory, beanName)) { try { Class<?> beanClass = this.beanFactory.getType(beanName); if (beanClass != null && callback.include(beanClass, beanName)) { boolean lazyInit = isBeanDefinitionLazyInit(this.beanFactory, beanName); Object beanInstance = (!lazyInit ? this.beanFactory.getBean(beanName) : null); if (!this.beans.containsValue(beanName) && (beanInstance == null || !CollectionUtils.containsInstance(this.beans.values(), beanInstance))) { // Not already registered for JMX exposure. this.beans.put(beanName, (beanInstance != null ? beanInstance : beanName)); if (logger.isInfoEnabled()) { logger.info("Bean with name '" + beanName + "' has been autodetected for JMX exposure"); } } else { if (logger.isDebugEnabled()) { logger.debug("Bean with name '" + beanName + "' is already registered for JMX exposure"); } } } } catch (CannotLoadBeanClassException ex) { if (this.allowEagerInit) { throw ex; } // otherwise ignore beans where the class is not resolvable } } } }
/** * Publish all {@link javax.jws.WebService} annotated beans in the * containing BeanFactory. * @see #publishEndpoint */ public void publishEndpoints() { Set<String> beanNames = new LinkedHashSet<String>(this.beanFactory.getBeanDefinitionCount()); beanNames.addAll(Arrays.asList(this.beanFactory.getBeanDefinitionNames())); if (this.beanFactory instanceof ConfigurableBeanFactory) { beanNames.addAll(Arrays.asList(((ConfigurableBeanFactory) this.beanFactory).getSingletonNames())); } for (String beanName : beanNames) { try { Class<?> type = this.beanFactory.getType(beanName); if (type != null && !type.isInterface()) { WebService wsAnnotation = type.getAnnotation(WebService.class); WebServiceProvider wsProviderAnnotation = type.getAnnotation(WebServiceProvider.class); if (wsAnnotation != null || wsProviderAnnotation != null) { Endpoint endpoint = createEndpoint(this.beanFactory.getBean(beanName)); if (this.endpointProperties != null) { endpoint.setProperties(this.endpointProperties); } if (this.executor != null) { endpoint.setExecutor(this.executor); } if (wsAnnotation != null) { publishEndpoint(endpoint, wsAnnotation); } else { publishEndpoint(endpoint, wsProviderAnnotation); } this.publishedEndpoints.add(endpoint); } } } catch (CannotLoadBeanClassException ex) { // ignore beans where the class is not resolvable } } }
/** * Get bean class from bean class name. * @param beanName Bean name * @param beanClassName Bean class naem (not null) * @param classLoader ClassLoader to use (null for default class loader) * @return Bean class * @throws CannotLoadBeanClassException Class name not found in given ClassLoader */ private static Class<?> getBeanClass(final String beanName, final String beanClassName, ClassLoader classLoader) throws CannotLoadBeanClassException { ObjectUtils.argumentNotNull(beanClassName, "Bean class name must be not null"); try { return ClassUtils.forName(beanClassName, classLoader); } catch (ClassNotFoundException e) { throw new CannotLoadBeanClassException(BeanRegistryUtils.class.getName(), beanName, beanClassName, e); } }
/** * Performs the actual autodetection process, delegating to an * {@code AutodetectCallback} instance to vote on the inclusion of a * given bean. * @param callback the {@code AutodetectCallback} to use when deciding * whether to include a bean or not */ private void autodetect(AutodetectCallback callback) { Set<String> beanNames = new LinkedHashSet<String>(this.beanFactory.getBeanDefinitionCount()); beanNames.addAll(Arrays.asList(this.beanFactory.getBeanDefinitionNames())); if (this.beanFactory instanceof ConfigurableBeanFactory) { beanNames.addAll(Arrays.asList(((ConfigurableBeanFactory) this.beanFactory).getSingletonNames())); } for (String beanName : beanNames) { if (!isExcluded(beanName) && !isBeanDefinitionAbstract(this.beanFactory, beanName)) { try { Class<?> beanClass = this.beanFactory.getType(beanName); if (beanClass != null && callback.include(beanClass, beanName)) { boolean lazyInit = isBeanDefinitionLazyInit(this.beanFactory, beanName); Object beanInstance = (!lazyInit ? this.beanFactory.getBean(beanName) : null); if (!ScopedProxyUtils.isScopedTarget(beanName) && !this.beans.containsValue(beanName) && (beanInstance == null || !CollectionUtils.containsInstance(this.beans.values(), beanInstance))) { // Not already registered for JMX exposure. this.beans.put(beanName, (beanInstance != null ? beanInstance : beanName)); if (logger.isInfoEnabled()) { logger.info("Bean with name '" + beanName + "' has been autodetected for JMX exposure"); } } else { if (logger.isDebugEnabled()) { logger.debug("Bean with name '" + beanName + "' is already registered for JMX exposure"); } } } } catch (CannotLoadBeanClassException ex) { if (this.allowEagerInit) { throw ex; } // otherwise ignore beans where the class is not resolvable } } } }
@Test public void testContextWithInvalidLazyClass() { ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext(INVALID_CLASS_CONTEXT, getClass()); assertTrue(ctx.containsBean("someMessageSource")); try { ctx.getBean("someMessageSource"); fail("Should have thrown CannotLoadBeanClassException"); } catch (CannotLoadBeanClassException ex) { assertTrue(ex.contains(ClassNotFoundException.class)); } ctx.close(); }
/** * Возвращает название класса по его имени * * @param className название класса * @return Возвращает класс */ private static Class<?> retrieveClassByName(String className) { try { return Class.forName(className); } catch (ClassNotFoundException ex) { throw new CannotLoadBeanClassException(null, null, className, ex); } }
@Test public void testContextWithInvalidLazyClass() { ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext( INVALID_CLASS_CONTEXT, getClass()); assertTrue(ctx.containsBean("someMessageSource")); try { ctx.getBean("someMessageSource"); fail("Should have thrown CannotLoadBeanClassException"); } catch (CannotLoadBeanClassException ex) { assertTrue(ex.contains(ClassNotFoundException.class)); } ctx.close(); }
public static Class<?> findClassByName(String className, String beanName, ParserContext parserContext) { String description = parserContext.getReaderContext().getResource().getDescription(); try { return Class.forName(className); } catch (ClassNotFoundException ex) { throw new CannotLoadBeanClassException(description, beanName, className, ex); } }
/** * Init {@linkplain #implementorManager} and * {@linkplain #implementorBeanNamesMap}. * <p> * Synchronization for {@linkplain #implementorManager} and * {@linkplain #implementorBeanNamesMap} are not necessary, because they are * initialized in #setBeanFactory(BeanFactory) which happens before any * other actions. * </p> * * @throws BeansException */ protected void initImplementorManagerAndImplementorBeanNamesMap() throws BeansException { String[] allBeanNames = beanFactory.getBeanDefinitionNames(); for (int i = 0; i < allBeanNames.length; i++) { String beanName = allBeanNames[i]; Class<?> beanClass = null; BeanDefinition beanDefinition = this.beanFactory .getBeanDefinition(beanName); String beanClassName = beanDefinition.getBeanClassName(); try { beanClass = Class.forName(beanClassName); } catch (ClassNotFoundException e) { throw new CannotLoadBeanClassException( beanDefinition.getResourceDescription(), beanName, beanClassName, e); } List<String> implementorBeanNames = this.implementorBeanNamesMap .get(beanClass); if (implementorBeanNames == null) { implementorBeanNames = new ArrayList<String>(); this.implementorBeanNamesMap.put(beanClass, implementorBeanNames); } implementorBeanNames.add(beanName); // Add itself, fix missing itself as an implementor when auto wired // class is not abstract this.implementorManager.addFor(beanClass, beanClass); this.implementorManager.add(beanClass); } }