Non-source files form src/main/java as resources and excluding *.java


(Wujek Srujek) #1

I need to pull all files under src/main/java which are not *.java files to resources (like hbm.xml files or html). I have the following code:

sourceSets {
  main {
    resources {
      srcDirs java.srcDirs as File[]
    }
  }
}
  sourceSets.main.resources.srcDirs.each { println it }

and this seems to work, but I have a few questions:

  1. if I don’t use the ‘as File[]’ cast, I get a warning and it doesn’t work, as there is no srcDirs method on SourceDirectorySet doesn’t have an overload for file (the warning I get is: Converting class java.util.LinkedHashSet to File using toString() method has been deprecated and is scheduled to be removed in Gradle 2.0. Please use java.io.File, java.lang.String, java.net.URL, or java.net.URI instead.) According to the docs the ‘as File[]’ should not be required. 2. how does this actually work? why are the *.java files from src/main/java filtered out, but if I put a java file to src/main/resources, it is not? who does this filtering? 3. I can only define exclude / include rules per sourceset, not per directory within a source set, right?

wujek


(René Groeschke) #2
  1. You get the warning because the ‘srcDirs’ accepts single Objects which can be converted to a File or an Array of Objects which can be converted. Passing a Set is not supported. Have a look at the Documentation of SourceDirectorySet. One point to mention is, that you might want to use “srcDirs = …” instead.

  2. All Java files which are part of the java SourceDirectorySet are automatically filtered out in the resource SourceDirectorySet

  3. Right, this is a “todo” in SourceDirectorySet.

cheers, René


(Wujek Srujek) #3

Thank you for your time to answer.

  1. I had taken a look at the docs before I came here, I actually spent quite some time looking for the problem, no worries ;d The method is:
SourceDirectorySet srcDirs(Object... srcPaths)
Adds the given source directories to this set.
Parameters:
srcPaths - The source directories. These are evaluated as per Project.files(Object...)

So, the method can be called with a single argument, and delegates to (I don’t know the code, this is only what I know from the Javadoc) Proect.files. And then, Project.files(Object…) Javadoc says it supports collections, which a Set definitely is, but tried toStirng on the argument. How come? I don’t want 'srcDirs = ’ in this case because I want to keep the already defined directories, in the example src/main/resources configured by the java plugin.

  1. Is this documented somewhere? Could you please point me to some text that describes how this exactly works? And where is this configured? Can this be overridden, say, when I do want all *.java files to land in resources? Running this:
sourceSets.main.java.filter.with {
  it.excludes.each { println "exclude: $it" }
  it.includes.each { println "include: $it" }
}

got me this:

include: **/*.java

so I have no idea where and when this exclusion happens. Does the ‘java’ SourceDirectorySet do it, or is the ‘resources’ one?

wujek


(Wujek Srujek) #4
  1. So the code doesn’t delegate to Project.files() at all, it eventually calls FileOrUriNotationParser.parseNotation(Object), which only handles: File, URL, URI, CharSequence (also with uri notation) or else logs a warning and calls toString on the object (like the LinkedHashSet in this case). Which makes it supports much much less than Project.files() does: no collections, no iterables, no closure and so on. Isn’t this a bug, either in the implementation being more restricted than Project.files(), or in the user guide / dsl api / javadoc?

  2. I got it now how the .java files are filtered out - this all happens in DefaultSourceSet, when the ‘resouces’ (and others, like allJava etc.) are created, there is an implicit filter applied that removes all files from the ‘javaSource’ property from ‘resources’. I guess this makes it impossible to simply contain src/main/java/**/.java as resources without extra configuration. But, there exists a way to do it nicely:

sourceSets {
  main {
    resources {
      source java
    }
  }
}

The ‘source’ method adds all dirs from the SourceDirectorySet that it takes as argument and voilla!

Should I file a bug for #1 about the API / implementation inconsistency?

wujek