Controller Test fails with MethodArgumentConversionNotSupportedException but not in the running application - rest

Spring Boot App using 2.0.3.RELEASE of Spring Boot.
So I have REST API controller written like this:
#RestController
#RequestMapping("/root/{id}")
#Slf4j
public class RootController {
#GetMapping
public ResponseEntity<?> getXXX(
#PathVariable String id,
#RequestParam(value = "status") Status status,
#RequestParam(value = "comment") String comment,
#RequestParam(value = "other") Optional<String> other) {
log.info("Requested getXXX id={} status={} other={} comment={}", id, status, other, comment);
return new ResponseEntity<>(HttpStatus.NOT_IMPLEMENTED);
}
}
So the interesting part is the Optional<String> other on the above definition. I have tested the above manually via calling curl:
curl -v -X GET 'http://localhost:8080/root/ID?status=OK&comment=Comment'
which results in logging output on console like this:
...Requested getXXX id=ID status=OK other=Optional.empty comment=Comment
and using curl like this:
curl -v -X GET 'http://localhost:8080/root/ID?status=OK&comment=Comment&other=MoreOther'
which results in the following output:
Requested getXXX id=ID status=OK other=Optional[MoreOther] comment=Comment
So far so good.
But of course I would like to check this via unit tests and not manually...So I wrote a REST controller test which looks like this:
#RunWith(SpringRunner.class)
#SpringBootTest(classes = RootController.class)
#AutoConfigureMockMvc
public class RootControllerTest {
#Autowired
private MockMvc mvc;
#Test
public void shouldReturnNotImplemented() throws Exception {
//#formatter:off
mvc.perform(
get("/root/xyz?status={status}&comment={comment}&other={other}", Status.NOTOK, "COMMENT", Optional.<String>of("Other"))
.characterEncoding("UTF-8")
.accept(MediaType.ALL)
)
.andExpect(
status().isNotImplemented()
);
//#formatter:on
}
But unfortunately the above test fails with:
MockHttpServletRequest:
HTTP Method = GET
Request URI = /root/xyz
Parameters = {status=[OK], comment=[Comment], other=[Optional[Other]]}
Headers = {Accept=[*/*]}
Body = null
Session Attrs = {}
Handler:
Type = ...RootController
Method = public org.springframework.http.ResponseEntity<?> .getRoot(java.lang.String,Status,java.lang.String,java.util.Optional<java.lang.String>)
Async:
Async started = false
Async result = null
Resolved Exception:
Type = org.springframework.web.method.annotation.MethodArgumentConversionNotSupportedException
ModelAndView:
View name = null
View = null
Model = null
FlashMap:
Attributes = null
MockHttpServletResponse:
Status = 500
Error message = null
Headers = {}
Content type = null
Body =
Forwarded URL = null
Redirected URL = null
Cookies = []
Where the exception: org.springframework.web.method.annotation.MethodArgumentConversionNotSupportedException is the thing I don't understand.
The final question is: Why does the test fail but the running application does not? Does someone has a hint / idea for me?
Update 1:
I have tested also the following:
get("/root/xyz?status={status}&comment={comment}&other={other}", Status.NOTOK, "COMMENT", "Other")
and furthermore which means using only strings.
get("/root/xyz?status={status}&comment={comment}&other={other}", "NOTOK", "COMMENT", "Other")
The point that the running application works perfectly but unfortunately the test do not.
Update 2:
So after turning on debugging mode in test I got the following output: This brings me more and more into the direction that there is a bug within it..cause the parameters are always converted into String instead of Optional...and based on the parameters of get(..., Object... uriVars)
it looks like there is some problem in the code...
2018-07-16 15:50:21.029 DEBUG 16022 --- [main] s.w.s.m.m.a.RequestMappingHandlerMapping : Looking up handler method for path /root/xyz
2018-07-16 15:50:21.031 DEBUG 16022 --- [main] s.w.s.m.m.a.RequestMappingHandlerMapping : Returning handler method [public org.springframework.http.ResponseEntity<?> de....RootController.getXXX(java.lang.String,de....Status,java.lang.String,java.util.Optional<java.lang.String>)]
2018-07-16 15:50:21.057 DEBUG 16022 --- [main] .w.s.m.m.a.ServletInvocableHandlerMethod : Failed to resolve argument 3 of type 'java.util.Optional'
org.springframework.web.method.annotation.MethodArgumentConversionNotSupportedException: Failed to convert value of type 'java.lang.String' to required type 'java.util.Optional'; nested exception is java.lang.IllegalStateException: Cannot convert value of type 'java.lang.String' to required type 'java.util.Optional': no matching editors or conversion strategy found
at org.springframework.web.method.annotation.AbstractNamedValueMethodArgumentResolver.resolveArgument(AbstractNamedValueMethodArgumentResolver.java:127)
at org.springframework.web.method.support.HandlerMethodArgumentResolverComposite.resolveArgument(HandlerMethodArgumentResolverComposite.java:124)
at org.springframework.web.method.support.InvocableHandlerMethod.getMethodArgumentValues(InvocableHandlerMethod.java:161)
at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:131)
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:102)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:877)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:783)
at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:991)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:925)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:974)
at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:866)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:635)
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:851)
at org.springframework.test.web.servlet.TestDispatcherServlet.service(TestDispatcherServlet.java:71)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:742)
at org.springframework.mock.web.MockFilterChain$ServletFilterProxy.doFilter(MockFilterChain.java:166)
at org.springframework.mock.web.MockFilterChain.doFilter(MockFilterChain.java:133)
at org.springframework.test.web.servlet.MockMvc.perform(MockMvc.java:165)
at de...RootControllerTest.shouldReturnNotImplemented(RootControllerTest.java:35)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.springframework.test.context.junit4.statements.RunBeforeTestExecutionCallbacks.evaluate(RunBeforeTestExecutionCallbacks.java:73)
at org.springframework.test.context.junit4.statements.RunAfterTestExecutionCallbacks.evaluate(RunAfterTestExecutionCallbacks.java:83)
at org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:75)
at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:86)
at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:84)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:251)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:97)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:70)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:190)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:86)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:538)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:760)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:460)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:206)
Caused by: java.lang.IllegalStateException: Cannot convert value of type 'java.lang.String' to required type 'java.util.Optional': no matching editors or conversion strategy found
at org.springframework.beans.TypeConverterDelegate.convertIfNecessary(TypeConverterDelegate.java:299)
at org.springframework.beans.TypeConverterDelegate.convertIfNecessary(TypeConverterDelegate.java:99)
at org.springframework.beans.TypeConverterSupport.doConvert(TypeConverterSupport.java:73)
at org.springframework.beans.TypeConverterSupport.convertIfNecessary(TypeConverterSupport.java:52)
at org.springframework.validation.DataBinder.convertIfNecessary(DataBinder.java:692)
at org.springframework.web.method.annotation.AbstractNamedValueMethodArgumentResolver.resolveArgument(AbstractNamedValueMethodArgumentResolver.java:123)
... 50 common frames omitted

This is an issue with how you are loading the test up.
When you specify #SpringBootTest(classes = RootController.class) a class with SpringBootTest it will only load that class into the context i.e. it allows you to specify certain configurations etc. that you would want to test for some integration tests rather than using ContextConfiguration.
You can either remove the RootController and load a full test application context, effectively loading your entire application.
or just specify,
#RunWith(SpringRunner.class)
#WebMvcTest
public class RootControllerTest {
To load a slice test, which will only load the required beans to completely test the WebMVC.
working tests,
https://github.com/Flaw101/mockmvctests
Edit,
I've updated my example and introduced a second controller but only load the RootController in the RootControllerMock via #WebMvcTest(controllers = RootController.class). You can see in the logged output that it only load this controller.
2018-07-16 15:34:28.264 INFO 6176 --- [ main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/root/{id}],methods=[GET]}" onto public org.springframework.http.ResponseEntity<?> com.darrenforsythe.mockmvc.RootController.getXXX(java.lang.String,java.lang.String,java.lang.String,java.util.Optional<java.lang.String>)
references,
https://docs.spring.io/spring-boot/docs/current/api/org/springframework/boot/test/autoconfigure/web/servlet/WebMvcTest.html
https://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-testing.html#boot-features-testing-spring-boot-applications-testing-autoconfigured-mvc-tests

Related

java.lang.ClassCastException: java.util.HashMap cannot be cast to com.spacestudy.model.Investigator

I am trying to write test case for Repository method. In that Test case I want to test Investigator name using assertEquals(). Return type of method is set for that I use for each loop to retrieve result from set and then checked expected and actual result using assertEquals() but I am getting java.lang.ClassCastException: java.util.HashMap cannot be cast to com.spacestudy.model.Investigator
can any one please tell me what I am doing wrong in test case?
InvestigatorRepository
#Query("select new map(invest.sInvestigatorName as sInvestigatorName)"
+ " from Investigator invest")
Set<Investigator> findSinvestigatorName();
I tried Like this
#RunWith(SpringRunner.class)
#DataJpaTest
public class TestInvestigatorRepository {
#Autowired
public TestEntityManager testEm;
#Autowired
InvestigatorRepository investRepo;
#Test
public void testFindSinvestigatorName() {
Investigator invest = new Investigator();
invest.setsInvestigatorName("abc");
invest.setnInstId(60);
Investigator saveInDb = testEm.merge(invest);
Set<Investigator> getFromDb = investRepo.findSinvestigatorName();
for(Investigator result : getFromDb) {
assertEquals(saveInDb.getsInvestigatorName(),result.sInvestigatorName);
}
}
}
Stack Trace
java.lang.ClassCastException: java.util.HashMap cannot be cast to com.spacestudy.model.Investigator
at com.spacestudy.repository.TestInvestigatorRepository.testFindSinvestigatorName(TestInvestigatorRepository.java:39)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:75)
at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:86)
at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:84)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:252)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:94)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:70)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:191)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:86)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:538)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:760)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:460)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:206)
The HQL query you specify explicitly returns a Map, but the return type specified for the method specifies Set<Investigator> which are incompatible types, hence the error.
Spring Data tries to convert the types but fails and in the end, just tries to cast the result to the desired type.
In order to fix this you need to use compatible types options are:
let your query return Investigators.
let your query return a tuple by just listing the attributes: select invest.sInvestigatorName as sInvestigatorName from Investigator invest. Spring Data should be able to map that to an Investigator although your "interesting" property names might cause some troubles.
Since you are really just return a single attribute you might as well make the method return a Set<String> and use the query given in the previous point.

How to use OAuth2RestTemplate + Spring 4?

I'm trying to understand how to use a OAuth2RestTemplate object to consume my OAuth2 secured REST service (which is running under a different project and let's assume also on a different server etc...)
f.e. my rest service is:
https://localhost:8443/rest/api/user
-> Accessing this URL generates an error as I am not authenticated
To request a token I would go to:
https://localhost:8443/rest/oauth/token?grant_type=password&client_id=test&client_secret=test&username=USERNAME&password=PASSWORD
After I receive the token I can then connect to the REST API by using the following URL (example token inserted)
https://localhost:8443/rest/api/user?access_token=06
I currently tried something with the following objects:
#EnableOAuth2Client
#Configuration
class MyConfig {
#Value("${oauth.resource:https://localhost:8443}")
private String baseUrl;
#Value("${oauth.authorize:https://localhost:8443/rest/oauth/authorize}")
private String authorizeUrl;
#Value("${oauth.token:https://localhost:8443/rest/oauth/token}")
private String tokenUrl;
#Bean
protected OAuth2ProtectedResourceDetails resource() {
ResourceOwnerPasswordResourceDetails resource = new ResourceOwnerPasswordResourceDetails();
List scopes = new ArrayList<String>(2);
scopes.add("write");
scopes.add("read");
resource.setAccessTokenUri(tokenUrl);
resource.setClientId("test");
resource.setClientSecret("test");
resource.setGrantType("password");
resource.setScope(scopes);
resource.setUsername("test");
resource.setPassword("test");
return resource;
}
#Bean
public OAuth2RestOperations restTemplate() {
CloseableHttpClient httpClient = HttpClients.custom().setSSLHostnameVerifier(new NoopHostnameVerifier())
.build();
HttpComponentsClientHttpRequestFactory requestFactory = new HttpComponentsClientHttpRequestFactory();
requestFactory.setHttpClient(httpClient);
AccessTokenRequest atr = new DefaultAccessTokenRequest();
OAuth2RestTemplate restTemplate = new OAuth2RestTemplate(resource(), new DefaultOAuth2ClientContext(atr));
AuthorizationCodeAccessTokenProvider provider = new AuthorizationCodeAccessTokenProvider();
provider.setRequestFactory(requestFactory);
restTemplate.setAccessTokenProvider(provider);
return restTemplate;
}
}
I am tried to get token in controller like below.
#Controller
public class TestController {
#Autowired
private OAuth2RestOperations restTemplate;
#RequestMapping(value="/", method= RequestMethod.GET)
public String TestForm() {
System.out.println("Token : " + restTemplate.getAccessToken().getValue());
}
}
But i got below exception
SEVERE: Servlet.service() for servlet [appServlet] in context with path [/web] threw exception [Request processing failed; nested exception is java.lang.ClassCastException: org.springframework.security.oauth2.client.token.grant.password.ResourceOwnerPasswordResourceDetails cannot be cast to org.springframework.security.oauth2.client.token.grant.code.AuthorizationCodeResourceDetails] with root cause
java.lang.ClassCastException: org.springframework.security.oauth2.client.token.grant.password.ResourceOwnerPasswordResourceDetails cannot be cast to org.springframework.security.oauth2.client.token.grant.code.AuthorizationCodeResourceDetails
at org.springframework.security.oauth2.client.token.grant.code.AuthorizationCodeAccessTokenProvider.obtainAccessToken(AuthorizationCodeAccessTokenProvider.java:190)
at org.springframework.security.oauth2.client.OAuth2RestTemplate.acquireAccessToken(OAuth2RestTemplate.java:221)
at org.springframework.security.oauth2.client.OAuth2RestTemplate.getAccessToken(OAuth2RestTemplate.java:173)
at com.divyshivglobalinvestor.web.controller.PersonalLoanController.PersonalLoanForm(PersonalLoanController.java:37)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:601)
at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:221)
at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:136)
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:114)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:827)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:738)
at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:85)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:963)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:897)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:970)
at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:861)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:624)
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:846)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:731)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:303)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:218)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:122)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:505)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:169)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:103)
at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:956)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:116)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:442)
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1082)
at org.apache.coyote.AreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:603)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.lang.Thread.run(Thread.java:722)bstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:623)
at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:316)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1110)
at java.util.concurrent.Th
From some blog I found that, if we need to grant password then, instead of ResourceOwnerPasswordResourceDetails, it should be used AccessTokenRequest (which is a Map and is ephemeral). It would be great if someone can help me in getting accessToken. :)
Thanks in advance !
You should use ResourceOwnerPasswordAccessTokenProvider instead of AuthorizationCodeAccessTokenProvider in restTemplate bean

NullPointerException from Jboss LdapExtLoginModule

I am attempting to configure Ldap authentication for a Jboss web-app. Jboss loads my module, but does not authenticate credentials that are known to be good. I should point out that my module just extends LdapExtLoginModule without adding any logic. I get the same error when defering directly to LdapExtLoginModule. The error:
PBOX000070: Password invalid/Password required
is returned when I attempt to login. I tracked the error down to a null pointer being thrown by a hashtable.put() operation in org.jboss.security.auth.spi.LdapExtLoginModule.constructInitialLdapContext. Here is the stack trace:
javax.security.auth.login.FailedLoginException: PBOX000070: Password invalid/Password required
at org.jboss.security.auth.spi.UsernamePasswordLoginModule.login(UsernamePasswordLoginModule.java:284)
at com.alstom.auth.login.ldap.CustomLdapLoginModule.login(CustomLdapLoginModule.java:164)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at javax.security.auth.login.LoginContext.invoke(LoginContext.java:762)
at javax.security.auth.login.LoginContext.access$000(LoginContext.java:203)
at javax.security.auth.login.LoginContext$4.run(LoginContext.java:690)
at javax.security.auth.login.LoginContext$4.run(LoginContext.java:688)
at java.security.AccessController.doPrivileged(Native Method)
at javax.security.auth.login.LoginContext.invokePriv(LoginContext.java:687)
at javax.security.auth.login.LoginContext.login(LoginContext.java:595)
at org.springframework.security.authentication.jaas.AbstractJaasAuthenticationProvider.authenticate(AbstractJaasAuthenticationProvider.java:149)
at org.springframework.security.authentication.ProviderManager.authenticate(ProviderManager.java:156)
at com.etse.security.SecureMethodAuthenticationManager.authenticate(SecureMethodAuthenticationManager.java:29)
at org.springframework.security.authentication.ProviderManager.authenticate(ProviderManager.java:174)
at org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter.attemptAuthentication(UsernamePasswordAuthenticationFilter.java:94)
at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:195)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:105)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:87)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:192)
at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:160)
at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:346)
at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:259)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:246)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:214)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:230)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:149)
at org.jboss.as.web.security.SecurityContextAssociationValve.invoke(SecurityContextAssociationValve.java:169)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:145)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:97)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:102)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:336)
at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:856)
at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:653)
at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:920)
at java.lang.Thread.run(Thread.java:745)
Caused by: java.lang.NullPointerException
at java.util.Hashtable.put(Hashtable.java:514)
at org.jboss.security.auth.spi.LdapExtLoginModule.constructInitialLdapContext(LdapExtLoginModule.java:742)
at org.jboss.security.auth.spi.LdapExtLoginModule.createLdapInitContext(LdapExtLoginModule.java:463)
at org.jboss.security.auth.spi.LdapExtLoginModule.validatePassword(LdapExtLoginModule.java:340)
at com.alstom.auth.login.ldap.CustomLdapLoginModule.validatePassword(CustomLdapLoginModule.java:152)
at org.jboss.security.auth.spi.UsernamePasswordLoginModule.login(UsernamePasswordLoginModule.java:281)
... 40 more
The function:
private InitialLdapContext constructInitialLdapContext(String dn, Object credential) throws NamingException
{
String protocol = (String)options.get(Context.SECURITY_PROTOCOL);
String providerURL = (String) options.get(Context.PROVIDER_URL);
if (providerURL == null)
providerURL = "ldap://localhost:" + ((protocol != null && protocol.equals("ssl")) ? "636" : "389");
Properties env = constructLdapContextEnvironment(providerURL, dn, credential);
return new InitialLdapContext(env, null);
}
No hashtable.put() operations there so it must come from the InitialLdapContext constructor right?
public InitialLdapContext(Hashtable<?,?> environment,Control[] connCtls) throws NamingException {
super(true); // don't initialize yet
// Clone environment since caller owns it.
Hashtable env = (environment == null)
? new Hashtable(11)
: (Hashtable)environment.clone();
// Put connect controls into environment. Copy them first since
// caller owns the array.
if (connCtls != null) {
Control[] copy = new Control[connCtls.length];
System.arraycopy(connCtls, 0, copy, 0, connCtls.length);
env.put(BIND_CONTROLS_PROPERTY, copy);
}
// set version to LDAPv3
env.put("java.naming.ldap.version", "3");
// Initialize with updated environment
init(env);
}
connCtls is null (see constructor call) so the only put operation is env.put("java.naming.ldap.version", "3") which is obviously fine.
Any idea what's going on here? Thanks.
HashTable does not allow keys to be null. Verify that none of the keys you put into Hashtable env is not null. For example, for
env.put(BIND_CONTROLS_PROPERTY, copy);
BIND_CONTROLS_PROPERTY must not be null.
Hope that helps
IMO, You have a code from another version of the LdapExtLoginModule. The correct one could be this one on GitHub.
The code there is:
private InitialLdapContext constructInitialLdapContext(String dn, Object credential) throws NamingException
{
Properties env = new Properties();
Iterator iter = options.entrySet().iterator();
while (iter.hasNext())
{
Entry entry = (Entry) iter.next();
env.put(entry.getKey(), entry.getValue()); /* this is the line 742 */
}
So there seems to be a login module option with null value. Try to check your configuration.
Please, share more details about your environment next time. It will help a lot to evaluate your problem. The most important details:
application server version
used server configuration (i.e. configuration of the security domain in this case)

Caused by: ognl.NoSuchPropertyException: org.springframework.webflow.engine.impl.RequestControlContextImpl

I'm kind of new to Spring Web Flow, My application uses Spring web flow version 2.0 and I've just started trying to implement some unit testing into my application(had no previous unit testing). This is my simple flow.
<?xml version="1.0" encoding="UTF-8"?>
<flow xmlns="http://www.springframework.org/schema/webflow"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/webflow
http://www.springframework.org/schema/webflow/spring-webflow-2.0.xsd"
abstract="false" start-state="isDynamicMenu" >
<action-state id="isDynamicMenu">
<evaluate expression="menuMakerTestAction.isDynamicMenu" result="res"/>
<transition on="yes" to="setDynamicMenu"/>
<transition on="no" to="setCommonMenu"/>
</action-state>
<view-state id="setDynamicMenu" />
<view-state id="setCommonMenu" />
</flow>
and this is the test code:
public class FlowTest1 extends AbstractXmlFlowExecutionTests {
private MenuMakerTestAction menuMakerTestAction;
protected void setUp() {
menuMakerTestAction = mock(MenuMakerTestAction.class);
}
#Override
protected FlowDefinitionResource getResource(
FlowDefinitionResourceFactory resourceFactory) {
FlowDefinitionResource resource = resourceFactory
.createResource("classpath:spring-webflow/config/menuMakerTest.xml");
Assert.notNull(resource);
return resource;
}
#Override
protected void configureFlowBuilderContext(
MockFlowBuilderContext builderContext) {
builderContext.registerBean("menuMakerTestAction", menuMakerTestAction);
}
#Test
public void testFlow() throws GlobalException {
MutableAttributeMap attrMap = new LocalAttributeMap();
attrMap.put("res", "no");
MockExternalContext context = new MockExternalContext();
startFlow(attrMap, context);
assertCurrentStateEquals("setCommonMenu");
}
}
And this is the error I am getting:
org.springframework.webflow.execution.ActionExecutionException: Exception thrown executing [AnnotatedAction#12f1bf0 targetAction = [EvaluateAction#1797795 expression = menuMakerTestAction.isDynamicMenu, resultExposer = [ActionResultExposer#19a0203 result = res, resultType = [null]]], attributes = map[[empty]]] in state 'isDynamicMenu' of flow 'menuMakerTest' -- action execution attributes were 'map[[empty]]'
at org.springframework.webflow.execution.ActionExecutor.execute(ActionExecutor.java:60)
at org.springframework.webflow.engine.ActionState.doEnter(ActionState.java:101)
at org.springframework.webflow.engine.State.enter(State.java:194)
at org.springframework.webflow.engine.Flow.start(Flow.java:535)
at org.springframework.webflow.engine.impl.FlowExecutionImpl.start(FlowExecutionImpl.java:350)
at org.springframework.webflow.engine.impl.FlowExecutionImpl.start(FlowExecutionImpl.java:221)
at org.springframework.webflow.test.execution.AbstractFlowExecutionTests.startFlow(AbstractFlowExecutionTests.java:123)
at ivr.latam.icg.view.menu.FlowTest1.testFlow(FlowTest1.java:71)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:585)
at junit.framework.TestCase.runTest(TestCase.java:176)
at junit.framework.TestCase.runBare(TestCase.java:141)
at junit.framework.TestResult$1.protect(TestResult.java:122)
at junit.framework.TestResult.runProtected(TestResult.java:142)
at junit.framework.TestResult.run(TestResult.java:125)
at junit.framework.TestCase.run(TestCase.java:129)
at junit.framework.TestSuite.runTest(TestSuite.java:255)
at junit.framework.TestSuite.run(TestSuite.java:250)
at org.junit.internal.runners.JUnit38ClassRunner.run(JUnit38ClassRunner.java:84)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)
Caused by: org.springframework.binding.expression.PropertyNotFoundException: Property 'menuMakerTestAction.isDynamicMenu' not found on context of class [org.springframework.webflow.engine.impl.RequestControlContextImpl]
at org.springframework.binding.expression.ognl.OgnlExpression.getValue(OgnlExpression.java:87)
at org.springframework.webflow.action.EvaluateAction.doExecute(EvaluateAction.java:77)
at org.springframework.webflow.action.AbstractAction.execute(AbstractAction.java:188)
at org.springframework.webflow.execution.AnnotatedAction.execute(AnnotatedAction.java:145)
at org.springframework.webflow.execution.ActionExecutor.execute(ActionExecutor.java:51)
... 26 more
Caused by: ognl.NoSuchPropertyException: com.view.action.config.MenuMakerTestAction$$EnhancerByMockitoWithCGLIB$$9f5b5273.isDynamicMenu
at ognl.ObjectPropertyAccessor.getProperty(ObjectPropertyAccessor.java:122)
at ognl.OgnlRuntime.getProperty(OgnlRuntime.java:1657)
at ognl.ASTProperty.getValueBody(ASTProperty.java:92)
at ognl.SimpleNode.evaluateGetValueBody(SimpleNode.java:170)
at ognl.SimpleNode.getValue(SimpleNode.java:210)
at ognl.ASTChain.getValueBody(ASTChain.java:109)
at ognl.SimpleNode.evaluateGetValueBody(SimpleNode.java:170)
at ognl.SimpleNode.getValue(SimpleNode.java:210)
at ognl.Ognl.getValue(Ognl.java:333)
at org.springframework.binding.expression.ognl.OgnlExpression.getValue(OgnlExpression.java:85)
... 30 more
Its my first time posting in a forum. I can't get past this. The method isDynamicMenu receives nothing at all, and returns just a string. Any help would really be appreciated.
Thanks!
SWF will not implicitly find Your "menuMakerTestAction" bean or any Spring bean registered to the application context. However, SWF will automatically register service classes (annotated with #Service,#Component) inside of SWF. (note: you can also call static methods from SWF)
So you must either:
A. explicitly initialize the menuMakerTestAction inside the flow definition
B. use a service method/static call to lookup the menuMakerTestAction bean
so if you have a service called myService then you can use myService.getMyMenuMakerTestAction() inside the evaluate expression in the flow.
or
Call a static method like such Printing log from flow.xml
also make sure:
"isDynamicMenu" is actually the attribute name on the class (and not the 'get' method name)

Endpoints API generation error when using Guava

We are using Appengine Endpoints Java with Guava and when Function is used inside an endpoint method the API generator returns an exception.
Function is NOT part of the method signature. Its just used inside the method to transform a list. Comment out this body part and it generates OK.
Guava sure is in the classpath, and other parts of the application uses it normally.
I'm not sure its related to Guava or any outside API would give the same error.
The method:
#ApiMethod(
httpMethod = "GET",
name = "ledgers.accountgroups.get",
path="ledgers/{ledgerId}/accountgroups")
public Collection<IAccountGroup> listAccountGroups(#Named("ledgerId") String ledgerId, User user) throws Exception {
collaboratorDAO.assertCollaboratorOn(ledgerId, user);
List<Group> groups = accountGroupsDAO.getAccountGroups(ledgerId);
List<IAccountGroup> transformedGroups = Lists.transform(groups, new Function<Group, IAccountGroup>() {
#Override
public IAccountGroup apply(Group group) {
return group.createClient();
}
});
return transformedGroups;
}
The exception:
INFO: Successfully processed ./war/WEB-INF/appengine-web.xml
interface com.google.api.server.spi.config.Api
interface com.google.api.server.spi.config.Api
Exception in thread "main" java.lang.NoClassDefFoundError: com/google/common/base/Function
at java.lang.Class.getDeclaredMethods0(Native Method)
at java.lang.Class.privateGetDeclaredMethods(Class.java:2436)
at java.lang.Class.getDeclaredMethods(Class.java:1793)
at com.google.api.server.spi.MethodHierarchyReader.addServiceMethods(MethodHierarchyReader.java:174)
at com.google.api.server.spi.MethodHierarchyReader.readMethodHierarchyIfNecessary(MethodHierarchyReader.java:44)
at com.google.api.server.spi.MethodHierarchyReader.getEndpointOverrides(MethodHierarchyReader.java:99)
at com.google.api.server.spi.config.annotationreader.ApiConfigAnnotationReader.readEndpointMethods(ApiConfigAnnotationReader.java:215)
at com.google.api.server.spi.config.annotationreader.ApiConfigAnnotationReader.loadEndpointMethods(ApiConfigAnnotationReader.java:92)
at com.google.api.server.spi.config.ApiConfigLoader.loadConfiguration(ApiConfigLoader.java:55)
at com.google.api.server.spi.tools.AnnotationApiConfigGenerator.generateConfigObjects(AnnotationApiConfigGenerator.java:237)
at com.google.api.server.spi.tools.AnnotationApiConfigGenerator.generateConfig(AnnotationApiConfigGenerator.java:185)
at com.google.api.server.spi.tools.GenApiConfigAction.genApiConfig(GenApiConfigAction.java:78)
at com.google.api.server.spi.tools.GetClientLibAction.getClientLib(GetClientLibAction.java:66)
at com.google.api.server.spi.tools.GetClientLibAction.execute(GetClientLibAction.java:49)
at com.google.api.server.spi.tools.EndpointsTool.execute(EndpointsTool.java:66)
at com.google.api.server.spi.tools.EndpointsTool.main(EndpointsTool.java:92)
Caused by: java.lang.ClassNotFoundException: com.google.common.base.Function
at java.net.URLClassLoader$1.run(URLClassLoader.java:202)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:190)
at java.lang.ClassLoader.loadClass(ClassLoader.java:306)
at java.lang.ClassLoader.loadClass(ClassLoader.java:247)
... 16 more
It's very simple not to use Guava at this point, and it works. I just want to know why this is happening as I need a more have use of Guava in other parts.
Update:
I think it the same problem as:
Google Cloud Endpoints doesn't know about the Work class from Objectify 4 Transaction, causing ClassNotFoundException
Any tips?
Thanks!