Maven Archetype With Custom File Structure - maven

I am trying to use Maven Archetypes to create a basic directory structure for a new project that is just a parent to several child projects. The structure inside archetype-resources looks like this:
root
|--- pom.xml
|--- subproject1
| \--- foo.xml
|
\--- subproject2
\--- bar.xml
Instead of generating this structure, I get the following error:
Template 'subproject1/foo.xml' not in directory 'src/main/java'
Is there a way to tell Maven to not assume the archetype is generating a Maven Java project?

Related

Share dependency versions between Maven (pom.xml) and Gradle (build.gradle)

I have projects built by Maven and Gradle. Is there a way to define dependency versions in a text file, e.g.:
.
|-- dep-versions.properties
|
|-- proj-by-gradle
| |-- build.gradle
| `-- settings.gradle
|
`-- proj-by-maven
`-- pom.xml
Is there an easy way to specify in dep-versions.properties, something like:
com.google.guava:guava = 26.0-jre
org.apache.commons:commons-pool2 = 2.5.0
And then use these versions in both the pom.xml and build.gradle?
You can create a BOM pom (Bill of materials) and use it in both builds. Support for importing maven BOM files was added to Gradle in version 4.6: https://docs.gradle.org/4.6/release-notes.html#bom-import

How many gradle files can inherit from one another? How "deep" can subprojects be?

I have a project with the following structure:
Root project 'ExampleProject'
+--- Project ':client'
| +--- Project ':client:android'
| +--- Project ':client:core'
| +--- Project ':client:desktop'
| +--- Project ':client:html'
| \--- Project ':client:ios'
+--- Project ':common'
+--- Project ':editor'
\--- Project ':server'
There is one settings.gradle like so:
include ":client", ":common", ":editor", ":server",
"client:desktop", ':client:android', ':client:ios',
':client:html', ':client:core'
rootProject.name = "ExampleProject"
There are build.gradle files at every level. There is one at the project root, one at the client root, one at client:android root, etc.
It appears that the client:android is not inheriting plugins,etc from the build.gradle for the :client project. Is there a maximum (of 2?) of how many build.gradle files can be "chained" and inherited from?
The client build.gradle has a block like this that is not being inherited:
project(":client:android") { //plugins and dependencies here
}
There is no special parent-child relationship in gradle other than the root project and all other modules. Meaning there is no core concept of a subproject that is also a "parent" to it's own subprojects. The documentation seems a little misleading in that respect. It says: "Properties and methods declared in a project are inherited to all its subprojects." But I think this really only relates to the root build.gradle and all others, it is not recursive. Maybe that already answers your question.
Why inheritance is not desired
It is also generally undesirable to have any such concept, because gradle tries to be as fast as possible by being modular and incremental. So build.gradle files should be self-sufficient without needing any parent to run (other than the root build.gradle). This is a fundamental difference to Maven, which relies heavily on inheritance to avoid duplicating XML code.
So while you could write custom gradle code to achieve this kind of inheritance, you probably should not. Instead to share gradle code, you should prefer composition (apply from), add custom code/custom plugins in the buildSrc folder, or define submodule groups in the root build.gradle file.
Workaround for this kind of project setup
So what several gradle projects would do is to define all subproject groups and their configuration in the root build.gradle file like so:
def clientProjects() {
return subprojects.findAll {
// some predicate that is true only for client projects
}
}
configure(clientProjects()) {
apply plugin: ...
}

Gradle multiproject doesn't add projects to classpath

I have some projects that depend on others. I also have a project that depends on two projects that each one depends on the same project. Something like this:
-Project A
* Project 1
** Project C
* Project 2
** Project C
And the structure of the workspace is like this:
-ProjectA
-ProjectC
-Project1
-Project2
All the projects are at the same level.
So in the settings.gradle in my Project A I have:
include ':Project1',':Project1:ProjectC',[...]
project(':Project1') = new File('../Project1')
project(':Project2') = new File('../Project2')
project(':Project1:ProjectC') = new File('../ProjectC')
project(':Project2:ProjectC') = new File('../ProjectC')
And in the build.gradle I do:
dependencies{ compile project('Project1'),project('Project2')
The problem is that it is not correctly added to the classpath. I think since both Project1 and Project2 depends on ProjectC it is overwritten somehow. Any ideas?
Thanks.
EDIT
Here is the tree of dependencies:
Root project 'ProjectA'
+--- Project ':ProjectB'
| \--- Project ':ProjectB:Project1'
| +--- Project ':ProjectB:Project1:Project2'
| \--- Project ':ProjectB:Project1:Project3'
\--- Project ':ProjectC'
\--- Project ':ProjectC:Project1'
+--- Project ':ProjectC:Project1:Project2'
\--- Project ':ProjectC:Project1:Project3'
For a workspace that looks like this:
rootFolder
|
|- build.gradle
|- settings.gradle
|
|- ProjectA
| |-build.gradle
|
|- Project1
| |-build.gradle
|
|- Project2
| |-build.gradle
|
|- ProjectC
|-build.gradle
Your settings.gradle should look like this (irrespective of dependency relationships of the sub projects):
include ':ProjectA',':Project1',':Project2',':ProjectC',
You're just telling the root project that there are 4 subprojects and where they are located. That's it.
Now the dependency relationships are handled inside each subproject's build.gradle files. For a dependency relationship that looks like this:
ProjectA
|-Project1
| |-ProjectC
|
|-Project2
|-ProjectC
ProjectA's build.gradle:
dependencies{
compile project(':Project1')
compile project(':Project2')
}
Project1's build.gradle:
dependencies{
compile project(':ProjectC')
}
Project2's build.gradle:
dependencies{
compile project(':ProjectC')
}
What I finally did is change in the classpath the paths that where wrong like this:
build.gradle
eclipse{
classpath{
file{
whenMerged { classpath ->
classpath.entries.find { entry ->
entry.kind == 'src' && entry.path.contains('ProjectC')
}.each{ entry ->
entry.path=file("/ProjectC")
}
}
}
}
}
And it works fine. I still don't know why gradle doesn't make the classpath correctly...

How to get this maven multi-project setup right (war + jars + static files)?

We have a (until now) small project, which consists of 4 eclipse projects. The main project consists of all the needed libs and an Ant script.
Now we want to convert this project(s) to Maven, while keeping the project stucture.
How it works:
Ant script compiles all projects (without main) to jar files
Ant script copies all those jar files into the lib folder of the main project
Ant script copies some static files (html, css, js, etc.) from the modules into some corresponding folders of the main project
Ant generates a war archive of the main project
The (maybe) problem with Maven:
All projects depend on main project
so I think it's not possible to use Maven's normal compiling behaviour
I read a bit about Maven's possibilities and it looks like the assembly plugin could solve the problem?! But I don't know how to get all that stuff working...
I thought of this project layout:
+ parent-pom (with packaging: pom)
- main-war (packaging: war)
- module1 (packaging: jar, depends on main-war)
- module2 (packaging: jar, depends on main-war)
- module3 (packaging: jar, depends on main-war and module1)
Now the parent-pom must have the <build> directive with the assembly plugin I think?
Please help me. Thank you :)
I would first suggest to change the structure of your project which means having the following folder layout:
+-- root (pom.xml packaging: pom)
+--- module1 (packaging: jar: depends on: module-common)
+--- module2 (packaging: jar: depends on: module-common)
+--- module3 (packaging: jar: depends on: module1, module-common)
+--- module-common (packaging: jar)
+--- module-war (packaging: war, depends on: module1, module2, module3)
The mentioned dependency to the war module does not make sense, cause usually you have a module which depends on an other but not on a war mdoule. So to solve that problem the simplest solution is to introduce a separate module-common which should take the code which is common for all modules. The war module has folders for html, static files etc. with a layout like the following:
.
|-- pom.xml
`-- src
`-- main
|-- java
| `-- com
| `-- example
| `-- projects
| `-- SampleAction.java
|-- resources
| `-- images
| `-- sampleimage.jpg
`-- webapp
|-- WEB-INF
| `-- web.xml
|-- index.html
`-- jsp
`-- websource.jsp
If you handle the things in a a structure like the above you don't need to use assembly plugin or what ever plugin to copy files etc. it will be handled by default. As a result you will get a war file which contains the things you need.

using common profile and filter in maven

I have 3 modules which are linked to a parent project similar to this.
root (pom.xml)
+--- mod1 (pom.xml)
+--- mod2 (pom.xml)
+--- mod3 (pom.xml)
Mod3 is the module used for packaging purposes. I have some configuration files in config folder of mod1 and mod2. I need to update some values in these property files using profile and filter. Is it possible to have a common profile and filter for these two modules. If so in which pom.xml should I include the profile and filter details.
You can define the same profile in all modules (with the same id), and when you call this profile from the paren module, this profile will be activated in child modules.
If you execute from parent module
mvn -P test clean package
It produces the same call in the tree call modules.
So in each pom.xml you specify what filtering you need.
Hope this help.

Resources