Gradle tomcat plugin and properties files - java

I would like to use the gradle tomcat plugin in order to do integration tests with gradle. The current project relies on some .properties files underneath the running tomcat's catalina.base directory (cannot be changed because another dependent project relies on them as well).
Does anybody know how to deploy those files to the embedded tomcat instance?

I figured out it's just a simple copy task issue. Here's my solution:
task copyDMConfigFiles << {
def srcDir = new File('src/test/resources/conf')
if(!srcDir.isDirectory())
println "Outlet configuration files missing!!!"
def buildDir = new File('build/tmp/tomcatRunWar/conf')
if(!buildDir.isDirectory()) {
println "Outlet target directory missing. Creating one"
buildDir.mkdirs()
}
copy {
from(srcDir)
into(buildDir)
include '**/*.properties'
include '**/*.xml'
}
copy {
from('src/main/webapp/WEB-INF')
into('build/tmp/tomcatRunWar/work/Tomcat/localhost/digitalmedia/WEB-INF')
include 'web.xml'
include 'dispatcherservlet.xml'
}
}

Related

Maven Plugin: Manipulate resources during packaging

in my maven project, I've got a xml file in resources. Depending on some input parameter I want the file to be adapted before packaged into a jar or war. Of course, the original file shall not be touched.
It is not an option to create multiple xml-files and select a suitable one, for example, with spring profiles as there can be numerous combinations of contents in the xml file.
So, I thought of creating a maven plugin, that manipulates the file before packaging. Probably, I need to manipulate the file, when maven has copied the file to the target folder but before maven packages the file into the jar/war.
#Mojo(name = "manipulate-xml", defaultPhase = LifecyclePhase.PREPARE_PACKAGE)
public class MyMojo extends AbstractMojo {
#Parameter(defaultValue = "${project}", required = true, readonly = true)
MavenProject project;
#Parameter(property = "option")
String option;
public void execute() throws MojoExecutionException {
if (option.equals("optionA")) {
// get file from target and manipulate
} else if (option.equals("optionB")) {
// get file from target and manipulate
}
}
}
Then, I could embedded the maven plugin into my project and build the project with
mvn clean package -Doption=optionA
However, now I am stuck. I do not know, how to get the file from target and even if this is the right approach.
Besides, is it possible during the packaging to prevent some dependencies from being packaged into the jar/war?
I appreciate any help.
Depending on what manipulating means, you can use the possibilities of the maven resources plugin (https://maven.apache.org/plugins/maven-resources-plugin/index.html).
If you need to modify some simple values inside the xml, use properties in the xml and let the resources plugin replace them during build. The values for the build can be either in the pom.xml or given to maven via -Dproperty=value.
If you want to select a different files, define multiple maven profiles, in each you can configure the resources plugin to copy only the wanted files and then select the correct profile in the build.
If the built-in possibilities are not enough, you might even program your own filter for the resources plugin, that might be easier than writing a custom full fledged maven plugin.

Gradle set name for jar created with spring-boot's assemble

I want to create an executable jar with gradle (kotlin-dsl) and I want to give it a custom name. For the executable jar I'm using the spring boot plugin and ./gradlew :app1:assemble:
plugins {
id("myproject.java-application-conventions")
id("org.springframework.boot") version "2.2.2.RELEASE"
}
dependencies {
implementation(project(":lib"))
}
application {
mainClass.set("org.myproject.app.Main")
}
init created two more files, buildSrc/build.gradle.kts:
plugins {
`kotlin-dsl`
}
repositories {
gradlePluginPortal()
mavenCentral()
}
and buildSrc/src/main/kotlin/myproject.java-application-conventions.gradle.kts:
plugins {
id("lomboker.java-common-conventions")
application
}
With ./gradlew :app1:assemble I can create an executable jar but I don't see how I can set its name.
This question deals with naming jars but I don't know how to apply any answers to my problem.
Adding a jar block to my gradle file does not work: Expression 'jar' cannot be invoked as a function. it is interpreted as sun.tools.jar.resources.jar. So I try tasks.jar instead.
For
tasks.jar {
archiveBaseName.set("myapp")
archiveVersion.set("version")
}
./gradlew :app1:jar while building successful creates no jar (it wouldn't be executable anyway) and ./gradlew :app1:assemble ignores the properties and just creates ./app1/build/libs/app1.jar.
Since I'm not using jar but assemble I guess I should use a tasks.assemble block. But that doesn't recognize archiveBaseName or archiveVersion and I don't know what the API is.
This is the page: https://plugins.gradle.org/plugin/org.springframework.boot but I find no API.
assemble is a lifecycle task which means that it doesn’t create anything. Its role is to trigger other tasks that it depends upon and that do have some output. You can see those tasks by running your build with --console=plain.
The task that creates the Spring Boot fat jar is named bootJar. As you can see from its javadoc, it’s a customization of Gradle’s Jar and can be configured in the same way:
tasks.bootJar {
archiveBaseName.set("myapp")
archiveVersion.set("version")
}

gradle: downloading specific file from ivy repository

We use an internal ivy repository and are in the process from moving away from ant / ivy and tasking everything in gradle. I have my ivy repository set up in gradle as so:
repositories {
ivy {
url "${ivy_repository_url}"
layout "pattern", {
ivy "repository/[organisation]/[module]/[revision]/[artifact].[ext]"
artifact "repository/[organisation]/[module]/[revision]/[artifact].[ext]"
m2compatible = true
}
credentials {
username "${ivy_repository_username}"
password "${ivy_repository_password}"
}
}
}
and upon executing a task it resolves as expected, however, in some instances it pulls down everything in the repository if the naming convention doesn't match so I end up with a lot of extra stuff, javadocs.zip, sources.zip and everything else.
To get around this I want to download the specific jar files to a temp folder first and then compile them from local but I have no clue how to tell gradle to download a file that is named differently from the module name.
Example:
ivyFiles 'net.sourceforge.jtidy:jtidy:r938#jar'
downloads just jtidy-r938.jar from the net.sourceforge.jtidy repository but something like
ivyFiles 'com.gargoylesoftware:htmlunit:2.7#jar'
would pull htmlunit-2.7.jar but not the file htmlunit-core-js-2.7.jar.
If I omit the #jar it reverts to calling the ivy.xml file and I am left with all the junk + dependencies which I am trying to avoid. I have tried the following with no success
ivyFiles ('com.gargoylesoftware:htmlunit:2.7'){
artifact{
name = 'htmlunit-core-js'
type = 'jar'
}
}
There must be a way to do this.
Thank you
I figured it out. This is what I ended up doing
ivyFiles ('com.gargoylesoftware:htmlunit:2.7'){
transitive = false
artifact {
name = 'htmlunit-core-js'
extension = 'jar'
type = 'jar'
}
}
Now only the htmlunit-core-js-2.7.jar file was downloaded

Gradle Project Resources Not Added to Classpath

I've been tasked with write some base classes for automated integration tests for an existing project, and I've run into a snag with project dependencies.
The (abstracted) project layout is this:
project /
MainProject
Plugins /
...
ConfigurationProject
IntegrationTestProject
IntegrationTestProject has a dependency upon ConfigurationProject, the latter having the following layout:
ConfigurationProject/
PluginConfigs/
<plugin configuration files>
<main configuration files>
Notably, the main configuration files reside in the root of the project. In an attempt to add them to my classpath, my primary build.gradle has the following:
project('ConfigurationProject') {
description = 'Configuration'
sourceSets.main.resources.srcDir projectDir
}
This seems to look okay, as eclipse shows all files in root as being part of the project resources, and assembling packages everything up as expected.
However, when I actually go to run the integration tests, the ConfigurationProject resources do not seem to be in the classpath, as it fails to pull config information, further confirmed by the lack of ConfigurationProject present in outputs from this snippet:
public void classpathScanner() {
ClassLoader c=getClass().getClassLoader();
System.out.println("c="+c);
URLClassLoader u=(URLClassLoader)c;
URL[] urls=u.getURLs();
for (URL i : urls) {
System.out.println("url: "+i);
}
}
The ConfigurationProject is included in IntegrationTestProject using the IntegrationTestProjects gradle.build
dependencies {
compile project(':ConfigurationProject')
}
I have only observed this problem when adding the project root as a resource, addng subfolders of a project to sourceSets seems fine (and is used elsewhere in this project). Moving the configuration files to a subfolder is an option I have considered, and will enact if I find no other solution, but I wanted to see if there were options that did not involve this course of action.
The answer to this is essentially "don't make project root a resource folder, Gradle hates that, and even if it didn't, it's bad form anyway" I fixed this by placing the configuration files to a more sensible resource path.

Gradle with Eclipse - resources are not filtered

I have a gradle configuration setup to filter some resources and substitute properties depending on the environment (e.g. dev, production). These are located at:
src/main/resources/config.xml
WebContent/WEB-INF/web.xml
An example of a property from my web.xml file is below:
<context-param>
<param-name>server.url</param-name>
<param-value>${server_url}</param-value>
</context-param>
An excerpt from my build.gradle is presented below:
apply plugin: 'eclipse-wtp'
processResources {
expand(props) // filter properties by environment
exclude 'log4j.properties'
}
war {
from 'WebContent'
exclude('WEB-INF/web.xml')
webInf {
from 'WebContent/WEB-INF/web.xml'
expand(props)
}
webXml = null
}
This works fine when I build a war from the command-line, but when I use this configuration from Eclipse it does not seem to filter the resource appropriately.
I previously had the Maven plugin working where the resources would get filtered as a part of the Eclipse build. Is it possible to get Eclipse to filter the resources?
You should use webAppDirNameproperty for your project and remove the manuell stuff in war { ... } block. I am not sure which Gradle version introduced this property but at least 2.0. See also http://www.gradle.org/docs/current/userguide/war_plugin.html.
Afterwards gradle eclipse should generate proper Eclipse artifacts to build your war or directly deploy to any server using wtp!

Categories