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

Error in compileJava task after upgrading to 4.2.1 #3249

Closed
cballesteros opened this issue Oct 19, 2017 · 5 comments
Closed

Error in compileJava task after upgrading to 4.2.1 #3249

cballesteros opened this issue Oct 19, 2017 · 5 comments

Comments

@cballesteros
Copy link

cballesteros commented Oct 19, 2017

Expected Behavior

compileJava task should use generated java beans in buildDir.

Current Behavior

compileJava Task cleans the buildDir folder before compile. It produces a "package does not exists" error since source code uses generated code in the buildDir.

Context

I'm using xmlBeans plugin to generates java beans. Also I'm using java plugin to compile the source code. The task compileJava from java plugin dependson task compileXmlSchemas from xmlBeans plugin. Since the generated beans are used in the source code, a "package does not exists" error appear in compilation time. With gradle 2.4, 3.5 and 4.0 everything works fine but after upgrading to 4.2.1 this error blocks the compileJava task.

I found that recently you introduce a change to Cleanup directories when sources become empty (here). I think that these change will clean the buildDir folder before compileJava execution. Additionally, I found this line in the logs:

16:16:15.821 [INFO] [org.gradle.api.internal.tasks.execution.CleanupStaleOutputsExecuter] Deleting stale output file: D:\main-project\java\sub-project\build\gen-classes\xmlbeans

I need that the gen-classes\xmlbeans folder stay there for compileJava execution.

How to reproduce

You can find a gradle sample using xmlBeans plugin in this repo https://github.com/cballesteros/xmlbeans-sample

Just execute compileJava task using Gradle 4.0 or lower and 4.2.1. With 4.0 or lower everything should work fine but in 4.2.1 version a "package does not exists" error appear.

@wolfs
Copy link
Member

wolfs commented Oct 19, 2017

Hi @cballesteros. Thank you for reporting. Could you provide an example build script where this problem appears? Could you point me to the xmlBeans plugin you are using?

@cballesteros
Copy link
Author

Thanks @wolfs, I'm using this plugin 2.5.0 version. I tried with the latest version but the same error appear. Let me prepare a simple project to reproduce the issue.

@cballesteros
Copy link
Author

@wolfs I just updated the issue description with an example. Thank you!

@wolfs
Copy link
Member

wolfs commented Oct 20, 2017

@cballesteros Thank you for your example! The problem you are experiencing is due to a new feature of Gradle 4.2.1: Safer handling of stale output files.
What is going on in your build is that

  1. The task compileXmlSchemas does not declare any outputs. It creates files in build/gen-classes/xmlbeans and build/gen-src/xmlbeans.
  2. The compileXmlSchemasJava task uses build/gen-classes/xmlbeans as an output directory.
  3. The processXmlSchemasResources task uses the resourcesDir of the xmlSchemas source set as output directory.

As a consequence

  1. Gradle does not know anything about compileXmlSchemas outputting to build/gen-classes/xmlbeans or build/gen-src/xmlbeans
  2. Gradle cleans up build/gen-classes/xmlbeans when compileXmlSchemasJava is executed, since it encounters some files which should not be there.
  3. Gradle cleans up build/gen-src/xmlbeans when compileXmlSchemasResources is executed, since it encounters some files which should not be there.

This problems can be fixed easily. If you declare the output directories of the compileXmlSchemas task, then Gradle will not clean the outputs. This can be done by using

task compileXmlSchemas {
    outputs.dir sourceSets.schemas.output.resourcesDir
    outputs.dir sourceSets.schemas.output.classesDir
}

If you declare some inputs for the task, too, then you will even benefit from incremental build! For more information about inputs and outputs see the userguide chapter about incremental build.
You also should not set the classesDir or resourcesDir on the schema source set (apart from classesDir being deprecated in Gradle 4.0). This will lead to overlapping outputs - i.e. different tasks outputting to the same directory. Use SourceSets.output.dir to register new output dirs for sourceSet. In your case, this would be:

sourceSets {
    schemas {
        output.dir "${buildDir}/gen-classes/xmlbeans", builtBy: 'compileXmlSchemas'
        output.dir "${buildDir}/gen-src/xmlbeans", builtBy: 'compileXmlSchemas'
    }
}

I hope that clarifies things a bit. I am closing this issue as I consider it not being a bug of Gradle. Please re-open if you think otherwise or ask on the forum if you need more help solving your use case.

@wolfs wolfs closed this as completed Oct 20, 2017
@wolfs wolfs self-assigned this Oct 20, 2017
@cballesteros
Copy link
Author

@wolfs I applied the suggested changes and everything works pretty fine for me! I will learn more about inputs and outputs. Thank you!

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

3 participants