Gradle未生成在META-INF中嵌入pom.xml的Springboot Library Jar

mcdcgff0  于 2024-01-06  发布在  Spring
关注(0)|答案(2)|浏览(199)

我有Springboot多模块库项目,Gradle 7.4和Springboot 3.2如下所示

  1. buildscript {
  2. dependencies {
  3. classpath "org.jfrog.buildinfo:build-info-extractor-gradle:4.21.0"
  4. }
  5. }
  6. plugins {
  7. id "com.diffplug.spotless" version "6.8.0"
  8. id 'io.spring.dependency-management' version '1.1.4'
  9. id 'org.springframework.boot' version '3.2.0' apply false
  10. id "org.openapi.generator" version "6.0.0"
  11. id "org.hidetake.swagger.generator" version "2.19.2"
  12. }
  13. ext.versions = [
  14. springBoot : '3.2.0',
  15. springCloud : '2022.0.4',
  16. micrometer : '1.10.3',
  17. commonLogging : '1.2',
  18. ]
  19. allprojects {
  20. apply plugin: 'io.spring.dependency-management'
  21. group 'com.springboot.web.library'
  22. version = '0.0.3-SNAPSHOT'
  23. dependencyManagement {
  24. imports {
  25. mavenBom("org.springframework.boot:spring-boot-dependencies:${versions.springBoot}")
  26. mavenBom("org.springframework.cloud:spring-cloud-dependencies:${versions.springCloud}")
  27. }
  28. dependencies {
  29. //dependency group: 'io.micrometer', name: 'micrometer-registry-prometheus', version: versions.micrometer
  30. dependency group: 'commons-logging', name: 'commons-logging', version: versions.commonLogging
  31. }
  32. }
  33. }
  34. subprojects {
  35. apply plugin: 'java'
  36. apply plugin: 'maven-publish'
  37. apply plugin: "com.diffplug.spotless"
  38. java {
  39. toolchain {
  40. languageVersion = JavaLanguageVersion.of(17)
  41. }
  42. withSourcesJar()
  43. }
  44. //https://dev.to/ankityadav33/standardize-code-formatting-with-spotless-2bdh
  45. spotless {
  46. java {
  47. //googleJavaFormat("1.15.0")
  48. target fileTree('.') {
  49. include '**/*.java'
  50. exclude '**/build/**', '**/build-*/**'
  51. }
  52. importOrder()
  53. toggleOffOn()
  54. palantirJavaFormat()
  55. removeUnusedImports()
  56. trimTrailingWhitespace()
  57. endWithNewline()
  58. }
  59. }
  60. afterEvaluate {
  61. def spotless = tasks.findByName('spotlessApply')
  62. if (spotless) {
  63. tasks.withType(JavaCompile) {
  64. finalizedBy(spotless)
  65. }
  66. }
  67. }
  68. dependencies {
  69. implementation 'org.springframework.boot:spring-boot-starter'
  70. compileOnly 'org.projectlombok:lombok:1.18.22'
  71. annotationProcessor 'org.projectlombok:lombok:1.18.22'
  72. testImplementation 'org.junit.jupiter:junit-jupiter-engine:5.8.2'
  73. }
  74. repositories {
  75. mavenLocal()
  76. mavenCentral()
  77. }
  78. test {
  79. useJUnitPlatform()
  80. }
  81. jar {
  82. enabled = true
  83. archiveClassifier=''
  84. }
  85. }

字符串
下面是我的module-commons build.gradle文件

  1. plugins {
  2. id 'java-library'
  3. }
  4. dependencies {
  5. compileOnly 'com.fasterxml.jackson.core:jackson-databind:2.16.0'
  6. compileOnly 'com.fasterxml.jackson.core:jackson-core:2.16.0'
  7. compileOnly 'com.fasterxml.jackson.datatype:jackson-datatype-jsr310:2.16.0'
  8. testImplementation 'org.junit.jupiter:junit-jupiter-api:5.8.2'
  9. testImplementation 'org.mockito:mockito-core:5.8.0'
  10. testImplementation 'org.projectlombok:lombok:1.18.30'
  11. testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.8.2'
  12. compileOnly 'org.projectlombok:lombok:1.18.30'
  13. }
  14. publishing {
  15. publications {
  16. mavenJava(MavenPublication) {
  17. artifact jar
  18. }
  19. }
  20. repositories {
  21. mavenLocal()
  22. }
  23. }


我在module-commons中有下面的类

  1. package com.springboot.web.library.commons.utils;
  2. import com.fasterxml.jackson.core.JsonProcessingException;
  3. import com.fasterxml.jackson.databind.ObjectMapper;
  4. public class JsonUtils {
  5. public String serialize(Object object) throws JsonProcessingException {
  6. ObjectMapper objectMapper = new ObjectMapper();
  7. return objectMapper.writeValueAsString(object);
  8. }
  9. }


我正在运行gradle build jar module-commons:publishToMavenLocal命令,以将该命令发布到本地maven repo。
我将在springboot-demo项目中导入module-commons库作为implementation 'com.springboot.web.library:module-commons:0.0.3-SNAPSHOT',下面是springboot-demo项目build.gradle

  1. plugins {
  2. id 'java'
  3. id 'org.springframework.boot' version '3.2.0'
  4. id 'io.spring.dependency-management' version '1.1.4'
  5. }
  6. group = 'com.springboot.web'
  7. version = '1.0-SNAPSHOT'
  8. repositories {
  9. mavenLocal()
  10. mavenCentral()
  11. }
  12. dependencies {
  13. implementation 'org.projectlombok:lombok:1.18.28'
  14. testImplementation platform('org.junit:junit-bom:5.9.1')
  15. testImplementation 'org.junit.jupiter:junit-jupiter'
  16. implementation 'org.springframework.boot:spring-boot-starter'
  17. testImplementation 'org.springframework.boot:spring-boot-starter-test'
  18. implementation 'com.springboot.web.library:module-commons:0.0.3-SNAPSHOT'
  19. }
  20. test {
  21. useJUnitPlatform()
  22. }


我在springboot-demo项目中导入JsonUtils Main类如下

  1. package com.springboot.web.library.commons;
  2. import com.springboot.web.library.commons.utils.JsonUtils;
  3. import org.springframework.boot.autoconfigure.SpringBootApplication;
  4. @SpringBootApplication
  5. public class Main {
  6. @lombok.SneakyThrows
  7. public static void main(String[] args) {
  8. JsonUtils jsonUtils = new JsonUtils();
  9. jsonUtils.serialize("test");
  10. System.out.println("Hello world!");
  11. }
  12. }


在运行Main类时,由于module-commons jar在META-INF目录中没有包含pom.xml的maven.com.springboot.web.library.module-commons目录,因此Gradle无法解析module-commons中引用的Jackson库,因此出现了编译器错误。我已经尝试了Github和Stackoverflow中提供的许多解决方案,但到目前为止都没有运气。我感谢任何人可以帮助解决这个问题。完整的项目可以在这里找到https://github.com/JavaSpringBooteer/springboot-gradle-library

  1. D:\Git\springboot-gradle-library\springboot-demo\src\main\java\com\springboot\web\library\commons\Main.java:12: error: cannot access JsonProcessingException
  2. jsonUtils.serialize("test");
  3. ^
  4. class file for com.fasterxml.jackson.core.JsonProcessingException not found


尝试Github和Stackoverflow的解决方案来调整build.gradle

carvr3hs

carvr3hs1#

你的项目应该是:

  1. [ Gradle Build System ]
  2. |
  3. |---[ module-commons Library ]
  4. | |---[ build.gradle ]
  5. | |---[ src ]
  6. | |---[ dependencies (Jackson, Lombok, etc.) ]
  7. |
  8. |---[ springboot-demo Project ]
  9. |---[ build.gradle ]
  10. |---[ src ]
  11. |---[ dependencies (including module-commons) ]

字符串
您需要修改您的module-commons构建脚本,以在发布的工件中包含依赖关系信息,这可以通过正确配置maven-publish plugin来实现。
你的module-commons/build.gradle是:

  1. publishing {
  2. publications {
  3. mavenJava(MavenPublication) {
  4. from components.java
  5. artifact sourcesJar
  6. pom.withXml {
  7. def dependenciesNode = asNode().appendNode('dependencies')
  8. configurations.compileClasspath.allDependencies.each { dep ->
  9. def dependencyNode = dependenciesNode.appendNode('dependency')
  10. dependencyNode.appendNode('groupId', dep.group)
  11. dependencyNode.appendNode('artifactId', dep.name)
  12. dependencyNode.appendNode('version', dep.version)
  13. }
  14. }
  15. }
  16. }
  17. repositories {
  18. mavenLocal()
  19. }
  20. }


这将包括主Java组件(from components.java),它确保编译的类和资源是发布的一部分。
它还向生成的POM文件中添加了一个自定义部分,其中列出了所有编译类路径依赖项。
运行./gradlew module-commons:publishToMavenLocal命令。将更新后的module-commons工件发布到本地Maven存储库后,构建并运行springboot-demo项目。它现在应该正确解析依赖项。

  1. Duplicated tag: 'dependencies'


我假设您的build.gradle中的pom.withXml块正在将一个新的<dependencies>节点附加到现有的POM结构中,该结构已经定义了一个<dependencies>标记。
让我们修改module-commons/build.gradle中的pom.withXml块,以正确处理现有的<dependencies>标记。

  1. publishing {
  2. publications {
  3. mavenJava(MavenPublication) {
  4. from components.java
  5. artifact sourcesJar
  6. pom.withXml {
  7. def pomNode = asNode()
  8. // Find or create the 'dependencies' node
  9. def dependenciesNode = pomNode.children().find { it.name() == 'dependencies' }
  10. if (dependenciesNode == null) {
  11. dependenciesNode = pomNode.appendNode('dependencies')
  12. }
  13. configurations.compileClasspath.allDependencies.each { dep ->
  14. if (dep.group != null && dep.version != null) {
  15. def dependencyNode = dependenciesNode.appendNode('dependency')
  16. dependencyNode.appendNode('groupId', dep.group)
  17. dependencyNode.appendNode('artifactId', dep.name)
  18. dependencyNode.appendNode('version', dep.version)
  19. }
  20. }
  21. }
  22. }
  23. }
  24. repositories {
  25. mavenLocal()
  26. }
  27. }


在追加依赖项之前,检查它们的groupversion是否不为null,以避免包含无效条目,这很重要。
将更新后的脚本应用于module-commons/build.gradle,并运行./gradlew clean build以确保正确应用所有更改并清除旧工件。
执行./gradlew module-commons:publishToMavenLocal。发布后,检查本地Maven仓库中的pom.xml,以确保其格式正确,没有重复的标记。
运行您的springboot-demo项目以检查问题是否已解决。
作为替代方法,您可以考虑清除任何现有的<dependencies>节点并重新创建它,而不是追加新的<dependencies>节点或尝试查找和增强现有节点。这将确保不会发生重复。
你的module-commons/build.gradle是:

  1. publishing {
  2. publications {
  3. mavenJava(MavenPublication) {
  4. from components.java
  5. artifact sourcesJar
  6. pom.withXml {
  7. def pomNode = asNode()
  8. // Remove existing 'dependencies' node if present
  9. def dependenciesNode = pomNode.children().find { it.name() == 'dependencies' }
  10. if (dependenciesNode != null) {
  11. dependenciesNode.replaceNode {}
  12. }
  13. // Re-create the 'dependencies' node
  14. dependenciesNode = pomNode.appendNode('dependencies')
  15. configurations.compileClasspath.allDependencies.each { dep ->
  16. if (dep.group != null && dep.version != null) {
  17. def dependencyNode = dependenciesNode.appendNode('dependency')
  18. dependencyNode.appendNode('groupId', dep.group)
  19. dependencyNode.appendNode('artifactId', dep.name)
  20. dependencyNode.appendNode('version', dep.version)
  21. }
  22. }
  23. }
  24. }
  25. }
  26. repositories {
  27. mavenLocal()
  28. }
  29. }

展开查看全部
moiiocjp

moiiocjp2#

您的Gradle构建版本没有在您的module-commons项目的META-INF目录中使用嵌入的pom.xml生成Sping Boot 库示例。当您将示例发布到Maven存储库时,需要使用此嵌入的pom.xml来正确解析依赖项。若要生成此pom.xml,您需要为您的module-commons项目配置MavenPublication。
以下是如何修改module-commons build.gradle文件以包含MavenPublication所需的配置:

  1. plugins {
  2. id 'java-library'
  3. id 'maven-publish' // Add the Maven Publish plugin
  4. }
  5. dependencies {
  6. // Your dependencies
  7. }
  8. publishing {
  9. publications {
  10. mavenJava(MavenPublication) {
  11. from components.java // This will include the Java component
  12. pom {
  13. // Customize the generated POM here if needed
  14. // For example, you can add dependencies or other metadata
  15. // Example:
  16. withXml {
  17. def dependenciesNode = asNode().appendNode('dependencies')
  18. dependenciesNode.appendNode('dependency')
  19. .appendNode('groupId', 'com.fasterxml.jackson.core')
  20. .appendNode('artifactId', 'jackson-databind')
  21. .appendNode('version', '2.16.0')
  22. .appendNode('scope', 'compile')
  23. }
  24. }
  25. }
  26. }
  27. repositories {
  28. mavenLocal()
  29. }
  30. }

字符串
在发布块中,我们配置一个名为mavenJava的MavenPublication,它包含项目的Java组件。在pom块中,您可以根据需要自定义生成的POM。在上面的示例中,我已经展示了如何为jackson-databind的POM添加依赖项,因为它是项目的编译依赖项。
在对module-commons build.gradle文件进行这些更改后,再次运行gradle build module-commons:jumshToMavenLocal,它应该会在META-INF目录中生成带有嵌入式pom.xml的xml。这应该会解决springboot-demo项目中的依赖问题。

展开查看全部

相关问题