NullPointerException from Jboss LdapExtLoginModule - jboss

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)

Related

Controller Test fails with MethodArgumentConversionNotSupportedException but not in the running application

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

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

Spring Batch ResultSet got closed by other before all data being fetched

I am trying to setup the DB2 source as the persistence for the Batch meta data. I am getting this stacktrace:
Caused by: org.springframework.jdbc.UncategorizedSQLException: PreparedStatementCallback; uncategorized SQLException for SQL [SELECT JOB_EXECUTION_ID, START_TIME, END_TIME, STATUS, EXIT_CODE, EXIT_MESSAGE, CREATE_TIME, LAST_UPDATED, VERSION, JOB_CONFIGURATION_LOCATION from rhall.BATCH_JOB_EXECUTION where JOB_INSTANCE_ID = ? order by JOB_EXECUTION_ID desc]; SQL state [null]; error code [-4470]; [jcc][t4][10120][10898][3.57.82] Invalid operation: result set is closed. ERRORCODE=-4470, SQLSTATE=null; nested exception is com.ibm.db2.jcc.am.SqlException: [jcc][t4][10120][10898][3.57.82] Invalid operation: result set is closed. ERRORCODE=-4470, SQLSTATE=null
at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:84)
at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:81)
at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:81)
at org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:645)
at org.springframework.jdbc.core.JdbcTemplate.query(JdbcTemplate.java:680)
at org.springframework.jdbc.core.JdbcTemplate.query(JdbcTemplate.java:712)
at org.springframework.jdbc.core.JdbcTemplate.query(JdbcTemplate.java:722)
at org.springframework.jdbc.core.JdbcTemplate.query(JdbcTemplate.java:777)
at org.springframework.batch.core.repository.dao.JdbcJobExecutionDao.findJobExecutions(JdbcJobExecutionDao.java:131)
at org.springframework.batch.core.repository.support.SimpleJobRepository.getStepExecutionCount(SimpleJobRepository.java:253)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:60)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:37)
at java.lang.reflect.Method.invoke(Method.java:611)
at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:317)
at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:190)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157)
at org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:99)
at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:281)
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:96)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:207)
at $Proxy32.getStepExecutionCount(Unknown Source)
at org.springframework.batch.core.job.flow.JobFlowExecutor.isStepRestart(JobFlowExecutor.java:82)
at org.springframework.batch.core.job.flow.JobFlowExecutor.executeStep(JobFlowExecutor.java:63)
at org.springframework.batch.core.job.flow.support.state.StepState.handle(StepState.java:67)
at org.springframework.batch.core.job.flow.support.SimpleFlow.resume(SimpleFlow.java:169) ... 22 more
Caused by: com.ibm.db2.jcc.am.SqlException: [jcc][t4][10120][10898][3.57.82] Invalid operation: result set is closed. ERRORCODE=-4470, SQLSTATE=null
at com.ibm.db2.jcc.am.bd.a(bd.java:660)
at com.ibm.db2.jcc.am.bd.a(bd.java:60)
at com.ibm.db2.jcc.am.bd.a(bd.java:103)
at com.ibm.db2.jcc.am.zl.Db(zl.java:4219)
at com.ibm.db2.jcc.am.zl.q(zl.java:4180)
at com.ibm.db2.jcc.am.zl.c(zl.java:1009)
at com.ibm.db2.jcc.am.zl.getTimestamp(zl.java:985)
at com.ibm.ws.rsadapter.jdbc.WSJdbcResultSet.getTimestamp(WSJdbcResultSet.java:2607)
at org.springframework.batch.core.repository.dao.JdbcJobExecutionDao$JobExecutionRowMapper.mapRow(JdbcJobExecutionDao.java:425)
at org.springframework.batch.core.repository.dao.JdbcJobExecutionDao$JobExecutionRowMapper.mapRow(JdbcJobExecutionDao.java:396)
at org.springframework.jdbc.core.RowMapperResultSetExtractor.extractData(RowMapperResultSetExtractor.java:93)
at org.springframework.jdbc.core.RowMapperResultSetExtractor.extractData(RowMapperResultSetExtractor.java:60)
at org.springframework.jdbc.core.JdbcTemplate$1.doInPreparedStatement(JdbcTemplate.java:693)
at org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:629)
... 45 more
I trace the code, and found the problem around this method: JdbcJobExecutionDao.mapRow(ResultSet rs, int rowNum)
(I am using Spring-batch version 3.0.6) List paste the method here for your
convenience,
public JobExecution mapRow(ResultSet rs, int rowNum)
throws SQLException {
Long id = rs.getLong(1);
String jobConfigurationLocation = rs.getString(10);
JobExecution jobExecution;
if (jobParameters == null) {
jobParameters = getJobParameters(id);
}
if (jobInstance == null) {
jobExecution = new JobExecution(id, jobParameters, jobConfigurationLocation);
} else {
jobExecution = new JobExecution(jobInstance, id, jobParameters, jobConfigurationLocation);
}
jobExecution.setStartTime(rs.getTimestamp(2));
jobExecution.setEndTime(rs.getTimestamp(3));
jobExecution.setStatus(BatchStatus.valueOf(rs.getString(4)));
jobExecution.setExitStatus(new ExitStatus(rs.getString(5), rs.getString(6)));
jobExecution.setCreateTime(rs.getTimestamp(7));
jobExecution.setLastUpdated(rs.getTimestamp(8));
jobExecution.setVersion(rs.getInt(9));
return jobExecution;
}
As I trace it, I notice that the problem is in the getJobParameters(id) method. This method performs another query to the JOB_EXECUTION_PARAMS table for paramaters for the given job id. But within this method, the getConnection method returns the same connection as in the current context. After the query, the finally block closes the resultSet. So when the control gets back to the mapRow method, it failed at this line:
jobExecution.setStartTime(rs.getTimestamp(2));
It is because the rs has already been closed by the getJobParameters(id) method.
Wondering if I did wrong? Please point me out.
Many thanks.
removing #Transactional from my method that uses the Batch Infrastructure classes, ie, JobExplorer, solves this issues around the closed ResultSet.

Solution to NullPointerException in my TestNG test case

I am trying to login Facebook by using multiple sets of login cridential from external excel sheet using TestNG but in between the code what i have written throws:
FAILED: f
java.lang.NullPointerException
at DataDriven.loginRetesting.f(loginRetesting.java:31)
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.testng.internal.MethodInvocationHelper.invokeMethod(MethodInvocationHelper.java:84)
at org.testng.internal.Invoker.invokeMethod(Invoker.java:714)
at org.testng.internal.Invoker.invokeTestMethod(Invoker.java:901)
at org.testng.internal.Invoker.invokeTestMethods(Invoker.java:1231)
at org.testng.internal.TestMethodWorker.invokeTestMethods(TestMethodWorker.java:127)
at org.testng.internal.TestMethodWorker.run(TestMethodWorker.java:111)
at org.testng.TestRunner.privateRun(TestRunner.java:767)
at org.testng.TestRunner.run(TestRunner.java:617)
at org.testng.SuiteRunner.runTest(SuiteRunner.java:334)
at org.testng.SuiteRunner.runSequentially(SuiteRunner.java:329)
at org.testng.SuiteRunner.privateRun(SuiteRunner.java:291)
at org.testng.SuiteRunner.run(SuiteRunner.java:240)
at org.testng.SuiteRunnerWorker.runSuite(SuiteRunnerWorker.java:52)
at org.testng.SuiteRunnerWorker.run(SuiteRunnerWorker.java:86)
at org.testng.TestNG.runSuitesSequentially(TestNG.java:1224)
at org.testng.TestNG.runSuitesLocally(TestNG.java:1149)
at org.testng.TestNG.run(TestNG.java:1057)
at org.testng.remote.RemoteTestNG.run(RemoteTestNG.java:111)
at org.testng.remote.RemoteTestNG.initAndRun(RemoteTestNG.java:204)
at org.testng.remote.RemoteTestNG.main(RemoteTestNG.java:175)
Code:
#Test
public void f() throws Exception{
FileInputStream fi=new FileInputStream("E:\\workspace99\\SeleniumAutomations\\testdata\\LoginData.xls");
Workbook w=Workbook.getWorkbook(fi);
Sheet s=w.getSheet(0);
for (int i = 1; i < 8; i++) {
driver.findElement(By.id("email")).sendKeys(s.getCell(0,i).getContents());
driver.findElement(By.id("pass")).sendKeys(s.getCell(1,i).getContents());
driver.findElement(By.id("u_0_1")).click();
Thread.sleep(1000);
if (selenium.isElementPresent("id=userNavigationLabel")) {
//driver.findElement(By.cssSelector("span.gb_V.gbii")).click();
driver.findElement(By.id("userNavigationLabel")).click();
driver.findElement(By.cssSelector("input.uiLinkButtonInput")).click();
Thread.sleep(1000);
}
else{
System.out.println("invalid cridential");
driver.findElement(By.id("email")).clear();
driver.findElement(By.id("pass")).clear();
}
}
}
I am not able to find out where the problem is? so how to solve it.
For one thing, don't use "throws Exception" in the method declaration. Instead, have a try block inside the method with a "not null assertion".
Keep in mind that you never want to throw typical exceptions in a test method because it will drop you out of the test lifecycle too early and skip your #After phases. An exception thrown in a #Before annotated method will probably cause a SkipAssertion.
So, what you want to do instead is fail assertions. So, if you have a exception condition that occurs sometimes, swallow the exception (don't throw it) and use an assertion to handle it.
For example:
try {
} catch ( NullPointerException e ) {
Assert.assertTrue( "There was an error in blah.", false );
}
Null pointer means, exepected value of variable is null.
Please check the file exists at the specified path "E:\workspace99\SeleniumAutomations\testdata\LoginData.xls" and you get the value correctly from the file.
The stack trace says the issue is line 31 in your code but your snippet does not allow us to work out where line 31 is .
you are calling "selenium.isElementPresent". Could "selenium" be nil?

Having trouble mocking an email server using JUnit

I'm trying to mock sending an email (for the purposes of JUnit, v4.8.1, testing) and decided to use Dumbster, which I found through SO. I'm using version 1.6. I have this in my JUnit test …
SimpleSmtpServer server = SimpleSmtpServer.start();
boolean ret = m_emailSvc.sendEmail("me#me.com",
"you#you.com",
"localhost",
"Test",
"Test Body");
Assert.assertTrue(ret);
server.stop();
and I send an email this way …
public boolean sendEmail(final String toEmail,
final String fromEmail,
final String smtpHost,
final String subject,
final String body)
{
boolean ret = true;
// Get system properties
Properties properties = System.getProperties();
// Setup mail server
properties.setProperty("mail.smtp.host", smtpHost);
// Get the default Session object.
Session session = Session.getDefaultInstance(properties);
try{
// Create a default MimeMessage object.
MimeMessage message = new MimeMessage(session);
// Set From: header field of the header.
message.setFrom(new InternetAddress(fromEmail));
// Set To: header field of the header.
message.addRecipient(Message.RecipientType.TO,
new InternetAddress(toEmail));
// Set Subject: header field
message.setSubject(subject);
// Now set the actual message
message.setText(body);
// Send message
Transport.send(message);
}catch (MessagingException mex) {
ret = false;
LOG.error(mex.getMessage(), mex);
} // try
return ret;
} // sendEmail
This fails with the exception below. Does anyone know what I'm doing wrong or is there an easier way to mock sending an email in a JUnit test?
java.net.BindException: Permission denied
at java.net.PlainSocketImpl.socketBind(Native Method)
at java.net.PlainSocketImpl.socketBind(PlainSocketImpl.java:521)
at java.net.PlainSocketImpl.bind(PlainSocketImpl.java:414)
at java.net.ServerSocket.bind(ServerSocket.java:326)
at java.net.ServerSocket.<init>(ServerSocket.java:192)
at java.net.ServerSocket.<init>(ServerSocket.java:104)
at com.dumbster.smtp.SimpleSmtpServer.run(Unknown Source)
at java.lang.Thread.run(Thread.java:680)
[ERROR]: org.mainco.subco.email.service.EmailServiceImpl - Could not connect to SMTP host: localhost, port: 25
javax.mail.MessagingException: Could not connect to SMTP host: localhost, port: 25;
nested exception is:
java.net.ConnectException: Connection refused
at com.sun.mail.smtp.SMTPTransport.openServer(SMTPTransport.java:1934)
at com.sun.mail.smtp.SMTPTransport.protocolConnect(SMTPTransport.java:638)
at javax.mail.Service.connect(Service.java:295)
at javax.mail.Service.connect(Service.java:176)
at javax.mail.Service.connect(Service.java:125)
at javax.mail.Transport.send0(Transport.java:194)
at javax.mail.Transport.send(Transport.java:124)
at org.mainco.subco.email.service.EmailServiceImpl.sendEmail(EmailServiceImpl.java:62)
at org.mainco.subco.email.service.EmailServiceTest.testSendEmail(EmailServiceTest.java:23)
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:597)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:44)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:41)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20)
at org.junit.runners.BlockJUnit4ClassRunner.runNotIgnored(BlockJUnit4ClassRunner.java:79)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:71)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:49)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:193)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:52)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:191)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:42)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:184)
at org.junit.runners.ParentRunner.run(ParentRunner.java:236)
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: java.net.ConnectException: Connection refused
at java.net.PlainSocketImpl.socketConnect(Native Method)
at java.net.PlainSocketImpl.doConnect(PlainSocketImpl.java:382)
at java.net.PlainSocketImpl.connectToAddress(PlainSocketImpl.java:241)
at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:228)
at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:384)
at java.net.Socket.connect(Socket.java:527)
at java.net.Socket.connect(Socket.java:476)
at com.sun.mail.util.SocketFetcher.createSocket(SocketFetcher.java:288)
at com.sun.mail.util.SocketFetcher.getSocket(SocketFetcher.java:231)
at com.sun.mail.smtp.SMTPTransport.openServer(SMTPTransport.java:1900)
I decided to mock the static call from the Transport class instead, using PowerMock (v.1.5.1).
#RunWith(PowerMockRunner.class)
public class EmailServiceTest
{
#Autowired
private EmailService m_emailSvc = new EmailServiceImpl();
#Test
#PrepareForTest( Transport.class )
public final void testSendEmail()
{
suppress(methodsDeclaredIn(Transport.class));
boolean ret = m_emailSvc.sendEmail("me#me.com",
"you#you.com",
"localhost",
"Test",
"Test Body");
Assert.assertTrue(ret);
} // testSendEmail
What about wrapping the call to Transport is a mockable object? Inject the mock and verify the call.
What I mean is something like this...
class MyTransport{
public void send(MimeMessage message){
Transport.send(message);
}
}
Then inject an instance of this class into your class above. In your production env you have the same code. However, when doing testing you could pass in a Mock for MyTransport and thereby verify the call to send without the need of a server.