Skip to content

Conversation

pledbrook
Copy link
Contributor

No description provided.

This is a first draft of a new chapter that takes a user-centric approach to
explaining how to build Java projects with Gradle.
@eriwen eriwen self-requested a review March 22, 2018 15:05
@bmuschko bmuschko self-requested a review March 29, 2018 19:55
Copy link
Contributor

@bmuschko bmuschko left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There's a lot of good content in this pull request. I would love to this see this shipped soon.

We may want to cut off the content into multiple chapters. I am sure reader will feel the amount of information overwhelming as single page.

[[base_plugin]]
== The Base Plugin

The Base Plugin provides features that are common to most builds and adds a structure to the build that promotes consistency in how they are run. Its most significant contribution is a set of <<sec:base_tasks,'lifecycle' tasks>> that act as an umbrella for the more specific tasks provided by other plugins and build authors.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd probably put an emphasis on the term "convention" here. You description basically says that but I wouldn't call it a feature I think.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It provides the clean and upload* tasks as well, hence the use of features. It's not just a set of conventions. That said, the conventions are its main focus I guess.

Copy link
Contributor Author

@pledbrook pledbrook Mar 30, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • Improve on 'features'

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's definitely a combination of both: tasks and conventions. For some reason "feature" sounds like something bigger but that may one by my perception.

[[base_plugin]]
== The Base Plugin

The Base Plugin provides features that are common to most builds and adds a structure to the build that promotes consistency in how they are run. Its most significant contribution is a set of <<sec:base_tasks,'lifecycle' tasks>> that act as an umbrella for the more specific tasks provided by other plugins and build authors.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a reason why you single-quoted "lifecycle"?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's not just an adjective, but a name that we give them. I don't particularly like the quotes, but not sure what to replace them with if anything.

Copy link
Contributor Author

@pledbrook pledbrook Mar 30, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • Italicise 'lifeycle' instead of quoting it

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe we can directly reference this subsection here: https://docs.gradle.org/current/userguide/more_about_tasks.html#sec:lifecycle_tasks

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good idea. Will be in the next commit.

[[sec:base_plugin_usage]]
=== Usage

----
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should probably include a really code example here that is tested automatically.

Copy link
Contributor Author

@pledbrook pledbrook Mar 30, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • Convert to tested code sample

=== Tasks

`clean` — type: `Delete`::
Deletes the build directory and everything in it, i.e. the path specified by the `buildDir` project property.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you add an API link to buildDir?

Copy link
Contributor Author

@pledbrook pledbrook Mar 30, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes. Unfortunately it will render as Project.getBuildDir(), which is really ugly.

  • Link to buildDir in API docs

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree that the rendered result is not as good looking. However, I'd rather have readers understand where the property comes from by linking to the API.

Plugins and build authors should attach tasks that produce distributions and other consumable artifacts to this lifecycle task. For example, `jar` produces the consumable artifact for Java libraries. Attach tasks to this lifecycle task using `assemble.dependsOn(__task__)`.

`build` — _lifecycle task_::
(Depends on `assemble` and `check`) Builds everything
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sentence should end with a dot.

Copy link
Contributor Author

@pledbrook pledbrook Mar 30, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think I wanted to continue that sentence but was distracted. I'll sort it out one way or the other.

  • Fix this sentence

</sample>
++++

The Gradle terminology for the three elements is as follows:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Contributor Author

@pledbrook pledbrook Mar 30, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • Review and update

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmmm...that page doesn't mention dependency coordinates. Deliberate? Is there another, preferred term for them?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe just be an oversight. We have the module version in there which is just a part of the usual coordinates.

@gradle/dependency-management Does anything speak against adding "Module coordinates" as term there?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we have the same confusion here as we had in other places. We should always use the term module if we talk about the concrete thing we depend on. While the term dependency should be used to describe the pointer at something.

So I would update the terminology here and to module coordinates:

Module coordinates — the ID of the module to depend on, usually in the form...

And yes, I think we can (should?) add "Module coordinates" to dependency_management_terminology.html.

* _Configuration_ - how the dependency will be used (`implementation`) — a more flexible form of Maven scopes
* _Dependency coordinate_ — the ID of the dependency, usually in the form '__<group>__:__<module>__:__<version>__' (or '__<groupId>__:__<artifactId>__:__<version>__' in Maven terminology)

As far as configurations go, the main ones of interest are:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should also list and explain api.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But that only exists for the Java Library Plugin. I'll review. Maybe it makes sense to call it out here as well as in the Building Java libraries section.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've called it out just after the list as I want it to be absolutely clear that it's not one of the configurations added by the Java Plugin.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For reference: https://github.com/gradle/gradle/blob/master/subprojects/plugins/src/main/java/org/gradle/api/plugins/JavaPlugin.java#L116. Though I'd have to admit that it is not fully clear to me when you would use api in a Java standalone application.

@gradle/dependency-management Can you comment on this?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The name is defined there, but the configuration is not added by the Java Plugin. Strangely, at first glance at least, the plugin does add the apiElements configuration.


++++
<sample xmlns:xi="http://www.w3.org/2001/XInclude" id="javaCrossCompilation" dir="java/crossCompilation" title="Configure Java 6 build">
<sourcefile file="gradle.properties"/>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you use proper indentation here?

Copy link
Contributor Author

@pledbrook pledbrook Mar 30, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure. I'd just like to point out that that was the original formatting in the Java Plugin chapter 😄

  • Fix indentation on samples

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Absolutely, many of the existing snippet pieces in their current form are not formatted properly.

When debugging for tests is enabled, Gradle will start the test process suspended and listening on port 5005.

[[test_filtering]]
==== Test filtering
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There's a lot of content on testing. We maybe want to split it out into its own chapter.

Copy link
Contributor Author

@pledbrook pledbrook Mar 30, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yup. I think Eric's OK with that too.

  • Refactor testing into its own chapter


The Java Plugin adds a `clean` task to your project by virtue of applying the Base Plugin. This task simply deletes everything in the `$buildDir` directory, hence why you should always put files generated by the build in there. The task is an instance of api:org.gradle.api.tasks.Delete[] and you can change what directory it deletes by setting its `dir` property.

[[sec:building_java_libraries]]
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We may want to split out the following section as separate chapters.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd rather keep it here. The sections aren't long and are an important topic for first look readers. These sections just don't seem to warrant a chapter to themselves, except perhaps individually, but we have the plugin chapters for that.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can split things up in a different PR if needed. It's fine to keep it as-is for now.

This is done by the `war` task, which effectively replaces the `jar` task — although that task remains — and is attached to the `assemble` lifecycle task. See the plugin's chapter for more details and configuration options.

TODO:Check that we do in fact recommend the following. I noticed that the Web Quickstart does so.
There is no core support for running your web application directly from the build, but we do recommend that you try the https://plugins.gradle.org/plugin/org.akhikhl.gretty[Gretty] community plugin, which provides an embedded Servlet container.
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@bmuschko I'm not sure what's going on with Gretty. It sounds as if it's being brought in house. Should I mention it here? Or leave that to the web-specific chapters?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The original Gretty plugin has gotten little updates in the past year. Somebody forked the project and is now publishing to the plugin portal. I am confident that we will not make the plugin part of Gradle core. The forked plugin is this one: https://plugins.gradle.org/plugin/org.gretty.

We'll need to clean up the references to Gretty across the board in the user guide. I created an issue for it: #4902. For now you can keep the link you are using.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I merged a PR that points to the new plugin: #4911. We should make the change here as well.

Copy link
Contributor

@eriwen eriwen left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is amazing. Sorry for my delayed review. Just a few small items to consider. I hope we can get users reading this very soon.

// limitations under the License.

[[base_plugin]]
== The Base Plugin
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This little chapter is really fantastic @pledbrook. Well done.

// See the License for the specific language governing permissions and
// limitations under the License.

[[java]]
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

❌ Could we please use a more specific page slug? This is important for search engines and users to distinguish this content from other Java-centric chapters.

[NOTE]
.Why no `compile` configuration?
====
The Java Plugin has historically used the `compile` configuration for dependencies that are required to both compile and run a project's production code. It is now deprecated because it doesn't distinguish between dependencies that impact the public API of a Java library project and those that don't. You can learn more about the importance of this distinction in _<<sec:building_java_libraries,Building Java libraries>>_.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was not aware that compile is deprecated. My understanding is that it's discouraged, but needed for certain situations. Maybe worth a double-check, but otherwise I trust you've gotten an authoritative answer from others on this.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's soft deprecated apparently. I'll propose an altered wording that's less likely to cause immediate concern, since it's unlikely to be removed anytime soon.

Since `processResources` is an instance of the `Copy` task, you can perform any of the processing described in the _<<sec:copying_files,Working With Files>>_ chapter.

[[sec:properties_files]]
==== Java properties files
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems like the title or section content should mention that this is useful for creating reproducible builds.


See api:org.gradle.api.tasks.bundling.Jar[] for more details on the configuration options available to you.

There are several options for publishing a JAR once it has been created, such as the `uploadArchives` task that can publish to Maven- and Ivy-compatible repositories. It's a big topic, so please see _<<artifact_management,Publishing artifacts>>_ for more details.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

artifact_management is only the old publishing mechanism. We're really only covering publishing in the very last paragraph. It seems like this would be worth expanding and linking off to the 3 relevant chapters, or omitting publishing here.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure what we can say about the two. I still don't know which is the preferred approach, if any. Is there anything useful we can say?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK, so @oehme says that this will be resolved with Gradle 4.8: the old mechanism will be deprecated. So I suggest mentioning all publishing options here without any major guidance, recognising that we will be updating this section (and others I suspect) with the release of the next version of Gradle.

There are several options for publishing a JAR once it has been created, such as the `uploadArchives` task that can publish to Maven- and Ivy-compatible repositories. It's a big topic, so please see _<<artifact_management,Publishing artifacts>>_ for more details.

[[sec:jar_manifest]]
==== Modifying the JAR manifest
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Very good

[[sec:generating_javadocs]]
=== Generating API documentation

The Java Plugin provides a `javadoc` task of type api:org.gradle.api.tasks.javadoc.Javadoc[], that will generate standard Javadocs for all your production code, i.e. whatever source is in the `main` source set. The task supports the core Javadoc and standard doclet options described in the http://docs.oracle.com/javase/7/docs/technotes/tools/windows/javadoc.html#options[Javadoc reference documentation]. See api:org.gradle.external.javadoc.CoreJavadocOptions[] and api:org.gradle.external.javadoc.StandardJavadocDocletOptions[] for a complete list of those options.TODO:Not sure if the user can rely on `options` being of type `StandardJavadocDocletOptions` rather than `MinimalJavadocOptions`
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

note there is a hanging TODO here

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's because I don't have an answer to it yet. Was hoping one of the reviewers could provide one 😉

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note that there is a hanging TODO in the Java testing chapter as well. The content was there originally, but I don't understand it. Unfortunately I haven't got an answer to that one yet.

The Java Plugin adds a `clean` task to your project by virtue of applying the <<base_plugin,Base Plugin>>. This task simply deletes everything in the `$buildDir` directory, hence why you should always put files generated by the build in there. The task is an instance of api:org.gradle.api.tasks.Delete[] and you can change what directory it deletes by setting its `dir` property.

[[sec:building_java_libraries]]
=== Building Java libraries
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Worth a link to the guide from this subsection?

You can learn more about these configurations and other aspects of building Java libraries in the plugin's chapter. Note that the Java Library Plugin automatically applies the standard Java Plugin as well.

[[sec:building_java_applications]]
=== Building Java applications
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Worth a link to the relevant guide from this subsection?

====

[[sec:debugging_java_tests]]
=== Debugging
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I weakly think we could make this title a bit more verbose: e.g. "Debugging Test Execution"

Copy link
Contributor

@eriwen eriwen left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is great. As far as I'm concerned, this is merge-able if we just rename java.adoc

// limitations under the License.

[[java]]
[[building_java_projects]]
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We will need to rename this file to buildingJavaProjects.adoc to preserve quick edit functionality

Copy link
Contributor

@oehme oehme left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a big improvement indeed! What happened to the other chapter on the Java and Java library plugin though? This seems to be mostly duplicate information now.

The Base Plugin adds no <<managing_dependency_configurations,configurations for dependencies>>, but it does add the following configurations for <<sec:artifacts_and_configurations,artifacts>>:

`default`::
By default, contains all the artifacts attached to all other configurations. It's used by consumer projects. For example, if project B has a `runtimeOnly` dependency on project A, then the artifacts in project A's `default` configuration are added to project B's `runtimeOnly` configuration.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

❌There are several errors in this:

It does not contain "all artifacts of all other configurations". Other plugins let the default configuration extend relevant other configurations, like "compile" and "runtime".

The explanation on what happens on a dependency is wrong. The default configuration is pretty much never used. Instead, matching on variant attributes is done to find the correct configuration to link against. This has nothing to do with where that dependency was declared, but where it is used. E.g. an api dependency will link against the apiElements when resolving the compileClasspath, but will link against the runtimeElements when resolving the runtimeClasspath.

The default configuration is only used if there are no configurations with attributes at all.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for checking the accuracy.

On the first point, I was going by this code in BasePlugin:

configurations.all(new Action<Configuration>() {
    public void execute(Configuration configuration) {
        configuration.getArtifacts().all(new Action<PublishArtifact>() {
            public void execute(PublishArtifact artifact) {
                defaultArtifacts.addCandidate(artifact);
            }
        });
    }
});

Looking further into it, defaultArtifacts only seems to be used if no artifacts are explicitly declared. And of course, the Java Plugin does do that with the archives configuration. Is that correct?

On the second point, was that behaviour added with variant-aware dependency resolution?

At this point, I'm wondering whether to mention the default configuration at all. On the one hand, it seems awfully confusing. On the other, this is the user manual and should be fairly comprehensive. And I think the configuration has a nasty way of rearing its head in real world builds. Or at least it did. Perhaps it's just not relevant any more.

Guidance would be much appreciated!

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The code you showed is about the archives configuration, not the default configuration.

Yes, the default configuration become essentially unused since the introduction of variant awareness. I think the proper description would be that "This is the configuration that will be used when no other configuration matches a dependency. It is only there for backwards compatibility and should not be used in new builds/plugins".

* the <<publishing_maven,Maven Publish Plugin>>
* the <<publishing_ivy,Ivy Publish Plugin>>

The latter two "Publish" plugins are the preferred options *unless* you need to sign POMs, for example when publishing to Maven Central. In that case, you need to use the original mechanism with the Maven Plugin.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⭕️ I'm a bit uneasy about sprinkling information about other plugins here, as it will make it harder to keep the documentation up-to-date when we change things.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree, but the above will change for the 4.8 docs anyway, so it's really just a stop gap.

You can control how the test process is launched via several properties on the `Test` task, including the following:

`maxParallelForks` — default: 1::
You can run your tests in parallel by setting this property to a value greater than 1. This may make your test suites complete faster, particularly if you run them on a multi-core CPU. When using parallel test execution, make sure your tests are properly isolated from one another. Tests that interact with the filesystem are particularly prone to conflict, causing intermittent test failures.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⭕️ I think a more common example of conflict is using the same database. For the file system people often know intuitively to use a temp dir.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

People with extensive experience that don't tend to forget hard-won knowledge 😉 But I'll add a mention of the database as well. The more examples the better in my view (until it becomes unwieldy).

Your tests can distinguish between parallel test processes by using the value of the `org.gradle.test.worker` property, which is unique for each process. You can use this for anything you want, but it's particularly useful for filenames and other resource identifiers to prevent the kind of conflict we just mentioned.

`forkEvery` - default: 0 (no max)::
This property specifies the maximum number of test classes that Gradle should run on a test process before its disposed of and a fresh one created. This is mainly used as a way to manage memory consumption during the test execution phase of the build.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

❌ I'm not convinced about the "memory consumption" argument. Memory should be freed as the tests progress. Only metaspace will grow. But how often does it actually happen that you can't fit your tests into metaspace?

The much more common reason I see for using this is that people have frameworks with some static state that can't be reset. In that case using forkEvery=1 is an (expensive) remedy. I've never seen a build where forkEvery was other than 0 or 1.

I would strongly advise against this option. It should be a last resort, as it severly limits test performance.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Leaky tests? It's been a while, but I vaguely remember the Grails tests using it.

Anyway, happy to add the other reason plus a warning that forkEvery = 1 (or a similarly low number) will hurt test performance heavily. Would that be OK? Would it be OK to add leaky tests as a reason as well?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sounds good.

```

[[sec:single_test_execution_via_system_properties]]
=== Single test execution via System Properties
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

❌ Let's remove this. We want to deprecate that -D property anyway. There is no more use case for it that isn't solved better by --tests.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The main reason to leave it in is so that people know what it's about when they encounter it in the wild, for example on forums. I'd be happy to rework the section to explicitly explain that the option should no longer be used and is only covered for that reason. Make sense? Or do you think it should be removed regardless?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Leaving a single sentence in for now would be okay, just not the full explanation.


// START SNIPPET practical-integ-test-source-set
sourceSets {
intTest {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

❌ This should include making the intTest configurations extend from their corresponding production configurations. E.g. intTestImplementation.extendsFrom(implementation) and so on. Also, depending on your idea of integration tests, you might want to extend from the test configurations as well, so you don't have to duplicate your test frame work dependencies either.

I'm not sure we should add this here, as I remember we had a guide on creating custom source sets, which we could link here.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can't find such a guide at https://guides.gradle.org and the Java Plugin chapter seems to be high on Google results for creating a custom source set.

I would actually like to add integration tests as a short(ish) HOWTO in the Java testing chapter, so I'd prefer to use a different (simpler) example here anyway. Any suggestions?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Generally custom source sets belong in plugins, not build scripts. It's almost never enough to just define the source set, you always have to wire it in somewhere.

That being said maybe you have some code generator which generates sources for the main sourceSet. That code generator needs its own sourceSet. Then again, I'd never write this in a build script, but in a plugin in buildSrc.


// START SNIPPET defining-sources-jar-task
task sourcesJar(type: Jar) {
appendix = 'sources'
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

❌ This should be classifier, not appendix, for proper publishing.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is appendix useful for anything in JAR publishing then? Are there any guidelines on when to use classifier vs appendix? I'd like to add such information to the chapter if possible.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure when appendix would be useful. It's definitely ignored by the maven-publish plugin, as that will use the classifier to publish multiple related things under the same GAV.

@pledbrook
Copy link
Contributor Author

@oehme I can't see how to respond to your top-level question, so doing it here. The Java and Java Library plugins remain, but become more reference like. In fact, the Java Library Plugin chapter hasn't been touched I think.

However, the original Java Plugin chapter was an odd mix of content. And now I see I haven't modified it yet. I need to trim it down. Thanks for catching that! I think I'll leave the in-depth discussion of api and implementation in the Java Library Plugin chapter though.

This covers a general overview in the Building Java projects chapter and a
fleshed out example in the Java testing chapter of setting up integration tests
in a Java build.
Much of the content was overlapping with the new Building Java & JVM projects
chapter, so it has now been removed. The chapter is now a pure reference.
@pledbrook
Copy link
Contributor Author

@eriwen I think I've now accounted for all of @oehme's feedback, although the changes to the Java Plugin page were a little rushed in case you want to merge ASAP.

Let me know how it looks and if there are any more changes needed.

@eriwen eriwen merged commit 11cd9ab into gradle:master Apr 10, 2018
eriwen pushed a commit that referenced this pull request Apr 11, 2018
Merge the following changes from @pledbrook:

* Create a new chapter on Java projects

This covers a general overview in the Building Java projects chapter and a
fleshed out example in the Java testing chapter of setting up integration tests
in a Java build.

* Prune the Java Plugin chapter

Much of the content was overlapping with the new Building Java & JVM projects
chapter, so it has now been removed. The chapter is now a pure reference.

* Add plugin reference chapter for Base Plugin
guylabs added a commit that referenced this pull request Apr 11, 2018
* master: (30 commits)
  Remove unused repository declaration in build-scan-init
  Use latest stable build scan plugin
  Remove confusing label from test
  Fail whenever 2 dependencies/constraints disagree on the value of an attribute
  Honor constraint attribute during selection
  Honor dependency attributes when they override configuration attributes
  Rename classes for clarity
  Use dependency attributes when selecting variants of a single component
  Avoid creating empty reject selector when no reject constraints exist
  Update integration test for fixed behaviour
  Add 'rejected' status to `ComponentIdResolveResult`
  Add test demonstrating inadequacy of current implementation
  Consider all reject constraints when resolving dynamic versions
  Simplify unit test to make it less tied to implementation
  Fix custom report dirs sample and test
  Fix samples tests in new Java chapters
  Create a new chapter on building Java projects (#4800)
  Fire buildFinished for the root build after finishing all included builds (#4991)
  Refactor graph visitors
  Refactorings following review comments
  ...
@pledbrook pledbrook deleted the java-chapter branch July 26, 2018 12:58
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

a:feature A new functionality

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants