12

I have strange behaviour when trying to compile sources after Spring 3.2.5 → 4.0.0 version update.

Faulty code snippet from ApplicationControllerTest.java (it is equivalent to code from documentation):

import org.springframework.test.context.web.WebAppConfiguration;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import org.springframework.web.context.WebApplicationContext;
...
@Autowired
private WebApplicationContext wac;

private MockMvc               mockMvc;

@Before
public void setUp() {
    mockMvc = MockMvcBuilders.webAppContextSetup(wac).build();
}

Error:

COMPILATION ERROR : /C:/Development/.../war/src/test/java/org/.../web/controller/ApplicationControllerTest.java:[59,61] C:\Development\...\war\src\test\java\org\...\web\controller\ApplicationControllerTest.java:59: incompatible types; inferred type argument(s) java.lang.Object do not conform to bounds of type variable(s) B found : <B>org.springframework.test.web.servlet.setup.DefaultMockMvcBuilder<B> required: java.lang.Object

If one looks into MockMvcBuilders sources, one can see the difference:

Spring 4.0.0:

public static <B extends DefaultMockMvcBuilder<B>> DefaultMockMvcBuilder<B> webAppContextSetup(WebApplicationContext context) {
    return new DefaultMockMvcBuilder<B>(context);
}

Spring 3.2.5:

public static DefaultMockMvcBuilder<DefaultMockMvcBuilder<?>> webAppContextSetup(WebApplicationContext context) {
    return new DefaultMockMvcBuilder<DefaultMockMvcBuilder<?>>(context);
}

My attempts to make it compilable did not succeeded.

Actually Spring documentation says that framework should be Java 1.6.0_10 compatible. I use Java 1.6.0_45.

dma_k
  • 10,431
  • 16
  • 76
  • 128
  • It looks like they switched up an unbounded wildcard type for a type parameter with bounds. I think you may have uncovered an issue. – Kevin Bowersox Dec 13 '13 at 20:00
  • Yes, I see the changes and they seem to make sense. I don't understand why compiler cannot cope with this parametrization and how can I workaround JDK 1.6.0_45 (or any other 1.6.x version). – dma_k Dec 16 '13 at 03:12

3 Answers3

8

I think the call of webAppContextSetup method now should be explicitly parameterized with the class of <B extends DefaultMockMvcBuilder<B>>. The obvious candidates are StandaloneMockMvcBuilder or simply DefaultMockMvcBuilder (though the later will generate a warning about unchecked or unsafe operations). So try this:

mockMvc = MockMvcBuilders.<StandaloneMockMvcBuilder>webAppContextSetup(wac).build();
Eugene Evdokimov
  • 2,220
  • 2
  • 28
  • 33
  • That means the documentation is not correct? Maybe with JDK 1.7 it compiles without problems... – dma_k Dec 17 '13 at 10:24
  • @dma_k To my mind there is no conflict in Spring docs regarding to jdk compatibility because the above code compiles and runs perfectly in JDK 1.6 given the small parameterization fix. Rather new version of Spring is not compatible with the older one. – Eugene Evdokimov Dec 17 '13 at 10:58
  • @dma_k And yes, there is no problem in JDK 1.7 and Spring 4 with your original code because of improved type inference (as i understand it) – Eugene Evdokimov Dec 17 '13 at 14:30
3

I had to tie the webAppContextSetup to the DefaultMockMvcBuilder in order to sort this problem out in my build (Java 1.6.0_65), and suppress the warnings that resulted from that.

@SuppressWarnings({"unchecked", "rawtypes"})
@Before
public void setUp()
{
   mockMvc = MockMvcBuilders.<DefaultMockMvcBuilder> webAppContextSetup(webApplicationContext).addFilter(springSecurityFilterChain).build();
}

As stated in another answer StandaloneMockMvcBuilder would work without warnings, if you are testing a stand alone controller rather than integration testing the full application context.

(Would have simply commented if I could have.)

englishteeth
  • 228
  • 2
  • 9
3

This has been fixed for Spring Framework 4.0.1.

See the following JIRA issue for details: https://jira.springsource.org/browse/SPR-11238

Sam Brannen
  • 29,611
  • 5
  • 104
  • 136