I have two beans. First bean languageOfSystem:
#Named(value = "languageOfSystem")
#SessionScoped
public class LanguageOfSystem implements Serializable {
#Inject private JsfUtils eeJsfUtils;
and the second bean, userBb:
#Named(value = "userBb")
#SessionScoped
public class UserBb implements Serializable, LangUpdInterface {
#EJB
private EjbUtils ejbUtils;
#EJB
private PuserFacade puserFacade;
#Inject
private Direction direction;
#Inject
private PortfelDao portfelDao;
#Inject
private LanguageOfSystem languageOfSystem;
I inject languageOfSystem into userBb, and NetBeans IDE gives me warning in line with that injection:
no enabled eligible for injection beans are found
But I'm able to call methods from languageOfSystem in userBb and it works fine. So is this warning important and should I change smth?
And the second question. I use in this case observer design pattern, where userBb is dependent and languageOfSystem is the subject which has a list of dependents. I register userBb in subject list by calling appropriate method from languageOfSystem. Is it right when it comes to the two session beans?
But I'm able to call methods from languageOfSystem in userBb and it
works fine.
Your code does not look wrong - and it works. So this seems to be a Netbeans issues.
And the second question. I use in this case observer design pattern,
where userBb is dependent and languageOfSystem is the subject which
has a list of dependents. I register userBb in subject list by calling
appropriate method from languageOfSystem. Is it right when it comes to
the two session beans?
Are you aware that the CDI spec includes a powerful and typesafe implementation of the observer pattern? You definitely should check this out.
And two more things to mention here:
#Named(value = "languageOfSystem")
#Named(value = "userBb")
The value you are providing is already default. So you can leave it
out and simply write #Named instead.
Regarding the code you are posting: #Named is not required at all -
all it does is providing an EL name for use in JSF. Your code will
work just as good if you skip #Named altogether...
As to your first question:
This is a known netbeans bug (see here and here). However, the discussion in the first link indicates that it is rather an issue of the weld implementation and Netbeans' warning is according to the specification.
Nevertheless the bugzilla file says it will be fixed in Netbeans v7.2.
Until then you can still disable the warning (Tools --> Options --> Editor --> Hints)
Related
My environment: Java 7/JSF 2.1/PrimeFaces 6.1.
My goal: to have a certain page of my application instantiated many times, one for each browser tab, each one with a different context.
My problem: everytime I open a second browser tab requesting from the same url, but with different object id, the previous one is destroyed, so only one backing bean instance is kept alive.
How do I know that: In my backing bean I have one method annotated with #PosConstruct and other with #PreDestroy, so I can track the life cicle of the instances.
My backing bean is annotated as follows:
#ViewController
public class MyBackingBeanMB extends AbstractBackingBeanMB {
private static final long serialVersionUID = 1L;
// many fields and methods
}
The #ViewController annotation is provided by the application framework I have to use. Such an annotation is declared as:
#Named
#Controller
#Stereotype
#ViewScoped // For me, this should do the trick, but...
#Target(value={TYPE})
#Retention(value=RUNTIME)
#Inherited
public #interface ViewController {
}
Update 1:
The #Controller annotation is also provided by the framework I use and is declared as:
#InterceptorBinding
#Inherited
#Target({ TYPE, METHOD })
#Retention(RUNTIME)
public #interface Controller {
}
Any ideas of what could be wrong?
TIA.
After some digging in the Internet I found Apache DeltaSpike, which provider a new kind of managed bean scope, WindowScoped.
Managed beans annotated with #WindowScoped` operate just like I wanted, providing me with the exact behaviour I needed and it is absolutely compatible with the framework I have to use.
I'm wondering if changing the EL resolver so a bean can use public fields in jsf could cause issues with the proxies? [That's why it isn't a duplicate.] Aall managed bean fields have to be private in the framework, because that's how the EL resolver does things. However it's a bit cumbersome and looks useless most of the time.
#Named
#RequestScoped
public class myBean{
public int age;
}
So would it cause issue with proxies trying to intercept things or whatnot?
This guy in this question apparently changed the el resolver so it's doable
Unfortunately yes, it will mess with CDI.
Why? Because public field access is impossible when bean is proxied. With Weld during startup you will get a definition error:
WELD-000075: Normal scoped managed bean implementation class has a public field ...
It's going to work fine only for non-proxied scopes (#Singleton and #Dependant).
I agree it's a bit cumbersome and looks useless sometimes, so you have two solutions:
Use IDE to generate them automatically.
Use lombok project.
But none of them is perfect.
I want to give on-the-go scope to a pojo bean in CDI during injection.
I created a plain bean and injected the same as #javax.enterprise.context.ApplicationScoped in a #javax.faces.bean.ViewScoped Managed Bean like this:
#Inject
#ApplicationScoped
Pojo pojo;
// POJO Class
Class Pojo {
private String var;
public Pojo() {
}
public String getVar() {
return var;
}
public void setVar(String var) {
this.var = var;
}
}
The Pojo bean's populated values could not be restored in a new view bean when I inject using the same syntax.
But it works when I use #ApplicationScoped in the class declaration instead, followed by non-scoped injection, like this:
#ApplicationScoped
Class Pojo {
private String var;
Injection:
#Inject
Pojo pojo;
The former case gets resolved when I make a producer and qualifier but I feel this would be an overhead I should do without. Being new to CDI, I want to ask what I am really missing here.
Scope and Context management are a very powerful feature in CDI. It is also part of the business logic of the components (an #ApplicationScoped bean won't be developed the same way than a #RequestScoped), that's why the scope is link to bean definition.
An injection point is only a place where you consume a bean and not a place where you define it, so there is no way to define the scope of a bean at the injection point at spec level.
Now if you really want to use this feature you could develop a portable extension to add this possibility. But you'll probably have to work on a qualifier system as well since scope is not used in bean resolving process (i.e. 2 beans with the same type in different scope will be in conflict for a given injection point if they don't have specific qualifier).
I am developing webapp where my MVC controller is JSF 2.1. I have several methods that are based on
FacesContext.getCurrentInstance()
I use this to
put/retrieve values from Flash scope
add messages on view
get request params map
examples:
public void addInfoMessage(String title, String description){
FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_INFO,title, description));
}
and
public void putFlashMessage(String code, String value){
FacesContext.getCurrentInstance().getExternalContext().getFlash().put(code, value);
}
etc.
I'm just wondering where is proper place to put this methods if I use this on every single managed bean? I consider two options:
a) create class "JSFUtils", where all method are public and static
b) create super class "ManagedBean" with no declared scope and no declared #ManagedBean annotation, but with these public methods. Every managed bean should be child of these class so it will have inherited these methods.
An utility class is the recommended approach. Instead of reinventing your own, you can use an existing JSF utility library, such as OmniFaces which has Faces and Messages utility classes for the purpose.
String foo = Faces.getRequestParameter("foo");
Messages.create(summary).detail(detail).add();
Messages.addGlobalInfo(summary); // Without detail.
Faces.setFlashAttribute(key, value);
You can indeed also abstract it away as a "super bean", but this is not reusable and you would keep repeating yourself in every JSF project. Also, a class can extend from only one class. So if your bean happen to need to extend from another super class, then you're lost.
I would recommend a utility class for the purpose simply because you allow the flexibility to extend other useful classes, such as those that have some common logic that you'd like to share across other beans.
Having said that, a JSFUtils class can grow quite cluttered with time with many many methods and can become very unmanageable. It would be better to categorize the util methods and put them in separate static utility classes.
I use Myfaces CODI #ViewAccessScoped backing beans in my JSF application. One of the
benefits is that I don't need to use view parameters to communicate information between
views. For the record #ViewAccessScoped ensures that a bean is accessible until until the first request of a new view doesn't access it. Take this case where I want to pass a string value from page1 to page2:
Page1Bean.java (backing bean for page1.xhtml)
#Inject private Page2Bean page2Bean;
private String source = "Hello, World!";
...
page2Bean.setTarget(source);
Page2Bean.java (backing bean for page2.xhtml)
private String target;
If I navigate directly from page1 to page2, then when I access #{page2Bean.target} from
page2 it has the value "hello, world!".
In effect I'm pushing the data from the page1 view to the page2 view. The other option is
to pull the data from the page1 view into the page2 view, so in the page2Bean I #Inject
Page1Bean and #ViewAccessScoped ensures that I can access page1Bean.getSource() (as long
as it was in the previous view).
This is all well and good, but in the real world I may want to navigate from page1 to any
one of a number of other pages, depending on user input. So Page1Bean.java ends up looking
like this:
Page1Bean.java (revised)
#Inject private Page2Bean page2Bean;
#Inject private Page3Bean page3Bean;
#Inject private Page4Bean page4Bean;
#Inject private Page5Bean page5Bean;
#Inject private Page6Bean page6Bean;
#Inject private Page7Bean page7Bean;
#Inject private Page8Bean page8Bean;
Now for my question: does the memory footprint of page1Bean always include page2Bean-
page8Bean? or will memory only be used if I access one of the #Inject'ed beans at
runtime?
I hope this isn't too naive a question, but I'm not sure exactly how it will work and
if the answer to the first question is yes, I'm more or less ending up using
#SessionScoped!.
Thanks for any clarification.
Well, I suppose it was pretty obvious really but having put some logging in the constructors of the beans that were being injected with #Inject, I could see that they were all being instantiated when the Page1Bean was instantiated, i.e. when navigating to page1. I found the solution in the JSR-299 CDI spec section 5.6 Programmatic lookup:
#Inject private Instance<Page2Bean> page2BeanDynamic;
...
if(someCondition) {
Page2Bean page2Bean = page2BeanDynamic.get();
page2Bean.setTarget(source);
}
so this is basically dynamic #Inject and ensures that I'm only instantiating the beans
at runtime when needed.
Putting finalize() & #PreDestroy methods in Page2Bean I see them both called when
navigating from page2 to page1, as expected.
No real memory footprint. Only proxies are generated. That's the reason for the constructor calls. You don't need to resolve beans manually!
You don't have to inject all beans. You are using it in a wrong way. Just keeping state between _ independent _ pages should be done via #WindowScoped. If they aren't independent use the beans in the target page (if you don't need the view-controller callbacks in the target pages).