Tomcat 8, Spring Boot, @Configurable LoadTimeWeaving without -javaagent?
Asked Answered
I

2

14

I'm trying to setup a @Configurable domain object(not managed by the spring container).
I've got this working by adding the -javaagent:path/to/spring-instrument.jar as a JVM argument but it's not 100% clear to me whether or not this -javaagent MUST be in place. I'm running this on Tomcat 8. I may be misinterpreting the documentation but it seems I may be able to use a another mechanism to accomplish this, in particular this line:

Do not define TomcatInstrumentableClassLoader anymore on Tomcat 8.0 and higher. Instead, let Spring automatically use Tomcat’s new native InstrumentableClassLoader facility through the TomcatLoadTimeWeaver strategy.

Code Samples below:

@SpringBootApplication
@EnableLoadTimeWeaving
public class TestApplication {

    public static void main(String[] args) {
        SpringApplication.run(TestApplication.class, args);
    }   
    @Bean
    public MyService myService(){
        return new MyService();
    }
}

@Configurable
public class MyDomainObject {

    @Autowired
    private MyService myService;

    public MyService getMyService(){
        return myService;
    }
}

 public class MyService {
    private static final Logger log = LoggerFactory.getLogger(MyService.class);

    public void test(){
        log.info("test");
    }
}

So is there a way to get these @Configrable objects woven without specifying the -javaagent? I'd be interested in learning if I can accomplish this when deploying as WAR to a Standalone Tomcat 8 server and/or using the embedded Tomcat 8 server when launching as a 'fat' jar.

As it stands deploying to Stand alone Tomcat 8 server doesn't throw an error but the getMyService() method above returns null. Launching as a fat jar throws the following error during startup:

Caused by: java.lang.IllegalStateException: ClassLoader [sun.misc.Launcher$AppClassLoader] does NOT provide an 'addTransformer(ClassFileTransformer)' method. Specify a custom LoadTimeWeaver or start your Java virtual machine with Spring's agent: -javaagent:org.springframework.instrument.jar

I suppose the real question is how do I Specify a custom LoadTimeWeaver in Tomcat 8? Nothing seems to be automatically happening as the documentation states but again I may be misinterpreting what that means exactly.

Invade answered 15/10, 2015 at 20:33 Comment(2)
I have the same issue right now, have you solved it ?Britannic
@Britannic unfortunately I have notInvade
T
1

you can try this :

@Bean
public InstrumentationLoadTimeWeaver loadTimeWeaver() {
    return new InstrumentationLoadTimeWeaver();
}

or

there is a new library that just solves to dynamically setup spring InstrumentationLoadTimeWeaver to enable support for aspects without having to start the JVM with an explicit java agent

<dependency>
    <groupId>de.invesdwin</groupId>
    <artifactId>invesdwin-instrument</artifactId>
    <version>1.0.2</version>
</dependency>

@SpringBootApplication
@EnableLoadTimeWeaving
public class TestApplication{
    public static void main(final String[] args) {
        DynamicInstrumentationLoader.waitForInitialized(); //dynamically attach java agent to jvm if not already present
        DynamicInstrumentationLoader.initLoadTimeWeavingContext(); //weave all classes before they are loaded as beans
        SpringApplication.run(TestApplication.class, args); //start application, load some classes
    }
}
Trapezium answered 16/6, 2020 at 21:53 Comment(0)
O
-2

what about creating your own annotation @MyConfigurable ? so you can do what ever you like when it's methods are called.

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target(ElementType.CONSTRUCTOR)
@Retention(RetentionPolicy.RUNTIME)
public @interface MyConfigurable
{}
Oxymoron answered 15/6, 2016 at 14:12 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.