Upgrade from Java Spring Boot Stack 1.0 to Java Spring Boot Stack 2.0
If a Java project was created with a version before IBM Industry Solutions Workbench 4.1.0, it will be based Java Spring Boot Stack 1.0 which comes with Spring Boot 2 and Java 11. The upgrade to Java Spring Boot Stack 2.0 based on Spring Boot 3 and Java 17 is possible following this guide.
Java 17 Migration
In order to migrate your project from Java 11 to Java 17 you should follow the Oracle JDK Migration Guide.
Spring Boot 3 Migration
In order to migrate your project from Spring Boot 2 to Spring Boot 3 you should follow the Spring Boot 3.0 Migration Guide.
Stack Upgrade
In addition, you have to migrate the project structure and the implementation code of your service project. To do this, clone your project to your local machine and edit the files in the described order.
General project structure
With Java Spring Boot Stack 2.0 the general project structure changed. The implementation files and also the generated code is no longer meant to be under folder <yourProject>-application. To adapt your project structure, please follow the steps:
Move all files from the folder
/<yourProject>-applicationinto your project root directoryMove all files from the folder
/src/main/filteredinto/src/main/resourcesDelete the following folders
/<yourProject>-application/.framework/src/main/generated/src/main/filtered
Adjustment of solution.yaml
To define that the project should use Java Spring Boot Stack 2.0, a dedicated flag in the solution.yml of your project needs to be set:
Open file
/solution.yamlExtend the property
extensionswithjava: 17
Example:
appAcronym: "APPACRONYM"
appType: "DDD"
language: "JAVA"
# ...
extensions:
# ...
java: 17
# ...Adjustment of pom.xml
Projects using Java Spring Boot Stack 2.0 also require some changes in the pom.xml of your project. You can either let the pom.xml re-generate automatically or do a manual migration. The automatic re-generation of the pom.xml is the recommended approach if you have not made any custom changes in your pom.xml.
Option 1: Re-generate pom.xml
pom.xml, the dependencies you have added manually and other changes you made to the pom.xml will get lost. Please make sure that you remember all custom changes before deleting the file.Delete the file
/pom.xmlTrigger
k5 generate-codecommand to generate thepom.xmlstub automaticallyApply all your custom changes to the generated stub file
Ensure your version number is set correctly
Depending on your IDE, it might be necessary to trigger a refresh of your project so that it recognizes the new generated files properly
e.g. in Eclipse 'Maven' --> 'Update Project'
Option 2: Manuel migration of pom.xml
Remove
repositoriesReplace
parentby<parent> <!-- Generated Parent - code-generation-provider --> <!-- This part will be overwritten --> <artifactId>spring-boot-starter-parent</artifactId> <groupId>org.springframework.boot</groupId> <version>3.1.2</version> <relativePath/> <!-- Generated Parent - code-generation-provider --> </parent>Replace
<java.version>11</java.version>by<java.version>17</java.version>Adjust
dependenciesRemove
<groupId>com.networknt</groupId><artifactId>json-schema-validator</artifactId><groupId>de.knowis.cp.sdk</groupId><artifactId>cp-framework-managed-sdk-autoconfiguration</artifactId><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><groupId>org.springframework.boot</groupId><artifactId>spring-boot-devtools</artifactId><groupId>org.springframework.kafka</groupId><artifactId>spring-kafka</artifactId><groupId>io.swagger.parser.v3</groupId><artifactId>swagger-parser</artifactId><groupId>io.apicurio</groupId><artifactId>apicurio-registry-serdes-jsonschema-serde</artifactId>
Add
<!-- Generated Dependencies - code-generation-provider --> <!-- This part will be overwritten --> <dependency> <groupId>com.networknt</groupId> <artifactId>json-schema-validator</artifactId> <version>1.0.77</version> </dependency> <dependency> <groupId>io.apicurio</groupId> <artifactId>apicurio-registry-serdes-jsonschema-serde</artifactId> <version>2.4.1.Final</version> <exclusions> <exclusion> <artifactId>slf4j-jboss-logmanager</artifactId> <groupId>org.jboss.slf4j</groupId> </exclusion> </exclusions> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-devtools</artifactId> <scope>runtime</scope> <optional>true</optional> </dependency> <dependency> <groupId>io.swagger.parser.v3</groupId> <artifactId>swagger-parser</artifactId> <version>2.1.16</version> <exclusions> <exclusion> <groupId>io.swagger</groupId> <artifactId>swagger-core</artifactId> </exclusion> <exclusion> <groupId>io.swagger.core.v3</groupId> <artifactId>swagger-core</artifactId> </exclusion> </exclusions> </dependency> <dependency> <groupId>org.springframework.kafka</groupId> <artifactId>spring-kafka</artifactId> </dependency> <dependency> <groupId>io.fabric8</groupId> <artifactId>kubernetes-server-mock</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-beans</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-kubernetes-fabric8</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-mongodb</artifactId> </dependency> <dependency> <groupId>org.springdoc</groupId> <artifactId>springdoc-openapi-starter-webmvc-ui</artifactId> <version>2.2.0</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-oauth2-client</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-oauth2-resource-server</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-validation</artifactId> </dependency> <dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-collections4</artifactId> </dependency> <dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-lang3</artifactId> </dependency> <dependency> <groupId>net.logstash.logback</groupId> <artifactId>logstash-logback-encoder</artifactId> <version>7.3</version> </dependency> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-api</artifactId> </dependency> <dependency> <groupId>com.fasterxml.jackson.datatype</groupId> <artifactId>jackson-datatype-jsr310</artifactId> </dependency> <dependency> <groupId>com.github.mifmif</groupId> <artifactId>generex</artifactId> <version>1.0.2</version> </dependency> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> </dependency> <dependency> <groupId>net.java.quickcheck</groupId> <artifactId>quickcheck</artifactId> <version>0.6</version> </dependency> <dependency> <groupId>org.junit.jupiter</groupId> <artifactId>junit-jupiter-engine</artifactId> </dependency> <dependency> <groupId>org.junit.vintage</groupId> <artifactId>junit-vintage-engine</artifactId> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-web</artifactId> </dependency> <dependency> <groupId>io.micrometer</groupId> <artifactId>micrometer-tracing</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <!-- Generated Dependencies - code-generation-provider -->
Adjust
resourcesand removesrc/main/filteredAdjust
pluginsRemove
git-commit-id-pluginAdjust
build-helper-maven-pluginIn
generate-sourcesreplacesrc/main/generatedbysrc/main/generated-javaAlso add
<execution> <id>add-test-source</id> <phase>generate-sources</phase> <goals> <goal>add-test-source</goal> </goals> <configuration> <sources> <source>src/test/generated-java</source> </sources> </configuration> </execution>
Add
dependencyManagement<dependencyManagement> <dependencies> <!-- Generated Dependency Management - ode-generation-provider --> <!-- This part will be overwritten --> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-dependencies</artifactId> <version>2022.0.3</version> <type>pom</type> <scope>import</scope> </dependency> <dependency> <groupId>org.apache.kafka</groupId> <artifactId>kafka-clients</artifactId> <version>3.5.1</version> <type>pom</type> <scope>import</scope> </dependency> <dependency> <groupId>org.apache.camel.springboot</groupId> <artifactId>camel-spring-boot-bom</artifactId> <version>4.0.0</version> <type>pom</type> <scope>import</scope> </dependency> <!-- Generated Dependency Management - code-generation-provider --> </dependencies> </dependencyManagement>
Update generated files
k5 generate-code in the previous stepExecute
k5 generate-codein the command line inside your project directory
Adjustment of application.yaml
Open file /src/main/resources/application.yaml
remove property
de.knowis.cp.ds
Adjustment of application-local.yaml
For local development, some keys in the files /src/main/resources/application-local.yaml and /src/main/resources/application-local.template.yaml need to be overwritten:
Replace
de.knowis.cp.deployment.identifierwithk5.sdk.springboot.deployment.identifierReplace
de.knowis.cp.binding.topicwithk5.sdk.springboot.binding.topicReplace
de.knowis.cp.server.baseurlwithk5.sdk.springboot.server.baseurlReplace
de.cp.consumer.api.bindingwithk5.sdk.springboot.api.bindingReplace
de.knowis.cp.oidc.clientRegistrationIdwithk5.sdk.springboot.oidc.clientRegistrationIdReplace
de.knowis.cp.consumer.kubernetes.namespacewithk5.sdk.springboot.kubernetes.namespace
Adjustment of Java implementation code
To get your custom implementation working for the new stack, some manual changes need to be done within your implementation files.
Application.java
Open the file
/src/main/java/<yourPackage>/<yourProject>Application.javaExtend annotation
@SpringBootApplicationAdd
k5.sdk.springboot.*toscanBasePackages
Example:
@SpringBootApplication(
exclude = { MongoAutoConfiguration.class, ServiceRegistryAutoConfiguration.class },
scanBasePackages = {
"<yourPackage>.<yourProjectAycronym>.*" ,
"k5.sdk.springboot.*"
}
)Custom implementation
The following adaptions are dependent on the features you have used during development. There might be less changes needed, than described in the following steps.
Please find the list of all possible adaptions below:
Replace
import <package-name>.<project-acronym>.sdk.domain.error.BusinessError;withimport k5.sdk.springboot.domain.error.BusinessError;wherever you have used it// Before import <packagename>.<projectacronym>.sdk.domain.error.BusinessError; // After import k5.sdk.springboot.domain.error.BusinessError;Replace
import <package-name>.<project-acronym>.sdk.domain.event.DomainEvent;withk5.sdk.springboot.domain.events.model.DomainEvent;wherever you have used it// Before import <packagename>.<projectacronym>.sdk.domain.event.DomainEvent; // After import k5.sdk.springboot.domain.events.model.DomainEvent;Replace
import de.knowis.cp.common.consumer.kubernetes.service.KubernetesServiceBindingService;withimport k5.sdk.springboot.kubernetes.service.KubernetesServiceBindingService;wherever you have used it// Before import de.knowis.cp.common.consumer.kubernetes.service.KubernetesServiceBindingService; // After import k5.sdk.springboot.kubernetes.service.KubernetesServiceBindingService;Replace
de.knowis.cp.deployment.identifierwithk5.sdk.springboot.deployment.identifierwherever you have used itReplace
de.knowis.cpwithk5.sdk.springbootat all remaining places where you used classes from the generated sdkReplace
javaxwithjakarta// Before import javax.annotation.PostConstruct; // After import jakarta.annotation.PostConstruct;Replace
import org.springframework.cloud.sleuth.annotation.NewSpan;withimport io.micrometer.tracing.annotation.NewSpan;// Before import org.springframework.cloud.sleuth.annotation.NewSpan; // After import io.micrometer.tracing.annotation.NewSpan;
Push your changes
After all the changes, your project should be successfully migrated and is ready to be pushed to the remote git repository:
Run
k5 compileto ensure that you do not have any compilation issues leftRun
k5 pushto push your changes to the remote gitTrigger a deploy or release pipeline and verify that everything is running smoothly
If you have used a separate branch for upgrading (as recommended), merge your branch into your default branch after you have ensured that everything still works
Update project in Solution Designer
Updating your project in Solution Designer is important to get the possibility to make use of additional features in the new stack also during the design of your project. This will not happen automatically and requires some manual steps in the Solution Designer.
Open your project in Solution Designer
Open your default branch
Trigger the action "Reset to remote" to pull the changes from your remote branch