Skip to content

Commit 2b14b77

Browse files
committed
Fix javac plugin compilation under JDK 17+
JavaToolchainPlugin (now removed) used to mask three JDK-17+ issues in the javacPlugin project by pinning its compile JDK to 11, stripping flags from the doc task, and forcing --release 11 on all Java code. With the plugin gone, all three surface: 1. JDK 14 added Plugin.autoStart(), so JDK 17/21 javac eagerly enumerates ServiceLoader<Plugin> providers from the processor path (or, if absent, the compile classpath). During incremental compilation our own META-INF/services/com.sun.source.util.Plugin descriptor sits on the classpath but SemanticdbPlugin.class isn't built yet, so ServiceLoader throws 'Provider com.sourcegraph.semanticdb_javac.SemanticdbPlugin not found'. Fix: pass an explicit empty -processorpath to javac so it doesn't scan our own output directory for Plugin providers. The descriptor stays in src/main/resources/ so that internal sbt consumers (e.g. the 'minimized' test project that depends on javacPlugin via dependsOn) and the Bazel build can still find it. 2. javadoc rejects the '-g' flag that was previously added via 'javacOptions += "-g"'. The old plugin worked around this with '(doc / javacOptions) --= List("-g")'. Fix: scope '-g' to 'Compile / javacOptions' so it never reaches the doc task. 3. sbt-assembly's shader ships an older ASM that cannot read class major version 61 (JDK 17). When sbt runs under JDK 17/21 the fat jar ends up with SemanticdbVisitor (and other classes that hit protobuf types) silently un-shaded, so at runtime javac fails with 'NoClassDefFoundError: com/google/protobuf/ProtocolMessageEnum'. Fix: add 'Compile / javacOptions ++= Seq("--release", "11")' to javaOnlySettings so Java code always emits class version 55, which the shader handles, regardless of which JDK runs sbt.
1 parent ab315b6 commit 2b14b77

1 file changed

Lines changed: 20 additions & 2 deletions

File tree

build.sbt

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,20 @@ lazy val javacPlugin = project
124124
fatjarPackageSettings,
125125
javaOnlySettings,
126126
moduleName := "semanticdb-javac",
127-
javacOptions += "-g",
127+
Compile / javacOptions += "-g",
128+
// JDK 14+ javac eagerly enumerates Plugin providers from the processor
129+
// path (or, if absent, the compile classpath). During incremental
130+
// compilation our own META-INF/services/com.sun.source.util.Plugin
131+
// resource is on the classpath but SemanticdbPlugin.class isn't built
132+
// yet, which trips ServiceLoader. Force an explicit empty processor
133+
// path so javac doesn't scan our own output directory. The resource
134+
// must stay in src/main/resources/ so that internal sbt dependents
135+
// (e.g. the `minimized` test project) can find the plugin descriptor.
136+
Compile / javacOptions ++= {
137+
val empty = target.value / "empty-processorpath"
138+
IO.createDirectory(empty)
139+
Seq("-processorpath", empty.getAbsolutePath)
140+
},
128141
(assembly / assemblyShadeRules) :=
129142
Seq(
130143
ShadeRule
@@ -635,7 +648,12 @@ lazy val javaOnlySettings = List[Def.Setting[_]](
635648
incOptions ~= { old =>
636649
old.withEnabled(false).withApiDebug(true)
637650
},
638-
crossPaths := false
651+
crossPaths := false,
652+
// Java 11 is our minimum supported runtime and sbt-assembly's shader uses
653+
// an ASM version that can't read newer class files (e.g. class major 61
654+
// emitted by JDK 17). Pinning the release target keeps the bytecode at
655+
// version 55 regardless of which JDK runs sbt, so shading still works.
656+
Compile / javacOptions ++= Seq("--release", "11")
639657
)
640658

641659
val testSettings = List(

0 commit comments

Comments
 (0)