recently I found a function like this in a generic JSR245 portlet class:
public class MyGenericPortlet extends GenericPortlet {
#Override
public void processAction(ActionRequest rq, ActionResponse rs) throws PortletException{
String actParam = rq.getParameter("myAction");
if( (actParam != null) && (!("").equals(actParam))) {
try{
Method m = this.getClass().getMethod(actParam, new Class[]{ActionRequest.class, ActionResponse.class});
m.invoke(this, new Object[]{rq, rs});
}
catch(Exception e){
setRequestAttribute(rq.getPortletSession(),"error", "Error in method:"+action);
e.printStackTrace();
}
}
else setRequestAttribute(rq.getPortletSession(),"error", "Error in method:"+action);
}
}
How safe is such code? As far as I can see the following problems might occur:
A parameter transmitted from the client is used unchecked to call a function. This allows anyone who can transmit data to the corresponding portlet to call any matching function. on the other hand the function to be called must have a specific interface. Usually such functions are very rare.
A programmer might accidentaly add a function with a corresponding interface. As only public functions seem to be found this is no problem as long as the function is private or protected.
The error message can reveal information about the software to the client. This shouldn't be a problem as the software itself is Open Source.
Obviously there is some room for programming errors that can be exploited. Are there other unwanted side effects that might occur? How should I (or the developers) judge the risk that comes from this function?
If you think it is safe, I'd like to know why.
The fact that only public methods with a specific signature can be invoked remotely is good. However, it could be made more secure by, for example, requiring a special annotation on action methods. This would indicate the developer specifically intended the method to be an invokable action.
A realistic scenario where the current implementation could be dangerous is when the developer adds an action that validates that the information in the request is safe, then passes the request and response to another method for actual processing. If an attacker could learn the name of the delegate method, he could invoke it directly, bypassing the parameter safety validation.
Related
I have a service that saves a tree-like structure to a database. Before persisting the tree, the tree gets validated, and during validation, a number of things can go wrong. The tree can have duplicate nodes, or a node can be missing an important field (such as its abbreviation, full name, or level).
In order to communicate to the service what went wrong, I'm using exceptions. When the validateTree() method encounters a problem, it throws the appropriate exception. The HttpService class then uses this exception to form the appropriate response (e.g. in response to an AJAX call).
public class HttpService {
private Service service;
private Logger logger;
// ...
public HttpServiceResponse saveTree(Node root) {
try {
service.saveTree(root);
} catch (DuplicateNodeException e) {
return HttpServiceResponse.failure(DUPLICATE_NODE);
} catch (MissingAbbreviationException e) {
return HttpServiceResponse.failure(MISSING_ABBREV);
} catch (MissingNameException e) {
return HttpServiceResponse.failure(MISSING_NAME);
} catch (MissingLevelException e) {
return HttpServiceResponse.failure(MISSING_LEVEL);
} catch (Exception e) {
logger.log(e.getMessage(), e. Logger.ERROR);
return HttpServiceResponse.failure(INTERNAL_SERVER_ERROR);
}
}
}
public class Service {
private TreeDao dao;
public void saveTree(Node root)
throws DuplicateNodeException, MissingAbbreviationException, MissingNameException, MissingLevelException {
validateTree(root);
dao.saveTree(root);
}
private void validateTree(Node root)
throws DuplicateNodeException, MissingAbbreviationException, MissingNameException, MissingLevelException {
// validate and throw checked exceptions if needed
}
}
I want to know, is this a good use of exceptions? Essentially, I'm using them to convey error messages. An alternative would be for my saveTree() method to return an integer, and that integer would convey the error. But in order to do this, I would have to document what each return value means. That seems to be more in the style of C/C++ than Java. Is my current use of exceptions a good practice in Java? If not, what's the best alternative?
No, exceptions aren't a good fit for the validation you need to do here. You will likely want to display multiple validation error messages, so that the user can see all the validation errors at once, and throwing a separate exception for each invalid input won't allow that.
Instead create a list and put errors in it. Then you can show the user the list of all the validation errors.
Waiting until your request has gotten all the way to the DAO seems like the wrong time to do this validation. A server-side front controller should be doing validation on these items before they get passed along any farther, as protection against attacks such as injection or cross-site scripting.
TL;DR The Java-side parts you showed us are nearly perfect. But you could add an independent validation check and use that from the client side before trying to save.
There are many software layers involved, so let's have a look at each of them - there's no "one size fits all" answer here.
For the Service object, it's the perfect solution to have it throw exceptions from the saveTree() method if it wasn't able to save the tree (for whatever reason, not limited to validation). That's what exceptions are meant for: to communicate that some method couldn't do its job. And the Service object shouldn't rely on some external validation, but make sure itself that only valid data are saved.
The HttpService.saveTree() should also communicate to its caller if it couldn't save the tree (typically indicated by an exception from the Service). But as it's an HTTP service, it can't throw exceptions, but has to return a result code plus a text message, just the way you do it. This can never contain the full information from the Java exception, so it's a good decision that you log any unclear errors here (but you should make sure that the stack trace gets logged too!), before you pass an error result to the HTTP client.
The web client UI software should of course present detailed error lists to the user and not just a translated single exception. So, I'd create an HttpService.validateTree(...) method that returns a list of validation errors and call that from the client before trying to save. This gives you the additional possibility to check for validity independent of saving.
Why do it this way?
You never have control what happens in the client, inside some browser, you don't even know whether the request is coming from your app or from something like curl. So you can't rely on any validation that your JavaScript (?) application might implement. All of your service methods should reject invalid data, by doing the validation themselves.
Implementing the validation checks in a JavaScript client application still needs the same validation inside the Java service (see above), so you'd have to maintain two pieces of code in different languages doing exactly the same business logic - don't repeat yourself! Only if the additional roundtrip isn't tolerable, then I'd regard this an acceptable solution.
Visible and highly noticeable, both in terms of the message itself and how it indicates which dialogue element users must repair.
From Guru Nielsen,
https://www.nngroup.com/articles/error-message-guidelines/
I'd like to ask something confuses me a lot. Here is the scenario, lets say I have a method preparePayload that takes some argument like messageType, destAddr etc. The duty of method is construct a fully payload (with headers, prefixes etc). Here is the problem, I want to return statusCode (which is enum, like STATUS_OK,STATUS_INVALID_DEST, STATUS_INVALID_MSG_TYPE etc.), and than respect to return status I'd like to implement my logic. But if there is no error (STATUS_OK), I need the prepared payload to move on. So my method should return eighter payload or status code.
In C language, simply sending payload buffer address as an argument to preparePayload method solves the problem perfectly. When the method returns, simply reading payload from the buffer address and moving on the application works. How can I implement this kind of logic in Java?
In addition, preparePayload method is just an example I gave, so the methods I implemented may return String, int[], some class object that I wrote etc. I mean, the type of object that method should return in success case may vary.
Any suggestion will very welcome.
Besides changing to exceptions, there is one more hackish way to allow for "input/output" parameters, like:
public ResultEnum preparePayLoad(List<PayLoad> toPrepare, ... other args) {
...
PayLoad newThing = ...
...
toPrepare.add(newThing);
return someEnum;
}
So, you could use such an approach to "emulate" the "C style"; but the more Java/OO would be
public PayLoad preparePayLoad(args) {
...
PayLoad newThing = ...
...
return newThing;
}
and to throw (checked or unchecked) exceptions for error situations.
The correct idiom in Java is to throw a checked exception (some will say unchecked is better, there is a slight controversy here).
The three important mechanisms you get is:
automatic propagation of error codes up the stack. If you do not handle some type of error in your code (don't check for it), it will get propagated up as an exception - you don't need layered checks (and avoid an error of returning an invalid result, quite common in C),
exceptions work as an "alternate return type", ensuring type safety for both correct results and the error messages (which are full objects - and can contain any number of useful information besides the code)
checked exceptions allow the compiler to check if all the important error statuses are handled in some way.
You can create a class, a wrapper, for example:
public class Result {
public enum Status {
STATUS_OK, STATUS_INVALID_DEST, STATUS_INVALID_MSG_TYPE
}
Status status;
String payload;
}
that will be returned by your method preparePayload. Then, when you call your method, you can do it like this:
Result result = preparePayload(args);
//better will be a switch with case for each possible status
if (result.state == Result.State.STATUS_OK)
//do what you want with payload
System.out.println(result.payload);
else
return;
There are countless questions here, how to solve the "could not initialize proxy" problem via eager fetching, keeping the transaction open, opening another one, OpenEntityManagerInViewFilter, and whatever.
But is it possible to simply tell Hibernate to ignore the problem and pretend the collection is empty? In my case, not fetching it before simply means that I don't care.
This is actually an XY problem with the following Y:
I'm having classes like
class Detail {
#ManyToOne(optional=false) Master master;
...
}
class Master {
#OneToMany(mappedBy="master") List<Detail> details;
...
}
and want to serve two kinds of requests: One returning a single master with all its details and another one returning a list of masters without details. The result gets converted to JSON by Gson.
I've tried session.clear and session.evict(master), but they don't touch the proxy used in place of details. What worked was
master.setDetails(nullOrSomeCollection)
which feels rather hacky. I'd prefer the "ignorance" as it'd be applicable generally without knowing what parts of what are proxied.
Writing a Gson TypeAdapter ignoring instances of AbstractPersistentCollection with initialized=false could be a way, but this would depend on org.hibernate.collection.internal, which is surely no good thing. Catching the exception in the TypeAdapter doesn't sound much better.
Update after some answers
My goal is not to "get the data loaded instead of the exception", but "how to get null instead of the exception"
I
Dragan raises a valid point that forgetting to fetch and returning a wrong data would be much worse than an exception. But there's an easy way around it:
do this for collections only
never use null for them
return null rather than an empty collection as an indication of unfetched data
This way, the result can never be wrongly interpreted. Should I ever forget to fetch something, the response will contain null which is invalid.
You could utilize Hibernate.isInitialized, which is part of the Hibernate public API.
So, in the TypeAdapter you can add something like this:
if ((value instanceof Collection) && !Hibernate.isInitialized(value)) {
result = new ArrayList();
}
However, in my modest opinion your approach in general is not the way to go.
"In my case, not fetching it before simply means that I don't care."
Or it means you forgot to fetch it and now you are returning wrong data (worse than getting the exception; the consumer of the service thinks the collection is empty, but it is not).
I would not like to propose "better" solutions (it is not topic of the question and each approach has its own advantages), but the way that I solve issues like these in most use cases (and it is one of the ways commonly adopted) is using DTOs: Simply define a DTO that represents the response of the service, fill it in the transactional context (no LazyInitializationExceptions there) and give it to the framework that will transform it to the service response (json, xml, etc).
What you can try is a solution like the following.
Creating an interface named LazyLoader
#FunctionalInterface // Java 8
public interface LazyLoader<T> {
void load(T t);
}
And in your Service
public class Service {
List<Master> getWithDetails(LazyLoader<Master> loader) {
// Code to get masterList from session
for(Master master:masterList) {
loader.load(master);
}
}
}
And call this service like below
Service.getWithDetails(new LazyLoader<Master>() {
public void load(Master master) {
for(Detail detail:master.getDetails()) {
detail.getId(); // This will load detail
}
}
});
And in Java 8 you can use Lambda as it is a Single Abstract Method (SAM).
Service.getWithDetails((master) -> {
for(Detail detail:master.getDetails()) {
detail.getId(); // This will load detail
}
});
You can use the solution above with session.clear and session.evict(master)
I have raised a similar question in the past (why dependent collection isn't evicted when parent entity is), and it has resulted an answer which you could try for your case.
The solution for this is to use queries instead of associations (one-to-many or many-to-many). Even one of the original authors of Hibernate said that Collections are a feature and not an end-goal.
In your case you can get better flexibility of removing the collections mapping and simply fetch the associated relations when you need them in your data access layer.
You could create a Java proxy for every entity, so that every method is surrounded by a try/catch block that returns null when a LazyInitializationException is catched.
For this to work, all your entities would need to implement an interface and you'd need to reference this interface (instead of the entity class) all throughout your program.
If you can't (or just don't want) to use interfaces, then you could try to build a dynamic proxy with javassist or cglib, or even manually, as explained in this article.
If you go by common Java proxies, here's a sketch:
public static <T> T ignoringLazyInitialization(
final Object entity,
final Class<T> entityInterface) {
return (T) Proxy.newProxyInstance(
entityInterface.getClassLoader(),
new Class[] { entityInterface },
new InvocationHandler() {
#Override
public Object invoke(
Object proxy,
Method method,
Object[] args)
throws Throwable {
try {
return method.invoke(entity, args);
} catch (InvocationTargetException e) {
Throwable cause = e.getTargetException();
if (cause instanceof LazyInitializationException) {
return null;
}
throw cause;
}
}
});
}
So, if you have an entity A as follows:
public interface A {
// getters & setters and other methods DEFINITIONS
}
with its implementation:
public class AImpl implements A {
// getters & setters and other methods IMPLEMENTATIONS
}
Then, assuming you have a reference to the entity class (as returned by Hibernate), you could create a proxy as follows:
AImpl entityAImpl = ...; // some query, load, etc
A entityA = ignoringLazyInitialization(entityAImpl, A.class);
NOTE 1: You'd need to proxy collections returned by Hibernate as well (left as an excersice to the reader) ;)
NOTE 2: Ideally, you should do all this proxying stuff in a DAO or in some type of facade, so that everything is transparent to the user of the entities
NOTE 3: This is by no means optimal, since it creates a stacktrace for every access to an non-initialized field
NOTE 4: This works, but adds complexity; consider if it's really necessary.
I'm writing javadoc for my jsp web application. So i have a class (created according to Command pattern and located in service layer) called AcceptOrder. This class contains method execute and it calls method acceptOrder from DAO layer. Class is located in service layer.
/**
* Class allows customer order (which was assigned by dispatcher) be accepted by driver.
*
*
*/
public class AcceptOrder implements Command {
private static final String USER_ATTRIBUTE = "user";
private static final String ORDER_ID_ATTRIBUTE = "order_id";
private static final String DAO_COMMAND_EXCEPTION_MESSAGE = "Exception on executing DAO command";
private static final String WRONG_ORDER_ID_EXCEPTION_MESSAGE = "Wrong order ID";
/** {#inheritDoc}
* <p> Accepts user order, which was assigned by dispatcher.
* #param request request object
* #param response response object
*/
#Override
public String execute(HttpServletRequest request, HttpServletResponse response) throws CommandException {
DriverDao driverDao = MySqlDaoFactory.getInstance().getDriverDao();
try {
User user = (User) request.getSession().getAttribute(USER_ATTRIBUTE);
int userId = user.getId();
int orderId = Integer.valueOf(request.getParameter(ORDER_ID_ATTRIBUTE));
driverDao.acceptOrder(orderId, userId);
} catch (DaoException e) {
throw new CommandException(DAO_COMMAND_EXCEPTION_MESSAGE, e);
} catch (NumberFormatException e) {
throw new CommandException(WRONG_ORDER_ID_EXCEPTION_MESSAGE, e);
}
return PageManager.getInstance().generatePageRequest(CommandName.SHOW_DRIVER_ORDER);
}
}
Aslo i have a method in driver DAO class (in DAO layer) called acceptOrder which connects to the database and apply some changes according to parameters.
#Override
public void acceptOrder(int orderId, int userId) throws DaoException {
ConnectionPool connectionPool = null;
Connection connection = null;
PreparedStatement preparedStatement = null;
ResultSet result = null;
try {
connectionPool = ConnectionPool.getInstance();
connection = connectionPool.takeConnection();
preparedStatement = connection.prepareStatement(SQL_ACCEPT_ORDER);
preparedStatement.setInt(1, userId);
preparedStatement.setInt(2, orderId);
preparedStatement.executeUpdate();
} catch (SQLException e) {
throw new DaoException(STATEMENT_EXCEPTION_MESSAGE, e);
} catch (ConnectionPoolException e) {
throw new DaoException(CONNECTION_POOL_EXCEPTION_MESSAGE, e);
} finally {
connectionPool.closeConnection(connection, preparedStatement, result);
}
}
So the question is: What javadoc should i write for it and is my javadoc for command method execute is correct? What should be written in the description of both methods. Seems like their descriptions are the same- accept customer order.
I think you should explain better what is the method doing, cases when exception is thrown, returned values, what is actually returned and why. How to call this method, examples. A common usage, dependencies used, general workflow, validation, modeling you can explain at the class level.
I try to follow the rules below.
Does the code you write provide an API for external users? Or maybe it's just an internal implementation hidden behind another interfaces and classes (and they should provide that javadoc)?
When you write the doc, think what you would like to see from the API you don't know
Don't write obvious things (e.g. trivial javadoc for getters and setters, don't just repeat method name without spaces etc.)
Probably you shouldn't share the implementation details as it shouldn't matter to the user of your API. However, sometimes there are some details that you need to share to warn users so they don't misuse your API. If you need to leave a message for future code maintainers leave it in the code comment, not public javadoc
Document null handling. Is it accepted as the parameter value? If yes, what meaning does it have? Can the method return null? If yes, under what circumstances?
Document exceptions. Provide useful information for API clients so they can appropriately handle them.
Document any assumptions about the class state. Does the object need to be in a particular state in order to call the method because otherwise it will throw an exception?
Inheritance: is the class designed for extension (otherwise it should be marked final, right)? If yes, should subclasses obey any specific rules?
Thread safety: is the class thread safe? If the class is designed for extension, how subclasses should preserve thread safety?
Depending on your domain, performance might be very important. Maybe you need to document time and space complexity.
And again, always try to think what information you would expect from an external library. I use Java SDK and Java EE javadoc a lot. Some parts of it are great. From others I would expect information like if I can use an object from multiple threads or not but there is no single word about it and I have to refer to sources (and there will never be guarantee that my findings will be correct).
On the other hand think also if you should write a javadoc comment at all. Is it worth it? Will you have external clients of your API (especially without access to your source code)? If you do, you probably should also write a reference manual. If you have a small application and a small team, it might be easier to just skim the short method body.
Note that I am not saying you shouldn't write javadoc at all. I am trying to say that javadoc is a tool with a specific purpose. Think if writing a specific snippet of javadoc will help you to fulfill it.
I am trying to understand the most suitable (Java) design pattern to use to process a series of messages. Each message includes a "type" which determines how the data contained in the message should be processed.
I have been considering the Command pattern, but are struggling to understand the roles/relevance of the specific Command classes. So far, I have determined that the receiver will contain the code that implements the message processing methods. Concrete commands would be instantiated based on message type. However, I have no idea how the actual message data should be passed. Should it be passed to the receiver constructor with the appropriate receiver methods being called by the concrete command execute method? Maybe the message data should be passed in the receiver action method invocations?
I am fairly new to all of this so any guidance would be appreciated.
This may help:
public interface Command {
public void execute(String msg);
}
public class AO1Command implements Command {
Receiver rec = new Receiver();
public void execute(String msg) {
rec.admit(msg);
}
}
public class CommandFactory {
public protected CommandFactory () { }
public static Command getInstance(String type) {
if (type.equals("A01")) return new A01Command();
else if (type.equals("A02")) return new A02Command();
else {
return null;
}
}
Ok, your title says a pattern for handling events. If you are talking about an actual event framework, then the Observer/Observable pattern comes to mind. This would work when you want do fire an event of some type, then have event handlers pick up the processing of the events.
Seems like your problem is in the implementation details of the command pattern. Can you post some code that shows where you are stuck?
Note that patterns are not mutually exclusive, you could use the command pattern in the context of the Observable pattern.
EDIT -- based on your code, you should
1) make the CommandFactory static.
2) pass the type to the getCommand method, which should also be static.
3) You don't need reflection for this, you can simply do
if (type == "type1") return new Command1();
else if (type == "type2") return new Command2();
...
Im not saying you can't use reflection, I'm saying its overcomplicating what you are trying to do. Plus, they way you are doing it binds the the String that represents the message type to the implementation details of the command class names, which seems unnecessary.
You are on the right track. A Command pattern is the appropriate solution to the outlined problem.
To answer your question, you would have your CommandFactory instantiate an appropriate Command instance based on the data differentiator (in this case some data in your message). You would then invoke a method on the Command instance, passing in your message. It is common (best) practice to call this method Execute(...), but you can call it whatever you want.
You may want to take a look to the Jakarta Digester project (to process XML), it has a SAX implementation, wich is an event based API as explained here http://www.saxproject.org/event.html, it's a short explanation but could serve as a starting point for you.