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 ... ).
Related
In my JSF application i have a process that takes to long to complete and i don't want that the user keeps waiting till its finish. I'm trying to implement some kind of 'fire and forget task' to run in background.
I'm doing it using an #Asynchronous method. This is the right approach?
My controller:
#ViewScoped
#Named
public class Controller implements Serializable {
private static final long serialVersionUID = -6252722069169270081L;
#Inject
private Record record;
#Inject
private Service service;
public void save() {
this.record.generateHash();
boolean alreadyExists = this.service.existsBy(this.record.getHash());
if (alreadyExists)
Messages.add(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, "Error", "This record already exists"));
else {
this.service.save(this.record);
this.clearFields();
}
}
}
My service:
#Stateless
public class Service extends AbstractService<Record> {
private static final long serialVersionUID = -6327726420832825798L;
#Inject
private BeanManager beanManager;
#Override
public void save(Record record) {
super.save(record);
this.preProcess(record);
}
#Asynchronous
private void preProcess(Cd cd) {
// Long task running here ...
this.beanManager.fireEvent(cd);
}
}
But even with this approach the user keeps stuck at the page till the preProcess method finishes.
The problem here is that annotations that modify the behavior of EJBs (and CDI beans) are only applied when called by the "proxy" object that gets injected to appropriate injection points, like fields annotated with #EJB or #Inject.
This is because of how the containers implement the functionality that modifies the behavior. The object that the container injects to clients of EJBs (and normal-scoped CDI beans) is actually a proxy that knows how to call the correct instance of the target bean (e.g. the correct instance of e #RequestScoped bean). The proxy also implements the extra behaviors, like #Transactional or #Asynchronous. Calling the method through this bypasses the proxy functionalities! For this reason placing these annotations on non-public methods is effectively a NO-OP!
A non-exclusive list of solutions:
Move preProcess() to a different EJB, make it public and keep the #Asynchronous annotation
Make preProcess() public and call it from the Controller
If the computation is truly private to the Service and exposing it would break design, and ou don't mind doing a bit more manual work, you can always run async tasks from the container-provided ManagedExecutorService:
#Resource
private ManagedExecutorService managedExecutorService;
Pay attention to the semantics of the thread that executes your code - more specifically to what context values are propagated and what not! Well, you have to pay attention to that for #Asynchronous methods too!
I have a simple controller e.g.
#Controller
public class FooController
{
#Autowired
private BarService barService;
#RequestMapping(value = "/foo", method = RequestMethod.GET)
public String displayFoo()
{
return "foo";
}
}
When I want to do a #WebMvcTest, I have to create a great number of #MockBeans to prevent a NoSuchBeanDefinitionException.
#RunWith(SpringRunner.class)
#WebMvcTest
#Import(WebSecurityConfig.class)
public class FooControllerTest
{
#MockBean ...
#MockBean ...
#MockBean ...
...
...
}
Does this mean that BarService is somehow creating a chain of dependencies? (it has some dependencies but some #MockBeans appear completely unrelated).
The problem is, is that each #WebMvcTest I add for different controllers also requires the same #MockBeans.
Should I be using an annotation like #TestConfiguration to specify all the #MockBeans for the DRY principal?
I looked at this again, and found you can pass the controller name to #WebMvcTest e.g. #WebMvcTest(FooController.class).
Specifies the controllers to test. May be left blank if all {#code
#Controller} beans should be added to the application context.
As Hal8k said, if you don't specify a controller like #WebMvcTest(YourController.class), it will try to load all #Controller components. And #Import(WebSecurityConfig.class) also try to inject components in WebSecurityConfig.class.
Refer : https://spring.io/blog/2016/08/30/custom-test-slice-with-spring-boot-1-4
This could happen when the bean scanning configuration is faulty or excessive.
In my case, I was still getting the error despite having specified the controller to test in #WebMvcTest(FooController.class).
I eventually realised it was due to the #ComponentScan of my application being needlessly cluttered up. My Application.java was something like this:
#SpringBootApplication
#ComponentScan({"fr.nevechris.projectname","fr.nevechris.projectname.otherpackage"})
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
I removed the #ComponentScan entirely and the issue was solved.
If your #ComponentScan is good or not specified, try searching for other places in your project where configuration is done (eg #Configuration tag).
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.
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.
All tutorials I've read till now about Singleton pattern were as below :
public sealed class Singleton
{
private static readonly Singleton instance = new Singleton();
private Singleton(){}
public static Singleton Instance
{
get
{
return instance;
}
}
}
but I already have a class in a assembly that I need to just have one instance of it during application lifetime . I don't know how to use pattern mentioned above .
for example suppose there is a class X in dll named Y . is the code below correct :
public sealed class Singleton
{
private static readonly Y.X instance = new Y.X();
private Singleton(){}
public static Y.X Instance
{
get
{
return instance;
}
}
}
is this a true singleton ? if not , what is a correct way to handle this situation ?
No its not the singleton pattern. The fact that you are calling new Y.X() means anyone can call it. This does not specifically disallow new instances of Y.X()
However the code is okay if you need to make sure that you refer to only one instance of Y.X in your application. Then you can get it by calling Singleton.Instance.
This is in fact the Factory pattern (A class dedicated to creating objects), and I would suggest you call the class XFactory or something similar, instead of singleton.
I would use something like :
public static class Singleton<T>
where T : new()
{
private static readonly Lazy<T> instance = new Lazy<T>();
public static T Instance
{
get
{
return instance.Value;
}
}
}
The idea is to use Generics in order to allow specify any type as type parameter.
The lazy is just an improvement to instantiate the actual instance of the object.
Please note that this won't disallow creating instances of T directly...