• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

pantsbuild / pants / 20147226056

11 Dec 2025 08:58PM UTC coverage: 78.827% (-1.5%) from 80.293%
20147226056

push

github

web-flow
Forwarded the `style` and `complete-platform` args from pants.toml to PEX (#22910)

## Context

After Apple switched to the `arm64` architecture, some package
publishers stopped releasing `x86_64` variants of their packages for
`darwin`. As a result, generating a universal lockfile now fails because
no single package version is compatible with both `x86_64` and `arm64`
on `darwin`.

The solution is to use the `--style` and `--complete-platform` flags
with PEX. For example:
```
pex3 lock create \
    --style strict \
    --complete-platform 3rdparty/platforms/manylinux_2_28_aarch64.json \
    --complete-platform 3rdparty/platforms/macosx_26_0_arm64.json \
    -r 3rdparty/python/requirements_pyarrow.txt \
    -o python-pyarrow.lock
```

See the Slack discussion here:
https://pantsbuild.slack.com/archives/C046T6T9U/p1760098582461759

## Reproduction

* `BUILD`
```
python_requirement(
    name="awswrangler",
    requirements=["awswrangler==3.12.1"],
    resolve="awswrangler",
)
```
* Run `pants generate-lockfiles --resolve=awswrangler` on macOS with an
`arm64` CPU
```
pip: ERROR: Cannot install awswrangler==3.12.1 because these package versions have conflicting dependencies.
pip: ERROR: ResolutionImpossible: for help visit https://pip.pypa.io/en/latest/topics/dependency-resolution/#dealing-with-dependency-conflicts
pip:  
pip:  The conflict is caused by:
pip:      awswrangler 3.12.1 depends on pyarrow<18.0.0 and >=8.0.0; sys_platform == "darwin" and platform_machine == "x86_64"
pip:      awswrangler 3.12.1 depends on pyarrow<21.0.0 and >=18.0.0; sys_platform != "darwin" or platform_machine != "x86_64"
pip:  
pip:  Additionally, some packages in these conflicts have no matching distributions available for your environment:
pip:      pyarrow
pip:  
pip:  To fix this you could try to:
pip:  1. loosen the range of package versions you've specified
pip:  2. remove package versions to allow pip to attempt to solve the dependency conflict
```

## Implementation
... (continued)

77 of 100 new or added lines in 6 files covered. (77.0%)

868 existing lines in 42 files now uncovered.

74471 of 94474 relevant lines covered (78.83%)

3.18 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

99.27
/src/python/pants/backend/java/compile/javac_test.py
1
# Copyright 2021 Pants project contributors (see CONTRIBUTORS.md).
2
# Licensed under the Apache License, Version 2.0 (see LICENSE).
3

4
from __future__ import annotations
1✔
5

6
from textwrap import dedent
1✔
7

8
import pytest
1✔
9

10
from internal_plugins.test_lockfile_fixtures.lockfile_fixture import (
1✔
11
    JVMLockfileFixture,
12
    JVMLockfileFixtureDefinition,
13
)
14
from pants.backend.java.compile.javac import CompileJavaSourceRequest
1✔
15
from pants.backend.java.compile.javac import rules as javac_rules
1✔
16
from pants.backend.java.dependency_inference.rules import rules as java_dep_inf_rules
1✔
17
from pants.backend.java.goals.check import JavacCheckRequest
1✔
18
from pants.backend.java.goals.check import rules as javac_check_rules
1✔
19
from pants.backend.java.target_types import JavaSourcesGeneratorTarget
1✔
20
from pants.backend.java.target_types import rules as target_types_rules
1✔
21
from pants.build_graph.address import Address
1✔
22
from pants.core.goals.check import CheckResult, CheckResults
1✔
23
from pants.core.util_rules import config_files, source_files, system_binaries
1✔
24
from pants.engine.addresses import Addresses
1✔
25
from pants.engine.internals.scheduler import ExecutionError
1✔
26
from pants.engine.target import CoarsenedTargets, Targets
1✔
27
from pants.jvm import jdk_rules, testutil
1✔
28
from pants.jvm.compile import ClasspathEntry, CompileResult, FallibleClasspathEntry
1✔
29
from pants.jvm.goals import lockfile
1✔
30
from pants.jvm.resolve import jvm_tool
1✔
31
from pants.jvm.resolve.coursier_test_util import EMPTY_JVM_LOCKFILE
1✔
32
from pants.jvm.strip_jar import strip_jar
1✔
33
from pants.jvm.target_types import JvmArtifactTarget
1✔
34
from pants.jvm.testutil import (
1✔
35
    RenderedClasspath,
36
    expect_single_expanded_coarsened_target,
37
    make_resolve,
38
    maybe_skip_jdk_test,
39
)
40
from pants.jvm.util_rules import rules as util_rules
1✔
41
from pants.testutil.rule_runner import PYTHON_BOOTSTRAP_ENV, QueryRule, RuleRunner, logging
1✔
42

43

44
@pytest.fixture
1✔
45
def rule_runner() -> RuleRunner:
1✔
46
    rule_runner = RuleRunner(
1✔
47
        rules=[
48
            *system_binaries.rules(),
49
            *config_files.rules(),
50
            *jvm_tool.rules(),
51
            *source_files.rules(),
52
            *strip_jar.rules(),
53
            *javac_rules(),
54
            *javac_check_rules(),
55
            *util_rules(),
56
            *target_types_rules(),
57
            *lockfile.rules(),
58
            *jdk_rules.rules(),
59
            *java_dep_inf_rules(),
60
            *source_files.rules(),
61
            *testutil.rules(),
62
            QueryRule(CheckResults, (JavacCheckRequest,)),
63
            QueryRule(ClasspathEntry, (CompileJavaSourceRequest,)),
64
            QueryRule(CoarsenedTargets, (Addresses,)),
65
            QueryRule(FallibleClasspathEntry, (CompileJavaSourceRequest,)),
66
            QueryRule(RenderedClasspath, (CompileJavaSourceRequest,)),
67
        ],
68
        target_types=[JavaSourcesGeneratorTarget, JvmArtifactTarget],
69
    )
70
    rule_runner.set_options([], env_inherit=PYTHON_BOOTSTRAP_ENV)
1✔
71
    return rule_runner
1✔
72

73

74
JAVA_LIB_SOURCE = dedent(
1✔
75
    """
76
    package org.pantsbuild.example.lib;
77

78
    public class ExampleLib {
79
        public static String hello() {
80
            return "Hello!";
81
        }
82
    }
83
    """
84
)
85

86

87
JAVA_LIB_JDK17_SOURCE = dedent(
1✔
88
    """
89
    package org.pantsbuild.example.lib;
90

91
    import javax.lang.model.SourceVersion;
92

93
    public class ExampleLib {
94
        public static String hello() {
95
            return "Hello " + SourceVersion.RELEASE_17 + "!";
96
        }
97
    }
98
    """
99
)
100

101

102
JAVA_LIB_MAIN_SOURCE = dedent(
1✔
103
    """
104
    package org.pantsbuild.example;
105

106
    import org.pantsbuild.example.lib.ExampleLib;
107

108
    public class Example {
109
        public static void main(String[] args) {
110
            System.out.println(ExampleLib.hello());
111
        }
112
    }
113
    """
114
)
115

116

117
@maybe_skip_jdk_test
1✔
118
def test_compile_no_deps(rule_runner: RuleRunner) -> None:
1✔
119
    rule_runner.write_files(
1✔
120
        {
121
            "BUILD": "java_sources(name='lib')",
122
            "3rdparty/jvm/default.lock": EMPTY_JVM_LOCKFILE,
123
            "ExampleLib.java": JAVA_LIB_SOURCE,
124
        }
125
    )
126
    coarsened_target = expect_single_expanded_coarsened_target(
1✔
127
        rule_runner, Address(spec_path="", target_name="lib")
128
    )
129

130
    classpath = rule_runner.request(
1✔
131
        RenderedClasspath,
132
        [CompileJavaSourceRequest(component=coarsened_target, resolve=make_resolve(rule_runner))],
133
    )
134
    assert classpath.content == {
1✔
135
        ".ExampleLib.java.lib.javac.jar": {"org/pantsbuild/example/lib/ExampleLib.class"}
136
    }
137

138
    # Additionally validate that `check` works.
139
    check_results = rule_runner.request(
1✔
140
        CheckResults,
141
        [
142
            JavacCheckRequest(
143
                [JavacCheckRequest.field_set_type.create(coarsened_target.representative)]
144
            )
145
        ],
146
    ).results
147
    assert set(check_results) == {CheckResult(0, "", "")}
1✔
148

149

150
@maybe_skip_jdk_test
1✔
151
def test_compile_jdk_versions(rule_runner: RuleRunner) -> None:
1✔
152
    rule_runner.write_files(
1✔
153
        {
154
            "BUILD": dedent(
155
                """\
156
                java_sources(
157
                    name = 'lib',
158

159
                )
160
                """
161
            ),
162
            "3rdparty/jvm/default.lock": EMPTY_JVM_LOCKFILE,
163
            "ExampleLib.java": JAVA_LIB_SOURCE,
164
        }
165
    )
166

167
    request = CompileJavaSourceRequest(
1✔
168
        component=expect_single_expanded_coarsened_target(
169
            rule_runner, Address(spec_path="", target_name="lib")
170
        ),
171
        resolve=make_resolve(rule_runner),
172
    )
173
    rule_runner.set_options(["--jvm-jdk=zulu:8.0.312"], env_inherit=PYTHON_BOOTSTRAP_ENV)
1✔
174
    classpath = rule_runner.request(RenderedClasspath, [request])
1✔
175
    assert classpath.content == {
1✔
176
        ".ExampleLib.java.lib.javac.jar": {"org/pantsbuild/example/lib/ExampleLib.class"}
177
    }
178

179
    rule_runner.set_options(["--jvm-jdk=bogusjdk:999"], env_inherit=PYTHON_BOOTSTRAP_ENV)
1✔
180
    expected_exception_msg = r".*?JVM bogusjdk:999 not found in index.*?"
1✔
181
    with pytest.raises(ExecutionError, match=expected_exception_msg):
1✔
182
        rule_runner.request(ClasspathEntry, [request])
1✔
183

184

185
@maybe_skip_jdk_test
1✔
186
def test_compile_jdk_specified_in_build_file(rule_runner: RuleRunner) -> None:
1✔
187
    rule_runner.write_files(
1✔
188
        {
189
            "BUILD": dedent(
190
                """\
191
                java_sources(
192
                    name = 'lib',
193
                    jdk = 'temurin:1.17',
194
                )
195
                """
196
            ),
197
            "3rdparty/jvm/default.lock": EMPTY_JVM_LOCKFILE,
198
            "ExampleLib.java": JAVA_LIB_JDK17_SOURCE,
199
        }
200
    )
201

202
    request = CompileJavaSourceRequest(
1✔
203
        component=expect_single_expanded_coarsened_target(
204
            rule_runner, Address(spec_path="", target_name="lib")
205
        ),
206
        resolve=make_resolve(rule_runner),
207
    )
208
    classpath = rule_runner.request(RenderedClasspath, [request])
1✔
UNCOV
209
    assert classpath.content == {
×
210
        ".ExampleLib.java.lib.javac.jar": {"org/pantsbuild/example/lib/ExampleLib.class"}
211
    }
212

213

214
@maybe_skip_jdk_test
1✔
215
def test_compile_jdk_17_file_fails_with_jdk_11(rule_runner: RuleRunner) -> None:
1✔
216
    rule_runner.write_files(
1✔
217
        {
218
            "BUILD": dedent(
219
                """\
220
                java_sources(
221
                    name = 'lib',
222
                    jdk = 'temurin:1.11.0.23',
223
                )
224
                """
225
            ),
226
            "3rdparty/jvm/default.lock": EMPTY_JVM_LOCKFILE,
227
            "ExampleLib.java": JAVA_LIB_JDK17_SOURCE,
228
        }
229
    )
230

231
    request = CompileJavaSourceRequest(
1✔
232
        component=expect_single_expanded_coarsened_target(
233
            rule_runner, Address(spec_path="", target_name="lib")
234
        ),
235
        resolve=make_resolve(rule_runner),
236
    )
237
    with pytest.raises(ExecutionError):
1✔
238
        rule_runner.request(RenderedClasspath, [request])
1✔
239

240

241
@maybe_skip_jdk_test
1✔
242
def test_compile_multiple_source_files(rule_runner: RuleRunner) -> None:
1✔
243
    rule_runner.write_files(
1✔
244
        {
245
            "BUILD": dedent(
246
                """\
247
                java_sources(
248
                    name = 'lib',
249

250
                )
251
                """
252
            ),
253
            "3rdparty/jvm/default.lock": EMPTY_JVM_LOCKFILE,
254
            "ExampleLib.java": JAVA_LIB_SOURCE,
255
            "OtherLib.java": dedent(
256
                """\
257
                package org.pantsbuild.example.lib;
258

259
                public class OtherLib {
260
                    public static String hello() {
261
                        return "Hello!";
262
                    }
263
                }
264
                """
265
            ),
266
        }
267
    )
268

269
    expanded_targets = rule_runner.request(
1✔
270
        Targets, [Addresses([Address(spec_path="", target_name="lib")])]
271
    )
272
    assert sorted(t.address.spec for t in expanded_targets) == [
1✔
273
        "//ExampleLib.java:lib",
274
        "//OtherLib.java:lib",
275
    ]
276

277
    coarsened_targets = rule_runner.request(
1✔
278
        CoarsenedTargets, [Addresses([t.address for t in expanded_targets])]
279
    )
280
    assert len(coarsened_targets) == 2
1✔
281
    assert all(len(ctgt.members) == 1 for ctgt in coarsened_targets)
1✔
282

283
    coarsened_targets_sorted = sorted(
1✔
284
        coarsened_targets, key=lambda ctgt: str(list(ctgt.members)[0].address)
285
    )
286

287
    request0 = CompileJavaSourceRequest(
1✔
288
        component=coarsened_targets_sorted[0], resolve=make_resolve(rule_runner)
289
    )
290
    classpath0 = rule_runner.request(RenderedClasspath, [request0])
1✔
291
    assert classpath0.content == {
1✔
292
        ".ExampleLib.java.lib.javac.jar": {
293
            "org/pantsbuild/example/lib/ExampleLib.class",
294
        }
295
    }
296

297
    request1 = CompileJavaSourceRequest(
1✔
298
        component=coarsened_targets_sorted[1], resolve=make_resolve(rule_runner)
299
    )
300
    classpath1 = rule_runner.request(RenderedClasspath, [request1])
1✔
301
    assert classpath1.content == {
1✔
302
        ".OtherLib.java.lib.javac.jar": {
303
            "org/pantsbuild/example/lib/OtherLib.class",
304
        }
305
    }
306

307

308
@maybe_skip_jdk_test
1✔
309
def test_compile_with_cycle(rule_runner: RuleRunner) -> None:
1✔
310
    """Test that javac can handle source-level cycles--even across build target boundaries--via
311
    graph coarsening.
312

313
    This test has to set up a contrived dependency since build-target cycles are forbidden by the graph.  However,
314
    file-target cycles are not forbidden, so we configure the graph like so:
315

316
    a:a has a single source file, which has file-target address a/A.java, and which inherits a:a's
317
    explicit dependency on b/B.java.
318
    b:b depends directly on a:a, and its source b/B.java inherits that dependency.
319

320
    Therefore, after target expansion via resolve_targets(**implicitly(Addresses(...))), we get the cycle of:
321

322
        a/A.java -> b/B.java -> a/A.java
323
    """
324

325
    rule_runner.write_files(
1✔
326
        {
327
            "BUILD": dedent(
328
                """\
329
                """
330
            ),
331
            "3rdparty/jvm/default.lock": EMPTY_JVM_LOCKFILE,
332
            "a/BUILD": dedent(
333
                """\
334
                java_sources(
335
                    name = 'a',
336

337
                    dependencies = [
338
                        'b/B.java',
339
                    ]
340
                )
341
                """
342
            ),
343
            "a/A.java": dedent(
344
                """\
345
                package org.pantsbuild.a;
346
                import org.pantsbuild.b.B;
347
                public interface A {}
348
                class C implements B {}
349
                """
350
            ),
351
            "b/BUILD": dedent(
352
                """\
353
                java_sources(
354
                    name = 'b',
355

356
                    dependencies = [
357
                        'a/A.java',
358
                    ]
359
                )
360
                """
361
            ),
362
            "b/B.java": dedent(
363
                """\
364
                package org.pantsbuild.b;
365
                import org.pantsbuild.a.A;
366
                public interface B {};
367
                class C implements A {}
368
                """
369
            ),
370
        }
371
    )
372
    coarsened_target = expect_single_expanded_coarsened_target(
1✔
373
        rule_runner, Address(spec_path="a", target_name="a")
374
    )
375
    assert sorted(t.address.spec for t in coarsened_target.members) == ["a/A.java", "b/B.java"]
1✔
376

377
    request = CompileJavaSourceRequest(
1✔
378
        component=coarsened_target, resolve=make_resolve(rule_runner)
379
    )
380

381
    classpath = rule_runner.request(RenderedClasspath, [request])
1✔
382
    assert classpath.content == {
1✔
383
        "a.A.java.javac.jar": {
384
            "org/pantsbuild/a/A.class",
385
            "org/pantsbuild/a/C.class",
386
            "org/pantsbuild/b/B.class",
387
            "org/pantsbuild/b/C.class",
388
        }
389
    }
390

391

392
@maybe_skip_jdk_test
1✔
393
def test_compile_with_transitive_cycle(rule_runner: RuleRunner) -> None:
1✔
394
    """Like test_compile_with_cycle, but the cycle occurs as a transitive dep of the requested
395
    target."""
396

397
    rule_runner.write_files(
1✔
398
        {
399
            "BUILD": dedent(
400
                """\
401
                java_sources(
402
                    name = 'main',
403

404
                    dependencies = [
405
                        'a:a',
406
                    ]
407
                )
408
                """
409
            ),
410
            "Main.java": dedent(
411
                """\
412
                package org.pantsbuild.main;
413
                import org.pantsbuild.a.A;
414
                public class Main implements A {}
415
                """
416
            ),
417
            "3rdparty/jvm/default.lock": EMPTY_JVM_LOCKFILE,
418
            "a/BUILD": dedent(
419
                """\
420
                java_sources(
421
                    name = 'a',
422

423
                    dependencies = [
424
                        'b/B.java',
425
                    ]
426
                )
427
                """
428
            ),
429
            "a/A.java": dedent(
430
                """\
431
                package org.pantsbuild.a;
432
                import org.pantsbuild.b.B;
433
                public interface A {}
434
                class C implements B {}
435
                """
436
            ),
437
            "b/BUILD": dedent(
438
                """\
439
                java_sources(
440
                    name = 'b',
441

442
                    dependencies = [
443
                        'a:a',
444
                    ]
445
                )
446
                """
447
            ),
448
            "b/B.java": dedent(
449
                """\
450
                package org.pantsbuild.b;
451
                import org.pantsbuild.a.A;
452
                public interface B {};
453
                class C implements A {}
454
                """
455
            ),
456
        }
457
    )
458

459
    classpath = rule_runner.request(
1✔
460
        RenderedClasspath,
461
        [
462
            CompileJavaSourceRequest(
463
                component=expect_single_expanded_coarsened_target(
464
                    rule_runner, Address(spec_path="", target_name="main")
465
                ),
466
                resolve=make_resolve(rule_runner),
467
            )
468
        ],
469
    )
470
    assert classpath.content == {".Main.java.main.javac.jar": {"org/pantsbuild/main/Main.class"}}
1✔
471

472

473
@logging
1✔
474
@maybe_skip_jdk_test
1✔
475
def test_compile_with_transitive_multiple_sources(rule_runner: RuleRunner) -> None:
1✔
476
    """Like test_compile_with_transitive_cycle, but the cycle occurs via subtarget source expansion
477
    rather than explicitly."""
478

479
    rule_runner.write_files(
1✔
480
        {
481
            "BUILD": dedent(
482
                """\
483
                java_sources(
484
                    name = 'main',
485

486
                    dependencies = [
487
                        'lib:lib',
488
                    ]
489
                )
490
                """
491
            ),
492
            "Main.java": dedent(
493
                """\
494
                package org.pantsbuild.main;
495
                import org.pantsbuild.a.A;
496
                import org.pantsbuild.b.B;
497
                public class Main implements A {}
498
                class Other implements B {}
499
                """
500
            ),
501
            "3rdparty/jvm/default.lock": EMPTY_JVM_LOCKFILE,
502
            "lib/BUILD": dedent(
503
                """\
504
                java_sources(
505
                    name = 'lib',
506

507
                )
508
                """
509
            ),
510
            "lib/A.java": dedent(
511
                """\
512
                package org.pantsbuild.a;
513
                import org.pantsbuild.b.B;
514
                public interface A {}
515
                class C implements B {}
516
                """
517
            ),
518
            "lib/B.java": dedent(
519
                """\
520
                package org.pantsbuild.b;
521
                import org.pantsbuild.a.A;
522
                public interface B {};
523
                class C implements A {}
524
                """
525
            ),
526
        }
527
    )
528

529
    ctgt = expect_single_expanded_coarsened_target(
1✔
530
        rule_runner, Address(spec_path="", target_name="main")
531
    )
532

533
    classpath = rule_runner.request(
1✔
534
        RenderedClasspath,
535
        [CompileJavaSourceRequest(component=ctgt, resolve=make_resolve(rule_runner))],
536
    )
537
    assert classpath.content == {
1✔
538
        ".Main.java.main.javac.jar": {
539
            "org/pantsbuild/main/Main.class",
540
            "org/pantsbuild/main/Other.class",
541
        }
542
    }
543

544

545
@maybe_skip_jdk_test
1✔
546
def test_compile_with_deps(rule_runner: RuleRunner) -> None:
1✔
547
    rule_runner.write_files(
1✔
548
        {
549
            "BUILD": dedent(
550
                """\
551
                java_sources(
552
                    name = 'main',
553

554
                    dependencies = [
555
                        'lib:lib',
556
                    ]
557
                )
558
                """
559
            ),
560
            "3rdparty/jvm/default.lock": EMPTY_JVM_LOCKFILE,
561
            "Example.java": JAVA_LIB_MAIN_SOURCE,
562
            "lib/BUILD": dedent(
563
                """\
564
                java_sources(
565
                    name = 'lib',
566

567
                )
568
                """
569
            ),
570
            "lib/ExampleLib.java": JAVA_LIB_SOURCE,
571
        }
572
    )
573
    classpath = rule_runner.request(
1✔
574
        RenderedClasspath,
575
        [
576
            CompileJavaSourceRequest(
577
                component=expect_single_expanded_coarsened_target(
578
                    rule_runner, Address(spec_path="", target_name="main")
579
                ),
580
                resolve=make_resolve(rule_runner),
581
            )
582
        ],
583
    )
584
    assert classpath.content == {
1✔
585
        ".Example.java.main.javac.jar": {"org/pantsbuild/example/Example.class"}
586
    }
587

588

589
@maybe_skip_jdk_test
1✔
590
def test_compile_of_package_info(rule_runner: RuleRunner) -> None:
1✔
591
    rule_runner.write_files(
1✔
592
        {
593
            "BUILD": dedent(
594
                """\
595
                java_sources(
596
                    name = 'main',
597

598
                )
599
                """
600
            ),
601
            "3rdparty/jvm/default.lock": EMPTY_JVM_LOCKFILE,
602
            "package-info.java": dedent(
603
                """
604
                package org.pantsbuild.example;
605
                /**
606
                  * This is a package-info.java file which can have package-level annotations and
607
                  * documentation comments. It does not generate any output.
608
                  */
609
                """
610
            ),
611
        }
612
    )
613
    classpath = rule_runner.request(
1✔
614
        RenderedClasspath,
615
        [
616
            CompileJavaSourceRequest(
617
                component=expect_single_expanded_coarsened_target(
618
                    rule_runner, Address(spec_path="", target_name="main")
619
                ),
620
                resolve=make_resolve(rule_runner),
621
            )
622
        ],
623
    )
624
    assert classpath.content == {}
1✔
625

626

627
@maybe_skip_jdk_test
1✔
628
def test_compile_with_missing_dep_fails(rule_runner: RuleRunner) -> None:
1✔
629
    rule_runner.write_files(
1✔
630
        {
631
            "BUILD": dedent(
632
                """\
633
                java_sources(
634
                    name = 'main',
635

636
                )
637
                """
638
            ),
639
            "Example.java": JAVA_LIB_MAIN_SOURCE,
640
            "3rdparty/jvm/default.lock": EMPTY_JVM_LOCKFILE,
641
        }
642
    )
643
    request = CompileJavaSourceRequest(
1✔
644
        component=expect_single_expanded_coarsened_target(
645
            rule_runner, Address(spec_path="", target_name="main")
646
        ),
647
        resolve=make_resolve(rule_runner),
648
    )
649
    fallible_result = rule_runner.request(FallibleClasspathEntry, [request])
1✔
650
    assert fallible_result.result == CompileResult.FAILED and fallible_result.stderr
1✔
651
    assert "package org.pantsbuild.example.lib does not exist" in fallible_result.stderr
1✔
652

653

654
@pytest.fixture
1✔
655
def joda_lockfile_def() -> JVMLockfileFixtureDefinition:
1✔
656
    return JVMLockfileFixtureDefinition(
1✔
657
        "joda.test.lock",
658
        ["joda-time:joda-time:2.10.10"],
659
    )
660

661

662
@pytest.fixture
1✔
663
def joda_lockfile(joda_lockfile_def: JVMLockfileFixtureDefinition, request) -> JVMLockfileFixture:
1✔
664
    return joda_lockfile_def.load(request)
1✔
665

666

667
@maybe_skip_jdk_test
1✔
668
def test_compile_with_maven_deps(
1✔
669
    rule_runner: RuleRunner, joda_lockfile: JVMLockfileFixture
670
) -> None:
671
    rule_runner.write_files(
1✔
672
        {
673
            "BUILD": dedent(
674
                """\
675
                java_sources(
676
                    name = 'main',
677

678
                    dependencies = [
679
                        '3rdparty/jvm:joda-time_joda-time',
680
                    ]
681
                )
682
                """
683
            ),
684
            "3rdparty/jvm/BUILD": joda_lockfile.requirements_as_jvm_artifact_targets(),
685
            "3rdparty/jvm/default.lock": joda_lockfile.serialized_lockfile,
686
            "Example.java": dedent(
687
                """
688
                package org.pantsbuild.example;
689

690
                import org.joda.time.DateTime;
691

692
                public class Example {
693
                    public static void main(String[] args) {
694
                        DateTime dt = new DateTime();
695
                        System.out.println(dt.getYear());
696
                    }
697
                }
698
                """
699
            ),
700
        }
701
    )
702
    request = CompileJavaSourceRequest(
1✔
703
        component=expect_single_expanded_coarsened_target(
704
            rule_runner, Address(spec_path="", target_name="main")
705
        ),
706
        resolve=make_resolve(rule_runner),
707
    )
708
    classpath = rule_runner.request(RenderedClasspath, [request])
1✔
709
    assert classpath.content == {
1✔
710
        ".Example.java.main.javac.jar": {"org/pantsbuild/example/Example.class"}
711
    }
712

713

714
@maybe_skip_jdk_test
1✔
715
def test_compile_with_missing_maven_dep_fails(rule_runner: RuleRunner) -> None:
1✔
716
    rule_runner.write_files(
1✔
717
        {
718
            "BUILD": dedent(
719
                """\
720
                java_sources(
721
                    name = 'main',
722
                )
723
                """
724
            ),
725
            "3rdparty/jvm/default.lock": EMPTY_JVM_LOCKFILE,
726
            "Example.java": dedent(
727
                """
728
                package org.pantsbuild.example;
729

730
                import org.joda.time.DateTime;
731

732
                public class Example {
733
                    public static void main(String[] args) {
734
                        DateTime dt = new DateTime();
735
                        System.out.println(dt.getYear());
736
                    }
737
                }
738
                """
739
            ),
740
        }
741
    )
742

743
    request = CompileJavaSourceRequest(
1✔
744
        component=expect_single_expanded_coarsened_target(
745
            rule_runner, Address(spec_path="", target_name="main")
746
        ),
747
        resolve=make_resolve(rule_runner),
748
    )
749
    fallible_result = rule_runner.request(FallibleClasspathEntry, [request])
1✔
750
    assert fallible_result.result == CompileResult.FAILED and fallible_result.stderr
1✔
751
    assert "package org.joda.time does not exist" in fallible_result.stderr
1✔
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc