| // Copyright 2014 The Bazel Authors. All rights reserved. |
| // |
| // Licensed under the Apache License, Version 2.0 (the "License"); |
| // you may not use this file except in compliance with the License. |
| // You may obtain a copy of the License at |
| // |
| // http://www.apache.org/licenses/LICENSE-2.0 |
| // |
| // Unless required by applicable law or agreed to in writing, software |
| // distributed under the License is distributed on an "AS IS" BASIS, |
| // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| // See the License for the specific language governing permissions and |
| // limitations under the License. |
| |
| package com.google.devtools.build.lib.bazel.rules.java; |
| |
| import static com.google.devtools.build.lib.packages.Attribute.attr; |
| import static com.google.devtools.build.lib.packages.BuildType.LABEL; |
| import static com.google.devtools.build.lib.packages.BuildType.LABEL_LIST; |
| import static com.google.devtools.build.lib.packages.Type.BOOLEAN; |
| |
| import com.google.devtools.build.lib.analysis.BaseRuleClasses; |
| import com.google.devtools.build.lib.analysis.RuleDefinition; |
| import com.google.devtools.build.lib.analysis.RuleDefinitionEnvironment; |
| import com.google.devtools.build.lib.analysis.test.TestConfiguration; |
| import com.google.devtools.build.lib.bazel.rules.java.BazelJavaRuleClasses.BaseJavaBinaryRule; |
| import com.google.devtools.build.lib.packages.Attribute; |
| import com.google.devtools.build.lib.packages.AttributeMap; |
| import com.google.devtools.build.lib.packages.RuleClass; |
| import com.google.devtools.build.lib.rules.cpp.CppConfiguration; |
| import com.google.devtools.build.lib.rules.cpp.CppRuleClasses; |
| import com.google.devtools.build.lib.rules.java.JavaConfiguration; |
| import com.google.devtools.build.lib.util.FileTypeSet; |
| |
| /** |
| * Rule definition for the java_binary rule. |
| */ |
| public final class BazelJavaBinaryRule implements RuleDefinition { |
| @Override |
| public RuleClass build(RuleClass.Builder builder, RuleDefinitionEnvironment env) { |
| /* <!-- #BLAZE_RULE(java_binary).NAME --> |
| <br/>It is good practice to use the name of the source file that is the main entry point of the |
| application (minus the extension). For example, if your entry point is called |
| <code>Main.java</code>, then your name could be <code>Main</code>. |
| <!-- #END_BLAZE_RULE.NAME --> */ |
| return builder |
| .requiresConfigurationFragments( |
| JavaConfiguration.class, |
| CppConfiguration.class, |
| // TestConfiguration is only required by the java rules to know when the persistent |
| // test runner is enabled. |
| TestConfiguration.class) |
| /* <!-- #BLAZE_RULE(java_binary).IMPLICIT_OUTPUTS --> |
| <ul> |
| <li><code><var>name</var>.jar</code>: A Java archive, containing the class files and other |
| resources corresponding to the binary's direct dependencies.</li> |
| <li><code><var>name</var>-src.jar</code>: An archive containing the sources ("source |
| jar").</li> |
| <li><code><var>name</var>_deploy.jar</code>: A Java archive suitable for deployment (only |
| built if explicitly requested). |
| <p> |
| Building the <code><<var>name</var>>_deploy.jar</code> target for your rule |
| creates a self-contained jar file with a manifest that allows it to be run with the |
| <code>java -jar</code> command or with the wrapper script's <code>--singlejar</code> |
| option. Using the wrapper script is preferred to <code>java -jar</code> because it |
| also passes the <a href="${link java_binary.jvm_flags}">JVM flags</a> and the options |
| to load native libraries. |
| </p> |
| <p> |
| The deploy jar contains all the classes that would be found by a classloader that |
| searched the classpath from the binary's wrapper script from beginning to end. It also |
| contains the native libraries needed for dependencies. These are automatically loaded |
| into the JVM at runtime. |
| </p> |
| <p>If your target specifies a <a href="#java_binary.launcher">launcher</a> |
| attribute, then instead of being a normal JAR file, the _deploy.jar will be a |
| native binary. This will contain the launcher plus any native (C++) dependencies of |
| your rule, all linked into a static binary. The actual jar file's bytes will be |
| appended to that native binary, creating a single binary blob containing both the |
| executable and the Java code. You can execute the resulting jar file directly |
| like you would execute any native binary.</p> |
| </li> |
| <li><code><var>name</var>_deploy-src.jar</code>: An archive containing the sources |
| collected from the transitive closure of the target. These will match the classes in the |
| <code>deploy.jar</code> except where jars have no matching source jar.</li> |
| </ul> |
| <!-- #END_BLAZE_RULE.IMPLICIT_OUTPUTS --> */ |
| .setImplicitOutputsFunction(BazelJavaRuleClasses.JAVA_BINARY_IMPLICIT_OUTPUTS) |
| /* <!-- #BLAZE_RULE(java_binary).ATTRIBUTE(deploy_env) --> |
| A list of other <code>java_binary</code> targets which represent the deployment |
| environment for this binary. |
| Set this attribute when building a plugin which will be loaded by another |
| <code>java_binary</code>.<br/> Setting this attribute excludes all dependencies from |
| the runtime classpath (and the deploy jar) of this binary that are shared between this |
| binary and the targets specified in <code>deploy_env</code>. |
| <!-- #END_BLAZE_RULE.ATTRIBUTE --> */ |
| .add( |
| attr("deploy_env", LABEL_LIST) |
| .allowedRuleClasses("java_binary") |
| .allowedFileTypes(FileTypeSet.NO_FILE)) |
| .override( |
| attr("$is_executable", BOOLEAN) |
| .nonconfigurable("automatic") |
| .value( |
| new Attribute.ComputedDefault() { |
| @Override |
| public Object getDefault(AttributeMap rule) { |
| return rule.get("create_executable", BOOLEAN); |
| } |
| })) |
| .add( |
| attr("$jacocorunner", LABEL) |
| .value(env.getToolsLabel("//tools/jdk:JacocoCoverageRunner"))) |
| .addRequiredToolchains(CppRuleClasses.ccToolchainTypeAttribute(env)) |
| .build(); |
| } |
| |
| @Override |
| public Metadata getMetadata() { |
| return RuleDefinition.Metadata.builder() |
| .name("java_binary") |
| .ancestors(BaseJavaBinaryRule.class, BaseRuleClasses.BinaryBaseRule.class) |
| .factoryClass(BazelJavaBinary.class) |
| .build(); |
| } |
| } |
| |
| /*<!-- #BLAZE_RULE (NAME = java_binary, TYPE = BINARY, FAMILY = Java) --> |
| |
| <p> |
| Builds a Java archive ("jar file"), plus a wrapper shell script with the same name as the rule. |
| The wrapper shell script uses a classpath that includes, among other things, a jar file for each |
| library on which the binary depends. |
| </p> |
| <p> |
| The wrapper script accepts several unique flags. Refer to |
| <code>//src/main/java/com/google/devtools/build/lib/bazel/rules/java/java_stub_template.txt</code> |
| for a list of configurable flags and environment variables accepted by the wrapper. |
| </p> |
| |
| ${IMPLICIT_OUTPUTS} |
| |
| <p> |
| A <code>deps</code> attribute is not allowed in a <code>java_binary</code> rule without |
| <a href="${link java_binary.srcs}"><code>srcs</code></a>; such a rule requires a |
| <a href="${link java_binary.main_class}"><code>main_class</code></a> provided by |
| <a href="${link java_binary.runtime_deps}"><code>runtime_deps</code></a>. |
| </p> |
| |
| <p>The following code snippet illustrates a common mistake:</p> |
| |
| <pre class="code"> |
| java_binary( |
| name = "DontDoThis", |
| srcs = [ |
| <var>...</var>, |
| <code class="deprecated">"GeneratedJavaFile.java"</code>, # a generated .java file |
| ], |
| deps = [<code class="deprecated">":generating_rule",</code>], # rule that generates that file |
| ) |
| </pre> |
| |
| <p>Do this instead:</p> |
| |
| <pre class="code"> |
| java_binary( |
| name = "DoThisInstead", |
| srcs = [ |
| <var>...</var>, |
| ":generating_rule", |
| ], |
| ) |
| </pre> |
| |
| <!-- #END_BLAZE_RULE -->*/ |