Manage generated resources for project in Gradle - gradle

I have a Gradle project which has a lot of resources in the /src/main/resources folder. For performance reasons, some resources have to be generated from other resources at build time. So I split everything up into sub-projects:
/MainProj/src/main/java - The application
/MainProj/src/main/resources
/InternalProj/src/main/java - Code for generating additional resources for MainProj
/InternalProj/src/main/resources
When I run InternalProj using a special Gradle task, it generates some files to /InternalProj/output which I then copy to /MainProj/src/main/resources. Needless to say, this is really ugly and I'd like to know how to do this in a better way. Should I put it somewhere into build or directly into /MainProj/src/main/resources? Maybe use a symlink?
Edit
I now use a relative symlink from /src/main/generated-resources to /build/something and so far it works fine. But now I have a different problem: I have task A that generates some resources and task B that depends on those resources and thus on A. If I run gradle B or gradle A B, B will still fail since the resources generated by A didn't get updated into its build folder. How can I force Gradle to update the resources?

You can add the output file to the main source set of the InternalProj:
Example Groovy Code:
sourceSets {
main {
resources {
srcDirs "src/main/resources", "output"
}
}
}
Related answer: https://stackoverflow.com/a/38982006/3708426

Related

Add a file to a specific folder with gradle build

I am currently working with a project (using gradle) that needs a properties file in the same package to the class that consumes it (I can't change this config). I have added the file in my package, but when I execute the gradle build command omits the file, and only adds the .class file. The app is deployed as a war file.
I have tried editing the war task, but I can't find the way to make the properties file to be added:
war {
from('src/main/com/foo/bar') {
include 'b.properties'
into 'WEB-INF/classes/com/foo/bar'
}
}
The war task does execute (I have added a prinln and it executes). Also, I have tried changing the paths, but no results. Also replacing from('path') to from (file('path')), but still doesn't seem to add the file anywhere.
How should I achieve this? Thanks!
Is there anything stopping you from following Gradle's convention for resources?
Eg put your property file at src/main/resources/com/foo/bar/b.properties
If you do this you won't need any task customisations

Corda: Import a local javascript library into a node

I'm using the J2V8 library to run some javascript functions in the cordapp, but I'm having troubles to access the js files (or refer to them) during runtime, because when the project is built the js code is copied into the build/resources folder, not reachable from any running node (as far as I know).
I realized that I need to include the js source code into the corda.jar files, produced when I run gradle deployNodes.
I tried to add the following to the build.gradle file:
jar {
baseName = 'something'
from('src/main/resources/js_library') {
include '*.js'
}
}
but it doesn't solve my problem. Do I need to extend some tasks in the net.corda.plugins in some way? Or is there a way to access the build/resource folder once the cordapp is running?
The corda.jar is the node JAR that your applications are intended to run on/against and it isn't intended to be modified for apps.
Your own CorDapp JAR should be generated automatically by the "jar" task if you're applying the correct gradle plugin (cordformation for V1, cordapp for later versions). This JAR will be on the classpath and contain all of the files in your resources directory. For example "src/main/resources/js_library" will be available in the root of the CorDapp JAR and can be accessed directly during runtime from the classloader of any of the classes in your CorDapp. See the answer here to learn how to access files within a JAR.

Gradle: consolidating multi project distributions into a single distribution

I'm working on a gradle multi project (java), where some of the sub-projects are applications (have a main class, and are executable) and some others are libraries (e.g, ends up being packaged as a jar, which some other sub-projects define a dependency on). It's working fine.
I'd like to be able to package (tar) the entire project for production, according to some structure that will make it easy for my users to deploy and use later on.
Currently, the distTar task creates a build/distribution/project-name.tar for each application project, and a build/libs/project-name.jar for each non application project, under each project build directory. That's a step in the right direction, but I'd like to consolidate the contents into one thing I can distribute.
As an example, right now after running distTar:
myapp/
README
docs/
services/
service1/
build/
libs/service1.jar
<other build dirs I don't want to distribute>
service2/
build/
distributions/service2.tar
<other build dirs I don't want to distribute>
service3/
build/
distributions/service3.tar
<other build dirs I don't want to distribute>
and the contents of service2.tar are:
service2/lib/service2.jar
service2/lib/some-service2-dependency.jar
service2/bin/service2 (start script)
service2/config.yml
(and similarly for service3.tar).
I'd like my final result to be a single myapp.tar(.gz) that includes a similar directory structure, but only with the production files:
README
docs/
services/
service1/
lib/service1.jar
service2/
lib/service2.jar
lib/some-service-dependency.jar
bin/service2 (start script)
config.yml
service3/
lib/service3.jar
lib/some-service-dependency.jar
bin/service3 (start script)
config.yml
Not sure what is the best way to achieve such a task. Do I create a parent level task that depends on distTar and copies files around, untar'ing stuff, etc? (tried that unsuccessfully).
Many thanks!
UPDATE:
I started doing something along these lines:
distributions {
main {
contents {
into('scripts') {
from {'scripts/sbin'}
}
into('service1') {
from {tarTree(tarFileForProject("service1"))}
}
into('service2') {
from {tarTree(tarFileForProject("service2"))}
}
into ...
}
}
}
distTar.dependsOn([subprojects.clean, subprojects.distTar])
(where tarFileForProject is a simple function that returns the path to the build/distributions/*.tar file of the given subproject name).
It seems to work, but also seems ugly. I wonder if there's a cleaner way to do this.

Gradle embedded Project

Is it possible to embed multiple projects in a single build.gradle?
Something along the lines of:
project projX {
task a << {
}
}
project projY {
task a << {
}
}
Both within the same build.gradle. Is this possible?
I am asking this because I have multiple projects with equivalent task names which I want to execute from the root project, e.g.
gradle a
However the projects contain only automation tasks, which require no source files or resource files at all. Creating subdirectories just for the build.gradle files to be stored seems very ugly to me.
I could live with a solution with different .gradle files for each project, such as: build.gradle (root)
projA.gradle, projB.gradle within the same directory, however embedding project objects in the root build.gradle seems like the better option, if it is available.
project(":projX") { ... }
project(":projY") { ... }
Note that you still need a settings.gradle.
PS: It's not clear to me why you would want multiple projects in your case.

Including a second jar file that's not a dependency into a fat onejar

I have a project that only builds the fat onejar file for testing purposes. Thus, there's a separate testing class that I don't want as a dependency to the main source, but I do want it included into the onejar. Odd scenario, I know.
I'm using the com.smokejumperit.gradle.OneJarPlugin plugin (source here), and clearly it gets the list of files to include in the onejar here:
project.task('oneJar', dependsOn:[project.tasks.jar, project.tasks.typedefOneJar]) {
...
inputs.files([jar.outputs.files, project.configurations.getByName("compile"), project.configurations.getByName("runtime")])
jar.output.files is used for publishing, so I don't want a this second jar file being published, and the two project.configurations would define dependencies for the main source jar, and I don't want this second jar to be a dependency of that either.
This second jar file is built with a task:
task integrationJar(type: Jar) {
from sourceSets.integrationTest.output
classifier = 'integration'
}
... so I can access the resulting FileCollection via integrationJar.outputs.files. If there was a clear way to add that to oneJar.input.files, I'd be golden, but I can't figure out how to do that. I've tried something like this:
oneJar {
dependsOn 'integrationJar'
println integrationJar.outputs.files.getAsPath()
inputs.files.add(integrationJar.outputs.files)
println inputs.files.getAsPath()
}
... but the result for the last print is still missing the integration jar file.
Ideas?
I'm not familiar with the implementation of that plugin, but I'd be surprised if inputs.files determined what gets included. (Usually, inputs is just consumed by Gradle's up-to-date check.) I recommend to try the gradle-one-jar plugin, which appears to be more flexible.

Resources