Skip to content

Commit

Permalink
Fail if no jars/jmods found and add envvar config option
Browse files Browse the repository at this point in the history
  • Loading branch information
johannescoetzee committed Jul 19, 2023
1 parent e2f29b0 commit 83f6926
Show file tree
Hide file tree
Showing 4 changed files with 59 additions and 7 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -50,4 +50,22 @@ object JavaSrc2Cpg {
new JavaTypeHintCallLinker(cpg)
)
}

def showEnv(): Unit = {
val value =
JavaSrcEnvVar.values.foreach { envVar =>
val currentValue = Option(System.getenv(envVar.name)).getOrElse("<unset>")
println(s"${envVar.name}:")
println(s"- Description : ${envVar.description}")
println(s"- Current value: $currentValue")
}
}

enum JavaSrcEnvVar(val name: String, val description: String) {
case JdkPath
extends JavaSrcEnvVar(
"JAVASRC_JDK_PATH",
"Path to the JDK home used for retrieving type information about builtin Java types."
)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@ final case class Config(
delombokMode: Option[String] = None,
enableTypeRecovery: Boolean = false,
disableDummyTypes: Boolean = false,
jdkPath: Option[String] = None
jdkPath: Option[String] = None,
showEnv: Boolean = false
) extends X2CpgConfig[Config] {
def withInferenceJarPaths(paths: Set[String]): Config = {
copy(inferenceJarPaths = paths).withInheritedFields(this)
Expand Down Expand Up @@ -47,6 +48,10 @@ final case class Config(
def withJdkPath(path: String): Config = {
copy(jdkPath = Some(path)).withInheritedFields(this)
}

def withShowEnv(value: Boolean): Config = {
copy(showEnv = value).withInheritedFields(this)
}
}

private object Frontend {
Expand Down Expand Up @@ -84,14 +89,25 @@ private object Frontend {
.text("disable generation of dummy types during type recovery"),
opt[String]("jdk-path")
.action((path, c) => c.withJdkPath(path))
.text("JDK used for resolving builtin Java types. If not set, current classpath will be used")
.text("JDK used for resolving builtin Java types. If not set, current classpath will be used"),
opt[Unit]("show-env")
.action((_, c) => c.withShowEnv(true))
// This should really be a print-and-exit but, with the current scopt setup, input paths
// are still required, so for now `javasrc2cpg --show-env <inputs>` is less confusing
// than `javasrc2cpg --show-env <dummy input to keep scopt happy>`
.text("print information about environment variables used by javasrc2cpg prior to analysis")
)
}
}

object Main extends X2CpgMain(cmdLineParser, new JavaSrc2Cpg()) {

def run(config: Config, javasrc2Cpg: JavaSrc2Cpg): Unit = {
javasrc2Cpg.run(config)
if (config.showEnv) {
JavaSrc2Cpg.showEnv()
} else {
javasrc2Cpg.run(config)
}
}

def getCmdLineParser = cmdLineParser
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ import com.github.javaparser.symbolsolver.resolution.typesolvers.ClassLoaderType
import java.net.URLClassLoader
import com.github.javaparser.symbolsolver.resolution.typesolvers.ReflectionTypeSolver
import io.joern.javasrc2cpg.typesolvers.CachingReflectionTypeSolver
import io.joern.javasrc2cpg.JavaSrc2Cpg.JavaSrcEnvVar

case class SourceDirectoryInfo(typeSolverSourceDirs: List[String], sourceFiles: List[SourceFileInfo])
case class SplitDirectories(analysisSourceDir: String, typesSourceDir: String)
Expand Down Expand Up @@ -90,10 +91,24 @@ class AstCreationPass(config: Config, cpg: Cpg, preCreatedAsts: Option[SplitJpAs

val combinedTypeSolver = new SimpleCombinedTypeSolver()

val jdkPath = config.jdkPath.getOrElse {
val javaHome = System.getProperty("java.home")
logger.debug("No explicit jdkPath set in config, so using system java.home at $javaHome")
javaHome
val jdkPathFromEnvVar = Option(System.getenv(JavaSrcEnvVar.JdkPath.name))
val jdkPath = (config.jdkPath, jdkPathFromEnvVar) match {
case (None, None) =>
val javaHome = System.getProperty("java.home")
logger.info(
s"No explicit jdk-path set in config, so using system java.home for JDK type information: $javaHome"
)
javaHome

case (None, Some(jdkPath)) =>
logger.info(
s"Using JDK path from environment variable ${JavaSrcEnvVar.JdkPath.name} for JDK type information: $jdkPath"
)
jdkPath

case (Some(jdkPath), _) =>
logger.info(s"Using JDK path set with jdk-path option for JDK type information: $jdkPath")
jdkPath
}

combinedTypeSolver.add(JdkJarTypeSolver.fromJdkPath(jdkPath))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,9 @@ object JdkJarTypeSolver {

def fromJdkPath(jdkPath: String): JdkJarTypeSolver = {
val jarPaths = SourceFiles.determine(jdkPath, Set(JarExtension, JmodExtension))
if (jarPaths.isEmpty) {
throw new IllegalArgumentException(s"No .jar or .jmod files found at JDK path ${jdkPath}")
}
new JdkJarTypeSolver(jdkPath).withJars(jarPaths)
}

Expand Down

0 comments on commit 83f6926

Please sign in to comment.