@@ -266,6 +266,113 @@ def _transitive_from_exports_test(name):
266
266
def _transitive_from_associates_test (name ):
267
267
_abi_test (name , _transitive_from_associates_test_impl )
268
268
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
+
269
376
def jvm_deps_test_suite (name ):
270
377
test_suite (
271
378
name ,
@@ -274,5 +381,6 @@ def jvm_deps_test_suite(name):
274
381
_fat_abi_test ,
275
382
_transitive_from_exports_test ,
276
383
_transitive_from_associates_test ,
384
+ _dep_infos_ordering_test ,
277
385
],
278
386
)
0 commit comments