#Retryable with exceptionExpression does not set any #root object neither variables - java

I'm using Spring Retry 1.2.4 with #Retryable annotation in a library dependency of a SpringBatch.
In the exceptionExpression attribute I specify an expression #root.status.is5xxServerError() of a custom exception for which I mention the class in the include attribute.
But it leads to an error with the following message :
org.springframework.retry.RetryException: Non-skippable exception in recoverer while processing; nested exception is org.springframework.expression.spel.SpelEvaluationException: EL1001E: Type conversion problem, cannot convert from java.lang.String to java.lang.Boolean
What I find strange is that the batch faultTolerant configuration seems to be in conflict with the library configuration, if I have a look at the "Non-skippable exception in recoverer while processing" into the final message.
Also while debugging in SpEL expression evaluation I notice no root object neither any variables are set in the EvaluationContext though it is trying to resolve #root.status.is5xxServerError(). Perhaps it is linked with the observation above.
Thanks for help

Expression support in those annotation is very basic.
I recently opened a GitHub issue to add improvements (runtime evaluation etc).

Related

How do you disable trusted.packages check for Spring-Kafka JsonDeserializer?

I have legacy Spring-Scala project. I have added new event type to one of the topics and now consumers throw exceptions
Caused by: java.lang.IllegalArgumentException: The class '...' is not in the trusted packages: [java.util, java.lang, ...].
It seems that a few classes are always added by Spring. I want to disable this feature but it seems that list of classes must be empty for the code to ignore it. But I don't see how that list would ever be empty if some java packages are added by Spring itself. Any suggestions?
I got this. There is a method called .addTrustedPackages and it handles "*" argument as one that clears the internal trustedPackages list. Neat design... >.<
So the following code works
val deserializer = new JsonDeserializer[...]()
deserializer.addTrustedPackages("*")

MvcUriComponentsBuilder and inccorect binding in Spring MVC

Code
I have my Controller method like this:
#RequestMapping("/{userId}/{configId}")
def edit(#PathVariable("userId") User user,
#PathVariable("configId") Configuration configuration) {
/* some code here*/
}
When I call this method from my browser it works very well, and user, and configuration args bind from DataBase by their id.
Problem
But, when I used MvcUriComponentsBuilder class, I got some exceptions for incorrect arguments type in the expected method.
MvcUriComponentsBuilder.fromMethodName(MyController.class, "edit", 1, 2).build()
Exception
java.lang.IllegalArgumentException: source to convert from must be an instance of #org.springframework.web.bind.annotation.PathVariable User; instead it was a java.lang.Long
Faced some body with similar problem? Are there any solution?
NOTE: I'm currently using Spring Web MVC 4.1.8.RELEASE
A bit more descriptions
I'm using MvcUriComponentsBuilder in Thymeleaf template like this:
th:action="${#mvc.url('CC#edit').arg(0, configuration.access.id).arg(1, configuration.id).build()}
As docs says that in arg method should be passed native method arg (in my example should passed User and Configuration instances). But, in my opinion better solution is using long values (for example) and then autobind it to object as it expected (as like it works over browser call)
Additional info!
I listened to #Sotirios Delimanolis, and use this function as it described in it docs
th:action="${#mvc.url('CC#edit').arg(0, configuration.access.user).arg(1, configuration).build()
Passed arguments are correct in this example.
BUT, I have gotten exception AGAIN!
org.springframework.core.convert.ConverterNotFoundException: No converter found capable of converting from type #org.springframework.web.bind.annotation.PathVariable #org.springframework.web.bind.annotation.ModelAttribute ua.smartsteamshop.web.app.domain.User to type java.lang.String
It is looks like a bug! Guys, I need your help! This question should be discussed!

Right exception to throw for the lack of a system property

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.

IllegalArgumentException when using SpinnerItem in SmartGWT

I am trying to use a SpinnerItem as the editor type for a ListGridField
final ListGridField quantityGridField = new ListGridField("quantity", "Cantidad");
quantityGridField.setEditorType(SpinnerItem.class);
quantityGridField.setCanEdit(true);
But after I compile the project and deploy it this error comes up.
java.lang.IllegalArgumentException: No BeanFactory has been registered for: com.smartgwt.client.widgets.form.fields.SpinnerItem
This is the first time that I get this error and I have not found any related question here.
As it's described in javadoc to the method that you use (setEditorType(class)) you use Reflection mechanism of smartgwt. You can read about it here: http://www.smartclient.com/smartgwt/javadoc/com/smartgwt/client/docs/Reflection.html .
According to this documentation you should register SpinnerItem(which is a subclass of FormItem) prior of using it:
Similarly, to register FormItem and all its subclasses found in the
classpath (including your custom subclasses), you can use the
BeanFactory.FormItemMetaFactory.
GWT.create(BeanFactory.FormItemMetaFactory.class);
So just try to insert this GWT.create line somewhere in your code before using it, so gwt compiler will be able to find your editor.

Strange Guice injection error

I have a very strange error when trying to inject with constructor with Guice. There is a particular line in the constructor as the following:
#Inject
public RoundRobinAssigner(
... arguments
) {
...stuff
assignments = Sets.synchronizedNavigableSet(Sets.<CountingEntry<String>>newTreeSet());
}
This fails upon injection with the following.
1) Error injecting constructor, java.lang.NoSuchMethodError: com.google.common.collect.Sets.synchronizedNavigableSet(Ljava/util/NavigableSet;)Ljava/util/NavigableSet;
at edu.harvard.econcs.turkserver.util.RoundRobinAssigner.<init>(RoundRobinAssigner.java:46)
at edu.harvard.econcs.turkserver.util.RoundRobinAssigner.class(RoundRobinAssigner.java:40)
while locating edu.harvard.econcs.turkserver.util.RoundRobinAssigner
But if I remove the Sets.synchronizedNavigableSet() wrapping, things inject just fine.
#Inject
public RoundRobinAssigner(
... arguments
) {
...stuff
assignments = Sets.<CountingEntry<String>>newTreeSet();
}
Clearly, this is suboptimal as I want to use the synchronized set. Is there any reason why a Guice-called instructor would behave any differently than a normal one? Neither of these code has any compile problems and the Sets class from guava has too have been loaded, so I have no idea what is causing this.
I suspect you're just seeing a problem which you'd otherwise see elsewhere - basically because Guice is involved when loading up the class via reflection, the "link time" error of Sets.synchronizedNavigableSet being unavailable is shown within the context of Guice instead of in a "normal" constructor call.
synchronizedNavigableSet was only introduced in 13.0 - is it possible that you're compiling against that, but running against an older version of Guava?

Categories

Resources