diff --git a/scala/BUILD b/scala/BUILD index 2f0b40bfe..932573fa2 100644 --- a/scala/BUILD +++ b/scala/BUILD @@ -27,6 +27,11 @@ scala_toolchain( name = "minimal_direct_source_deps_impl", dependency_mode = "plus-one", dependency_tracking_method = "ast", + # Exclude the shadowing test package from strict-deps to allow classpath-order coverage without disabling strict-deps globally in CI runs. + dependency_tracking_strict_deps_patterns = [ + "", # keep default include + "-//test/src/main/scala/scalarules/test/java_classpath_order", + ], strict_deps_mode = "error", unused_dependency_checker_mode = "error", ) diff --git a/scala/private/phases/phase_compile.bzl b/scala/private/phases/phase_compile.bzl index 185f7219d..4159a7b07 100644 --- a/scala/private/phases/phase_compile.bzl +++ b/scala/private/phases/phase_compile.bzl @@ -251,10 +251,10 @@ def _compile_or_empty( full_jars = [ctx.outputs.jar] if java_jar: - full_jars.append(java_jar.jar) + full_jars.insert(0, java_jar.jar) if java_jar: - merged_provider = java_common.merge([scala_compilation_provider, java_jar.java_compilation_provider]) + merged_provider = java_common.merge([java_jar.java_compilation_provider, scala_compilation_provider]) else: merged_provider = scala_compilation_provider diff --git a/test/src/main/scala/scalarules/test/java_classpath_order/BUILD b/test/src/main/scala/scalarules/test/java_classpath_order/BUILD new file mode 100644 index 000000000..3252caffe --- /dev/null +++ b/test/src/main/scala/scalarules/test/java_classpath_order/BUILD @@ -0,0 +1,27 @@ +load("//scala:scala.bzl", "scala_library", "scala_test") + +# Original library with the class to be shadowed +scala_library( + name = "original", + srcs = ["Original.scala"], +) + +# Library that shadows the Overridable class with a Java file +# The Java file (Overridable.java) should take precedence over +# the Overridable class from the :original dependency +scala_library( + name = "with_java_override", + srcs = ["Overridable.java"], + deps = [":original"], +) + +# Test that verifies the Java override works correctly +# Note: This test is incompatible with strict deps checking because the checker +# doesn't understand class shadowing - it sees Overridable as coming from :original +# rather than the shadowed version from :with_java_override +scala_test( + name = "verify_override_test", + srcs = ["VerifyOverride.scala"], + unused_dependency_checker_mode = "off", + deps = [":with_java_override"], +) diff --git a/test/src/main/scala/scalarules/test/java_classpath_order/Original.scala b/test/src/main/scala/scalarules/test/java_classpath_order/Original.scala new file mode 100644 index 000000000..e29c13ab0 --- /dev/null +++ b/test/src/main/scala/scalarules/test/java_classpath_order/Original.scala @@ -0,0 +1,6 @@ +package scalarules.test.java_classpath_order + +class Overridable { + def getValue(): String = "original" +} + diff --git a/test/src/main/scala/scalarules/test/java_classpath_order/Overridable.java b/test/src/main/scala/scalarules/test/java_classpath_order/Overridable.java new file mode 100644 index 000000000..007b9bed0 --- /dev/null +++ b/test/src/main/scala/scalarules/test/java_classpath_order/Overridable.java @@ -0,0 +1,8 @@ +package scalarules.test.java_classpath_order; + +public class Overridable { + public String getValue() { + return "overridden"; + } +} + diff --git a/test/src/main/scala/scalarules/test/java_classpath_order/VerifyOverride.scala b/test/src/main/scala/scalarules/test/java_classpath_order/VerifyOverride.scala new file mode 100644 index 000000000..2d91c3c29 --- /dev/null +++ b/test/src/main/scala/scalarules/test/java_classpath_order/VerifyOverride.scala @@ -0,0 +1,25 @@ +package scalarules.test.java_classpath_order + +import org.scalatest.flatspec.AnyFlatSpec +import org.scalatest.matchers.should.Matchers + +/** + * This test verifies that the Java class (Overridable) shadows + * the Scala class from the dependency. + * + * The expected behavior is: + * - The Java file compiled in the scala_library with_java_override should + * appear first on the classpath + * - When instantiating Overridable, we should get the Java version + * which returns "overridden" + */ +class VerifyOverrideTest extends AnyFlatSpec with Matchers { + + "Java class in scala_library" should "shadow the dependency's class" in { + val instance = new Overridable() + val value = instance.getValue() + + value shouldBe "overridden" + } +} +