0

Hey everyone! For context I am working on a simple spring project in intelliJ to configure it with HotswapAgent using DCEVM [8u181 build 2 ] along with the compatible JDK [ 8u181 ] on the Payara 5.0 Application Server.

Please bear with me in the next few snippets of code and my plausible explanation of what's happening and this is not a question regarding Spring MVC syntax or it's working.

This is the sample code I am testing on Hotswapping [ Not the Inbuilt on JVM but using DCEVM ] and HotswapAgent[1.3.0]

HelloWorldController.java

@Controller
public class HelloWorldController {



 @Autowired HelloService helloService;



@RequestMapping("/hello")
public String hello(
        @RequestParam(value = "name", required = false, defaultValue = "World") String name,
        Model model) {


    model.addAttribute("name", name);
    System.out.println( helloService.sayHello() );

    return "helloworld";
}

I don't want to include the code for helloService as it might bloat this post.

HelloService.sayHello() just churns out the quintessential Hello World in the console

As you can see above that auto-wiring has been turned on and it does the proper function(said above).

After this I comment out the Autowired Annotation and the function call, and this gives me an error which is :

org.springframework.web.util.NestedServletException: Handler dispatch     failed; nested exception is java.lang.annotation.AnnotationFormatError: java.lang.IllegalArgumentException: Wrong type at constant pool index

Focus on :

java.lang.IllegalArgumentException: Wrong type at constant pool index

I debugged the application and found out that the IllegalArgumentException was raised when AnnotationParser was parsing the annotations of the Spring Controller class from the Constant Pool and the members(of one of the annotation which is 'type' of the annotation) was not correct when it was taken from the Constant Pool of the Class.

So from my knowledge the hotdeploying is not being done correct ( even though HotswapAgent says it has reloaded the class on the Payara Server) or there is something wrong with the JVM communication or the JDK, and I say this because when I do the opposite that is comment out autowiring then hot deploy and then run, so then I get a null pointer exception.

Note: just for added information

org.springframework.web.util.NestedServletException: Request processing failed; nested exception is java.lang.NullPointerException

If anyone needs more information or code or logs on this then I'd be more than happy to clarify. Thank you for your time everyone.

Bakar
  • 383
  • 1
  • 9
  • 27

2 Answers2

0

The retention policy of the Autowire is @Retention(RetentionPolicy.RUNTIME).

According to the JVM specification , the annotation should be available in binary form. (Reference : https://docs.oracle.com/javase/specs/jls/se8/html/jls-9.html#jls-9.6.4.2)

My assumption is java keeps the reference in the constant pool of all the classes with RUNTIME annotation. When you hotswap it, the class is hot swapped but constant pool is not refrenshed to reflect the class swap.

There is an similar open issue with hotswapagent : https://github.com/HotswapProjects/HotswapAgent/issues/256

Ashraff Ali Wahab
  • 1,088
  • 9
  • 19
  • Your assumption is correct, is there any way I can check the constant pool of the class or access it ? I mean any way I can practically check your assumption. Thank You. – Bakar Oct 24 '18 at 08:32
  • Yes you can by doing javap -c but you cannot view that easily during the runtime. – Ashraff Ali Wahab Oct 24 '18 at 13:37
0

Well this was weird to solve but it's not related to JDK version or DCEVM, but to the dispatcher servlet of Spring.

My Dispatcher Servlet was missing:

<annotation-driven />

Which is why it couldn't register the controller class and caused unwanted behavior. Also missing was the added XML Schemas.

xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd
        http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"

Just for completion purposes or if would be of help to anyone, I'll post the complete dispatcher servlet configuration.

<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns="http://www.springframework.org/schema/mvc"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xmlns:beans="http://www.springframework.org/schema/beans"
             xmlns:context="http://www.springframework.org/schema/context"
             xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd
        http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">

    <annotation-driven />

    <beans:bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <beans:property name="prefix" value="/WEB-INF/views/" />
        <beans:property name="suffix" value=".jsp" />
    </beans:bean>

    <context:component-scan base-package="com.test" />
    </beans:beans>
Bakar
  • 383
  • 1
  • 9
  • 27