Verify Error while invoke static function in playframework controller - java

I am trying to invoke a static function (Users.dashboard()) at runtime and I am getting a Verify Error exception. Users class inherits CRUD.java and does not take any params.
In Home.index():
public class Home extends Controller {
public static void index() {
for (Class<CRUD> clazz : play.Play.classloader
.getAssignableClasses(CRUD.class)) {
Dashboard d;
try {
Method m = clazz.getMethod("dashboard");
if (m != null) {
d = (Dashboard) m.invoke(clazz.newInstance(), new Object[] {});
}
} catch (SecurityException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
} catch (Exception e) {
}
}
render(dashboards);
}
Console Output:
#69iahfk3j
Internal Server Error (500) for request GET /home
Oops: VerifyError
An unexpected error occured caused by exception VerifyError: (class: controllers/Home, method: index signature: ()V) Register 1 contains wrong type
play.exceptions.UnexpectedException: Unexpected Error
at play.Invoker$Invocation.onException(Invoker.java:242)
at play.Invoker$Invocation.run(Invoker.java:284)
at Invocation.HTTP Request(Play!)
Caused by: java.lang.VerifyError: (class: controllers/Home, method: index signature: ()V) Register 1 contains wrong type
at java.lang.Class.getDeclaredMethods0(Native Method)
at java.lang.Class.privateGetDeclaredMethods(Class.java:2427)
at java.lang.Class.getDeclaredMethods(Class.java:1791)
at play.utils.Java.findActionMethod(Java.java:98)
at play.mvc.ActionInvoker.getActionMethod(ActionInvoker.java:602)
at play.mvc.ActionInvoker.resolve(ActionInvoker.java:85)
... 1 more

Public static methods in controllers are enhanced by Play so invocation on these methods can be problematic.
Did you annotation this method with #Util if it is a utility method ?
If you just wan to redirect to dashboard in this case, you can simply use redirect on the action, something like
redirect("Users.dashboard");

Related

How to disable springboot authentication for internal method invoke. [AuthenticationCredentialsNotFoundException]

I was trying to invoke all the controller methods when the service is up to warmup the cache.
But our methods has some permission control like:
#PreAuthorize(value = "hasPermission(#securedObject.application(), 'READ_PRODUCT')
The way how I invoke methods is like this:
private void adaptAndExecute(HandlerMethod handlerMethod, Map requestParas, List<Future> taskStaus) {
Object[] parameters = adaptParas(handlerMethod.getMethodParameters(), requestParas);
Object controllerInstance = applicationContext.getBean(handlerMethod.getBeanType());
taskStaus.add(pool.submit(() -> {
try {
handlerMethod.getMethod().invoke(controllerInstance, parameters);
} catch (Exception e) {
logger.warn("invoke method failed.", e);
}
}));
}
But I got this errors:
Caused by: org.springframework.security.authentication.AuthenticationCredentialsNotFoundException: An Authentication object was not found in the SecurityContext
at org.springframework.security.access.intercept.AbstractSecurityInterceptor.credentialsNotFound(AbstractSecurityInterceptor.java:336)
at org.springframework.security.access.intercept.AbstractSecurityInterceptor.beforeInvocation(AbstractSecurityInterceptor.java:200)
at org.springframework.security.access.intercept.aopalliance.MethodSecurityInterceptor.invoke(MethodSecurityInterceptor.java:58)
So, how can I disable the authentication if I invoke internally?
Thanks
Currently I have no idea about this.

How to test exception scenario in junit 5 in spring boot?

I have a void method that does some tasks trying to test exception scenarios but the test case is getting failed.
public void completetask(){
try{
RemoteUser rm = usrRepo.findById(12);
assistenRepo.save(rm);
}catch(Exception e){
log.error("Exception occurred while making changes {}", e,getMessage());
}
}
How can we test the exception scenario here on JUnit 5?
I have tried this but it's not working
#Test
public void completetaskTest(){
RemoteUser rm = getDummyRemoteUsr();
Mockito.when(usrRepo.findById(12)).thenReturn(rm);
Mockito.when(assistenRepo.save(rm)).thenThrow(new Exception("Error Abnormal"));
Exception exception = Assestions.assertThrow(Exception.class, () -> usrService.completetask());
String expectedMessage = "Exception occurred while making changes";
String actualMessage = exception.getMessage();
Assertions.assetTrue(actualMessage.contains(expectedMessage));
}
I am getting an error for this test case - the check exception is invalid for this method
Invalid java.lang.Exception : Error
Can I know what wrong I am doing here ?
You are not throwing your error, you are just writing a log with one log line.
catch(Exception e){
log.error("Exception occurred while making changes {}", e,getMessage());
}
Here is the javadoc on Assertions.assertThrows:
Assert that execution of the supplied executable throws an exception of the expectedType and return the exception.
If no exception is thrown, or if an exception of a different type is thrown, this method will fail.
If you do not want to perform additional checks on the exception instance, ignore the return value.
That's why your assertThrows method will fail under all circumstances.
So either throw an error in your method you want to test, or check the log print in exceptions for testing.
You are expecting your method to thrown an exception but in your code, you're handling and logging the exception and no exception is thrown:
public void completetask(){
try {
RemoteUser rm = usrRepo.findById(12);
assistenRepo.save(rm); // <-- Exception is thrown...
} catch(Exception e){ // <-- Catched here
log.error("Exception occurred while making changes {}", e,getMessage());
}
// <-- Method finishes normally.
}
You should be seeing the following in the output:
Exception occurred while making changes Error Abnormal
But your test will be failing here:
Exception exception = Assestions.assertThrow(Exception.class, () -> usrService.completetask());
Because the exception was never thrown. If you comment out the exception handling try / catch it will pass that point but now it will fail comparing the error messages.
EDIT:
I know this scenario but the problem here is how to solve this issue? How can we write test scenario for this condition –
If you want to verify your exception was handled just remove verification:
#Test
public void completetaskTest(){
RemoteUser rm = getDummyRemoteUsr();
when(usrRepo.findById(12)).thenReturn(rm);
when(assistenRepo.save(rm)).thenThrow(new Exception("Error Abnormal"));
assertTrue(true); // if we reached this line, in means the error has handled.
}
If you really want to go further and check if the message matches (which it might be overkill) you can check the logger, but again, I would't recommend it.
Something like this:
#Auto
Logger log;
...
#Test
public void completetaskTest(){
RemoteUser rm = getDummyRemoteUsr();
when(usrRepo.findById(12)).thenReturn(rm);
when(assistenRepo.save(rm)).thenThrow(new Exception("Error Abnormal"));
// Verify the `log.error` was invoked with exactly those parameters
verify(log, times(1)).error("Exception occurred while making changes {}", "Error Abnormal");
}
That means the exception was thrown, cached and the logger was invoked.

GenericJDBCException catched by wrong part of the try/catch block

I have this block of code:
} catch (HibernateException e) {
loginAnswer = new LoginCustomerAreaAnswer(999);
//This function use the error code save inside loginAnswer
this.logOp.error(logsUtilities.logException(e, "HibernateException"));
} catch (Exception e) {
loginAnswer = new LoginCustomerAreaAnswer(997);
//This function use the error code save inside loginAnswer
this.logOp.error(logsUtilities.logException(e, "Exception"));
} finally {
return loginAnswer;
}
As you can see, I catch first the HibernateException type exception and then the generic Exception.
But when I look into the log file, when I have a org.hibernate.exception.GenericJDBCException exception it is catched like a generic Exception!
Why?, GenericJDBCException it is not "a son" of HibernateException? Would not have to be catched by the HibernateException??
This is an example of my log file
2013-05-21 11:01:02 [Level: ERROR]*** Exception: Error code: 997 - Could not open Hibernate Session for transaction; nested exception is org.hibernate.exception.GenericJDBCException: Cannot open connection
I really lost with this, can somebody help me?
Most probably you caught the Spring Exception:
org.springframework.transaction.CannotCreateTransactionException: Could not open Hibernate Session for transaction; nested exception is org.hibernate.exception.GenericJDBCException: Cannot open connection
I believe the problem is your constructor:
new LoginCustomerAreaAnswer(...)
With passed value 997.
Running this code:
public class Test
{
public static void main( String[] args )
{
try
{
throw new GenericJDBCException( "I'm dead", new SQLException() );
} catch ( HibernateException hex )
{
System.err.println( "HibernateException" );
hex.printStackTrace();
} catch ( Exception ex )
{
System.err.println( "Exception" );
ex.printStackTrace();
}
}
}
Gives me, as expected, HibernateException:
HibernateException
org.hibernate.exception.GenericJDBCException: I'm dead
at com.execon.utils.Test.main(Test.java:19)
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 com.intellij.rt.execution.application.AppMain.main(AppMain.java:120)
Caused by: java.sql.SQLException
... 6 more

org.apache.axis2.AxisFault: org.apache.axis2.databinding.ADBException: Unexpected subelement underTimelyRenewal

I am getting the below exception before hitting a axis 2 webservice.
org.apache.axis2.AxisFault: org.apache.axis2.databinding.ADBException: Unexpected subelement underTimelyRenewal
I can't reproduce the same issue locally on tomcat or in DEV environment which runs in Weblogic. It justs happens only in 1 environment which runs on Weblogic 11g. This makes to think that I am missing some config in that environment, I am not sure what it is. Any help on this is highly appreciated.
Here is code that calls web service.
public com.ibs.accouting.employeeVerificationResponse getEmployeeVerificationRequest(
com.ibs.accounting.EmployeeVerificationRequest employeeVerificationRequest108)
throws java.rmi.RemoteException
{
org.apache.axis2.context.MessageContext _messageContext = null;
try{
org.apache.axis2.client.OperationClient _operationClient = _serviceClient.createClient(_operations[5].getName());
_operationClient.getOptions().setAction("http://ibs.com/accounting/WBLEmployeeVerificationRequest");
_operationClient.getOptions().setExceptionToBeThrownOnSOAPFault(true);
addPropertyToOperationClient(_operationClient,org.apache.axis2.description.WSDL2Constants.ATTR_WHTTP_QUERY_PARAMETER_SEPARATOR,"&");
// create a message context
_messageContext = new org.apache.axis2.context.MessageContext();
// create SOAP envelope with that payload
org.apache.axiom.soap.SOAPEnvelope env = null;
env = toEnvelope(getFactory(_operationClient.getOptions().getSoapVersionURI()),
employeeVerificationRequest108,
optimizeContent(new javax.xml.namespace.QName("http://ibs.com/accounting",
"getEmployeeVerificationRequest")));
//adding SOAP soap_headers
_serviceClient.addHeadersToEnvelope(env);
// set the message context with that soap envelope
_messageContext.setEnvelope(env);
// add the message contxt to the operation client
_operationClient.addMessageContext(_messageContext);
//execute the operation client
_operationClient.execute(true);
org.apache.axis2.context.MessageContext _returnMessageContext = _operationClient.getMessageContext(
org.apache.axis2.wsdl.WSDLConstants.MESSAGE_LABEL_IN_VALUE);
org.apache.axiom.soap.SOAPEnvelope _returnEnv = _returnMessageContext.getEnvelope();
java.lang.Object object = fromOM(
_returnEnv.getBody().getFirstElement() ,
com.ibs.accounting.EmployeeVerificationResponse.class,
getEnvelopeNamespaces(_returnEnv));
return (com.ibs.accounting.EmployeeVerificationResponse)object;
}catch(org.apache.axis2.AxisFault f){
org.apache.axiom.om.OMElement faultElt = f.getDetail();
if (faultElt!=null){
if (faultExceptionNameMap.containsKey(faultElt.getQName())){
//make the fault by reflection
try{
java.lang.String exceptionClassName = (java.lang.String)faultExceptionClassNameMap.get(faultElt.getQName());
java.lang.Class exceptionClass = java.lang.Class.forName(exceptionClassName);
java.lang.Exception ex=
(java.lang.Exception) exceptionClass.newInstance();
//message class
java.lang.String messageClassName = (java.lang.String)faultMessageMap.get(faultElt.getQName());
java.lang.Class messageClass = java.lang.Class.forName(messageClassName);
java.lang.Object messageObject = fromOM(faultElt,messageClass,null);
java.lang.reflect.Method m = exceptionClass.getMethod("setFaultMessage",
new java.lang.Class[]{messageClass});
m.invoke(ex,new java.lang.Object[]{messageObject});
throw new java.rmi.RemoteException(ex.getMessage(), ex);
}catch(java.lang.ClassCastException e){
// we cannot intantiate the class - throw the original Axis fault
throw f;
} catch (java.lang.ClassNotFoundException e) {
// we cannot intantiate the class - throw the original Axis fault
throw f;
}catch (java.lang.NoSuchMethodException e) {
// we cannot intantiate the class - throw the original Axis fault
throw f;
} catch (java.lang.reflect.InvocationTargetException e) {
// we cannot intantiate the class - throw the original Axis fault
throw f;
} catch (java.lang.IllegalAccessException e) {
// we cannot intantiate the class - throw the original Axis fault
throw f;
} catch (java.lang.InstantiationException e) {
// we cannot intantiate the class - throw the original Axis fault
throw f;
}
}else{
throw f;
}
}else{
throw f;
}
} finally {
_messageContext.getTransportOut().getSender().cleanup(_messageContext);
}
}
This error can be kind of misleading. AFter I modified the WSDL and added a new mandatory element, I created my client. Than this error appeared. The solution was, that I forgot to fill this element in one method of the my web service. If this error appears, also check if your mandatory elements are filled within the server.
That it works under one environment and not in an other can also mean, that a mandatory item is filled on one server (development server) and not under the other (productive server).

Custom exceptions handling - java Web Services

Its my first time posting here so please be patient and correct me whenever necessary...
I am building simple web service-based application using NetBeans with GlassFish. NetBeans does help a lot in terms of generating code for new web services and their operations, one thing drives me mad though - web service exception handling. Operation like:
#WebMethod(operationName = "checkUserExist")
public String checkUserExist(#WebParam(name = "login") String login, #WebParam(name = "password") String password) throws LoginException {
String auth_code = "";
bk_end.Validate val = new bk_end.Validate();
boolean isValidated = val.check(login, password);
if(isValidated)
{
auth_code = val.return_AuthCode();
bank_services.CustomerSerice.setAuth_Code(auth_code);
return auth_code;
}
throw new LoginException("Something is wrong!");
}
and the exception class:
public class LoginException extends Exception
{
String message;
public LoginException(String message)
{
super();
this.message = message;
}
public String getErrorMessage()
{
return this.message;
}
}
throws a massive
Exceptions details : java.lang.reflect.InvocationTargetException
plus tons of other exceptions..
I realise it is a very much so nooby question, but after many hours of trying various things I just do not know what tot do.
I've read about the #WebFault thing but got no idea how to specify this correctly (attach my exception to a particular method..)
Please help, all ideas are more than welcome!
Exceptions that I'm getting:
Service invocation threw an exception with message : null; Refer to the server log for more details
Exceptions details : java.lang.reflect.InvocationTargetException
javax.servlet.ServletException: java.lang.reflect.InvocationTargetException
at org.glassfish.webservices.monitoring.WebServiceTesterServlet.doPost(WebServiceTesterServlet.java:330)
at org.glassfish.webservices.monitoring.WebServiceTesterServlet.invoke(WebServiceTesterServlet.java:106)
at org.glassfish.webservices.EjbWebServiceServlet.service(EjbWebServiceServlet.java:114)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:847)
at com.sun.grizzly.http.servlet.ServletAdapter$FilterChainImpl.doFilter(ServletAdapter.java:1002)
at com.sun.grizzly.http.servlet.ServletAdapter$FilterChainImpl.invokeFilterChain(ServletAdapter.java:942)
at com.sun.grizzly.http.servlet.ServletAdapter.doService(ServletAdapter.java:404)
...
Caused by: java.lang.reflect.InvocationTargetException 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.glassfish.webservices.monitoring.WebServiceTesterServlet.doPost(WebServiceTesterServlet.java:301)
... 24 more
Caused by: bank_services.LoginException_Exception: excepts.LoginException
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:57)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.lang.reflect.Constructor.newInstance(Constructor.java:525)
at com.sun.xml.ws.fault.SOAPFaultBuilder.createException(SOAPFaultBuilder.java:145)
at com.sun.xml.ws.client.sei.SyncMethodHandler.invoke(SyncMethodHandler.java:123)
at com.sun.xml.ws.client.sei.SyncMethodHandler.invoke(SyncMethodHandler.java:93)
at com.sun.xml.ws.client.sei.SEIStub.invoke(SEIStub.java:144)
at $Proxy383.checkUserExist(Unknown Source) ... 29 more
Oh ok. You want to see the "Something is wrong" message.
So I think the ultimate problem here is that you are not using the standard detailMessage field in the Throwable. If you just pass the message to the base class (super(message);) then I bet you would see the exception in the trace. Did you try another Exception type such as just Exception?
You could also define the LoginException.toString() to be something like:
#Override
public String toString() {
String s = getClass().getName();
return (message != null) ? (s + ": " + message) : s;
}
Alternatively, you will need to do something like this:
try {
...
} catch (Exception e) {
if (e instanceof ServletException) {
e = e.getCause();
}
if (e instanceof InvocationTargetException) {
e = e.getCause();
}
if (e instanceof LoginException) {
System.err.println("Login exception returned message: "
+ ((LoginException)e). getErrorMessage());
} else {
System.err.println("Exception returned message: " + e);
}
}
But I think my recommendation is to use super(message); in your constructor.

Categories