Seam Classes and #Asynchronous processing related issue - asynchronous

I have an Interface defined as:
public interface DocExporter{
public void exportDoc();
}
with two implementing classes defined as:
#Service(value="docExporter")
#Scope(value="BeanDefinition.SCOPE_PROTOTYPE)
public class PdfDocExporter implements DocExporter{
public void exportDoc(){
// do Pdf Export stuff
}
}
AND
#Service(value="docExporter")
#Scope(value="BeanDefinition.SCOPE_PROTOTYPE)
public class ExcelDocExporter implements DocExporter{
public void exportDoc(){
// do Excel Export stuff
}
}
So can I say like :
#Name("docExportReporter")
#Scope(ScopeType.EVENT)
public class DocExportReporter {
#In("#{docExporter}")
private DocExporter pdfDocExporter;
#In("#{docExporter}")
private DocExporter excelDocExporter;
#Asynchronous
public void reportGen(){
**excelDocExporter.exportDoc()** // THIS THROWS Seam Exception #In attribute requires a not null value
}
}
I am new to Seam with Spring and would like to know if in both impl classes #Service would have values as "docExporter" (name of interface) or would it be like "pdfDocExporter" "excelDocExporter" ?
And with the above, I get #In attribute requires a non null value exception when using pdfDocExporter or excelDocExporter objects within the reportGen async method. Can two implementations of an interface be declared in a third class and work fine
with Seam #Asynchronous annotation ?

You cannot have two components with the same name, otherwise Seam would not know which one to inject. Use two different names.

Related

How to get some common data in a custom ConstraintValidator

I am validating a input class using Java validation api and hibernate validator.
i have created few custom annontation for some business validation and i am using these annotation on the input class. below is an example of such annotation validator -
import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
public class DBColumnConstraintValidator implements ConstraintValidator<DatabaseColumnConstraint, Object> {
private DBColumnConstraintValidator databaseColumnConstraint;
private final List<DatabaseConstraintValidationStep> steps = new ArrayList<DatabaseConstraintValidationStep>();
#Override
public void initialize(DBColumnConstraintValidator databaseColumnConstraint) {
}
#Override
public boolean isValid(Object value, ConstraintValidatorContext context) {
//Validation logic
}
}
I want to use some data for my validation logic inside isValid() method and this data is common and will be used by few other validator classes as well.
is there any way to set or make that common data available to isValid() method?
If you are using CDI or Spring, you can simply use dependency injection (e.g. using #Inject) within your constraint validator implementation to obtain whatever contextual service or data your need.

Java Object with static variable instance inside Stateless Bean

Is it ok to have an object inside of EAR like the Calculator class to be used as a utility for other stateless classes?
Is it a bad design? If so what appropriate approach should be applied?
#Stateless
class A{
public void sumForA(){
System.out.println("SUM IS : "+ (Calculator.getInstance().add(4+6)));
}
}
#Stateless
class B{
public void sumForB(){
System.out.println("SUM IS : "+(Calculator.getInstance().add(1+2)));
}
}
public class Calculator{
static{
INSTANCE=new Calculator();
}
private static INSTANCE;
public Calculator getInstance(){
return INSTANCE;
}
public int add(int x,int y){
return x+y;
}
}
First, there is no such name "static variable instance", there is instance variables and static variables, you can find an example here: Java Static vs Instance.
Second, regarding your Calculator class, you need to mark the getInstance() method as static beacause you are calling it directly. And, you seem trying to use the singleton pattern, I suggest you take a look at this SO question: What is an efficient way to implement a singleton pattern in Java?
Third, in your example there is no static variable in the statless bean, and to make it simple: you are only invoking a method in the Class Calculator which has static members. So why not?! you are using your utility class inside your method, it doesn't matter if it's a stateless bean or any kind of beans (EJB session beans, CDI / JSF beans, Spring Components ... ).

Is there a better method than ListWrapper to bind a List<T> in a Spring MVC method?

In order to retrieve a list in a Spring MVC application I would like to write something like:
public String myMethod(#RequestParam("foo") List<FooUi> foos)
But the only solution I've found so far is the following :
public String myMethod(FooListWrapperUi fooListWrapperUi)
I don't like this solution because I have to write a wrapper each time I need to retrieve a list. In this example, the wrapper is the following :
#Data
#JsonIgnoreProperties(ignoreUnknown = true)
public class FooListWrapperUi
{
private ArrayList<FooUi> fooList;
}
So my question is, is it possible to use something like the first solution or is it impossible and I need to write a wrapper?
Thanks.
You can accommodate your use case by creating your own HandlerMethodArgumentResolver:
public class FooUiResolver implements HandlerMethodArgumentResolver {
#Override
public boolean supportsParameter(MethodParameter methodParameter) {
return (methodParameter.getParameterType().equals(FooUi.class) ||
(methodParameter instanceof Collection<?> && ((ParameterizedType) methodParameter.getParameterType().getGenericSuperclass()).getActualTypeArguments()[0] == FooUi.class));
}
#Override
public Object resolveArgument(MethodParameter methodParameter,
ModelAndViewContainer modelAndViewContainer, NativeWebRequest nativeWebRequest,
WebDataBinderFactory webDataBinderFactory) throws Exception {
// Create instances of FooUi by accessing requests parameters in nativeWebRequest.getParameterMap()
}
}
The actual implementation will depend on how you would create one or more FooUi instances from the request parameters or body. You then need to register FooUiResolver in your servlet config:
#Override
public void addArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers){
argumentResolvers.add(new FooUiResolver());
super.addArgumentResolvers(argumentResolvers);
}
Once registered, you can use FooUi in your controller method arguments without RequestParam or any other annotation:
#RequestMapping(value = "/foo")
public String myMethod(List<FooUi> foos){}

How can I use same EJB in two different CDI beans and retrieve the values set from one bean into the another?

I have a stateful session bean where a list is maintained:
#Stateful
public class CartDAO{
private List<ShoppingCart> tempCart;
public void add(ShoppingCart shoppingCart){
tempCart.add(shoppingCart);
}
public List<ShoppingCart> getCart(){
return tempCart;
}
#PostConstruct
public void init(){
tempCart = new ArrayList<>();
}
}
Controller1 to add to the cart:
#Named
#SessionScoped
public class Controller1 implements Serializable {
#EJB
CartDAO cartDao;
public String addToShoppingCart() {
cartDao.add(shoppingCart);
}
}
Now, i want to ask you could i get the added items to the list from another cart?
#Named
#SessionScoped
public class Controller2 implements Serializable {
#EJB
CartDAO cartDao;
public String getShoppingCart() {
System.out.println(cartDao.getCart());//returns null
}
}
Obviously the above code returns null.
How do I retrieve the list from another controller. Any help will be much appreciated.
I don't see any obvious mistake here (are you sure that you don't call Controller2#getShoppingCart() before adding any items do your CartDAO?) but here are couple of my notions
you should have your CartDAO implement some interface or make it #LocalBean
all stateful beans should have method annotated with #Remove so you can clean the resources used in the bean (close datasources and son) and bean will be removed from the memory after this call
now it's recommended to use #Inject everywhere instead of #EJB, it's the same (you have to use #EJB only when you inject remote beans)
And also one point, if the System.out.println(cartDao.getCart()); returns null than it means the #PostConstruct haven't been called which is strange. Can you provide some more info about container and your environment?Also show us imports, this is big source of mistakes.

Hadoop Map output IOException when emitting subclass of a class defined in Configuration as an ouput

I have 3 simple classes:
public abstract class Container implements WritableComparable<Container> {} //empty
public class WeightedEdge extends Container { ... }
public class NodeWeightContainer extends Container { ... }
The Map phase was configured as such
JobConf createGraphPConf = new JobConf(new Configuration());
Job job = new Job(createGraphPConf);
...
createGraphPConf.setMapOutputValueClass(Container.class);
However I am receiving this error:
java.io.IOException: Type mismatch in value from map: expected org.hadoop.test.data.util.Container, recieved org.hadoop.test.data.WeightedEdge
at org.apache.hadoop.mapred.MapTask$MapOutputBuffer.collect(MapTask.java:1018)
at org.apache.hadoop.mapred.MapTask$OldOutputCollector.collect(MapTask.java:591)
at org.hadoop.test.map.CreateGPMap.map(CreateGPMap.java:33)
at org.hadoop.test.map.CreateGPMap.map(CreateGPMap.java:19)
at org.apache.hadoop.mapred.MapRunner.run(MapRunner.java:50)
at org.apache.hadoop.mapred.MapTask.runOldMapper(MapTask.java:435)
at org.apache.hadoop.mapred.MapTask.run(MapTask.java:371)
at org.apache.hadoop.mapred.LocalJobRunner$Job.run(LocalJobRunner.java:210)
Why I can't return a subclass of a class that was defined in the configuration? Is there a way around it? The problem is that my Map phase has to emit two distinct object types.
You can not return a subclass of a class that was defined in the configuration because Hadoop explicitly checks class type specified in setMapOutputValueClass and the type it receives from Mappers.
It does so because it needs to serialize/deserialize objects you emit from mappers. When it performs deserialization it creates new object of type that is specified in setMapOutputValueClass call and then uses methods of WriteableComparable interface to fill newly created object with data.
To be able to emit different object types you may define container non-abstract class and place actual object and its type identifier inside
public enum ELEM_TYPE { WE, WECONTAINER }
public class Container implements WritableComparable<Container>
{
ELEM_TYPE type; //actual element type -
// WeightedEdge or NodeWeightContainer
object value;
//WritableComparable implementation
// that casts value to the appropriate type
}
public class WeightedEdge { ... }
public class NodeWeightContainer { ... }
I faced the same problem today. There is a Writable class org.apache.hadoop.io.GenericWritable which can be used to address this problem. You need to extend the class and implement an abstract method:
public class Container extends GenericWritable {
private static Class[] CLASSES = {
WeightedEdge.class,
NodeWeightContainer.class,
};
protected Class[] getTypes() {
return CLASSES;
}
}
public class WeightedEdge implemets Writable {...}
public class NodeWeightContainer implements Writable {...}
Now you can use the class Container as the output value type of your mapper.
Important: Your actual map output classes (WeightedEdge and NodeWeightContainer) must implement the Writable interface.

Resources