Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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.

like image 833
mjj1409 Avatar asked Oct 15 '15 20:10

mjj1409


People also ask

Does Spring AOP affect performance?

Say your application is not so big, and then you can very well use Spring AOP, because the performance impact due to Spring AOP will be negligible as the number of methods involved to serve a request will not be very high.

What is the difference between AspectJ and Spring AOP?

Spring AOP and AspectJ have different goals. Spring AOP aims to provide a simple AOP implementation across Spring IoC to solve the most common problems that programmers face. On the other hand, AspectJ is the original AOP technology which aims to provide complete AOP solution.

Is Spring AOP compile time weaving?

Weaving: linking aspects with other application types or objects to create an advised object. This can be done at compile time (using the AspectJ compiler, for example), load time, or at runtime. Spring AOP, like other pure Java AOP frameworks, performs weaving at runtime.

Does Spring use AOP internally?

Internal Structure and Application. Spring AOP is a proxy-based AOP framework. This means that to implement aspects to the target objects, it'll create proxies of that object.


1 Answers

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
    }
}
like image 171
Nitesh Sharma Avatar answered Sep 18 '22 09:09

Nitesh Sharma