Possibility to provide classpath dir. Updated help and documentation.
[javainspect.git] / src / main / java / eu / svjatoslav / inspector / java / commandline / Main.java
index 8fcf5f6..0c63a55 100644 (file)
@@ -1,6 +1,5 @@
 package eu.svjatoslav.inspector.java.commandline;
 
-import eu.svjatoslav.inspector.java.commandline.CommandlineConfiguration;
 import eu.svjatoslav.inspector.java.structure.ClassGraph;
 
 import java.io.File;
@@ -14,18 +13,19 @@ import java.util.List;
 import java.util.jar.JarEntry;
 import java.util.jar.JarInputStream;
 
-import static java.io.File.separator;
-import static java.lang.System.getProperty;
-
 /**
  * This class acts as a commandline interface for JavaInspect.
  */
 public class Main {
     public static void main(String[] args) throws IOException, ClassNotFoundException {
         CommandlineConfiguration configuration = new CommandlineConfiguration(args);
-        if (!configuration.configurationOk)
+        if (!configuration.configurationOk) {
+            configuration.parser.showHelp();
             System.exit(1);
-            
+        }
+
+        if (configuration.showHelp.isSpecified()) configuration.parser.showHelp();
+
         getClassGraph(configuration).generateGraph(configuration.graphName.getValue());
 
         if (configuration.isDebug())
@@ -36,21 +36,29 @@ public class Main {
         List<File> jarFiles = configuration.jarFiles.getValue();
 
         URLClassLoader classLoader = new URLClassLoader(
-                getFileUrls(jarFiles),
+                getClasspathUrls(jarFiles, configuration.classPaths.getValue()),
                 configuration.getClass().getClassLoader());
 
         ClassGraph classGraph = new ClassGraph();
 
-        classGraph.setTargetDirectory(getTargetDirectory(configuration));
+        if (configuration.targetDirectory.isSpecified())
+            classGraph.setTargetDirectory(configuration.targetDirectory.getValue());
 
         if (configuration.targetImageType.isSpecified())
             classGraph.setTargetImageType(configuration.targetImageType.getValue());
 
         classGraph.setKeepDotFile(configuration.keepDotFile.getValue());
 
-        for (File jarFile : jarFiles)
-            addJarToGraph(jarFile, classLoader, classGraph, configuration);
+        if (configuration.rootClasses.isSpecified()) {
+            // add only selected root classes
+            for (String rootClass : configuration.rootClasses.getValue())
+                attemptClassAdditionByName(classLoader, classGraph, configuration, rootClass);
 
+        } else {
+            // add all classes in the jar files to graph
+            for (File jarFile : jarFiles)
+                addJarToGraph(jarFile, classLoader, classGraph, configuration);
+        }
         configuration.blacklistGlob.getValue().forEach(classGraph::blacklistClassGlob);
         configuration.whitelistGlob.getValue().forEach(classGraph::whitelistClassGlob);
 
@@ -60,16 +68,17 @@ public class Main {
         return classGraph;
     }
 
-    private static File getTargetDirectory(CommandlineConfiguration configuration) {
-        if (configuration.targetDirectory.isSpecified())
-            return configuration.targetDirectory.getValue();
+    private static URL[] getClasspathUrls(List<File> jarFiles, List<File> classpathDirectories) {
+        List<URL> urls = new ArrayList<>();
 
-        // default to current directory
-        return new File(getProperty("user.dir") + separator);
-    }
+        classpathDirectories.forEach(classpathDirectory -> {
+            try {
+                urls.add(classpathDirectory.toURI().toURL());
+            } catch (MalformedURLException e) {
+                throw new RuntimeException(e);
+            }
+        });
 
-    private static URL[] getFileUrls(List<File> jarFiles) {
-        List<URL> urls = new ArrayList<>();
         jarFiles.forEach((File file) -> {
             try {
                 urls.add(file.toURI().toURL());
@@ -85,11 +94,20 @@ public class Main {
             File jarFile, URLClassLoader classLoader, ClassGraph classGraph, CommandlineConfiguration configuration)
             throws IOException, ClassNotFoundException {
 
-        for (String className : getClassNamesFromJar(jarFile)) {
-            if (configuration.isDebug())
-                System.out.println("Adding class to graph: " + className);
+        for (String className : getClassNamesFromJar(jarFile))
+            attemptClassAdditionByName(classLoader, classGraph, configuration, className);
+    }
 
+    private static void attemptClassAdditionByName(URLClassLoader classLoader, ClassGraph classGraph, CommandlineConfiguration configuration, String className) throws ClassNotFoundException {
+        if (configuration.isDebug())
+            System.out.println("Adding class to graph: " + className);
+        try {
             classGraph.add(loadClassByName(classLoader, className));
+        } catch (NoClassDefFoundError e) {
+            if (configuration.isDebug())
+                System.out.println("Class definition was not found.");
+            // Sometimes referenced classes are not found in the same Jar.
+            // Let's ignore this and proceed with the classes that we have.
         }
     }