ClassPool bootstrap refactoring
kabirkhan Apr 23, 2010 10:00 AMFollowing on from http://community.jboss.org/message/539041#539041 I have started refactoring how the ClassPools are initialized during bootstrap and moving code into the classpools project. The following (uncommitted, but working) test in ClassPools demonstrates how I see this working in the bootstrap.
/** * Simulates the steps to be taken during AS bootstrap */ public void testBootstrap() throws Exception { //Initialize the config. This wires together the parts of the system JBossClClassPoolConfig config = JBossClClassPoolConfig.getInstance(); assertNotNull(config.getClassPoolFactory()); assertNotNull(config.getClassPoolRepository()); assertNotNull(config.getDomainRegistry()); assertNotNull(config.getRegisterModuleCallback()); assertNull(config.getClassLoading()); //Check that the classpool factory works before we have deployed the classpool system ClassLoader urlCl = createChildURLLoader(null, JAR_A_URL); ClassPool urlPool = config.getClassPoolRepository().registerClassLoader(urlCl); assertNotNull(urlPool); CtClass aUrl = urlPool.get(CLASS_A); CtClass stringUrl = urlPool.get(String.class.getName()); //Install the bean to get notified when ClassLoading is installed BeanMetaDataBuilder builder = BeanMetaDataBuilder.createBuilder("JBossClClassPoolConfig", JBossClClassPoolConfig.class.getName()); builder.setFactoryClass(JBossClClassPoolConfig.class.getName()); builder.setFactoryMethod("getInstance"); ValueMetaData inject = builder.createContextualInject(null, null, AutowireType.BY_NAME, InjectOption.CALLBACK); ((AbstractInjectionValueMetaData)inject).setValue("ClassLoading"); builder.addPropertyMetaData("classLoading", inject); getDelegate().deploy(builder.getBeanMetaData()); //Deploy the ClassLoading. This causes the RegistryModuleCallback //to get installed as a module registry in ClassLoading getDelegate().deployCommon(); assertNotNull(config.getClassLoading()); testScenario = new ClassPoolTestScenario<CLDeploymentBuilder>(getClassLoaderFactory(), config.getClassPoolRepository()); ClassPool poolA = testScenario.createLoader(new CLDeploymentBuilder("A", JAR_A_URL)); CtClass aDomain = poolA.get(CLASS_A); assertNotSame(aUrl, aDomain); assertSame(stringUrl, poolA.get(String.class.getName())); ClassPool poolB = testScenario.createLoader(new CLDeploymentBuilder("B", JAR_B_URL)); assertSame(aDomain, poolB.get(CLASS_A)); }
The JBossClClassPoolConfig singleton wires together a lot of the things that are needed for running this in AS (getters ommitted)
public class JBossClClassPoolConfig { private static volatile JBossClClassPoolConfig config; private final DomainRegistry domainRegistry; private final RegisterModuleCallback registerModuleCallback; private ClassLoading classLoading; private JBossClDelegatingClassPoolFactory classPoolFactory; private ClassPoolRepository classPoolRepository; private JBossClClassPoolConfig(DomainRegistry domainRegistry, RegisterModuleCallback registerModuleCallback, JBossClDelegatingClassPoolFactory classPoolFactory) { this.domainRegistry = domainRegistry; this.registerModuleCallback = registerModuleCallback; this.classPoolFactory = classPoolFactory; classPoolRepository = ClassPoolRepository.getInstance(); classPoolRepository.setClassPoolFactory(classPoolFactory); } public static JBossClClassPoolConfig getInstance() { if (config == null) { config = initialize(); } return config; } private synchronized static JBossClClassPoolConfig initialize() { if (config != null) return config; DomainRegistry domainRegistry = new VFSClassLoaderDomainRegistry(); RegisterModuleCallback registerModuleCallback = new RegisterModuleCallback(domainRegistry); JBossClDelegatingClassPoolFactory classPoolFactory = new JBossClDelegatingClassPoolFactory(domainRegistry, registerModuleCallback); return new JBossClClassPoolConfig(domainRegistry, registerModuleCallback, classPoolFactory); } /** * Set the classLoading. This should be set via a property * by the MC * * @param cl the classLoading to set */ public void setClassLoading(ClassLoading cl) { if (cl != null) cl.addModuleRegistry(registerModuleCallback); else if (classLoading != null) classLoading.removeModuleRegistry(registerModuleCallback); classLoading = cl; } }
So basically all the AS bootstrap will need to do is to call JBossClClassPoolConfig.getInstance() to initialize the classpool parts, and then deploy the JBossClClassPoolConfig bean whose purpose is to add the RegisterModuleCallback as a module registry in ClassLoading once that is deployed.
With this in place and with a few small changes to how the aop classes work, what is in bootstrap/aop.xml will reuse things from JBossClClassPoolConfig where appropriate.