I have a published gradle plugin which looks something like this:
|__root
| |
| |
| |__java
| | |__SomeJavaClass.java
| | |__SomeJavaClass2.java
| |
| |__kotlin
| |__MyPluginClass.kts
| |__MyTaskClass.kts
| |__Utils.kts
I would like to include this plugin as a project in my multi project build instead of publishing it to a repo for easier developement.
This plugin has 3 Kotlin files Project A is using. MyPluginClass.kts has my own plugin class, MyTaskClass.kts has my own task class and Utils.kts contains only kotlin functions. The java classes are used in MyPlugin and MyTask.
It is being put on Project A's build.gradle.kts classpath as
classpath("com.my:custom.plugin:version")
A very simplified project structure I would like to achieve:
root
|
|__Project A
| |
| |__build.gradle.kts
| |__x.gradle.kts
| |__y.gradle.kts
| |__settings.gradle
|
|__Project build-logic
| |
| |__build.gradle.kts
| |
| |__java
| | |__SomeJavaClass.java
| | |__SomeJavaClass2.java
| |
| |__kotlin
| |__MyPluginClass.gradle.kts
| |__MyTaskClass.gradle.kts
| |__Utils.gradle.kts
I'm trying to create plugins from those kotlin files and include them in my main build because i need them precompiled, but i cant seem to find a way to put them on Project A's classpath when build.gradle is running there. Is it even possible? what would be the proper solution?
I'm using gradle 7.3
You can combine multiple, independent, Gradle projects using composite builds. The same is also true for Gradle plugins.
Including a Gradle plugin from another directory is documented in the Testing Gradle plugins section.
So if you have a shared-build-logic project that provides a Gradle plugin with an ID my.shared-build-logic, and you want to use that in project-a.
my-projects/
├── shared-build-logic/
│ ├── src/
│ │ └── ...
│ ├── build.gradle.kts
│ └── settings.gradle.kts
└── project-a/
├── src/
│ └── ...
├── build.gradle.kts
└── settings.gradle.kts
Then you need to include shared-build-logic in your project-a Gradle settings file.
// my-projects/project-a/settings.gradle.kts
rootProject.name = "project-a"
pluginManagement {
includeBuild("../shared-build-logic")
}
Now, so long as shared-build-logic correctly provides a Gradle plugin, in project-a you can reference that plugin.
// my-projects/project-a/settings.gradle.kts
plugins {
id("my.shared-build-logic")
}
Finnaly figured out. I didn't create plugins from build-logic, left them as kotlin files. Since it is a separate gradle project, i can just build the project and point project A's classpath to the produced jar file like
buildscript {
dependencies {
classpath(files("path.to.the.jar"))
}
}
this way i can access methods and the MyTask from Project A.
The other issue was that i wanted to apply MyPlugin like
plugins{
id("my-plugin-name")
}
which wasnt working, i guess because it is a class. But now since i had the whole project jar on my build classpath, i can do this:
apply<my-plugin-name>()
Related
I have a gradle multiple projects. The structure is like below:
|--MyProject
| |--ejb-project
| | --build.gradle
| |--spring-project
| --com.mine.demo
| --Test.java
| | --build.gradle
| |--build.gradle
| |--settings.gradle
in the settings.gradle
include: ':ejb-project'
include: ':spring-project'
I defined a Test.java in the spring-project.
Now, if I wanna use Test.java in the EJB projects, How can I use it? Are there configurations to be configured?
Questions can be simplfy as this: Can I use a class from spring project in a ejb project within a gradle(or maven) multiple projects? If can, How can I use it?
I've never done this before, so barely know how to integrate spring in ejb. HELP!
Previously I have worked with multi-module Maven projects that consisted out of two hierarchies. The parent POM followed by modules in their own directories and POMs.
But now I have taken over a project that contains a parent, followed by modules which again contain modules.
Is this all according to Maven guidelines or am I dealing with something customized?
And how to I interpret these sub-modules? Know a guide you can point me to?
I can run all Maven lifecycles successfully. Though I'm unsure whether and how to refactor the application and start inserting my own code.
Here is a tree of my project structure with only a few modules left:
top-parent
| pom.xml (modules: applications, checks, core, test)
|
+---applications
| | pom.xml (parent: top-parent) (modules: batch, surefire, web)
| <parent>
| <artifactId>applications</artifactId>
| <groupId>com.a.b.codechecker</groupId>
| <version>1.0</version>
| </parent>
| <artifactId>batch</artifactId>
|
| |
| \---web
| | pom.xml
| <parent>
| <groupId>com.a.b.codechecker</groupId>
| <artifactId>applications</artifactId>
| <version>1.0</version>
| </parent>
| <artifactId>web</artifactId>
|
+---checks
| | pom.xml (parent: top parent) (modules: aggregator, blacklist-check)
| <parent>
| <groupId>com.a.b.codechecker</groupId>
| <artifactId>parent</artifactId>
| <version>1.0</version>
| </parent>
| <groupId>com.a.b.codechecker.checks</groupId>
| <artifactId>checks</artifactId>
| |
| +---aggregator
| | pom.xml
<parent>
<artifactId>checks</artifactId>
<groupId>com.a.b.codechecker.checks</groupId>
<version>1.0</version>
</parent>
<artifactId>aggregator</artifactId>
I provide below few outlines.
As per the question,
Is this all according to Maven guidelines or am I dealing with something customized?
Yes, you can have Parent, Child, Grand child type module structure.Parent and Child type maven multi module hierarchy is simple, but in some cases, developers design to have several sub modules inside a module. If you have large project having n number of modules and m number of submodules, it becomes complex for different levels of developers.
As per this question,
And how to I interpret these sub-modules? Know a guide you can point me to?
It is upto the development team about how to manage for simplicity. I would recommend, if you have many sub modules, you can create/maintain another independent project and you can add the dependency to the main project wherever it is required. It will provide you the granularity and a separate team work on this project without considering the main project.
In case of large project, it is always recommended to maintain independent projects and you can add the dependency in other projects. For this you can use Nexus or Artifactory for artifact management.
I have a Spring Boot project where project structure looks like below
example(artifactId = example)
+- demo(artifactId = demo)
| +- src
| | +-main
| | +-java
| | +-com
| | +-example
| | +-DemoService
| | +-resources
| | +-application.properties
| +- pom.xml
+- demo2(artifactId = demo2)
| +- src
| | +-main
| | +-java
| | +-resources
| | +-application.properties
| +- pom.xml
+-pom.xml
In this project "demo2" is the dependency of "demo". The "example" module is the parent of both demo and demo2. The
The problem is that when I set the property(site.password=password) in application.properties of demo, I can't resolve it in demo module like this
#Service
public class DemoService {
#Value("${site.password}")
private String password;
}
But if I set it to the application.properties in demo2, it can be solved in the DemoService in demo module.
Thanks in advance!
To clarify:
Demo2 is the main class.
You have the same classpath resource (classpath:application.properties) on both jars, only one will be visible. Usually, configuration should not be packaged in a jar. It should be specified in the package with main method (demo2 in your case).
You can also specify some default values for #Value annotations like: #Value("${site.password:mypassword}") Details
If you still want to include properties in a jar, try putting it in a unique directory like: src/main/resources/com/example/demo.properties and include it in demo2 via spring.config.location.
Application properties packaged inside your jar takes precedence, more details can be found there https://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-external-config.html
But you can also set which properties file to use like this
--spring.config.location=classpath:/mydefault.properties
In light of a recent problem I had, I would like to make sure it does not happen again. Kind of like a regression test for my build system.
I need a way to scan an ear (or other jar style package) to make sure a class is only once in it.
Example:
- test.ear
| - lib (folder)
| | - api.jar (zipped file)
| | - packageName
| | - ClassName.class
| - connector.rar (zipped file)
| - api.jar (zipped file)
| - packageName
| - ClassName.class
| - ejbs.jar
The pom.xml of ejbs.jar has a dependency on the api that brings the api.jar to the lib folder. The pom.xml of the connector.rar also has a dependency on the api that brings the api.jar to the connector.rar file, so while the reference to the same dependency, it still causes the above result.
As I have a maven build I'm looking for a way that integrates well there (if possible).
There's this enforcer rule you can use. Have a look at http://www.mojohaus.org/extra-enforcer-rules/banDuplicateClasses.html
A JUnit book says " protected method ... this is one reason the test classes are located in the same package as the classes they are testing"
Can someone share their experience on how to organize the unit tests and integration tests (package/directory wise)?
I prefer the maven directory layout. It helps you separate the test sources and test resources from your application sources in a nice way and still allow them to be part of the same package.
I use this for both maven and ant based projects.
project
|
+- src
|
+- main
| |
| +- java // com.company.packge (sources)
| +- resources
|
+- test
|
+- java // com.company.package (tests)
+- resources
in my build process, the source directories are
java/src
java/test/unit
java/test/integration
The test and the source code are in different paths, but the packages are the same
java/src/com/mypackage/domain/Foo.java
java/test/unit/com/mypackage/domain/FooTest.java
java/test/integration/com/mypackage/domain/FooTest.java