in my application the follwoing code is used. Can some one give a detailed explanation for the code that is highlighted?
I understood that in first highlighted block java reflection is used in invoking the method handle_validation..but need the detailed explanation.
Then in second highlighted block RemoteException is thrown..
My exact question is why they used reflection to call EngineHandlerIF and then why they are using RMI in this EngineHandlerIF to invoke the definition of method in EngineHandler?
private static EngineHandlerIF init() {
ApplicationContext ctx = new ClassPathXmlApplicationContext(new String[] { "validation.xml" });
String[] beans = ctx.getBeanDefinitionNames();
for (String string : beans) {
logger.info(string);
}
EngineHandlerIF engine = (EngineHandlerIF) ctx.getBean("engine");
return engine;
}
private Object callEngineMethod(MiddlewareMessage mmsg) {
Object resultObj;
try {
**String methodName = "handle_validation";
Method method = EngineHandlerIF.class.getDeclaredMethod(methodName, MiddlewareMessage.class);
method.setAccessible(true);
resultObj = method.invoke(engine, new Object[] { mmsg });**
} catch (Exception e) {
logger.error("sendMessage Exception: ", e);
return new Boolean(false);
}
return resultObj;
}
EngineHandlerIF:
----------------
**public abstract String handle_validation(MiddlewareMessage mmsg) throws RemoteException;**
EngineHandler:
--------------
public String handle_validation(MiddlewareMessage mmsg) throws Exception {
//some code
}
I understood that in first highlighted block java reflection is used
in invoking the method handle_validation..but need the detailed
explanation.
That's pretty much it. The only other bit is the
method.setAccessible(true);
which makes the method accessible to the caller (e.g. from private to public), thus allowing you to call it. However the above method does appear to be public already. Perhaps this is some legacy following a refactor ?
Note that this isn't RMI (remote method invocation), but rather reflection. The only RMI I can see here is the handle_validation() method possibly throwing a RemoteException.
Maybe someone had just discovered the hammer of a reflection so everything, including method that were already public, started looking like a nut.
It is garbage: throw it away. Just call the method directly.
Related
I am trying to create a client library that reads JSON from an external file online. I already know about the function interfaces and optionals, but I was wondering if there is a way to allow users to supply callback functions such that the parent function exits completely. For JavaScript, such a function is as follows:
file.read('hello', function(err, data) {
// something here
});
Basically, I wish to do the same in Java. How can I do this such that the error callback supersedes the read function? What I mean is that in the event that the error callback is called, then read should not return a value at all. If the callback is not called then the read should return the value.
You could have the user pass in a function and then just not do anything with it if there is no error.
This example assumes that you have a custom class called Error that the caller is aware of and would like to interact with in case of an error.
public void read (String str, Function<Error,Void> errorFunc)
{
//interact w/ libraries, boolean error = true or false
//if there is an error, variable err of type Error contains information
if (error)
{
errorFunc.apply(err);
}
}
In Java upto 1.7 the only way to achieve javascript like callbacks is thru interface. The api user who calls your method read has the liberty of implementing what he feels needs to be done to handle the error by writing an implementation class for the interface at the invocation point.
public String read(String options,IErrorCallBack errorHandler) throws Exception {
try {
// When everything works fine return what you think should be returned.
return "Success";
}
catch(Exception e) {
// On Error call the function on the error handler.
errorHandler.doSomething();
throw e;
}
}
public interface IErrorCallBack {
public void doSomething();
}
// The invocation point.
read("myString", new IErrorCallBack() {
public void doSomething() {
// Your implementation.
}
});
Something I've always been curious of
public class FileDataValidator {
private String[] lineData;
public FileDataValidator(String[] lineData){
this.lineData = lineData;
removeLeadingAndTrailingQuotes();
try
{
validateName();
validateAge();
validateTown();
}
catch(InvalidFormatException e)
{
e.printStackTrace();
}
}
//validation methods below all throwing InvalidFormatException
Is is not advisable to include the try/catch block within my Constructor?
I know I could have the Constructor throw the Exception back to the caller. What do you guys prefer in calling methods like I have done in Constructor? In the calling class would you prefer creating an instance of FileDataValidator and calling the methods there on that instance? Just interested to hear some feedback!
In the code you show, the validation problems don't communicate back to the code that is creating this object instance. That's probably not a GOOD THING.
Variation 1:
If you catch the exception inside the method/constructor, be sure to pass something back to the caller. You could put a field isValid that gets set to true if all works. That would look like this:
private boolean isValid = false;
public FileDataValidator(String[] lineData){
this.lineData = lineData;
removeLeadingAndTrailingQuotes();
try
{
validateName();
validateAge();
validateTown();
isValid = true;
}
catch(InvalidFormatException e)
{
isValid = false;
}
}
public boolean isValid() {
return isValid;
}
Variation 2:
Or you could let the exception or some other exception propagate to the caller. I have shown it as a non-checked exception but do whatever works according to your exception handling religion:
public FileDataValidator(String[] lineData){
this.lineData = lineData;
removeLeadingAndTrailingQuotes();
try
{
validateName();
validateAge();
validateTown();
}
catch(InvalidFormatException e)
{
throw new com.myco.myapp.errors.InvalidDataException(e.getMessage());
}
}
Variation 3:
The third method I want to mention has code like this. In the calling code you have to call the constructor and then call the build() function which will either work or not.
String[] lineData = readLineData();
FileDataValidator onePerson = new FileDataValidator();
try {
onePerson.build(lineData);
} catch (InvalidDataException e) {
// What to do it its bad?
}
Here is the class code:
public FileDataValidator() {
// maybe you need some code in here, maybe not
}
public void build(String[] lineData){
this.lineData = lineData;
removeLeadingAndTrailingQuotes();
try
{
validateName();
validateAge();
validateTown();
}
catch(InvalidFormatException e)
{
throw new com.myco.myapp.errors.InvalidDataException(e.getMessage());
}
}
Of course, the build() function could use a isValid() method that you call to see if its right but an exception seems the right way to me for the build function.
Variation 4:
The fourth method I want to mention is what I like best. It has code like this. In the calling code you have to call the constructor and then call the build() function which will either work or not.
This sort of follows the way JaxB and JaxRS work, which is a similar situation to what you have.
An external source of data - you have a file, they have an incoming message in XML or JSON format.
Code to build the objects - you have your code, they have their libraries of code working according the specifications in the various JSRs.
Validation is not tied to the building of the objects.
The calling code:
String[] lineData = readLineData();
Person onePerson = new Person();
FileDataUtilities util = new FileDataUtilities();
try {
util.build(onePerson, lineData);
util.validate(onePerson);
} catch (InvalidDataException e) {
// What to do it its bad?
}
Here is the class code where the data lives:
public class Person {
private Name name;
private Age age;
private Town town;
... lots more stuff here ...
}
And the utility code to build and validate:
public FileDataValidator() {
// maybe you need some code in here, maybe not
}
public void build(Person person, String[] lineData){
this.lineData = lineData;
removeLeadingAndTrailingQuotes();
setNameFromData(person);
setAgeFromData(person);
setTownFromData(person);
}
public boolean validate(Person person) {
try
{
validateName(person);
validateAge(person);
validateTown(person);
return true;
}
catch(InvalidFormatException e)
{
throw new com.myco.myapp.errors.InvalidDataException(e.getMessage());
}
}
You should consider the static factory pattern. Make your all-arguments constructor private. Provide a static FileDataValidator(args...) method. This accepts and validates all the arguments. If everything is fine, it can call the private constructor and return the newly created object. If anything fails, throw an Exception to inform the caller that it provided bad values.
I must also mention that this:
catch (Exception e) {
printSomeThing(e);
}
Is the deadliest antipattern you could do with Exceptions. Yes, you can read some error values on the command line, and then? The caller (who provided the bad values) doesn't get informed of the bad values, the program execution will continue.
My preference is for exceptions to be dealt with by the bit of code that knows how to deal with them. In this case I would assume that the bit of code creating a FileDataValidator knows what should happen if the file data is not valid, and the exceptions should be dealt with there (I am advocating propagating to the caller).
Whilst discussing best practice - the class name FileDataValidator smells to me. If the object you're creating stores file data then I would call it FileData - perhaps with a validate method? If you only want to validate your file data then a static method would suffice.
I'm creating a sandbox for JEXL scripts to execute in so that a malicious user can't access data outside the variables we give them access to and also can't perform a DOS attack on the server. I'd like to document this for anybody else also doing this and also get other people's input into the approach.
The following is a list of the things I'm aware of that needs to be addressed:
Only allow instantiating classes using 'new' that are on a whitelist.
Do not allow accessing the getClass method on any class because then forName can be called and any class can be accessed.
Restrict access to resources such as files.
Allow an expression only a certain amount of time to execute so that we can limit the amount of resources it consumes.
This does not apply to JEXL but may apply to the scripting language you are using:
Do not allow an object to have a custom finalize method because the finalize method is called from the finalizer thread and will execute with the original AccessControlContext instead of the one being used to create the object and execute the code in it.
UPDATE: This was all done using JEXL 2.0.1. You may have to adapt this to make it work with newer versions.
Here is my approach for dealing with each of these cases. I've created unit tests to test each of these cases and I have verified that they work.
JEXL makes this pretty easy. Just create a custom ClassLoader. Override the two loadClass() methods. On JexlEngine call setClassLoader().
Again, JEXL makes this pretty easy. You must block both '.class' and '.getClass()'. Create your own Uberspect class which extends UberspectImpl. Override getPropertyGet, if identifier equals "class" return null. Override getMethod, if method equals "getClass" return null. When constructing JexlEngine pass a reference to your Uberspect implementation.
class MyUberspectImpl extends UberspectImpl {
public MyUberspectImpl(Log jexlLog) {
super(jexlLog);
}
#Override
public JexlPropertyGet getPropertyGet(Object obj, Object identifier, JexlInfo info) {
// for security we do not allow access to .class property
if ("class".equals(identifier)) throw new RuntimeException("Access to getClass() method is not allowed");
JexlPropertyGet propertyGet = super.getPropertyGet(obj, identifier, info);
return propertyGet;
}
#Override
public JexlMethod getMethod(Object obj, String method, Object[] args, JexlInfo info) {
// for security we do not allow access to .getClass() method
if ("getClass".equals(method)) throw new RuntimeException("Access to getClass() method is not allowed");
return super.getMethod(obj, method, args, info);
}
}
You do this using Java's AccessController mechanism. I'll give a quick run-down of doing this. Start java with -Djava.security.policy=policyfile. Make a file named policyfile containing this line:
grant { permission java.security.AllPermission; };
Set the default SecurityManager with this call: System.setSecurityManager(new SecurityManager()); Now you can control permissions and your app by default has all permissions. It would be better if you limit the permissions of your app to only what it requires of course. Next, create an AccessControlContext that limits the permissions to the bare minimum and call AccessController.doPrivileged() and pass the AccessControlContext, then execute the JEXL script inside doPrivileged(). Here is a small program that demonstrates this. The JEXL script calls System.exit(1) and if it isn't wrapped in doPrivileged() it would successfully terminate the JVM.
System.out.println("java.security.policy=" + System.getProperty("java.security.policy"));
System.setSecurityManager(new SecurityManager());
try {
Permissions perms = new Permissions();
perms.add(new RuntimePermission("accessDeclaredMembers"));
ProtectionDomain domain = new ProtectionDomain(new CodeSource( null, (Certificate[]) null ), perms );
AccessControlContext restrictedAccessControlContext = new AccessControlContext(new ProtectionDomain[] { domain } );
JexlEngine jexlEngine = new JexlEngine();
final Script finalExpression = jexlEngine.createScript(
"i = 0; intClazz = i.class; "
+ "clazz = intClazz.forName(\"java.lang.System\"); "
+ "m = clazz.methods; m[0].invoke(null, 1); c");
AccessController.doPrivileged(new PrivilegedExceptionAction<Object>() {
#Override
public Object run() throws Exception {
return finalExpression.execute(new MapContext());
}
}, restrictedAccessControlContext);
}
catch (Throwable ex) {
ex.printStackTrace();
}
The trick with this is interrupting the script before it finishes. One way I found to do this is to create a custom JexlArithmetic class. Then override each method in that class and before calling the real method in the super class check if the script should stop executing. I'm using an ExecutorService to create threads. When Future.get() is called pass the amount of time to wait. If a TimeoutException is thrown call Future.cancel() which interrupts the Thread running the script. Inside each overridden method in the new JexlArithmetic class check Thread.interrupted() and if true throw java.util.concurrent.CancellationException.
Is there a better location to put code which will get executed regularly as a script is being executed so that it can be interrupted?
Here is an excerpt of the MyJexlArithmetic class. You have to add all the other methods:
public class MyJexlArithmetic extends JexlArithmetic {
public MyJexlArithmetic(boolean lenient) {
super(lenient);
}
private void checkInterrupted() {
if (Thread.interrupted()) throw new CancellationException();
}
#Override
public boolean equals(Object left, Object right) {
checkInterrupted();
return super.equals(left, right); //To change body of generated methods, choose Tools | Templates.
}
#Override
public Object add(Object left, Object right) {
checkInterrupted();
return super.add(left, right);
}
}
Here is how I am instantiating JexlEngine:
Log jexlLog = LogFactory.getLog("JEXL");
Map <String, Object> functions = new HashMap();
jexlEngine = new JexlEngine(new MyUberspectImpl(jexlLog), new MyJexlArithmetic(false), functions, jexlLog);
Our application uses several back-end services and we maintain wrappers which contain the methods to make the actual service calls. If any exception occurs in any of those methods while invoking a service, we throw a custom exception encapsulating the original exception as shown below.
interface IServiceA {
public void submit(String user, String attributes);
}
public class ServiceAWrapper implements IserviceA {
private ActualService getActualService() {
.....
}
public void submit(String user, String attributes) {
try {
Request request = new Request();
request.setUser(user);
request.setAttributes(attributes);
getActualService().call(request);
} catch(ServiceException1 e) {
throw new MyException(e, reason1);
} catch(ServiceException2 e) {
throw new MyException(e, reason2);
}
}
}
I would like to know if there's any framework that would allow me to
capture (and probably log) all the
parameters passed to my wrapper
methods at run-time; if the methods
are called.
capture the actual exception
object(MyException instance in above
example), if any thrown; so that I
could append the passed parameters
to the object at run-time.
I am currently exploring AspectJ to see if it can address my requirements, but I am not sure if it can be used to capture the parameters passed to methods at runtime and also to capture exception objects, if any occur.
Thanks.
With AspectJ, you can use around advice to execute advice instead of the code at the join point. You can then execute the actual join-point from within the advice by calling proceed. This would allow you to capture the input parameters, log them, and proceed to call the actual method.
Within the same advice you could capture any logs throw from the method, and inspect or log them before passing it back up to higher levels.
Matt B's answer is right. Specifically, you can do something like this:
aspect MonitorServiceCalls {
private final Logger LOG = LoggerFactory.getLog("ServiceCallLog");
Object around() throws MyException: call(public * *(..) throws MyException)
&& target(IServiceA+) {
MethodSignature msig = (MethodSignature)thisJoinPoint;
String fullMethName = msig.getMethod().toString();
try {
Object result = proceed();
LOG.info("Successful call to {} with arguments {}",
fullMethName,
thisJoinPoint.getArgs());
return result;
} catch(MyException e) {
LOG.warn("MyException thrown from {}: {}", msig.getMethod(), e);
throw e;
}
}
}
AspectJ is the right option. You will be able to get hold of the parameters by way of a JoinPoint object that will be passed to your advise methods. You can also get hold of the exception either by implementing an after throwing advise or an around advise.
I have an ArrayList and wish to be able to call an index and use the returned string for a method call.
e.g.
stringList.get(2)();
Is there any way I could go about this?
So you want the returned String to be used as the name of the method to call?
You can do that using reflection, but I'd strongly discourage this.
Instead you will want to look into implementing a strategy pattern for example.
Yes, there is a way to use the returned string from the list for a method call.
As others users already pointed out, you need to use Reflection API. Can be complicated deal with that, depends on the particular scenario you are facing.
Just to show you the basic approach in a concrete but simplified example, I create this code. Copy it and play changing the index, and creating new methods with parameters after learn the basics of the API.
import java.lang.reflect.*;
import java.util.*;
public class DemoReflection {
public static void main(String[] args) {
List<String> myStringList = new ArrayList<String>();
myStringList.add(0, "foo");
myStringList.add(1, "printStr");
myStringList.add(2, "otherMethod");
myStringList.add(3, "stackoverflow");
int index = 3;
String methodName = myStringList.get(index);
try {
Class<?> c = Class.forName("DemoReflection");
Object obj = c.newInstance();
Method method = c.getDeclaredMethod(methodName, null);
method.invoke(obj, null);
} catch (SecurityException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
}
}
public void stackoverflow() {
System.out.println("Stackoverflow rules!");
}
public void printStr() {
System.out.println("Method printStr invoked...");
}
}
First of call you can't call a method in java without an object to call it on. Is that in the list also.
It would be better to have a list of Runnable...
List<Runnable> runnables = ...
runnables.get(2).call();
If you have the object you need to call, and you want to use reflection (can be slow) then commons-beans can help make it simple. See http://commons.apache.org/beanutils
import org.apache.commons.beanutils.MethodUtils;
Object target = ...
List<String> methodNames = ...
MethodUtils.invokeMethod(target, methodNames.get(2), /*args*/ null);
To give better I'd advice I'd need to know more about the problem you are trying to solve.
One would have to use reflection. See http://tutorials.jenkov.com/java-reflection/methods.html.
Does the ArrayList have to contain Strings?
Otherwise you could populate it with java.lang.reflect.Method instances, and call Method.invoke() on the returned instance.
If I understand your needs, here is an example based on an interface; the list then contains implementations of the interface rather than method names:
import java.util.ArrayList;
import java.util.List;
public class Test {
public static void main(String[] args) throws Exception {
List<Action> actions = new ArrayList<Action>();
actions.add(new Action(){
public void execute() {
System.out.println("Action 0");
}});
actions.add(new Action(){
public void execute() {
System.out.println("Action 1");
}});
actions.get(0).execute();
actions.get(1).execute();
}
static interface Action{
void execute();
}
}
Or maybe polymorphism and a factory method would be a better idea. You'd have to circumscribe the methods you'll be able to call, but that wouldn't be a bad idea.
If you want the full Monty, and you're using Java 6, maybe you can create a JavaScript function object and invoke it with Rhino.
Or if you insist on making the idea work regardless of any obstacles, you could call out to a dynamic language like JRuby or Clojure, both of which are willing to eval() a String.
Or Jython or Groovy or...
In Java - no way. That's not a Java language feature. Your're hoping for something like
// NOT VALID JAVA
String myColoring = paintBlackOrWhite() ? "black" : "white";
myColoring(myBathroomWall);
// NOT VALID JAVA
Like others suggested, a pure technical solution would be using reflections: take the result string, find the corresponding method and invoke it. A technical solution could even be a map like
Map<String, java.lang.reflect.Method> myMethods;
and do something like
get("black").invoke(myObject, myParams);
but all of that is nice to know and you shouldn't use it unless forced or you have a concrete problem where even SO doesn't have a solution ;)