Repository: camel
Updated Branches:
  refs/heads/master d1d2993f9 -> 977604bd7


Some tweaks to the classloaders to adapt to the new jar structure


Project: http://git-wip-us.apache.org/repos/asf/camel/repo
Commit: http://git-wip-us.apache.org/repos/asf/camel/commit/977604bd
Tree: http://git-wip-us.apache.org/repos/asf/camel/tree/977604bd
Diff: http://git-wip-us.apache.org/repos/asf/camel/diff/977604bd

Branch: refs/heads/master
Commit: 977604bd73e80b25b453413481f36708337080cd
Parents: d1d2993
Author: Nicola Ferraro <ni.ferr...@gmail.com>
Authored: Fri Jul 29 17:51:43 2016 +0200
Committer: Nicola Ferraro <ni.ferr...@gmail.com>
Committed: Fri Jul 29 17:51:43 2016 +0200

----------------------------------------------------------------------
 .../ArquillianSyncBootJarLauncher.java          | 21 +++++
 .../springboot/util/ArquillianPackager.java     | 80 ++++++++++++--------
 2 files changed, 69 insertions(+), 32 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/camel/blob/977604bd/tests/camel-itest-spring-boot/src/test/java/org/apache/camel/itest/springboot/arquillian/ArquillianSyncBootJarLauncher.java
----------------------------------------------------------------------
diff --git 
a/tests/camel-itest-spring-boot/src/test/java/org/apache/camel/itest/springboot/arquillian/ArquillianSyncBootJarLauncher.java
 
b/tests/camel-itest-spring-boot/src/test/java/org/apache/camel/itest/springboot/arquillian/ArquillianSyncBootJarLauncher.java
index 2a8c987..cd08c36 100644
--- 
a/tests/camel-itest-spring-boot/src/test/java/org/apache/camel/itest/springboot/arquillian/ArquillianSyncBootJarLauncher.java
+++ 
b/tests/camel-itest-spring-boot/src/test/java/org/apache/camel/itest/springboot/arquillian/ArquillianSyncBootJarLauncher.java
@@ -16,7 +16,15 @@
  */
 package org.apache.camel.itest.springboot.arquillian;
 
+import java.net.URL;
+import java.net.URLClassLoader;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.stream.Collectors;
+
 import org.springframework.boot.loader.JarLauncher;
+import org.springframework.boot.loader.LaunchedURLClassLoader;
 import org.springframework.boot.loader.MainMethodRunner;
 
 /**
@@ -43,6 +51,19 @@ public class ArquillianSyncBootJarLauncher extends 
JarLauncher {
         runner.run();
     }
 
+    @Override
+    protected ClassLoader createClassLoader(URL[] urls) throws Exception {
+        // The spring classloader should not be built on top of the current 
classloader, it should just share the test classes if available
+        List<URL> parentUrls = Arrays.asList(((URLClassLoader) 
this.getClass().getClassLoader()).getURLs());
+        List<URL> additionalURLs = parentUrls.stream().filter(u -> 
u.toString().startsWith("file") && 
!u.toString().endsWith(".jar")).collect(Collectors.toList());
+
+        ArrayList<URL> newURLs = new ArrayList(Arrays.asList(urls));
+        newURLs.addAll(additionalURLs);
+
+        return new LaunchedURLClassLoader(newURLs.toArray(new URL[0]), null);
+    }
+
+
     /**
      * Returns the classloader used by spring, to communicate with it.
      *

http://git-wip-us.apache.org/repos/asf/camel/blob/977604bd/tests/camel-itest-spring-boot/src/test/java/org/apache/camel/itest/springboot/util/ArquillianPackager.java
----------------------------------------------------------------------
diff --git 
a/tests/camel-itest-spring-boot/src/test/java/org/apache/camel/itest/springboot/util/ArquillianPackager.java
 
b/tests/camel-itest-spring-boot/src/test/java/org/apache/camel/itest/springboot/util/ArquillianPackager.java
index 1c6e969..85be90e 100644
--- 
a/tests/camel-itest-spring-boot/src/test/java/org/apache/camel/itest/springboot/util/ArquillianPackager.java
+++ 
b/tests/camel-itest-spring-boot/src/test/java/org/apache/camel/itest/springboot/util/ArquillianPackager.java
@@ -38,16 +38,21 @@ import 
org.apache.camel.itest.springboot.arquillian.SpringBootZipExporterImpl;
 import org.apache.commons.io.FileUtils;
 import org.jboss.arquillian.container.se.api.ClassPath;
 import org.jboss.shrinkwrap.api.Archive;
+import org.jboss.shrinkwrap.api.ArchivePath;
 import org.jboss.shrinkwrap.api.Configuration;
 import org.jboss.shrinkwrap.api.ConfigurationBuilder;
 import org.jboss.shrinkwrap.api.Domain;
 import org.jboss.shrinkwrap.api.ExtensionLoader;
-import org.jboss.shrinkwrap.api.GenericArchive;
 import org.jboss.shrinkwrap.api.ShrinkWrap;
+import org.jboss.shrinkwrap.api.asset.Asset;
+import org.jboss.shrinkwrap.api.asset.ClassLoaderAsset;
 import org.jboss.shrinkwrap.api.asset.FileAsset;
 import org.jboss.shrinkwrap.api.exporter.ZipExporter;
 import org.jboss.shrinkwrap.api.spec.JavaArchive;
 import org.jboss.shrinkwrap.impl.base.ServiceExtensionLoader;
+import org.jboss.shrinkwrap.impl.base.URLPackageScanner;
+import org.jboss.shrinkwrap.impl.base.asset.AssetUtil;
+import org.jboss.shrinkwrap.impl.base.path.BasicPath;
 import org.jboss.shrinkwrap.resolver.api.maven.ConfigurableMavenResolverSystem;
 import org.jboss.shrinkwrap.resolver.api.maven.Maven;
 import org.jboss.shrinkwrap.resolver.api.maven.MavenResolvedArtifact;
@@ -71,6 +76,9 @@ public final class ArquillianPackager {
      */
     private static final boolean DEBUG_ENABLED = false;
 
+    private static final String LIB_FOLDER = "/BOOT-INF/lib";
+    private static final String CLASSES_FOLDER = "BOOT-INF/classes";
+
     private ArquillianPackager() {
     }
 
@@ -85,18 +93,22 @@ public final class ArquillianPackager {
 
         JavaArchive ark = domain.getArchiveFactory().create(JavaArchive.class, 
"test.jar");
 
+
         ark = ark.addAsManifestResource("BOOT-MANIFEST.MF", "MANIFEST.MF");
 
+        ark = ark.addAsDirectories(LIB_FOLDER);
+        if (!CLASSES_FOLDER.equals("")) {
+            ark = ark.addAsDirectories(CLASSES_FOLDER);
+        }
+
         if (config.getUseCustomLog()) {
-            ark = ark.addAsResource("spring-logback.xml");
+            ark = ark.addAsResource("spring-logback.xml", CLASSES_FOLDER + 
"/spring-logback.xml");
         }
 
         for (Map.Entry<String, String> res : config.getResources().entrySet()) 
{
-            ark = ark.addAsResource(res.getKey(), res.getValue());
+            ark = ark.addAsResource(res.getKey(), CLASSES_FOLDER + "/" + 
res.getValue());
         }
 
-        ark = ark.addAsDirectories("/lib");
-
         String version = 
System.getProperty("version_org.apache.camel:camel-core");
         if (version == null) {
             config.getMavenVersion();
@@ -223,12 +235,17 @@ public final class ArquillianPackager {
         ark = addDependencies(ark, dependencies);
 
         // Add common packages to main jar
-        ark = ark.addPackages(true, "org.apache.camel.itest.springboot");
-        ark = ark.addPackages(true, "org.springframework.boot.loader");
         ark = ark.addPackages(true, "org.jboss.shrinkwrap");
 
-        ark = ark.addPackages(true, "org.apache.camel.converter.myconverter"); 
// to overcome CAMEL-10060
-        ark = ark.addPackages(true, "org.apache.camel.osgi.test"); // to 
overcome CAMEL-10060
+        // Add current classes to both location to be used by different 
classloaders
+        ark = ark.addPackages(true, "org.apache.camel.itest.springboot");
+        ark = addSpringbootPackage(ark, "org.apache.camel.itest.springboot");
+
+        // CAMEL-10060 is resolved since 2.18 but probably the package scanner 
should be adapted to Spring-boot 1.4.0.RELEASE new packaging structure
+//        ark = addSpringbootPackage(ark, 
"org.apache.camel.converter.myconverter"); // to overcome CAMEL-10060
+//        ark = addSpringbootPackage(ark, "org.apache.camel.osgi.test"); // to 
overcome CAMEL-10060
+
+        ark = ark.addPackages(true, "org.springframework.boot.loader");
 
         ClassPath.Builder external = ClassPath.builder().add(ark);
 
@@ -343,7 +360,7 @@ public final class ArquillianPackager {
         Set<File> dependencySet = new HashSet<>(deps);
         for (File d : dependencySet) {
             debug("Adding spring-boot dependency: " + d.getName());
-            ark = ark.add(new FileAsset(d), "/lib/" + d.getName());
+            ark = ark.add(new FileAsset(d), LIB_FOLDER + "/" + d.getName());
         }
 
         return ark;
@@ -362,10 +379,10 @@ public final class ArquillianPackager {
             String relative = 
test.getCanonicalFile().toURI().relativize(f.getCanonicalFile().toURI()).getPath();
             if (f.isFile()) {
                 if (f.getName().endsWith(".class")) {
-                    mainArk = mainArk.addAsResource(f, relative);
+                    mainArk = mainArk.addAsResource(f, CLASSES_FOLDER + "/" + 
relative);
                 }
             } else {
-                mainArk = mainArk.addAsDirectory(relative);
+                mainArk = mainArk.addAsDirectory(CLASSES_FOLDER + "/" + 
relative);
                 File[] files = f.listFiles();
                 if (files == null) {
                     files = new File[]{};
@@ -377,33 +394,32 @@ public final class ArquillianPackager {
         return mainArk;
     }
 
-    private static GenericArchive addSources(GenericArchive ark, ITestConfig 
config) throws IOException {
-        File sources = new File(config.getModuleBasePath() + "/src/");
-        ark.addAsDirectory("src");
+    private static JavaArchive addSpringbootPackage(JavaArchive ark, String... 
packageNames) throws Exception {
 
-        File[] fs = sources.listFiles();
-        if (fs == null) {
-            fs = new File[]{};
-        }
-        LinkedList<File> sourceFiles = new LinkedList<>(Arrays.asList(fs));
-        while (!sourceFiles.isEmpty()) {
-            File f = sourceFiles.pop();
-            String relative = 
sources.getParentFile().getCanonicalFile().toURI().relativize(f.getCanonicalFile().toURI()).getPath();
-            if (f.isFile()) {
-                ark.add(new FileAsset(f), relative);
-            } else {
-                ark = ark.addAsDirectory(relative);
-                File[] files = f.listFiles();
-                if (files == null) {
-                    files = new File[]{};
-                }
-                sourceFiles.addAll(Arrays.asList(files));
+        Iterable<ClassLoader> classLoaders = 
Collections.singleton(Thread.currentThread().getContextClassLoader());
+
+        for (String packageName : packageNames) {
+            for (final ClassLoader classLoader : classLoaders) {
+
+                final URLPackageScanner.Callback callback = new 
URLPackageScanner.Callback() {
+                    @Override
+                    public void classFound(String className) {
+                        ArchivePath classNamePath = 
AssetUtil.getFullPathForClassResource(className);
+
+                        Asset asset = new 
ClassLoaderAsset(classNamePath.get().substring(1), classLoader);
+                        ArchivePath location = new BasicPath(CLASSES_FOLDER + 
"/", classNamePath);
+                        ark.add(asset, location);
+                    }
+                };
+                final URLPackageScanner scanner = 
URLPackageScanner.newInstance(true, classLoader, callback, packageName);
+                scanner.scanPackage();
             }
         }
 
         return ark;
     }
 
+
     private static void debug(String str) {
         if (DEBUG_ENABLED) {
             System.out.println("DEBUG>>> " + str);

Reply via email to