HotswapProjects/HotswapAgent

spring java bean @Order annotation is not working

michaelhaessig opened this issue · 0 comments

I was getting very strange behaviour from spring security with filters not being executed in the right order, upon debugging i found that the @Order(1) annotation is not working when the hotswap agent is active.

With spring security 6 the following code for the SecurityFilterChain is critical to be applied before other filterChains:

@Order(1) // configure first > most specific
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
      ...
}

When the order is not preserved, the security config of the spring boot application is broken.

Test case

The following single spring java configuration can reproduce the issue:

import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.annotation.Order;

import java.util.List;

@Configuration
public class TestOrderConfiguration {

    public static class OrderBean {
        private int order;

        public OrderBean(int order) {
            this.order = order;
        }

        public int getOrder() {
            return order;
        }
    }

   // define beans with @Order annotation on the method:  (it seems the method annotations are not preserved) 

    @Order(2)
    @Bean
    public OrderBean orderTwo() {
        return new OrderBean(2);
    }

    @Bean
    public OrderBean orderLast() {
        return new OrderBean(100);
    }

    @Order(1)
    @Bean
    public OrderBean orderOne() {
        return new OrderBean(1);
    }


    @Configuration
    public static class OrderListConfiguration implements InitializingBean {

        @Autowired  // beans in list should be ordered automatically
        public List<OrderBean> orders;

        @Override
        public void afterPropertiesSet() throws Exception {
            // print beans to check order
            for (OrderBean order : orders) {
                System.out.println("order: " + order.getOrder());
            }
        }
    }

}

Output without hotswap enabled: (correctly ordered by Order value)

order: 1
order: 2
order: 100

With hotswap the order is not resolved correctly: (ordered in the bean definition order)

order: 2
order: 100
order: 1

I suspect the @Order annotation on the method on the Spring configuration is lost?

Or if anybody has another idea i would be curious to know!

Test system

Spring framework: 6.0.7
Spring boot: 3.0.5
Hotswap version: 1.4.2-SNAPSHOT
JVM: Jet brains runtime 17.0.6
JVM args: -XX:+AllowEnhancedClassRedefinition -XX:HotswapAgent=fatjar
Startup log:

/Library/Java/JavaVirtualMachines/jbr-17.0.6-osx-x64-b829.1/Contents/Home/bin/java -agentlib:jdwp=transport=dt_socket,address=127.0.0.1:54080,suspend=y,server=n -Dvisualvm.id=614910673722622 -XX:+AllowEnhancedClassRedefinition -XX:HotswapAgent=fatjar -Dserver.port=8888 -XX:TieredStopAtLevel=1 -Dspring.profiles.active=dev,miki,sql -Dspring.output.ansi.enabled=always -Dcom.sun.management.jmxremote -Dspring.jmx.enabled=true -Dspring.liveBeansView.mbeanDomain -Dspring.application.admin.enabled=true -
HOTSWAP AGENT: 13:17:35.836 INFO (org.hotswap.agent.HotswapAgent) - Loading Hotswap agent {1.4.2-SNAPSHOT} - unlimited runtime class redefinition.
HOTSWAP AGENT: 13:17:36.169 INFO (org.hotswap.agent.config.PluginRegistry) - Discovered plugins: [Hotswapper, WatchResources, AnonymousClassPatch, ClassInitPlugin, JdkPlugin, Hibernate, Hibernate3JPA, Hibernate3, Spring, Jersey1, Jersey2, Jetty, Tomcat, ZK, Logback, Log4j2, MyFaces, Mojarra, Omnifaces, ELResolver, WildFlyELResolver, OsgiEquinox, Owb, OwbJakarta, Proxy, WebObjects, Weld, WeldJakarta, JBossModules, ResteasyRegistry, Deltaspike, GlassFish, Weblogic, Vaadin, Wicket, CxfJAXRS, FreeMarker, Undertow, MyBatis, IBatis, JacksonPlugin, Idea]
Starting HotswapAgent '/Library/Java/JavaVirtualMachines/jbr-17.0.6-osx-x64-b829.1/Contents/Home/lib/hotswap/hotswap-agent.jar'