Skip to content

Commit d3522ca

Browse files
authored
Restore user dependency precedence over stdlib in classpath (#1369)
User dependencies should take precedence over the Kotlin stdlib to prevent stdlib classes from shadowing explicit user dependencies. This restores the ordering behavior from 2.1.7 while preserving the associates feature added in 2.1.8. Fixes #1368
1 parent b00b680 commit d3522ca

File tree

2 files changed

+111
-3
lines changed

2 files changed

+111
-3
lines changed

kotlin/internal/jvm/jvm_deps.bzl

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,10 +29,10 @@ def _jvm_deps(ctx, toolchains, associate_deps, deps = [], deps_java_infos = [],
2929
associates = associate_deps,
3030
)
3131
dep_infos = (
32-
[toolchains.kt.jvm_stdlibs] +
33-
associates.dep_infos +
3432
deps_java_infos +
35-
[_java_info(d) for d in deps]
33+
[_java_info(d) for d in deps] +
34+
associates.dep_infos +
35+
[toolchains.kt.jvm_stdlibs]
3636
)
3737

3838
# Reduced classpath, exclude transitive deps from compilation

src/test/starlark/internal/jvm/jvm_deps_tests.bzl

Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -266,6 +266,113 @@ def _transitive_from_exports_test(name):
266266
def _transitive_from_associates_test(name):
267267
_abi_test(name, _transitive_from_associates_test_impl)
268268

269+
def _dep_infos_ordering_test_impl(env, target):
270+
"""Test that user deps take precedence over stdlib in dep_infos ordering.
271+
272+
This is a regression test for https://github.com/bazelbuild/rules_kotlin/issues/1368
273+
where the stdlib was placed first in the classpath, causing it to shadow user
274+
dependencies with conflicting classes (e.g., org.jetbrains.annotations.NotNull).
275+
"""
276+
user_dep_java_info = JavaInfo(
277+
compile_jar = _file(env.ctx.attr.user_dep_jar),
278+
output_jar = _file(env.ctx.attr.user_dep_jar),
279+
)
280+
281+
associate_java_info = JavaInfo(
282+
compile_jar = _file(env.ctx.attr.associate_jar),
283+
output_jar = _file(env.ctx.attr.associate_jar),
284+
)
285+
286+
stdlib_java_info = JavaInfo(
287+
compile_jar = _file(env.ctx.attr.jvm_jar),
288+
output_jar = _file(env.ctx.attr.jvm_jar),
289+
)
290+
291+
associate_deps = [
292+
{
293+
JavaInfo: associate_java_info,
294+
_KtJvmInfo: _KtJvmInfo(
295+
module_name = "associate_name",
296+
),
297+
},
298+
]
299+
300+
user_deps = [
301+
{
302+
JavaInfo: user_dep_java_info,
303+
},
304+
]
305+
306+
fake_ctx = struct(
307+
label = target.label,
308+
attr = struct(
309+
module_name = "",
310+
tags = [],
311+
),
312+
)
313+
314+
toolchains = struct(
315+
kt = struct(
316+
experimental_remove_private_classes_in_abi_jars = False,
317+
experimental_prune_transitive_deps = False,
318+
experimental_strict_associate_dependencies = False,
319+
jvm_stdlibs = stdlib_java_info,
320+
),
321+
)
322+
323+
result = _jvm_deps_utils.jvm_deps(
324+
ctx = fake_ctx,
325+
toolchains = toolchains,
326+
associate_deps = associate_deps,
327+
deps = user_deps,
328+
)
329+
330+
# Assert the ordering: result.deps should be [user_deps, associates, stdlib]
331+
env.expect.that_int(len(result.deps)).equals(3)
332+
333+
# Verify compile_jars contains all deps in correct order
334+
classpath_list = result.compile_jars.to_list()
335+
user_dep_file = _file(env.ctx.attr.user_dep_jar)
336+
stdlib_file = _file(env.ctx.attr.jvm_jar)
337+
338+
# Find indices of user dep and stdlib in classpath
339+
user_dep_idx = -1
340+
stdlib_idx = -1
341+
for idx, jar in enumerate(classpath_list):
342+
if jar == user_dep_file:
343+
user_dep_idx = idx
344+
if jar == stdlib_file:
345+
stdlib_idx = idx
346+
347+
# Both should be found
348+
env.expect.that_bool(user_dep_idx >= 0).equals(True)
349+
env.expect.that_bool(stdlib_idx >= 0).equals(True)
350+
351+
# User dep should come before stdlib in the classpath
352+
env.expect.that_bool(user_dep_idx < stdlib_idx).equals(True)
353+
354+
def _dep_infos_ordering_test(name):
355+
util.helper_target(
356+
native.filegroup,
357+
name = name + "_subject",
358+
srcs = [],
359+
)
360+
analysis_test(
361+
name = name,
362+
impl = _dep_infos_ordering_test_impl,
363+
target = name + "_subject",
364+
attr_values = {
365+
"user_dep_jar": util.empty_file(name + "user_dep.jar"),
366+
"associate_jar": util.empty_file(name + "associate.jar"),
367+
"jvm_jar": util.empty_file(name + "jvm.jar"),
368+
},
369+
attrs = {
370+
"user_dep_jar": attr.label(allow_files = True),
371+
"associate_jar": attr.label(allow_files = True),
372+
"jvm_jar": attr.label(allow_files = True),
373+
},
374+
)
375+
269376
def jvm_deps_test_suite(name):
270377
test_suite(
271378
name,
@@ -274,5 +381,6 @@ def jvm_deps_test_suite(name):
274381
_fat_abi_test,
275382
_transitive_from_exports_test,
276383
_transitive_from_associates_test,
384+
_dep_infos_ordering_test,
277385
],
278386
)

0 commit comments

Comments
 (0)