Search in sources :

Example 6 with WatchEventListener

use of org.hotswap.agent.watch.WatchEventListener in project HotswapAgent by HotswapProjects.

the class SpringPlugin method registerComponentScanBasePackage.

/**
 * Register both hotswap transformer AND watcher - in case of new file the file is not known
 * to JVM and hence no hotswap is called. The file may even exist, but until is loaded by Spring
 * it will not be known by the JVM. File events are processed only if the class is not known to the
 * classloader yet.
 *
 * @param basePackage only files in a basePackage
 */
public void registerComponentScanBasePackage(final String basePackage) {
    LOGGER.info("Registering basePackage {}", basePackage);
    this.registerBasePackage(basePackage);
    Enumeration<URL> resourceUrls = null;
    try {
        resourceUrls = getResources(basePackage);
    } catch (IOException e) {
        LOGGER.error("Unable to resolve base package {} in classloader {}.", basePackage, appClassLoader);
        return;
    }
    // for all application resources watch for changes
    while (resourceUrls.hasMoreElements()) {
        URL basePackageURL = resourceUrls.nextElement();
        if (!IOUtils.isFileURL(basePackageURL)) {
            LOGGER.debug("Spring basePackage '{}' - unable to watch files on URL '{}' for changes (JAR file?), limited hotswap reload support. " + "Use extraClassPath configuration to locate class file on filesystem.", basePackage, basePackageURL);
            continue;
        } else {
            watcher.addEventListener(appClassLoader, basePackageURL, new WatchEventListener() {

                @Override
                public void onEvent(WatchFileEvent event) {
                    if (event.isFile() && event.getURI().toString().endsWith(".class")) {
                        // check that the class is not loaded by the classloader yet (avoid duplicate reload)
                        String className;
                        try {
                            className = IOUtils.urlToClassName(event.getURI());
                        } catch (IOException e) {
                            LOGGER.trace("Watch event on resource '{}' skipped, probably Ok because of delete/create event sequence (compilation not finished yet).", e, event.getURI());
                            return;
                        }
                        if (!ClassLoaderHelper.isClassLoaded(appClassLoader, className)) {
                            // refresh spring only for new classes
                            scheduler.scheduleCommand(new ClassPathBeanRefreshCommand(appClassLoader, basePackage, className, event), WAIT_ON_CREATE);
                        }
                    }
                }
            });
        }
    }
}
Also used : WatchFileEvent(org.hotswap.agent.watch.WatchFileEvent) IOException(java.io.IOException) WatchEventListener(org.hotswap.agent.watch.WatchEventListener) URL(java.net.URL)

Example 7 with WatchEventListener

use of org.hotswap.agent.watch.WatchEventListener in project HotswapAgent by HotswapProjects.

the class WatchResourcesClassLoader method initWatchResources.

/**
 * Configure new instance with urls and watcher service.
 *
 * @param watchResources the URLs from which to load resources
 * @param watcher        watcher service to register watch events
 */
public void initWatchResources(URL[] watchResources, Watcher watcher) {
    // create classloader to serve resources only from watchResources URL's
    this.watchResourcesClassLoader = new UrlOnlyClassLoader(watchResources);
    // register watch resources - on change event each modified resource will be added to changedUrls.
    for (URL resource : watchResources) {
        try {
            URI uri = resource.toURI();
            LOGGER.debug("Watching directory '{}' for changes.", uri);
            watcher.addEventListener(this, uri, new WatchEventListener() {

                @Override
                public void onEvent(WatchFileEvent event) {
                    try {
                        if (event.isFile() || event.isDirectory()) {
                            changedUrls.add(event.getURI().toURL());
                            LOGGER.trace("File '{}' changed and will be returned instead of original classloader equivalent.", event.getURI().toURL());
                        }
                    } catch (MalformedURLException e) {
                        LOGGER.error("Unexpected - cannot convert URI {} to URL.", e, event.getURI());
                    }
                }
            });
        } catch (URISyntaxException e) {
            LOGGER.warning("Unable to convert watchResources URL '{}' to URI. URL is skipped.", e, resource);
        }
    }
}
Also used : WatchFileEvent(org.hotswap.agent.watch.WatchFileEvent) WatchEventListener(org.hotswap.agent.watch.WatchEventListener)

Example 8 with WatchEventListener

use of org.hotswap.agent.watch.WatchEventListener in project HotswapAgent by HotswapProjects.

the class AbstractNIO2Watcher method addEventListener.

@Override
public synchronized void addEventListener(ClassLoader classLoader, URI pathPrefix, WatchEventListener listener) {
    File path;
    try {
        // check that it is regular file
        // toString() is weird and solves HiarchicalUriException for URI
        // like "file:./src/resources/file.txt".
        path = new File(pathPrefix);
    } catch (IllegalArgumentException e) {
        if (!LOGGER.isLevelEnabled(Level.TRACE)) {
            LOGGER.warning("Unable to watch for path {}, not a local regular file or directory.", pathPrefix);
        } else {
            LOGGER.trace("Unable to watch for path {} exception", e, pathPrefix);
        }
        return;
    }
    try {
        addDirectory(path.toPath());
    } catch (IOException e) {
        if (!LOGGER.isLevelEnabled(Level.TRACE)) {
            LOGGER.warning("Unable to watch for path {}, not a local regular file or directory.", pathPrefix);
        } else {
            LOGGER.trace("Unable to watch path with prefix '{}' for changes.", e, pathPrefix);
        }
        return;
    }
    List<WatchEventListener> list = listeners.get(Paths.get(pathPrefix));
    if (list == null) {
        list = new ArrayList<WatchEventListener>();
        listeners.put(Paths.get(pathPrefix), list);
    }
    list.add(listener);
    if (classLoader != null) {
        classLoaderListeners.put(listener, classLoader);
    }
}
Also used : IOException(java.io.IOException) WatchEventListener(org.hotswap.agent.watch.WatchEventListener) File(java.io.File)

Example 9 with WatchEventListener

use of org.hotswap.agent.watch.WatchEventListener in project HotswapAgent by HotswapProjects.

the class OwbPlugin method registerBeansXmls.

/**
 * Register BeanArchive's paths to watcher. In case of new class the class file is not known
 * to JVM hence no hotswap is called and therefore it must be handled by watcher.
 *
 * @param bdaLocations the Set of URLs of archive locations
 */
public void registerBeansXmls(Set bdaLocations) {
    // for all application resources watch for changes
    for (final URL beanArchiveUrl : (Set<URL>) bdaLocations) {
        String beansXmlPath = beanArchiveUrl.getPath();
        if (!beansXmlPath.endsWith("beans.xml")) {
            LOGGER.debug("Skipping bda location: '{}' ", beanArchiveUrl);
            continue;
        }
        final String archivePath;
        if (beansXmlPath.endsWith("META-INF/beans.xml")) {
            archivePath = beansXmlPath.substring(0, beansXmlPath.length() - "META-INF/beans.xml".length());
        } else if (beansXmlPath.endsWith("WEB-INF/beans.xml")) {
            archivePath = beansXmlPath.substring(0, beansXmlPath.length() - "beans.xml".length()) + "classes";
        } else {
            LOGGER.warning("Unexpected beans.xml location '{}'", beansXmlPath);
            continue;
        }
        if (archivePath.endsWith(".jar!/")) {
            LOGGER.debug("Skipping unsupported jar beans.xml location '{}'", beansXmlPath);
            continue;
        }
        // store path for unit tests (single archive expected)
        OwbPlugin.archivePath = archivePath;
        try {
            URL archivePathUrl = resourceNameToURL(archivePath);
            if (registeredArchives.containsKey(archivePathUrl)) {
                continue;
            }
            registeredArchives.put(archivePathUrl, beanArchiveUrl);
            URI uri = archivePathUrl.toURI();
            watcher.addEventListener(appClassLoader, uri, new WatchEventListener() {

                @Override
                public void onEvent(WatchFileEvent event) {
                    if (event.isFile() && event.getURI().toString().endsWith(".class")) {
                        // check that the class is not loaded by the classloader yet (avoid duplicate reload)
                        String className;
                        try {
                            className = IOUtils.urlToClassName(event.getURI());
                        } catch (IOException e) {
                            LOGGER.trace("Watch event on resource '{}' skipped, probably Ok because of delete/create event sequence (compilation not finished yet).", e, event.getURI());
                            return;
                        }
                        if (!ClassLoaderHelper.isClassLoaded(appClassLoader, className) || isTestEnvironment) {
                            // refresh weld only for new classes
                            LOGGER.trace("register reload command: {} ", className);
                            scheduler.scheduleCommand(new BeanClassRefreshCommand(appClassLoader, archivePath, beanArchiveUrl, event), WAIT_ON_CREATE);
                        }
                    }
                }
            });
            LOGGER.info("Registered  watch for path '{}' for changes.", archivePathUrl);
        } catch (URISyntaxException e) {
            LOGGER.error("Unable to watch path '{}' for changes.", e, archivePath);
        } catch (Exception e) {
            LOGGER.warning("registerBeanDeplArchivePath() exception : {}", e.getMessage());
        }
    }
}
Also used : Set(java.util.Set) WatchFileEvent(org.hotswap.agent.watch.WatchFileEvent) BeanClassRefreshCommand(org.hotswap.agent.plugin.owb.command.BeanClassRefreshCommand) IOException(java.io.IOException) URISyntaxException(java.net.URISyntaxException) WatchEventListener(org.hotswap.agent.watch.WatchEventListener) URI(java.net.URI) URL(java.net.URL) URISyntaxException(java.net.URISyntaxException) NotFoundException(org.hotswap.agent.javassist.NotFoundException) MalformedURLException(java.net.MalformedURLException) IOException(java.io.IOException)

Example 10 with WatchEventListener

use of org.hotswap.agent.watch.WatchEventListener in project HotswapAgent by HotswapProjects.

the class WatcherNIO2Test method testTargetClasses.

// ensure it works on file:/ URIs as returned by classloader
// @Test
public void testTargetClasses() throws Exception {
    URI uri = new URI("file:/" + temp);
    final ResultHolder resultHolder = new ResultHolder();
    watcher.addEventListener(null, uri, new WatchEventListener() {

        @Override
        public void onEvent(WatchFileEvent event) {
            assertTrue("File name", event.getURI().toString().endsWith("test.class"));
            resultHolder.result = true;
        }
    });
    File testFile = new File(uri.toURL().getFile(), "test.class");
    testFile.createNewFile();
    assertTrue("Event listener not called", waitForResult(resultHolder));
    testFile.delete();
}
Also used : WatchFileEvent(org.hotswap.agent.watch.WatchFileEvent) WatchEventListener(org.hotswap.agent.watch.WatchEventListener) URI(java.net.URI) File(java.io.File)

Aggregations

WatchEventListener (org.hotswap.agent.watch.WatchEventListener)10 WatchFileEvent (org.hotswap.agent.watch.WatchFileEvent)8 IOException (java.io.IOException)5 URI (java.net.URI)5 File (java.io.File)3 URISyntaxException (java.net.URISyntaxException)3 URL (java.net.URL)3 NotFoundException (org.hotswap.agent.javassist.NotFoundException)3 MalformedURLException (java.net.MalformedURLException)2 Path (java.nio.file.Path)1 WatchKey (java.nio.file.WatchKey)1 ArrayList (java.util.ArrayList)1 List (java.util.List)1 Entry (java.util.Map.Entry)1 Set (java.util.Set)1 CannotCompileException (org.hotswap.agent.javassist.CannotCompileException)1 BeanClassRefreshCommand (org.hotswap.agent.plugin.owb.command.BeanClassRefreshCommand)1 BeanClassRefreshCommand (org.hotswap.agent.plugin.weld.command.BeanClassRefreshCommand)1 Test (org.junit.Test)1