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

java_library: Support manifest manipulation #4197

Closed
marcohu opened this issue Nov 30, 2017 · 6 comments
Closed

java_library: Support manifest manipulation #4197

marcohu opened this issue Nov 30, 2017 · 6 comments
Assignees

Comments

@marcohu
Copy link
Contributor

marcohu commented Nov 30, 2017

I'm new to Bazel and I was quite surprised that (as of Bazel 0.8) manipulating the MANIFEST.MF does not seem to be supported out-of-the-box with the java_library rule.

With java_binary, we have deploy_manifest_lines. A similar option should be available for java_library as well.

It's not a big deal once your are experienced, but as a total beginner it took some time to come up with a solution. But the added convenience would be nice anyway.

@marcohu marcohu changed the title java_library: Support MANIFEST.MF manipulation java_library: Support manifest manipulation Nov 30, 2017
@iirina
Copy link
Contributor

iirina commented Dec 4, 2017

(as of Bazel 0.8) manipulating the MANIFEST.MF does not seem to be supported out-of-the-box with the java_library rule

How would you do this prior to Bazel 0.8?

With java_binary, we have deploy_manifest_lines. A similar option should be available for java_library as well.

deploy_manifest_lines lets you add lines to the manifest of the deploy jar generated by java_binary. java_library doesn't create any deploy jar.

as a total beginner it took some time to come up with a solution

Why did you need to manipulate the manifest file? Can you describe how would this help you? Thanks!

@marcohu
Copy link
Contributor Author

marcohu commented Dec 4, 2017

How would you do this prior to Bazel 0.8?

I'm on 0.8. For now I'm simply using a genrule that manually updates the .jar file with the necessary manifest data. Instead of the java_library rule, I'm invoking it to create the final .jar.

genrule(
    name = "CreateGenfilesLib",
    srcs = [":CreateLib", ":manifest"],
    outs = ["eclipse-genfiles.jar"],
    tools = ["@local_jdk//:jar"],
    cmd = "cp $(location :CreateLib) $@; $(location @local_jdk//:jar) ufm $@ $(location :manifest)"
)

It's certainly not a big deal. Coming from other build tools I was surprised that it's not possible with java_library directly. As a novice it took some time to create the workaround. Maybe there is a more idiomatic solution?

deploy_manifest_lines lets you add lines to the manifest of the deploy jar generated by java_binary. java_library doesn't create any deploy jar.

Sure. The option would have to be named differently.

Why did you need to manipulate the manifest file?

For deployment of an Eclipse plugin I need to add the necessary manifest information. I first tried to simply include the manifest with the input files. But Bazel either seems to override or not include the custom MANIFEST.MF file. I'm pretty sure I will need this feature in other projects as well.

Can you describe how would this help you?

Direct support would save me from using additional code and overhead unless I'm missing something. Thanks.

@iirina
Copy link
Contributor

iirina commented Dec 5, 2017

Thanks for the information!

For deployment of an Eclipse plugin I need to add the necessary manifest information. I first tried to simply include the manifest with the input files. But Bazel either seems to override or not include the custom MANIFEST.MF file. I'm pretty sure I will need this feature in other projects as well.

Yes, Bazel will just ignore your manifest. Bazel considers only java_binary or java_test as rules that output something for deployment. The other rules should be used as intermediary and the user, in theory, should not depend on the jars created (e.g. by java_library) or implementation details.

I still don't understand why you need to add manifest information to the output jars of java_library and not to the final deploy jar created by java_binary. How does the Eclipse plugin work?

@marcohu
Copy link
Contributor Author

marcohu commented Dec 5, 2017

Yes, Bazel will just ignore your manifest. Bazel considers only java_binary or java_test as rules that output something for deployment. The other rules should be used as intermediary and the user, in theory, should not depend on the jars created (e.g. by java_library) or implementation details.

Thanks for the clarification. I was not aware of that distinction. Given the documentation for java_binary I was lead to believe that java_library is the better fit for my needs.

I've now tried java_binary, but I was not able to achieve the desired result. deploy_manifest_lines seems to only work with the special _deploy.jar target (does the manual explain how to request that?). But if I request that target, the final _deploy.jar file has all dependencies embedded as well. Clearly not what I what. Is there a way to build a _deploy.jar without the dependencies embedded?

I still don't understand why you need to add manifest information to the output jars of java_library and not to the final deploy jar created by java_binary. How does the Eclipse plugin work?

It's just a standard Eclipse plugin archive. It's for internal use only and will be dropped into the dropins folder of Eclipse. Just a bunch of .class files, the plugin.xml descriptor in the root directory and the META-INF/MANIFEST.MF with the required additions.

@iirina
Copy link
Contributor

iirina commented Dec 6, 2017

deploy_manifest_lines seems to only work with the special _deploy.jar target (does the manual explain how to request that?).

Yes, the idea is to control only what goes into the _deploy.jar (not the regular compile jar). You can build this jar by bazel build <your_target>_deploy.jar. The deploy jar contains the classes from the transitive closure as well so it can be run with the java -jar command.

But if I request that target, the final _deploy.jar file has all dependencies embedded as well. Clearly not what I what. Is there a way to build a _deploy.jar without the dependencies embedded?

Why wouldn't you want the dependencies embedded? I'm not sure if there is a way not to include them. Maybe if you mark your java_library dependencies as neverlink, since only the jars needed at runtime are added to the deploy jar.

@iirina iirina self-assigned this Dec 6, 2017
@marcohu
Copy link
Contributor Author

marcohu commented Dec 6, 2017

Yes, the idea is to control only what goes into the _deploy.jar (not the regular compile jar). You can build this jar by bazel build <your_target>_deploy.jar. The deploy jar contains the classes from the transitive closure as well so it can be run with the java -jar command.

That's why I initially thought java_binary is the wrong choice. The Eclipse plug-is is only run in the context of the IDE and not directly.

Why wouldn't you want the dependencies embedded? I'm not sure if there is a way not to include them. Maybe if you mark your java_library dependencies as neverlink, since only the jars needed at runtime are added to the deploy jar.

Thanks for the pointer. I think this will work. java_import explicitly mentions my plugin usecase. I need to change the way the necessary dependencies are imported to be able to "neverlink" them, but it should be possible to achieve the desired result this way.

Thanks very much for your support!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants