I never used the #Singleton new feature of JavaEE 6 and i want to give it a try.
I was thinking in creating s Singleton to just hold a password that will allow the app adiministrator(The person that knows the password),to access some content of the app.
I tried to implement it following this tutorial, but it does not work.
This is what i did:
I created the singleton bean:
#Singleton
#Startup
#TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
public class AdminAcountEJB implements IAdminAcountEJB {
private String password;
#PostConstruct
public void init() {
password = "password";
}
#Lock(LockType.READ)
public String getPassword() {
return password;
}
}
I extracted an interface
public interface IAdminAcountEJB {
public abstract String getPassword();
}
Then i try to inject the singleton in a managed bean using #EJB
#Named("managementBB")
#SessionScoped
public class ManagementBB implements Serializable{
#EJB
private IAdminAcountEJB managementEJB;
private String input;
private boolean authorized;
public String seeWhatsUp() {
if(input.equals(managementEJB.getPassword())) {
authorized = true;
return "manage?faces-redirect=true;";
}
return "index?faces-redirect=true;";
}
//Get set methods...
}
The last thing i do is create some markup that is displayed in case the correct password is entered:
<h:form rendered="#{managementBB.authorized == false}">
<h:inputSecret value="#{managementEJB.input}"/>
<h:commandButton value="..." action="#{managementEJB.seeWhatsUp}"/>
</h:form>
<h:form rendered="#{managementBB.authorized}">
CORRECT PASSWORD!!
</h:form>
It all seems ok to me, but when i access the page, the console says:
javax.naming.NameNotFoundException:
ejbinterfaces.IAdminAcountEJB#ejbinterfaces.IAdminAcountEJB not found
I don't understand why it don't work, this is how i inject other EJB's that are not Singletones but with #Singleton it does not work.
-How can i fix it?
-I am also interested in knowing what do you think about using a singletone for this purpose, you think is a good and safe idea?
I guess the problem is, that since you refer to your singleton within an EL expression in the view, it has to be annotated with #Named. If you use your beans only within others, this is not necessary.
Concerning your design, my 2 pennies are these:
Since you are using Java EE 6, you won't need to specify an interface for it. If you want/need it nevertheless, don't call it ISomething (except you work for Apple ;-) but give it a domain related name.
Using a singleton which allows concurrent read access is ok for core data. Only, I wouldn't put the password within the code, but into a database table, preferrably hashed and use the singleton as a provider for that which reads the table at startup.
Singletons in general may always introduce a bottleneck into the application because by definition they don't scale. So for your use case it's ok, since we can assume the access rate is very low. The other problem which might be introduced are race conditions (also not in your case) if we have data that changes, since we only have one instance being called in parallel.
Related
I have just started learning Spring. I am confused with some simple concept of concurrency.
I have a class containing only 1 field uid:
#Service("Class1")
#Data
public class Class1 {
private String uid;
}
And I have request mapper with Class1 Autowired in it.
#RestController
#RequestMapping("/web")
#Scope("session")
public class Web {
#Autowired
Class1 class1;
#GetMapping("/hello")
public String sayHello(#RequestParam(value = "myName", defaultValue = "World") String name) {
class1.setUid(name);
try{
Thread.sleep(5000);
}
catch (InterruptedException e){
}
return String.format("Hello %s and uid %s!", name,class1.getUid());
}
}
Now if I hit two request at the same time with two different parameters say, myName=name1 and myName=name2, the uid is shown same in both the requests. But i think it should be equal to that particular name which is being passed.
I want to assign uid equal to the name which is being passed. How cannot be there 2 different instances of Class1 in both the request? Why is this concurrency happening?
I know Spring handle 2 different sessions by generating 2 different threads. But my concern is that both the threads use same bean. But i want different instance for different sessions. What is the proper way to do so?
I'm not sure if this is the issue, but at first glance I could relate this to the fact that the default(implicitly used) scope is Singleton, which means there is only one instance of bean (in your case the service bean). Usually, to handle state inside of the beans it is better to use #RequestScope for the service class (if you want to store the state there), which will create bean instance exactly for each particular request.
No sure but u are using #Service at the class level so its shared between all sessions. so the final result depends on which request is served later.
So
R1 -> "string1"
R2 -> "string2"
at the time when u call
return String.format("Hello %s and uid %s!", name,class1.getUid());
it will fetch the latest value which was set
as per my understanding the data class should not be a shared component(#Component or its derivatives) as by default scope is singleton u need to change the scope(prototype or other). so that it get instantiated at every request for more detail u can read https://www.geeksforgeeks.org/singleton-and-prototype-bean-scopes-in-java-spring.
I am facing a problem in converting my state pattern using plain java to spring DI since I am new to spring.
Actually I made a project using state pattern but I took the approach that every state knows it successive states not the context class.
The context class has a field "currentState" its type is IState, and it has method setState(IState state).
The IState has one method geNext(Context context).
And in the context class I made a while(keepOn) keepOn is true and it become false in ExitState to stop processing, in this loop I call currentState.goNext().
Each state make some database transactions and webservice's calls and depending on the result it set the next state using context.setState(new StateFour()) -for example-.
The first state is set by the client after creating the context.
Code sample:
public interface IState{public void goNext(Context context);}
public class StateOne implements IState{
public void goNext(Context context){
//do some logic
if(user.getTitle.equals("manager"){context.setState(new StateThree());}
else if(user.getTitle.equals("teamLead"){context.setState(new StateTwo());}
else{context.setState(new ExitState());}
}
}
public class Context{
private boolean keepOn = true;
private IState currentState;
public void setState(IState state){
currentState = state;
}
while(keepOn){currentState.goNext(this);}
}
Now I am trying to use spring DI annotation-based, the problem I am facing is that the context will annotated "currentState field" with #Autowired but I need the spring container to do the same logic if I am in state one and "if statement" success inject state three "else if" inject state two otherwise inject exitState.
If I use #Qualifier(value ="stateOne") it will specify only the first state which implements the interface but the other states which I set depending on the situation I don't know how to specify it in spring.
Also org.springframework.core.Ordered need specifying the orders of the beans in advance but I don't know the values I will receive from the database or webservice in advance, it should be specified at runtime.
So is it possible to replace this plain java with spring DI and how?
Thanks in advance for any help and sorry for lengthening.
You should use ApplicationContext. Example below:
// Inject application context into your bean
#Autowired
ApplicationContext applicationContext;
// Get bean from the context (equivalent to #Autowired)
applicationContext.getBean(StateThree.class);
The most versatile way to auto wire the state is by registering a resolvable dependency with a ConfigurableListableBeanFactory. As a dependency you could drop in your implementation of org.springframework.beans.factory.ObjectFactory<T> which will get the current user and creates/fetches the state to be injected.
This is exactly what happens when you, for instance, auto wire a field of type HttpServletRequest. A RequestObjectFactory will get the current request and inject it using this implementation.
// org.springframework.web.context.support.WebApplicationContextUtils
private static class RequestObjectFactory implements ObjectFactory<ServletRequest>, Serializable {
#Override
public ServletRequest getObject() {
return currentRequestAttributes().getRequest();
}
#Override
public String toString() {
return "Current HttpServletRequest";
}
}
I have two ManagedBeans.
Concerning my problem, they do the following:
First:
#ManagedBean
public class Provider {
private Event<ProvideEvent> event;
private static boolean handling = false;
public provide(#Observes ConsumeEvent consume){
if(!handling){
//provide some stuff
event.fire(new ProvideEvent(ProvidedStuff stuff);
}
}
}
Second:
#ManagedBean
#SessionScoped
public class Consumer {
private Event<ConsumeEvent> event;
#PostConstruct
public void initialize(){
event.fire(new ConsumeEvent());
}
private static boolean handling = false;
public consume(#Observes ProvideEvent providedStuff){
if(!handling){
//use the provided stuff
}
}
}
This happens, when the website is called:
1. Consumer is instantiated.
2. Consumer fires the event.
3. Provider is instantiated.
4. provide() is called.
5. A NEW CONSUMER IS INSTANTIATED
6. consume() is called.
As you can see, I had to use a boolean "handling" to keep the application from looping infinitly.
Why is the container not using the instantiated SessionScoped ManagedBean? I thought SessionScoped ManagedBeans are like Singleton for the Session?
I guess I could work around this by:
A: Using static variables for the changed properties.
B: Implementing the Observer-Pattern manually.
But there has to be an easier way here!?
I believe the problem could be that you fire the event in the #PostConstruct method of your Customer.
From the javadocs:
This method MUST be invoked before the class is put into service.
As far as I understand, that results in a race condition. The Provider is probably firing the second event earlier than your Customer instance finishes executing initialize() and the container puts it into service. Hence, it won't receive the event. I'm too inexperienced with Java EE to give good advice how to prevent that race condition though. I would probably work around it with an ugly SynchronousQueue as a meeting point.
Additional info: the default with #Observes is to create a new instance of the event receiver if none exists (is in service). That's why another customer is created. Use #Observes(notifyObserver = Reception.IF_EXISTS) to only notify existing instances that are in service.
I thought SessionScoped ManagedBeans are like Singleton for the Session?
No, it just defines the lifetime of the object(s). It doesn't really enforce session-singleton behavior. The container would probably prefer the existing instance though, if it was in service at the time the second event is fired.
I am currently using the Owasp ESAPI to manage authentication in my java web application, and I am injecting the Singleton MyAuthenticator with guice.injectMembers(this). I would like to step away from this approach and use a guice-created Singleton-Scoped object. I liked the thread-safety of the ESAPI singleton, and the safety of singletons in general, using Double-Checked Locking, IODH Idiom, or Bloch's Enum INSTANCE style.
What do I need to do to my Guicified Singleton-Scoped Authenticator to make it thread-safe, as well as the ThreadLocal field I am using to get and set my current User?
I would like to make the entire application work with dependency-injection, but don't want it to break upon web-app concurrent access. Any suggestions or common pitfalls?
The ThreadLocal object I am using looks like the code below:
private final ThreadLocalUser currentUser = new ThreadLocalUser();
private class ThreadLocalUser extends InheritableThreadLocal<User> {
#Override
public User initialValue() {
return User.ANONYMOUS;
}
public User getUser() {
return super.get();
}
public void setUser(User newUser) {
super.set(newUser);
}
}
Unfortunately I don't know enough about Owasp ESAPI to give a specific answer, but you may have some luck looking into Guice's AOP support. You can intercept all method invocations on the class and provide whatever concurrency behavior you like.
http://code.google.com/p/google-guice/wiki/AOP
Beware using the "Double-Check Locking" pattern in Java. This design pattern doesn't reliably work in Java (for instance, see http://www.cs.umd.edu/~pugh/java/memoryModel/DoubleCheckedLocking.html) unless you declare the singleton instance as "volatile".
What is a JavaBean and why do I need it? Since I can create all apps with the class and interface structure? Why do I need beans? And can you give me some examples where beans are essential instead of classes and interfaces?
Please explain the essentiality of a bean in the below context:
Wep apps
Standalone apps
They often just represent real world data. Here's a simple example of a Javabean:
public class User implements java.io.Serializable {
// Properties.
private Long id;
private String name;
private Date birthdate;
// Getters.
public Long getId() { return id; }
public String getName() { return name; }
public Date getBirthdate() { return birthdate; }
// Setters.
public void setId(Long id) { this.id = id; }
public void setName(String name) { this.name = name; }
public void setBirthdate(Date birthdate) { this.birthdate = birthdate; }
// Important java.lang.Object overrides.
public boolean equals(Object other) {
return (other instanceof User) && (id != null) ? id.equals(((User) other).id) : (other == this);
}
public int hashCode() {
return (id != null) ? (getClass().hashCode() + id.hashCode()) : super.hashCode();
}
public String toString() {
return String.format("User[id=%d,name=%s,birthdate=%d]", id, name, birthdate);
}
}
Implementing Serializable is not per se mandatory, but very useful if you'd like to be able to persist or transfer Javabeans outside Java's memory, e.g. in harddisk or over network.
In for example a DAO class you can use it to create a list of users wherein you store the data of the user table in the database:
List<User> users = new ArrayList<User>();
while (resultSet.next()) {
User user = new User();
user.setId(resultSet.getLong("id"));
user.setName(resultSet.getString("name"));
user.setBirthdate(resultSet.getDate("birthdate"));
users.add(user);
}
return users;
In for example a Servlet class you can use it to transfer data from the database to the UI:
protected void doGet(HttpServletRequest request, HttpServletResponse response) {
List<User> users = userDAO.list();
request.setAttribute("users", users);
request.getRequestDispatcher("users.jsp").forward(request, response);
}
In for example a JSP page you can access it by EL, which follows the Javabean conventions, to display the data:
<table>
<tr>
<th>ID</th>
<th>Name</th>
<th>Birthdate</th>
</tr>
<c:forEach items="${users}" var="user">
<tr>
<td>${user.id}</td>
<td><c:out value="${user.name}" /></td>
<td><fmt:formatDate value="${user.birthdate}" pattern="yyyy-MM-dd" /></td>
</tr>
</c:forEach>
</table>
Does it make sense? You see, it's kind of a convention which you can use everywhere to store, transfer and access data.
See also:
JavaBeans specification
Beans themselves
JavaBeans are everywhere, they're a convention and just about every single slightly larger library out there uses those conventions to automate things. Just a few reasons why JavaBeans should be used:
They serialize nicely.
Can be instantiated using reflection.
Can otherwise be controlled using reflection very easily.
Good for encapsulating actual data from business code.
Common conventions mean anyone can use your beans AND YOU CAN USE EVERYONE ELSE'S BEANS without any kind of documentation/manual easily and in consistent manner.
Very close to POJOs which actually means even more interoperability between distinct parts of the system.
Also there's of course Enterprise JavaBeans which are a whole another matter and shouldn't be mixed with plain JavaBeans. I just wanted to mention EJB:s because the names are similar and it's easy to get those two confused.
Beans in web applications
If you consider "normal" JavaBeans in web app context, they make more sense than wearing shoes in your legs. Since the Servlet specification requires for sessions to be serializable, it means you should store your data in session as something that's serializable - why not make it a bean then! Just throw your SomeBusinessDataBean into the session and you're good to go, laughably easy, specification-compliant and convenient.
Also transferring that data around the application is easy too since JavaBeans help you to decouple parts of your application completely. Think JavaBeans as a letter and various subsystems of the application as departments within a very large corporation: Dept.A mails a bunch of data to Dept.B, Dept.B doesn't know -or even care- where the data came from just as it should be and can just open the letter, read stuff from it and do its thing based on that data.
Beans in standalone applications
Actually what's above applies to standalone apps too, the only difference is that you can mess up with the UI a bit more since standalone applications have stateful UI:s while web applications have statelss UI:s which in some cases only simulate stateful UI:s. Because of this difference, it's easier to make a mess with standalone application but that's worth a whole another topic and isn't directly related to JavaBeans at all.
A bean is nothing much, really. For a class to be a "bean", all it requires is:
to have a public, no argument constructor
to be serializable (to implement the Serializable interface, either directly or through one of its super classes).
To that, you can add getters and setters for properties of the class that conform to a specific naming convention if you want the fields to be discoverable in certain circumstances (e.g. making that class some object you can drag and drop from a visual editor in your IDE, for example).
You can find more directly from Sun here.
A Java Bean is a software component that has been designed to be reusable in a variety of different environments. There is no restriction on the capability of a Bean. It may perform a simple function, such as checking the spelling of a document, or a complex function, such as forecasting the performance of a stock portfolio. A Bean may be visible to an end user. One example of this is a button on a graphical user interface. A Bean may also be invisible to a user. Software to decode a stream of multimedia information in real time is an example of this type of building block. Finally, a Bean may be designed to work autonomously on a user's workstation or to work in cooperation with a set of other distributed components. Software to generate a pie chart from a set of data points is an example of a Bean that can execute locally. However, a Bean that provides real-time price information from a stock or commodities exchange would need to work in cooperation with other distributed software to obtain its data.
We will see shortly what specific changes a software developer must make to a class so that it is usable as a Java Bean. However, one of the goals of the Java designers was to make it easy to use this technology. Therefore, the code changes are minimal.
Advantages of Java Beans
A software component architecture provides standard mechanisms to deal with software building blocks. The following list enumerates some of the specific benefits that Java technology provides for a component developer:
A Bean obtains all the benefits of Java's "write-once, run-anywhere" paradigm.
The properties, events, and methods of a Bean that are exposed to an application
builder tool can be controlled.
A Bean may be designed to operate correctly in different locales, which makes it
useful in global markets.
Auxiliary software can be provided to help a person configure a Bean. This software is
only needed when the design-time parameters for that component are being set. It
does not need to be included in the run-time environment.
The configuration settings of a Bean can be saved in persistent storage and restored
at a later time.
A Bean may register to receive events from other objects and can generate events that
are sent to other objects.
Here's a simple example of a Javabean:
public class MyBean implements java.io.Serializable
{
protected int theValue;
public MyBean()
{
}
public void setMyValue(int newValue)
{
theValue = newValue;
}
public int getMyValue()
{
return theValue;
}
}
This is a real Bean named MyBean that has state (the variable theValue) that will automatically be saved and restored by the JavaBeans persistence mechanism, and it has a property named MyValue that is usable by a visual programming environment. This Bean doesn't have any visual representation, but that isn't a requirement for a JavaBean component.