Right exception to throw for the lack of a system property - java

Say I have a system property MY_PROP:
java -DMY_PROP="My value"
This property is necessary for my system to work.
What is the right exception to throw if this property is not set?
#PostConstruct
private void init() {
myProp = System.getProperty("MY_PROP");
if (myProp == null) {
throw new ????
}
// ...
}
Somehow IllegalArgumentException does not feel right. Maybe IllegalStateException, MissingResourceException, TypeNotPresentException? What is the standard practice for this scenario?

There is none. I would throw the IllegalStateException, because you are missing the parameter. This mean that configuration validator has failed and your application is in invalid state. In other words you should never be able to call the init() at all.
In case the value of parameter would be invalid, then i would throw an IllegalArgumentException.
If you are writing a validator, you should decide between using RuntimeException or checked one. When using for example javax.naming.ConfigurationException`, or created own one configuration exception. You API will be able to handle such exception and react properly in term of legacy.
Definitions:
IllegalStateException - Signals that a method has been invoked at an illegal or inappropriate time. In other words, the Java environment or Java application is not in an appropriate state for the requested operation.
IllegalArgumentException - Thrown to indicate that a method has been passed an illegal or inappropriate argument.

I only add to Vash's answer for the Spring Framework. If your using the Spring Framework and you want to be consistent with how most of the components in Spring do it then I would say you should use IllegalStateException (or your own derivation).
In Spring most components that do a #PostConstruct or #Override void afterPropertiesSet() throw IllegalStateException using the util org.springframework.util.Assert.state(..).
You can see this done in Spring AMQP as one example.
That being said I have actually filed bugs against Spring MVC where they used IllegalArgumentException instead of a custom and more explicit derived class. With static inline classes its very easy to create a custom exception with out creating another Java file.

Because a system property is not always defined, the standard pratice is to use a default value when you can't find the property.
I just checked some standard code in java 7 (apache tomcat, java.lang, java.awt, ...), they always use a default "fallback" when the property is null.
So maybe your problem is somewhere else ?
Why don't you take this parameters as a required argument of your jar ? Then you can use IllegalArgumentException.

Related

Mock Java implementation of an intermediate throw event in Camunda

I would like to mock the Java implementation for an intermediate throw event until it is implemented later on. However, I do not know what method I have to use when I want to mock it through a Java Class. I only know that for a service task, I can use
public void execute(DelegateExecution execution) throws Exception {
LOGGER.info("Java Class is called! - not yet implemented!");
}
Can I use this method for an intermediate throw event as well and specify the Java class name in the properties of the throw event in the BPMN diagram?
Yes, you can. Implement org.camunda.bpm.engine.delegate.JavaDelegate and configure the class. In BPMN XML it looks like this:
<intermediateThrowEvent id="message">
<messageEventDefinition camunda:class="org.camunda.bpm.MyMessageServiceDelegate" />
</intermediateThrowEvent>
See https://docs.camunda.org/manual/7.6/reference/bpmn20/events/message-events/#message-intermediate-throwing-event

Enforcing a throw statement for a method using annotations

I am currently implementing a system in which I am using aspectJ to check whether a user is allowed to call a method or not. My methods look something like this:
#Constrained(
mayUsers = {Constrained.Types.ADMIN,
Constrained.Types.SELLER, Constrained.Types.ORGANIZER}
)
public boolean save() {
/* code */
}
I am able to use AspectJ to intercept the message call and do the check, but if the call is not allowed I want to throw an exception. If I just throw the Exception the user of the method is not informed about the Exception which might be thrown.
Now my question is:
Is it possible to enforce that the every method that has the #Constrained Annotation throws a specific Exception?
Is it possible to enforce that the every method that has the
#Constrained Annotation throws a specific Exception?
No it is not possible to do that right now. But what you can do is that at runtime you can check that all the methods that have this annotation must throw exception. If any of method does not declare throws clause, you can throw some Illegal*Exception to tell the developer that each method must declare throws clause.
You have two solutions:
Compile time annotation checking using APT (Annotation Processing Tool)
Runtime checks (pre-conditions)

Transaction rollback in OSGi

I have an OSGi bundle in which I declare a service and inject into it a transaction with blueprint:
<bean id="MyServiceImpl"
class="com.test.impl.MyServiceImpl">
<jpa:context property="em" unitname="mypu" />
<tx:transaction method="*" value="Required" />
</bean>
<service id="MyService" ref="MyServiceImpl" interface="com.test.api.MyService" />
In this service I have two methods each one of which is writing data in the database, something like the following:
public void createParent() throws MyException {
Parent parent = new Parent();
... // Set parent fields
em.persist(parent);
createChild();
// Checks that could throw MyException
}
public void createChild() throws MyException {
Child child = new Child();
... // Set child fields
em.persist(child);
// Checks that could throw MyException
}
My problems are the following:
If I throw a runtime exception in the createParent method between em.persist(parent); and createChild(); the transaction rolls back (as I would expect) and parent is not persisted in the DB. However if at the same point I throw MyException (which is a checked exception) the transaction commits and parent is persisted. I saw in the Aries mailing list that a declared (checked) exception in a blueprint declarative transaction does not trigger a rollback. Is there a way to configure this behavior and specify that I want my exception to rollback the transaction when thrown?
If I throw a runtime exception in the createChild method (after em.persist(child);) child is not persisted in the database, however parent is persisted, as if the two methods are running in two different transactions. Why is that? Shouldn't createChild join in the transaction started by createParent?
If I throw a runtime exception in the createParent method after the call to createChild I get the same behavior as in point 2 (ie. parent is persisted and child is not persisted) which confuses me even more since even if I assume that createChild starts a new transaction then this should not get rolled back when an exception is thrown in createParent.
If in points 2 and 3 above the two methods are in different services then everything works as expected, ie. a runtime exception thrown in any of the methods rolls back the whole transaction.
Can someone please explain the above behavior?
After getting some help form the Aries mailing list it turns out the problem was in the datasource configuration and not in the blueprint configuration. Although I was using MysqlXADataSource as a driver class the datasource service was registered as a javax.sql.DataSource instead of javax.sql.XADataSource which is what was messing up my transactions.
1: A couple of years ago I asked the same. While in Spring you can specify that some transactions should cause rollback and some not, in blueprint you cannot do this. After a while I found the book "Clean code" and read the chapter "Error handling". And I got enlightened. I do not really try to write down the same as the book says. I think after you read it you will get some useful basic thoughts to build up your opinion if this is a right behaviour.
2: There can be two options:
You throw the exception before the persist function. You catch the exception in the parent. The child function is only wrapped with intercepting logic if the function is called from outside of there is not rollback when the call from child goes back to parent in whatever way. Just think of class wrapping. At least if you do not use bytecode manipulation or runtime class inheritance (but only java proxy classes) you cannot write wrap a class in a way that it intercepts function calls between functions inside. Probably Aries with ASM tries to do the trick (is ASM-4 is present) but personally I do not like this kind of tricks.
You found a bug
3: That confuses me, too :). Are you sure you do not throw the exception after persisting in the parent but before calling the child? Probably ASM is present and if that is there jta-blueprint has a bug... Debugging would be necessary to find out what happens.
4: Nice to hear that it can work somehow :)

Catch subclass of exception AND Exception in camel route

I have a camel route that I am using my own route builder to listen for the specific types of exceptions that I have created in my code.
so to my route, I have added
onException();
onMyTypeException();
I have also created the corresponding methods in my route builder
public OnExceptionDefinition onException(){
return onException(Exception.class)
....
public OnExceptionDefinition onMyTypeException(){
return onException(MyTypeException.class)
....
The problem is, onException() seems to catch everything, instead of letting me catch the more specific error first. The idea here being that in my system I have not accounted for every type of error, so if some get by, catch them in the onException()
Any ideas?
Camel will look for the explicit exception match first...but I think your initialization of the clauses is the issue. you shouldn't need to return them in your methods, etc...
overall, make sure you define your onException() clauses in the RouteBuilder's configure() method before any routes are setup...
see this page for more details...something like this...
public void configure() throws Exception {
onException(Exception.class).handled(true).log("general exception!!!");
onException(MyException.class).handled(true).log("my exception!!!");
from("direct:start").to("bean:myBean");
...
}
You can read overall about error handling with Camel here
http://camel.apache.org/error-handling-in-camel.html
And for using onException (which is also called exception clause) there is documentation here: http://camel.apache.org/exception-clause.html
However error handling in Camel is very flexible and elaborate. And also dealing and handling errors in integration use-cases is often hard. That is why we have devoted a full chapter in the Camel in Action book to cover this extensively. So if you got the book, then make sure to read chapter 5, it will help you a lot.

ApplicationError when trying to implement an edited version of the Secure module

I'm implementing an edited version of the Secure controller, default in the latest Play Framework.
I have read several times that, if you want to customize the Secure behaviour, you're better off copying the source of the Secure module, and start customizing it.
So I did, and after editing the needed dependencies I received following error:
Execution exception
NullPointerException occured : null
In /app/controllers/SecureController.java (around line 194)
190:
security = classes.get(0);
191:
}
192:
if(security==null)System.out.println("security is null");
193:
try {
194:
return Java.invokeStaticOrParent(security, m, args);
195:
} catch(InvocationTargetException e) {
196:
throw e.getTargetException();
197:
}
198:
}
199:
200:
}
The first logic conclusion to jump to is: there are no classes that implement the needed Secure$Security inner class. But there most certainly is a subclass, so I was wondering how this error can be fixed.
A debugging session learns that the classes.get(0) does contain the class that has the #With annotation. So the null pointer exception must be caused by something within the class that contains the #With(SecureController). But I left that class just the way it was, I just edited the reference within the With annotation.
So my guess is that somehow, there is a null pointer within the class implementation.
But even when I implement default behaviour, without any references, it still generates a nullpointerexception.
EDIT:
I found the cause of this error, but the 'why' isn't clear.
This line is found in the implementation of the authenticate(...) method in the subclass of SecureController$Security:
flash.put("url", request.url);
Why does this fail?
I understand this situation may be very hard to reproduce, but I was wondering if someone already experienced the same issue.
Thanks for the help (on many Play! related topics) so far.
the Scope.Flash class does not allow you to store null values. Perhaps you unset or failed to set request.url elsewhere in your modifications?

Categories

Resources