Gradle bootJar task skip encoding some file - spring-boot

Here is a keystore file in springboot resources directory, when I ran bootJar task I found this file got bigger. I found it was because of a change in a way it was encodes.
I knew maven can solve this issue by adding nonFilteredFileExtension config. But how to solve this problem in Gradle

I solved this problem by setting processResource config.
First I set DupicatesStrategy to EXCLUDE to make sure the first founded file can be inclueded. After that I exclude and then include that file to achieve the purpose.
processResources {
duplicatesStrategy = DuplicatesStrategy.EXCLUDE
from('/src/main/resources') {
exclude("*.keystore")
}
from('/src/main/resources') {
include("*.keystore")
}
}

Related

How do you add text files to the classpath in Gradle? [duplicate]

How do I add config files or any other resources into my jar using gradle?
My project structure:
src/main/java/com/perseus/.. --- Java packages (source files)
src/main/java/config/*.xml --- Spring config files
Expected jar structure:
com/perseus/.. --- Java packages (class files)
config/*.xml --- Spring config files
I came across this post searching how to add an extra directory for resources. I found a solution that may be useful to someone. Here is my final configuration to get that:
sourceSets {
main {
resources {
srcDirs "src/main/resources", "src/main/configs"
}
}
}
Move the config files from src/main/java to src/main/resources.
Thanks guys, I was migrating an existing project to Gradle and didn't like the idea of changing the project structure that much.
I have figured it out, thought this information could be useful to beginners.
Here is a sample task from my 'build.gradle':
version = '1.0.0'
jar {
baseName = 'analytics'
from('src/main/java') {
include 'config/**/*.xml'
}
manifest {
attributes 'Implementation-Title': 'Analytics Library', 'Implementation-Version': version
}
}
By default any files you add to src/main/resources will be included in the jar.
If you need to change that behavior for whatever reason, you can do so by configuring sourceSets.
This part of the documentation has all the details
I ran into the same problem. I had a PNG file in a Java package and it wasn't exported in the final JAR along with the sources, which caused the app to crash upon start (file not found).
None of the answers above solved my problem but I found the solution on the Gradle forums. I added the following to my build.gradle file :
sourceSets.main.resources.srcDirs = [ "src/" ]
sourceSets.main.resources.includes = [ "**/*.png" ]
It tells Gradle to look for resources in the src folder, and ask it to include only PNG files.
EDIT: Beware that if you're using Eclipse, this will break your run configurations and you'll get a main class not found error when trying to run your program. To fix that, the only solution I've found is to move the image(s) to another directory, res/ for example, and to set it as srcDirs instead of src/.
Be aware that the path under src/main/resources must match the package path of your .class files wishing to access the resource. See my answer here.
As I have answered here, for more granularity while configuring the resource directories it's also possible to use srcDir.
sourceSets {
main {
resources {
srcDir "src/main/resources"
srcDir "src/main"
include "configs/**/*.xml"
}
}
}
So, if you have src/main/java/config/*.xml jar structure will have configs/*.xml as asked.
This is for Kotlin DSL (build.gradle.kts).
Add the following code to your subproject or app build.gradle.kts file:
sourceSets {
main {
resources {
srcDirs("src/main/configs", "src/main/misc")
}
}
// OR another notation
// main.get().resources.srcDirs("src/main/configs", "src/main/misc")
}
As mentioned by other answers, files in src/main/resources/ are automatically added to JAR. The srcDirs() function in above code adds its given paths to that existing path so files in those directories will be included in the JAR as well. You can add as many entries as you want.
Note that after adding the above code and syncing your changes with the IDE, some IDEs like IntelliJ IDEA and Android Studio show a helpful icon for those directories to indicate they are resources root directories:

How to set the gradle outout folder for the kotlin2JS plugin?

I have a KotlinJs only project which I use official kotlin2js gradle to build, and no problems there.
How to setup the output folder, currently, the building of subproject will result in a build which locates inside the subproject folder, how to set it to somewhere else? I tried:
sourceSets {
main {
kotlin.outputDir = new File(‘./out/‘)
}
}
and
sourceSets {
main.kotlin.outputDir = new File(‘./out/’)
}
No luck.
What I want is to no matter how many subprojects are there, the output folder should be in some path like ./build/projectA and ./build/projectB, rather than all in their own folder. How to do this?
Currently, it's done through the task configuration, namely setting its kotlinOptions.outputFile:
compileKotlin2Js.kotlinOptions.outputFile = "out/output.js"
It's briefly mentioned in the tutorial: Getting Started with Kotlin and JavaScript with Gradle

Gradle zip task ignores files having filename starting with .#

I have a simple gradle zip task,
I found out any files starting with .# from input folder are ignored
task zipIt(type: Zip) {
from 'input/'
archiveName = 'output.zip'
}
Does someone knows why is so? And how can I override this behavior so I include those files in the zip?
Later edit:
Adding the file pattern explicitly doesn't seem to help
On the other hand, looking over #opal links led me to a solution:
import org.apache.tools.ant.DirectoryScanner
task zipIt(type: Zip) {
doFirst{
DirectoryScanner.removeDefaultExclude("**/.#*")
}
from 'input/'
archiveName = 'output.zip'
}
Expounding on Opal's answer, Gradle uses ANT's default excludes which are as follows:
As of Ant 1.8.1 they are:
**/*~
**/#*#
**/.#*
**/%*%
**/._*
**/CVS
**/CVS/**
**/.cvsignore
**/SCCS
**/SCCS/**
**/vssver.scc
**/.svn
**/.svn/**
**/.DS_Store
Ant 1.8.2 adds the following default excludes:
**/.git
**/.git/**
**/.gitattributes
**/.gitignore
**/.gitmodules
**/.hg
**/.hg/**
**/.hgignore
**/.hgsub
**/.hgsubstate
**/.hgtags
**/.bzr
**/.bzr/**
**/.bzrignore
The .# is by default excluded. Updating your build.gradle file with a task similar to the following should allow you to overwrite the default excludes.
task copyPoundFiles(type: Copy) {
from '/path/to/files'
into '/dest/for/files'
include '**/.#*'
}
As far as I remember gradle used the same default excludes as ant does. Have you tried including the file explicitly?
Please have some further reading here and here.

How do I copy a file into my WAR based on profile?

I’m using Gradle 2.7 on Mac Yosemite. I have the following files:
src/main/environment/dev/context.xml
src/main/environment/qa/context.xml
src/main/environment/prod/context.xml
What I would like is if I run a build gradle -Pqa build, the appropriate context.xml file above is copied into my WAR (into the WEB-INF/classes directory is fine). How do I set this up with gradle?
There're many ways of solving the problem. You can configure sourceSets, or include or exclude particular resources when building war file. You can also have single context.xml and perform resource filtering with ReplaceTokens filter.
I've chosen sourceSets:
apply plugin: 'war'
ext.env = project.hasProperty('env') ? project.env : 'dev'
sourceSets {
main {
resources {
srcDir "src/main/environment/$env"
}
}
}
The trick is to include/process only the env being passed. If no env is passed dev will be picked for further processing. Have a look a the demo.
You would have to do that using the environment variable. Have the system properties in a file. Read them in the build.gradle and based on it include the context.xml into the war.

How to expand property references in jar resources?

I'm using Gradle to build a jar containing an xml file in META-INF. This file has a row like
<property name="databasePlatform" value="${sqlDialect}" />
to allow for different SQL databases for different environments. I want to tell gradle to expand ${sqlDialect} from the project properties.
I tried this:
jar {
expand project.properties
}
but it fails with a GroovyRuntimeException that seems to me like the Jar task attempts to expand properties in .class files as well. So then I tried
jar {
from(sourceSets.main.resources) {
expand project.properties
}
}
which does not throw the above exception, but instead results in all resources being copied twice - once with property expansion and once without. I managed to work around this with
jar {
eachFile {
if(it.relativePath.segments[0] in ['META-INF']) {
expand project.properties
}
}
}
which does what I want, since in my use case I only need to expand properties of files in the META-INF directory. But this feels like a pretty ugly hack, is there a better way to do this?
I stumbled across this post in a thread about a different but closely related issue. Turns out you want to configure the processResources task, not the jar task:
processResources {
expand project.properties
}
For some reason, though, I did have to clean once before Gradle noticed the change.
In addition to #emil-lundberg 's excellent solution, I'd limit the resource processing to just the desired target file:
build.gradle
processResources {
filesMatching("**/applicationContext.xml") {
expand(project: project)
}
}
An additional note: if the ${...} parentheses are causing "Could not resolve placeholder" errors, you can alternatively use <%=...%>. N.B. tested with a *.properties file, not sure how this would work for an XML file.
I've had similar problems migrating from maven to gradle build. And so far the simplest/easiest solution was to simply do the filtering yourself such as:
processResources {
def buildProps = new Properties()
buildProps.load(file('build.properties').newReader())
filter { String line ->
line.findAll(/\$\{([a-z,A-Z,0-9,\.]+)\}/).each {
def key = it.replace("\${", "").replace("}", "")
if (buildProps[key] != null)
{
line = line.replace(it, buildProps[key])
}
}
line
}
}
This will load all the properties from the specified properties file and filter all the "${some.property.here}" type placeholders. Fully supports dot-separated properties in the *.properties file.
As an added bonus, it doesn't clash with $someVar type placeholders like expand() does. Also, if the placeholder could not be matched with a property, it's left untouched, thus reducing the possibility of property clashes from different sources.
here is what worked for me (Gradle 4.0.1) in a multi-module project:
in /webshared/build.gradle:
import org.apache.tools.ant.filters.*
afterEvaluate {
configure(allProcessResourcesTasks()) {
filter(ReplaceTokens,
tokens: [myAppVersion: MY_APP_VERSION])
}
}
def allProcessResourcesTasks() {
sourceSets*.processResourcesTaskName.collect {
tasks[it]
}
}
and my MY_APP_VERSION variable is defined in top-level build.gradle file:
ext {
// application release version.
// it is used in the ZIP file name and is shown in "About" dialog.
MY_APP_VERSION = "1.0.0-SNAPSHOT"
}
and my resource file is in /webshared/src/main/resources/version.properties :
# Do NOT set application version here, set it in "build.gradle" file
# This file is transformed/populated during the Gradle build.
version=#myAppVersion#
I took your first attempt and created a test project. I put a pom file from a jenkins plugin in ./src/main/resources/META-INF/. I assume it is a good enough xml example. I replaced the artifactId line to look like the following:
<artifactId>${artifactId}</artifactId>
My build.gradle:
apply plugin: 'java'
jar {
expand project.properties
}
When I ran gradle jar for the first time it exploded because I forgot to define a value for the property. My second attempt succeeded with the following commandline:
gradle jar -PartifactId=WhoCares
For testing purposes I just defined the property using -P. I'm not sure how you are trying to define your property, but perhaps that is the missing piece. Without seeing the stacktrace of your exception it's hard to know for sure, but the above example worked perfectly for me and seems to solve your problem.

Resources