6 Replies Latest reply on Nov 25, 2008 3:47 AM by dazz_x

    [VFS] Better way to scan for modifications

    dazz_x

      Hi all,

      I didn't see any forum for VFS, so I post here since I use it with the MicroContainer.

      My question is about the possibility to know if a VirtualFile or one of its children has been recently modified.

      Context :
      I work on a grid that executes jobs. Each job instance arriving at a node is of the same type and delegates execution to an engine whose implementation depends on some metadata hold by the instance. The grid node is started as a service by the microcontainer, but messaging between nodes is performed by the Grid. I would like to be able to put jars in a predefined directory that could serve as an implementation for the Engine interface in a hot manner (i want to be able to hot deploy some implementations). I tried to understand deeply MC deployment framework to achieve that, but i certainly misunderstood some concepts as I've come to think that it was mandatory for me to write my own deployers (and the way to effectively implement that is a bit blur to me, since some parts of docs are not written).

      So, I have a periodic scanner that is meant to determine if a directory has appeared elsewhere and then trigger a loading of the classes included in it (as jar files).
      In my scanning method, I wanted to do a snapshot of the current VirtualFile hierarchy in order to compare it to the future hierarchy (found by the next scan).
      But I didn't see any way to "freeze" the VirtualFile hierarchy as the VirtualFiles are bound to the handler objects so I can't do a freeze copy (or immutable if you prefer) that I can store and compare later.
      I saw the hasBeenModified() method of Virtual File, but the modification time is said to be initialized at Handler's instantiation, so when the file is first "discovered" by the VSF.

      I hope you'll see my point and give advice to me

      Cheers

      dazz_x

      PS : sorry for my poor english

        • 1. Re: [VFS] Better way to scan for modifications
          alesj

          Have a look at my demos, its bootstrap to be exact:
          - http://anonsvn.jboss.org/repos/jbossas/projects/demos/microcontainer/trunk/
          See HDScanner class, its usage of files Map.

          A bit more complicated impl is here:
          - http://anonsvn.jboss.org/repos/jbossas/trunk/system/src/main/org/jboss/system/server/profile/basic/MetaDataAwareProfile.java

          HTH

          And for any VFS or Deployers issues you might have,
          this is the right forum. ;-)

          • 2. Re: [VFS] Better way to scan for modifications
            dazz_x

            Hi alesj,

            Thanks for your response, which was helpul to me.

            I finally handled this case in a satisfactory way.
            So, when I add/remove/modify a file under my hierarchy, i get a log that says "this file have been added, removed, modified" under the TRACE log level.

            A the same time I log, I fire an EngineDeployment event to alert registered listeners that an event has happened.

            Unfortunately, that doesn't work... I give you my deployment file :

             <bean name="ClassLoaderManager" class="com.mycompany.classloaders.MasterClassLoader">
             <constructor factoryMethod="getInstance"/>
             </bean>
            
             <bean name="Scanner" class="com.mycompany.deployers.scanner.Scanner">
             <install method="addListener">
             <parameter>
             <inject bean="ClassLoaderManager"/>
             </parameter>
             </install>
             <constructor>
             <parameter>/home/user/test/</parameter>
             </constructor>
             </bean>
            


            With this xml portion, I want to add my ClassLoaderManager as a listener (simple addition to a CopyOnWriteArrayList in Scanner)
            But it isn't registered... I see an error in the deployment of ClassLoaderManager at startup that is
            12:52:17,886 ERROR [AbstractKernelController] Error installing to Instantiated: name=ClassLoaderManager state=Described
            org.jboss.joinpoint.spi.JoinpointException: Constructor not found com.mycompany.classloaders.MasterClassLoader[] in [ReflectConstructorInfoImpl@1b66b06{[ReflectClassInfoImpl@12c9557{name=java.lang.ClassLoader}]}, ReflectConstructorInfoImpl@9f0d{[ReflectClassInfoImpl@12c9557{name=java.lang.ClassLoader}, ReflectClassInfoImpl@ca3783{name=com.mycompany.classloaders.MasterClassLoader$1}]}]
             at org.jboss.joinpoint.plugins.Config.findConstructorInfo(Config.java:274)
             at org.jboss.kernel.plugins.config.Configurator.resolveConstructor(Configurator.java:289)
             at org.jboss.kernel.plugins.config.Configurator.findConstructor(Configurator.java:255)
             at org.jboss.kernel.plugins.config.Configurator.getConstructorJoinPoint(Configurator.java:198)
             at org.jboss.kernel.plugins.config.AbstractKernelConfigurator.getConstructorJoinPoint(AbstractKernelConfigurator.java:137)
             at org.jboss.kernel.plugins.dependency.InstantiateAction.installActionInternal(InstantiateAction.java:61)
             at org.jboss.kernel.plugins.dependency.InstallsAwareAction.installAction(InstallsAwareAction.java:54)
             at org.jboss.kernel.plugins.dependency.InstallsAwareAction.installAction(InstallsAwareAction.java:42)
             at org.jboss.dependency.plugins.action.SimpleControllerContextAction.simpleInstallAction(SimpleControllerContextAction.java:62)
             at org.jboss.dependency.plugins.action.AccessControllerContextAction.install(AccessControllerContextAction.java:71)
             at org.jboss.dependency.plugins.AbstractControllerContextActions.install(AbstractControllerContextActions.java:51)
             at org.jboss.dependency.plugins.AbstractControllerContext.install(AbstractControllerContext.java:348)
             at org.jboss.dependency.plugins.AbstractController.install(AbstractController.java:1598)
             at org.jboss.dependency.plugins.AbstractController.incrementState(AbstractController.java:934)
             at org.jboss.dependency.plugins.AbstractController.resolveContexts(AbstractController.java:1062)
             at org.jboss.dependency.plugins.AbstractController.resolveContexts(AbstractController.java:984)
             at org.jboss.dependency.plugins.AbstractController.install(AbstractController.java:774)
             at org.jboss.dependency.plugins.AbstractController.install(AbstractController.java:540)
             at org.jboss.kernel.plugins.deployment.AbstractKernelDeployer.deployBean(AbstractKernelDeployer.java:331)
             at org.jboss.kernel.plugins.deployment.AbstractKernelDeployer.deployBeans(AbstractKernelDeployer.java:309)
             at org.jboss.kernel.plugins.deployment.AbstractKernelDeployer.deploy(AbstractKernelDeployer.java:130)
             at org.jboss.kernel.plugins.deployment.BasicKernelDeployer.deploy(BasicKernelDeployer.java:76)
             at org.jboss.kernel.plugins.deployment.xml.BasicXMLDeployer.deploy(BasicXMLDeployer.java:88)
             at org.jboss.kernel.plugins.deployment.xml.BasicXMLDeployer.deploy(BasicXMLDeployer.java:158)
            
            


            Here is the relevant part of the code for my MasterClassLoader class :
            public class MasterClassLoader extends ClassLoader implements EngineDeploymentListener{
            
             /**
             * Application Logger
             */
             private static final Logger log = Logger.getLogger(MasterClassLoader.class);
            
             private Map<File, EngineClassLoader> engineClassLoaders = new HashMap<File, EngineClassLoader>();
            
             private MasterClassLoader(ClassLoader parent) {
             super(parent);
             }
            
             @Override
             public void onDeploymentEvent(EngineDeploymentEvent e) {
             log.info("[********] Deployment Event : " + e.getType().toString());
             }
            
             /**
             * Static initializer to ensure Singleton
             * @return single instance of MasterClassLoader
             */
             public static MasterClassLoader getInstance() {
             return MasterClassLoaderHolder.instance;
             }
            
             private static class MasterClassLoaderHolder {
            
             public static MasterClassLoader instance = new MasterClassLoader(ClassLoader.getSystemClassLoader());
             }
            }
            
            


            Why do you think my MasterClassLoader is not deployed ? My static factory method run well in standard call...

            Thanks in advance

            dazz_x

            • 3. Re: [VFS] Better way to scan for modifications
              dazz_x

              OK, I've been a bit fast to post ....

              But it seems a bit weird for me...

              So, I add a factoryClass="com.mycompany.classloaders.MasterClassLoader" attribute to the constructor tag...

              I don't get this error anymore.
              It seems a bit strange that if a factory class is not provided, the system does not use Object class as default factory...

              Thanks for having read me...

              • 4. Re: [VFS] Better way to scan for modifications
                alesj

                Yeah, I thought that was the case.

                Hmmm, but I remember we already did this.
                I guess it got lost with xml + metadata transition to jbossxb.
                I'll check.

                • 5. Re: [VFS] Better way to scan for modifications
                  alesj
                  • 6. Re: [VFS] Better way to scan for modifications
                    dazz_x

                    well done,

                    that seems logical

                    thanks