-
1. Re: Add all classes in src/main/java
bmajsak Oct 8, 2013 12:09 PM (in response to pmm)1 of 1 people found this helpfulActually it is quite a tricky question
DISCLAIMER: This solution depends on both build system and ClassLoader implementation used, but might work for you
public static Collection<Class<?>> fetchAllClassesMatching(String classLocation) { final List<Class<?>> classes = new ArrayList<Class<?>>(); try { final ClassPath classPath = ClassPath.from(Thread.currentThread().getContextClassLoader()); for (ClassPath.ClassInfo classInfo : classPath.getTopLevelClasses()) { try { final Class<?> cls = classInfo.load(); final CodeSource codeSource = cls.getProtectionDomain().getCodeSource(); if (codeSource == null) { continue; } final String location = codeSource.getLocation().getPath(); if (location != null && location.contains(classLocation) && !location.startsWith("file:") /*we omit jars*/) { classes.add(cls); } } catch (java.lang.NoClassDefFoundError e) { // Log it somehow. this might occur on runtime, as we try to aggressively load all classes from all classloaders available. } } } catch (IOException e) { throw new RuntimeException("Failed loading classes.", e); } return classes; }
In case of using Maven all classes from src/main/java end up in /classes/ folder so this you can use as classLocation. This code will include all "main" classes from your classpath when Maven is used. From the command line this will be narrowed to the given maven module, but if you have multi-module maven project imported in the IDE (in my case IDEA) this will basically fetch "main" classes from all the modules imported.
Possible improvement here might be to use package prefix to narrow down import. This is as simple as adding additional parameter to this method and replacing
classPath.getTopLevelClasses();
with
classPath.getTopLevelClassesRecursive(packageName);
I'm using Google Guava here for loading classes (but by all means highly recommended library for a lot of tasks)
<dependency> <groupId>com.google.guava</groupId> <artifactId>guava</artifactId> <version>14.0.1</version> <scope>test</scope> </dependency>
This is the best I could come up with.
On the other hand most of the times classes under src/test/java are either tests (so can be filtered out by some sort of class name prefix or suffix) or are utilities/test doubles which can be packaged into something having .test. in the package name (so again can be filtered out using ShrinkWrap filter).
Small example on how to use Shrinkwrap filters:
addPackages(true, Filters.exclude(“.*Test.*“), ….)
-
2. Re: Add all classes in src/main/java
pmm Oct 9, 2013 5:28 AM (in response to bmajsak)Bartosz Majsak wrote:
Actually it is quite a tricky question
:-)
Bartosz Majsak wrote:
…
In case of using Maven all classes from src/main/java end up in /classes/ folder so this you can use as classLocation.
…
Wouldn't it be simpler to just add this? I have one file in src/main/resources and need that as well. Something like
.addAsDirectory("target/classes")
-