Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cannot publish jvm_binary #2401

Closed
jhump opened this issue Oct 19, 2015 · 4 comments
Closed

Cannot publish jvm_binary #2401

jhump opened this issue Oct 19, 2015 · 4 comments

Comments

@jhump
Copy link
Contributor

jhump commented Oct 19, 2015

I am converting a repo from using Maven to using Pants. The repo includes a protoc plugin, implemented in Java. The resulting artifact is a runnable program (e.g. can do java -jar plugin.jar).

In Maven, this is configured in the pom.xml file by providing configuration for the maven shade plugin. The configuration tells it to include a shaded artifact (e.g. the self-contained fat jar) and also configures it to include the Main-Class entry in the resulting JAR's META-INF/MANIFEST.MF file.

When I first got the repo running and CI working correctly with Pants, I had accidentally defined the main artifact as a java_library. Everything worked fine, but the published artifact was not a fat JAR and didn't indicate the main class in the manifest.

So I changed it to jvm_binary. This step required a couple of changes:

  • Kept the java_library target, which references the sources and dependencies.
  • Created a new jvm_binary that simply referred to the java_library (since jvm_binary targets can't actually have sources other than a single main class). I also moved the provides attribute here since this is the target I want to publish.

Several things went wrong at this point:

  1. Attempting to publish failed silently: it printed "SUCCESS" but just did nothing. The online doc talks about this symptom, but only indicates the need for provides attributes on targets to publish.
  2. After playing around with command-line incantations to get something to happen, I found that indicating the target in an --override argument produced an error: FAILURE: src/main/java:protobuf-plugin is not an exported target
  3. After not understanding this at all, I began wading through Pants source code and found that jvm_binary targets do not have an exportable label. @ericzundel helped me out by giving me a custom PEX where jvm_binary targets are exportable.
  4. With the custom PEX, I ran into different errors:
FAILURE: The following errors must be resolved to publish.
  Cannot publish BuildFileAddress(FilesystemBuildFile(/Users/jh/Development/protobuf-plugins/src/main/java/BUILD), protobuf-plugin) due to:
    BuildFileAddress(FilesystemBuildFile(/Users/jh/Development/protobuf-plugins/src/main/java/BUILD), protobuf-plugin) - No sources.
    BuildFileAddress(FilesystemBuildFile(/Users/jh/Development/protobuf-plugins/src/main/java/BUILD), protobuf-plugin-lib) - Does not provide a binary artifact.

I'm okay with just omitting source artifacts for this. And the thing I really want published is a fat jar, so I shouldn't have to publish internal dependencies since they'll be bundled into the published artifact. (It would also be nice if I just had a java_binary target that let me include all of my sources. Then I wouldn't need an internal unpublished target and I'd have sources to publish...)

@jsirois
Copy link
Contributor

jsirois commented Oct 19, 2015

Historically pants has not allowed publishing jvm_binary objects with intention. The idea being an unshaded fatjar can only cause chaos when it contains other libraries and gets on a classpath that has those other libraries mixed, say [my binary using guava, guava, other things needing guava]. You know the rest of the story...

So either pants would need to be able to verify all 3rdparty deps in the fat jar are shaded or pants needs to loosen up and allow folks to shoot themselves in the foot.

Opinons on these paths are welcome. I'm also interested in the use case. How is publishing a fat jar useful for you and your teams?

@jhump
Copy link
Contributor Author

jhump commented Oct 20, 2015

To prevent the dependency problem, the fat jar artifact has a classifier. So it wouldn't inadvertently be used if the target were simply added to something else as a dependency. That would still use the standard jar artifact. We currently use a convention of classifier = "shaded" for the fat jar files (not sure if there's a standard.)

The reason it is useful is so that other places that want to use the protoc plugin can just download the fat jar and run it via java -jar. That is far simpler than having to crawl its associated pom.xml file, download all of its transitive dependencies, and build a classpath before being able to run the program. (I suppose a tool that encapsulates all of these steps might suffice, too...)

Why is it necessary to split binaries that have more than one source file into two targets (the binary and accompanying library)? This seems like an arbitrary constraint whose value isn't immediately apparent.

@jsirois
Copy link
Contributor

jsirois commented Oct 20, 2015

OK - thanks for the example. Just plopping the binaries on a fileserver or standard dev or prod binary distrbution mechanism would work as well OOB from pants, but it may be the case that you or someone else uses an artifactory or nexus install for that purpose.

I'll try to explain the current state of things here more fully - in short this presents as a bug to you, but pants has not yet been designed to publish anything but library level jars, from the internal pants product scheduling pipeline to the target UIs.

In more detail, the jvm_binary single file restriction was not motivated as a restriction but as an affordance - I don't think publish even existed as a goal at that point. The idea was jvm_binary was fundamentally just a metadata target saying this classpath over here has this main, but then its grew the ability to contribute the actual source file that carried the main to permit both simple binaries of 1 file and encourage most code to be structured (code-wise) as a library even if just to present an API to the main. IIRC the push here was to get folks at Twitter to write mainly testable code and just have the main gather flags and positional args and instantiate and use the api. The former being hard to test w/o shelling out, the latter being standard unit test fodder.

On to solving this. Right now publish does not allow combination of libraries in a single publish artifact at all. It does this to ensure in the simplest way possible that the same classfiles don't get published in 2 different jars. So that structure and aim works against combining jars natively, dooming any attempts by Eric to help you out here at the very end. There is though a customization mechanism, and its designed explicitly to allow attachment of additional artifacts beyond primary + sources + javadoc (+ CHANGELOG). I think this is the way to go. If this works well enough for you all, then it may make sense to land this in contrib so it can be a standard feature repos can turn on.

The high level docs are here: https://pantsbuild.github.io/dev_tasks_publish_extras.html
If this sounds sane to you and @ericzundel I can provide more help getting a publish plugin to attach "shaded" fatjars.

@Eric-Arellano
Copy link
Contributor

Closing due to being stale.

asherf added a commit to asherf/pants that referenced this issue Feb 3, 2021
[setuptools](https://github.com/pypa/setuptools/blob/main/CHANGES.rst)
v53.0.0
-------

Breaking Changes
^^^^^^^^^^^^^^^^
* pantsbuild#1527: Removed bootstrap script. Now Setuptools requires pip or another pep517-compliant builder such as 'build' to build. Now Setuptools can be installed from Github main branch.

v52.0.0
-------

Breaking Changes
^^^^^^^^^^^^^^^^
* pantsbuild#2537: Remove fallback support for fetch_build_eggs using easy_install. Now pip is required for setup_requires to succeed.
* pantsbuild#2544: Removed 'easy_install' top-level model (runpy entry point) and 'easy_install' console script.
* pantsbuild#2545: Removed support for eggsecutables.

Changes
^^^^^^^
* pantsbuild#2459: Tests now run in parallel via pytest-xdist, completing in about half the time. Special thanks to :user:`webknjaz` for hard work implementing test isolation. To run without parallelization, disable the plugin with ``tox -- -p no:xdist``.

v51.3.3
-------

Misc
^^^^
* pantsbuild#2539: Fix AttributeError in Description validation.

v51.3.2
-------

Misc
^^^^
* pantsbuild#1390: Validation of Description field now is more lenient, emitting a warning and mangling the value to be valid (replacing newlines with spaces).

v51.3.1
-------

Misc
^^^^
* pantsbuild#2536: Reverted tag deduplication handling.

v51.3.0
-------

Changes
^^^^^^^
* pantsbuild#1390: Newlines in metadata description/Summary now trigger a ValueError.
* pantsbuild#2481: Define ``create_module()`` and ``exec_module()`` methods in ``VendorImporter``
  to get rid of ``ImportWarning`` -- by :user:`hroncok`
* pantsbuild#2489: ``pkg_resources`` behavior for zipimport now matches the regular behavior, and finds
  ``.egg-info`` (previoulsy would only find ``.dist-info``) -- by :user:`thatch`
* pantsbuild#2529: Fixed an issue where version tags may be added multiple times

v51.2.0
-------

Changes
^^^^^^^
* pantsbuild#2493: Use importlib.import_module() rather than the deprectated loader.load_module()
  in pkg_resources namespace delaration -- by :user:`encukou`

Documentation changes
^^^^^^^^^^^^^^^^^^^^^
* pantsbuild#2525: Fix typo in the document page about entry point. -- by :user:`jtr109`

Misc
^^^^
* pantsbuild#2534: Avoid hitting network during test_easy_install.

v51.1.2
-------

Misc
^^^^
* pantsbuild#2505: Disable inclusion of package data as it causes 'tests' to be included as data.

v51.1.1
-------

Misc
^^^^
* pantsbuild#2534: Avoid hitting network during test_virtualenv.test_test_command.

v51.1.0
-------

Changes
^^^^^^^
* pantsbuild#2486: Project adopts jaraco/skeleton for shared package maintenance.

Misc
^^^^
* pantsbuild#2477: Restore inclusion of rst files in sdist.
* pantsbuild#2484: Setuptools has replaced the master branch with the main branch.
* pantsbuild#2485: Fixed failing test when pip 20.3+ is present.
  -- by :user:`yan12125`
* pantsbuild#2487: Fix tests with pytest 6.2
  -- by :user:`yan12125`

v51.0.0
-------

Breaking Changes
^^^^^^^^^^^^^^^^
* pantsbuild#2435: Require Python 3.6 or later.

Documentation changes
^^^^^^^^^^^^^^^^^^^^^
* pantsbuild#2430: Fixed inconsistent RST title nesting levels caused by pantsbuild#2399
  -- by :user:`webknjaz`
* pantsbuild#2430: Fixed a typo in Sphinx docs that made docs dev section disappear
  as a result of PR pantsbuild#2426 -- by :user:`webknjaz`

Misc
^^^^
* pantsbuild#2471: Removed the tests that guarantee that the vendored dependencies can be built by distutils.

v50.3.2
-------

Documentation changes
^^^^^^^^^^^^^^^^^^^^^
* pantsbuild#2394: Extended towncrier news template to include change note categories.
  This allows to see what types of changes a given version introduces
  -- by :user:`webknjaz`
* pantsbuild#2427: Started enforcing strict syntax and reference validation
  in the Sphinx docs -- by :user:`webknjaz`
* pantsbuild#2428: Removed redundant Sphinx ``Makefile`` support -- by :user:`webknjaz`

Misc
^^^^
* pantsbuild#2401: Enabled test results reporting in AppVeyor CI
  -- by :user:`webknjaz`
* pantsbuild#2420: Replace Python 3.9.0 beta with 3.9.0 final on GitHub Actions.
* pantsbuild#2421: Python 3.9 Trove classifier got added to the dist metadata
  -- by :user:`webknjaz`

v50.3.1
-------

Documentation changes
^^^^^^^^^^^^^^^^^^^^^
* pantsbuild#2093: Finalized doc revamp.
* pantsbuild#2097: doc: simplify index and group deprecated files
* pantsbuild#2102: doc overhaul step 2: break main doc into multiple sections
* pantsbuild#2111: doc overhaul step 3: update userguide
* pantsbuild#2395: Added a ``:user:`` role to Sphinx config -- by :user:`webknjaz`
* pantsbuild#2395: Added an illustrative explanation about the change notes to fragments dir -- by :user:`webknjaz`

Misc
^^^^
* pantsbuild#2379: Travis CI test suite now tests against PPC64.
* pantsbuild#2413: Suppress EOF errors (and other exceptions) when importing lib2to3.

[Wheel](https://github.com/pypa/wheel/blob/4fb47f98550f3f43fc0b8c73f518592124ae21bd/docs/news.rst)
**0.36.2 (2020-12-13)**

- Updated vendored ``packaging`` library to v20.8
- Fixed wheel sdist missing ``LICENSE.txt``
- Don't use default ``macos/arm64`` deployment target in calculating the
  platform tag for fat binaries (PR by Ronald Oussoren)

**0.36.1 (2020-12-04)**

- Fixed ``AssertionError`` when ``MACOSX_DEPLOYMENT_TARGET`` was set to ``11``
  (PR by Grzegorz Bokota and François-Xavier Coudert)
- Fixed regression introduced in 0.36.0 on Python 2.7 when a custom generator
  name was passed as unicode (Scikit-build)
  (``TypeError: 'unicode' does not have the buffer interface``)

**0.36.0 (2020-12-01)**

- Added official Python 3.9 support
- Updated vendored ``packaging`` library to v20.7
- Switched to always using LF as line separator when generating ``WHEEL`` files
  (on Windows, CRLF was being used instead)
- The ABI tag is taken from  the sysconfig SOABI value. On PyPy the SOABI value
  is ``pypy37-pp73`` which is not compliant with PEP 3149, as it should have
  both the API tag and the platform tag. This change future-proofs any change
  in PyPy's SOABI tag to make sure only the ABI tag is used by wheel.
- Fixed regression and test for ``bdist_wheel --plat-name``. It was ignored for
  C extensions in v0.35, but the regression was not detected by tests.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants