Friday, April 26, 2024
HomeJavaAutomated Refactoring With Spring Boot Migrator - Java Code Geeks

Automated Refactoring With Spring Boot Migrator – Java Code Geeks


Spring Boot Migrator is a device emigrate purposes to Spring Boot. On this article, we’re going to see the way it works and the way you need to use it. This may occasionally appear a slim matter, however it’s an fascinating instance of an utility that may manipulate your code. The reason being that the device offers with reworking code and purposes at scale. So, we could study one thing new by taking a look at the way it works.

Spring Boot Migrator as A part of Legacy Modernization

Within the bigger scheme of issues, that is the type of device you could use in a strategy of legacy modernization. Legacy modernization in itself is a big matter that might warrant its personal e-book. Right here, we simply wish to enable you to perceive how the device suits in modernizing an utility. Even the very best designed tasks accumulate technical debt with time, that is just because the world evolves and subsequently greatest practices change.

For instance, the very best designed mainframe utility is now outdated just because mainframes are not the very best platform on which to construct purposes. You can not blame whoever designed the applying for that, it’s simply that the world has modified.

So, you might be at a degree the place you have got an outdated codebase to take care of. In some instances you may have to migrate growth language, for instance passing from COBOL to Java. In another instances, you may get away migrating from an outdated framework to a brand new one. You may even have to do each, in a number of steps. First, you migrate from a legacy language to a brand new one, then you definitely change the purposes themselves.

If it’s essential to change a Java utility to a Spring Boot utility, there’s a device that may enable you to with that. That is the very best case situation, you’ll not all the time be so fortunate for different legacy purposes. In such instances you’ll have to make investments on a regular basis and energy to vary your utility.

What’s Spring Boot?

Let’s begin from the start: Spring is a Java framework. Spring Boot is a undertaking/framework that will get you an entire net app primarily based on Spring.

Spring Boot makes it simple to create stand-alone, production-grade Spring primarily based Purposes you can “simply run”.

It routinely configures Spring and wire collectively a manufacturing prepared beginning undertaking with included a webserver and options like metrics, well being checks, and so forth.

You employ Spring if you wish to create a tailor-made Spring utility or combine it with current software program. As an alternative you utilize Spring Boot if you wish to create a brand new net utility primarily based on Spring following some established conventions.

You may even use the device Spring Initializr to generate a Spring Boot utility, both on the internet or in a supported IDE.

Dash Initializr on the internet

Spring Boot Migrator

Because the identify suggests, Spring Boot Migrator is a device emigrate current purposes to Spring Boot. Sadly, it isn’t made from magic, so it can’t migrate all the things to Spring Boot, the preliminary undertaking should respect some fundamental necessities:

  • should be a Maven undertaking (however no Maven Reactor, just one pom.xml)
  • should comply with Maven dir format
  • latest construct with mvn clear package deal and goal dir nonetheless exists

The device itself is a straightforward JAR utility, so to run it you solely want a system with a JVM model 11+ put in. So, the excellent news is that you do not want to comply with difficult set up procedures simply to make use of it.

Utilizing it is usually fairly easy, the device comes with a sequence of recipes for automated refactoring. A recipe performs a sequence of operations in your code and configuration information.

You may see the present listing of obtainable recipes from this system itself, with the command listing.

migrator:> listing
 
Discovered these recipes:
 
🤖    = 'automated recipe'
💪 🤖 = 'partially automated recipe'
💪    = 'handbook recipe'
 
 - initialize-spring-boot-migration [🤖]
    -> Initialize an utility as Spring Boot utility.
 - migrate-jndi-lookup [🤖]
    -> Migrate JNDI lookup utilizing InitialContext to Spring Boot
 - migrate-jpa-to-spring-boot [🤖]
    -> Migrate JPA to Spring Boot
 - migrate-ejb-jar-deployment-descriptor [🤖]
    -> Add or overrides @Stateless annotation as outlined in ejb deployment descriptor
 - migrate-weblogic-ejb-deployment-descriptor [🤖]
    -> Migrate weblogic-ejb-jar.xml deployment descriptor
 - mark-and-clean-remote-ejbs [🤖]
    -> Search @Stateless EJBs implementing a @Distant interface
 - migrate-stateless-ejb [🤖]
    -> Migration of stateless EJB to Spring elements.
 - migrate-annotated-servlets [🤖]
    -> Enable Spring Boot to deploy servlets annotated with @WebServlet
 - migrate-jax-ws [🤖]
    -> Migrate Jax Net-Service implementation to Spring Boot bases Net-Service
 - migrate-jax-rs [🤖]
    -> Any class has import beginning with javax.ws.rs
 - migrate-mule-to-boot [🤖]
    -> Migrate Mulesoft to Spring Boot
 - migrate-tx-to-spring-boot [🤖]
    -> Migration of @TransactionAttribute to @Transactionsl
 - spring-context-xml-import [🤖]
    -> Import Spring Framework xml bean configuration into Java configuration with out changing them.
 - migrate-spring-xml-to-java-config [🤖]
    -> Migrate Spring Framework xml bean configuration to Java configuration.
 - sql-access-in-java-ee-apps [💪]
    -> SQL Entry in Java EE Apps
 - migrate-jms [🤖]
    -> Convert JEE JMS app into Spring Boot JMS app
 - documentation-actions [🤖]
    -> Create Documentation for Actions
 - migrate-jsf-2.x-to-spring-boot [🤖]
    -> Use joinfaces to combine JSF 2.x with Spring Boot.
 - bootifying-java-ee-jaxb [💪]
    -> Bootifying Java EE JAXB
 - cn-spring-cloud-config-server [🤖]
    -> Externalize properties to Spring Cloud Config Server
 - boot-2.4-2.5-upgrade-report [🤖]
    -> Create Improve Report for a Spring Boot 2.4 Utility
 - boot-2.4-2.5-datasource-initializer [🤖]
    -> null
 - boot-2.4-2.5-spring-data-jpa [🤖]
    -> null
 - boot-2.4-2.5-dependency-version-update [🤖]
    -> Replace Spring Boot dependencies from 2.4 to 2.5
 - boot-2.4-2.5-sql-init-properties [🤖]
    -> null
 - migrate-raml-to-spring-mvc [🤖]
    -> Create Spring Boot @RestController from .raml information.
 - migrate-boot-2.3-2.4 [🤖]
    -> Migrate from Spring Boot 2.3 to 2.4
 - upgrade-boot-1x-to-2x [🤖]
    -> Migrates Spring Boot 1.x to 2.x together with greatest practices.
 
Run command '> apply recipe-name' to use a recipe.

Discover that on Home windows you won’t see the emoji characters indicating the grade of automation of the recipe (e.g., 🤖) as a substitute you may see a query mark.

You need to use the command scan to see which recipes might be utilized to your current undertaking after which apply them with the corresponding command. 

Spring Boot Migrator in Motion

The Spring Boot Migrator github repository has just a few instance tasks to point out what the device is able to. For those who attempt the scan command on the the Mulesoft instance app, you get these outcomes:

scanning 'spring-amqp-mule'
 
Checked preconditions for 'spring-amqp-mule'
[ok] Discovered pom.xml.
[ok] 'sbm.gitSupportEnabled' is 'false', Nothing will probably be dedicated.
[ok] Required Java model (11) was discovered.
[ok] Discovered required supply dir 'src/foremost/java'.
 
 
Maven        100% │████████████████████████│ 3/3 (0:00:01 / 0:00:00)
Java [main]: 100% │████████████████████████│ 3/3 (0:00:00 / 0:00:00)
Xml          100% │████████████████████████│ 2/2 (0:00:00 / 0:00:00)
 
Relevant recipes:
 
🤖    = 'automated recipe'
💪 🤖 = 'partially automated recipe'
💪    = 'handbook recipe'
 
 - initialize-spring-boot-migration [🤖]
    -> Initialize an utility as Spring Boot utility.
 - migrate-mule-to-boot [🤖]
    -> Migrate Mulesoft to Spring Boot
 - cn-spring-cloud-config-server [🤖]
    -> Externalize properties to Spring Cloud Config Server
 - boot-2.4-2.5-upgrade-report [🤖]
    -> Create Improve Report for a Spring Boot 2.4 Utility
 - boot-2.4-2.5-sql-init-properties [🤖]
    -> null
 
Run command '> apply recipe-name' to use a recipe.

This command will scan the undertaking and supply a listing of recipes it will possibly apply to it. We select to use the one emigrate a Mule utility to Spring Boot.

spring-amqp-mule:> apply migrate-mule-to-boot
Making use of recipe 'migrate-mule-to-boot'
[..] Migrating Mulesoft to Spring Boot
   [..] Changing Mulesoft information
       [ok] Including 3 dependencies
       [ok] Including 1 strategies
   [ok] Changing Mulesoft information
[ok] Migrating Mulesoft to Spring Boot
 
migrate-mule-to-boot efficiently utilized the next actions:
 (x)
 (x)
 (x) Migrating Mulesoft to Spring Boot
 (x)
 (x)

The device offers a short description of the modifications it made. It may additionally make the most of git and routinely make a commit after making use of a recipe, which is a helpful function in case you wish to assessment and presumably revert the code modifications.

If we run git present on the final commit we will see that the device modified dependencies (the pom.xml file), the code of the applying (Foo.java) and added a required configuration file (utility.properties). It is a good illustration of what it will possibly do.

The Know-how Behind the Instrument

Now that you’ve got a really feel of how the device works, we will see what expertise powers it. It has a reputation: OpenRewrite. That is one other open supply undertaking tailor-made at automated code refactoring:

OpenRewrite undertaking is a mass refactoring ecosystem for Java and different supply code, designed to remove technical debt throughout an engineering group. This undertaking delivers scalable automated code upkeep, greatest practices, vulnerability patching, API migrations, dependency administration, and extra.

At its core, OpenRewrite parses the undertaking information after which manipulates the AST representing the totally different information. A recipe is nothing greater than a sequence of transformations utilized to the AST of a file. You may clearly see that by wanting on the Spring Boot Migrator recipe for Mule migration that we utilized within the earlier instance.

@Configuration
public class MigrateMuleToBoot {
    @Autowired
    non-public JavaDSLAction2 javaDSLAction2;
    @Bean
    public Recipe muleRecipe() {
        return Recipe.builder()
                .identify("migrate-mule-to-boot")
                .description("Migrate Mulesoft 3.9 to Spring Boot")
                .order(60)
                .description("Migrate Mulesoft to Spring Boot")
                .situation(new MuleConfigFileExist())
                .actions(Listing.of(
                        /*
                        * Add dependencies for spring integration
                        */
                        AddDependencies.builder()
                                .situation(
                                        NoDependencyExistMatchingRegex.builder()
                                            .dependencies(Listing.of(
                                                    "org.springframework.boot:spring-boot-starter-web:2.5.5",
                                                    "org.springframework.boot:spring-boot-starter-integration:2.5.5",
                                                    "org.springframework.integration:spring-integration-http",
                                                    "org.springframework.integration:spring-integration-amqp:2.5.5",
                                                    "org.springframework.integration:spring-integration-stream:2.5.5"
                                            )
                                        )
                                        .construct()
                                )
                                .dependencies(
                                    Listing.of(
                                        Dependency.builder()
                                                .groupId("org.springframework.boot")
                                                .artifactId("spring-boot-starter-web")
                                                .model("2.5.5")
                                                .construct(),
                                        Dependency.builder()
                                                .groupId("org.springframework.boot")
                                                .artifactId("spring-boot-starter-integration")
                                                .model("2.5.5")
                                                .construct(),
                                        Dependency.builder()
                                                .groupId("org.springframework.integration")
                                                .artifactId("spring-integration-amqp")
                                                .model("5.4.4")
                                                .construct(),
                                        Dependency.builder()
                                                .groupId("org.springframework.integration")
                                                .artifactId("spring-integration-stream")
                                                .model("5.4.4")
                                                .construct(),
                                        Dependency.builder()
                                                .groupId("org.springframework.integration")
                                                .artifactId("spring-integration-http")
                                                .model("5.4.4")
                                                .construct()
                                    )
                                )
                                .construct(),

                        /*
                        * Annotate Spring Boot Utility class with @EnableIntegration
                        */
                        AddTypeAnnotationToTypeAnnotatedWith.builder()
                                .annotatedWith("org.springframework.boot.autoconfigure.SpringBootApplication")
                                .annotation("org.springframework.integration.config.EnableIntegration")
                                .situation(
                                        HasNoTypeAnnotation.builder()
                                                .hasTypeAnnotation(
                                                   HasTypeAnnotation.builder()
                                                    .annotation("org.springframework.integration.config.EnableIntegration")
                                                    .construct()
                                                ).construct()
                                ).construct(),


                        /*
                         * Add java class with Spring Integration DSL statements
                         */
                        javaDSLAction2,

//                        /*
//                        * Migrate Mulesoft XML to Spring Integration XML
//                        */
//                        MigrateMulesoftFile.builder().configuration(configuration).construct(),

                        /*
                        * Take away Mule dependencies
                        */
                        RemoveDependenciesMatchingRegex.builder()
                                .situation(Situation.TRUE)
                                .dependenciesRegex(Listing.of("org.mule..*", "com.mulesoft..*"))
                                .construct(),

                        /*
                        * Take away Mule plugins
                        */
                        RemovePluginsMatchingRegex.builder()
                                .situation(Situation.TRUE)
                                .pluginsRegex(Listing.of("org.mule..*", "com.mulesoft..*"))
                                .construct()

                        /*
                        * TODO: Learn how to discover out if all components had been efficiently migrated and Mule XML might be deleted?
                        */
                ))
                .construct();
    }
}

You may also outline a recipe utilizing declarative syntax in a YAML file, however the rules stay the identical.

OpenRewrite and Spring Boot Migrator add options, robustness, checks… a number of worth on high of this fundamental thought, however at its core you might be parsing some code and reworking it.

It’s type of the static evaluation and refactoring options of your IDE on steroids. Your IDE can do issues like renaming strategies and variables, producing some stub strategies, and so forth. This device makes use of the identical fundamental thought, however on a a lot bigger scale and with a much bigger plan. The result’s a number of time saved.

The truth is it’s also possible to use OpenRewrite to carry out complicated refactorings apart from migrations. You need to use it to construct your customized linter, to verify and apply some fashion to your code and clear up particular issues you have got. For instance, if it’s essential to migrate an utility it’s affordable to count on that you could be additionally want to vary coding patterns. A undertaking may be utilizing outdated patterns or just patterns that aren’t optimum with the brand new framework. You may outline a customized recipe with OpenRewrite to take care of such points.

Abstract

Spring Boot Migrator is an fascinating device in its personal proper but additionally for instance of what you’ll be able to construct in the fitting surroundings and the way a lot legacy modernization issues these days. 

Software program constructed a long time in the past powers an vital a part of our companies and private lives. For those who work in a corporation with a number of such code, you’ll spend most of your effort and time simply on sustaining it. So, utilizing a device like Spring Boot Migrator and even creating one thing customized on high of OpenRewrite, will help you scale back prices or enhance your life as a developer.

One other fascinating level to make is that the device is smart as a result of Spring Boot itself is an opinionated framework. That’s to say, all Spring Boot purposes are purported to behave in a sure method. It could not make sense emigrate to a generic Spring utility, as a result of there is no such thing as a such factor. 

It is a not-so-obvious profit of getting firm insurance policies and elegance guidelines. If all your firm software program behaves in a sure method, you’ll be able to apply shared patterns and use shared instruments to take care of and improve them.

RELATED ARTICLES

LEAVE A REPLY

Please enter your comment!
Please enter your name here

Most Popular

Recent Comments