Sreenivas
01/27/2025, 1:55 PMrootProject.name = 'my-root-project'
include 'platform'
include 'api-container-framework'
rootproject's build.gradle
plugins {
id 'java-platform'
id 'maven-publish'
}
ext {
repoConfig = {
url = uri(myserver)
credentials {
username = repoUsername
password = repoPassword
}
allowInsecureProtocol true
}
}
allprojects {
repositories {
//for fetching dependencies...
maven repoConfig
}
}
subprojects {
//except platform, remaining need to be published as jars...
//if (project != project(':platform')) {
apply plugin: 'maven-publish'
//}
publishing {
repositories {
//repoConfig() //for publishing artifacts...
maven repoConfig
}
publications {
if (plugins.hasPlugin('java')) { //publish java plugin projects only
mavenJava(MavenPublication) {
from components.java
}
}
}
}
}
platform/build.gradle
plugins {
id 'java-platform'
}
dependencies {
constraints {
api "org.springframework:spring-core:5.3.22"
api "org.springframework:spring-beans:5.3.22"
api "org.springframework:spring-context:5.3.22"
api "org.springframework:spring-aop:5.3.22"
api "org.springframework:spring-web:5.3.22"
api 'org.apache.cxf:cxf-core:3.5.3'
api "org.apache.cxf:cxf-rt-transports-http:3.5.3"
api "org.apache.cxf:cxf-rt-frontend-jaxrs:3.5.3"
...
}
}
api-container-framework/build.gradle
plugins {
id 'java'
}
dependencies {
implementation(enforcedPlatform(project(':platform')))
implementation 'org.springframework:spring-core'
implementation "org.slf4j:slf4j-api"
//this will be provided by containers like tomcat at runtime, so just add it for compilation
compileOnly "jakarta.servlet:jakarta.servlet-api"
}
Vampire
01/27/2025, 3:22 PM--stacktrace
(resp. the according Gradle property org.gradle.logging.stacktrace
as you said it is not happening from commandline).
But anyway as you said it is only while syncing in VSC and not when building from commandline, it sounds like VSC is doing something evil that you need to report.
Besides that you follow quite some bad practices in your build scripts if you care.
For example:
⢠do not use ext
when you could use a local variable, or actually never use ext
anyway, each time you use ext
it is a sign that you do some work-around instead of doing it properly
⢠better use the built-in credential handling instead of reading Gradle properties manually and setting them explicitly (https://docs.gradle.org/7.6.4/userguide/declaring_repositories.html#sec:handling_credentials)
⢠do not use any way of cross-project configuration like allprojects { ... }
, subprojects { ... }
, project(...) { ... }
, or any other means. This immediately introduces project coupling, working against some more sophisticated Gradle features and optimizations. Better consider using convention plugins from buildSrc
or and included build, for example implemented as precompiled script plugins
⢠do not use the legacy apply ...
to apply plugins, but always the plugins { ... }
block
⢠never use project.plugins
(see its Javadoc), instead if you want to react to a plugin being applied use pluginManager.withPlugin(...) { ... }
which also works independent from when the plugin is applied, now or later
⢠enforcedPlatform
should be a really exceptional very-last-resort thing and should almost never be used. Especially not in something that is a library but if at all then only in an end project. Given the name "...-framework" I at least assume this is a library, not an end product. Also if it is a library, better use java-library
plugin, not java
.
⢠And last but not least more a personal recommendation. Consider switching to Kotlin DSL. By now it is the default DSL, you immediately get type-safe build scripts, actually helpfule error messages if you mess up the syntax, and amazingly better IDE support when using a good IDE like IntelliJ IDE or Android Studio.Sreenivas
01/27/2025, 4:05 PMSreenivas
01/29/2025, 10:54 AMbuild.gradle
..
def isLocal = project.findProperty('bom.mode') == 'local'
println "islocal: $isLocal"
dependencies {
constraints {
if (isLocal) {
// Use local project references
api platform(project(':platform'))
api project(':api-container-framework')
api project(':api-container-common')
//api project(':api-container-introspector')
} else {
// Use published artifacts for external consumers
api "pg-inhouse:api-framework-platform-bom:${version}"
api "pg-inhouse:api-container-framework:${version}"
api "pg-inhouse:api-container-common:${version}"
//api "pg-inhouse:api-container-introspector:${version}"
}
}
}
//centralized configuration for publishing
ext.configurePublishingRepositories = {
repositories {
println "inside configurePublishingRepositories islocal: $isLocal"
if (isLocal) {
maven {
name = 'local'
url = uri("${rootProject.buildDir}/repo")
}
} else {
maven {
name = 'ivyRepo'
url = uri(repoUrl)
credentials(PasswordCredentials)
allowInsecureProtocol true
}
}
}
}
Sreenivas
01/29/2025, 10:54 AMpublishing {
publications {
mavenJava(MavenPublication) {
from components.java
}
}
configurePublishingRepositories()
}
Sreenivas
01/29/2025, 10:55 AMSreenivas
01/29/2025, 10:55 AMVampire
01/29/2025, 3:06 PMif (isLocal) {
for the dependencies / constraints should not be necessary, when you publish, the project dependencies should be written to the POM as normal coordinates.
if (isLocal) {
for the publishing repositories, better just declare two repositories, then you get a task for each of them and can just choose by the task you call to which you want to publish and even can publish to both at once if you want.
Btw. you said you followed all recommendations, but I still see an ext.
. š
not sure what i'm missing.You miss, that you use ChatGPT for something it is not suited for. All those AI tools are very good in giving answers that look correct, but utterly bad in giving answers that are correct. They are suitable to do things for you that you could do yourself but are too lazy to do. (the good kind of lazy, not the bad one) But you always have to understand exactly what it gave you and need to be able to verify and fix the non-sense it produces.
Sreenivas
01/29/2025, 3:53 PMext
for this logic only to share the method across all subprojects.. anyways, will get rid of that.. thanks for the witty reply .. š .. just few doubts,
i) for dependencies, you are saying, i dont need to have isLocal logic at all .. instead i can simply use referencing projects itself whether its local or to external consumers.. ultimately only dependencies co-ordinates will be published to BOMs/POMs..
ii) for publishing, i don't want to publish to org artifactory when publishing from local machine to verify changes.. so i put that condition.. will try your task suggestions for this..
I agree these AI tools are not always correct, will verify the solutions before i actually put them in use.. š