Java EE Notes
Here are some notes I made during a Java Enterprise Edition course I recently completed.
- Interface, not implementation.
- Container runs various applications and manages the communication between them. Never communicate directly with an app, ask container to communicate for you.
- Container masks request details, converts to http request to servlet.
- Everyone imlements the standard (to be certified as Java EE server), some add extra things to it.
- Glassfish – reference, first on the market with new editions, nothing special/extra. "Vanilla".
- IBM Websphere – extensible, configurable, can do everything, complex to configure/administer.
- Oracle Weblogic – user friendly, easy to configure, GUI.
- Apache Tomcat – not full implementation of standard. Just web bits, like servlets. Really fast.
- JBOSS – relatively vanilla, more robust than Glassfish.
EE Server Components
- Many more
- Reusability – share between applications.
- Stateful session bean
- Stateless session bean
- Message driven bean
- Entity EJB (deprecated)
Servlet 3.0 Annotations
- Web.xml optional. Annotations can be used instead.
- Annotations require recompilation to change.
- Web.xml overrides annotations in case of conflict.
- The annotation @WebServlet defines a servlet.
EJB Interface Annotations and Options
- Many options are offered in EJB 3.1.
- @Local dictates local EJB interface.
- @Remote dictates remote EJB interface.
- @LocalBean means expose the bean itself.
- @Implements(TheInterface.class) (or something like that) on the bean itself is equivalent to putting an @Local annotation on the interface in question. It means the ejb libraries are not necessary to compile or work with the interface.
- An EJB can be injected with @EJB and any interface that it implements, even if the interface is not annotated. Obviously, it is problematic to use an interface which many EJBs implement because the server won't know which EJB to inject.
- Basically any combination of these annotations is possible, even ones which don't make a lot of sense, based on convention over configuration.
EJB Passing by Reference / Copy
Parameters are pasesd by copy to remote beans but by reference to local beans. It's best not to modify the parameters passed in, otherwise one can end up with different behaviour when calling the local and calling the remote interface.
- Server creates EJB whenever it wants, runs no-argument constructor. Don't use this constructor for business logic or EJB-dependent things.
- Generally EJB built only when it's actually called. Directly after it's built, the method annotated with @PostConstruct is called. Here you can put EJB-dependent logic.
- Stateful bean can be “passivated”, which means serialized to storage, in order to liberate space. There are annotations to hook into pre- and post. During standard Java deserialisation, the constructor of the class is not run. However in EJBs the class constructor is run during deserialisation.
- @Singletons can have an annotation @Startup which causes them to be created and decorated with EJB methods at startup, that is, keenly instead of lazily.
- The spec says that one @Singleton should be created per JVM. This means that if you have a cluster, there will be multiple Singletons created and each one will run its PostConstruct method.
- Ejb must be deployed in jars
- Servlets must be deployed in wars
- These two can be combined in an ear to be recognised by the server as one application.
- However, as of EJB 3.1, you can deploy everything in one war.
- Simplest method: Simply adding the @Asynchronous annotation (3.1 only) to a method causes the method to execute asynchronously. It must return void.
- Callbacks: have @Asynchronous-annotated method return Future<V>. E.g. if method returns Future<String>, return new AsyncResult<String>(“hello”);.
- Be careful with stateful and stateless and asynchronicity. If there are two calls where one call depends on the other, you must use stateful. But the second will block.
- Get access to send messages via a ConnectionFactory.
- Receive messages in a message driven bean.
Message Driven Beans
- In 3.0, Message Driven Beans are the only way to do tasks asynchronously, as the @asynchronous annotation doesn't exist.
Timers and Calendars
- Inject TimerService with @Resource. Since there's only one object of TimerService in JNDI, no further identification is needed.
- Needs to be an EJB to allow injection of TimerService.
- Timers can be created and stopped in code (as opposed to schedules)
- Any EJB annotated with @Timeout will trigger when any timer expires. You have to manually compare objects to see if this is the one you want to react to.
Calendars / Schedules
- Schedule is basically a way to execute a method according to a cron schedule.
- @Schedule(“xyz”) where xyz represents a cron-type expression, though syntax differs.
- Needs to be an EJB to allow injection of Schedule.
- Calendars (@Schedule) require recompilation to modify.
Injection Annotation Syntax
- @EJB for an EJB
- @Resource for a resource
- @Inject for a declared using CDI
CDI - Context and Dependency Injection
- Requires a file called beans.xml in WEB-INF. It doesn't necessarily need content if you're going to use annotations.
- Like EJB, you don't need setters for the recipients of the injection.
- Annotate bean with @RequestScoped, @SessionScoped, @ApplicationScoped (or more).
- Annotate recipient field with @Inject.
- @Named annotation causes the bean to be available in EL with its class name.
- @SessionScoped annotation requires the bean to be serializable, since sessions have to be serializable.
- If there are two objects that could be used to fulfill an injection contract, i.e. to be injected, you create your own “qualifier” annotation and then annotate the injection target and the injected object with this qualifier. Any object that doesn't have a qualifier is considered to have the default one.
- Fields can be injected (instead of objects). The source can be annotated with @Produces and the recipient with @Inject. The source might be a method which produces the field as a result. Any @Produces which returns the same type as the @Inject will match, so you'll probably need qualifiers to distinguish the correct one.
- If you inject objects into servlets, since there is only one servlet for everyone, make sure to inject factories, not instances, since they are shared.
JSF - Java Server Faces
- Part of JavaEE standard
- @ConversationScoped is a way to do "web flow". You can only have one conversation active at a time, so it's sort of like a "mini-session".
- Using CDI you can prototype reasonably quickly.
- Convenient, flexible.
- Problem: keeps all control on server-side. Uses lots of session memory. Slow and scales badly.
- Hibernate is an implementation.
- JPA is a standard, an interface. This is its greatest disadvantage, like the Java EE standard as a whole. It can't be as specific as Hibernate can be.
- Before JPA there were EntityBeans. These were designed before reflection was invented/robust, and were incredibly complex.
Inheritance Mapping Strategies
Fastest and simplest but you can't implement DB-level restrictions which differ between the classes, e.g. you can't make a field mandatory in a subclass if that field doesn't exist in the parent.
Flexibility, stucture duplicated, possible consistency issues (ensure id not duplicated, etc). Join required for all selects.
Table Per Class
Flexibility, stucture duplicated, possible consistency issues (ensure id not duplicated, etc). Join select and union required for selected superclass. Selecting subclases is only one select though.
There was heaps of info about JPA and excercises but I didn't take any notes because it's all basically the same as what I learned working with Hibernate and Grails, just with a different syntax sometimes. Often a much more complicated syntax.
- Not part of JavaEE but we covered it because it's interesting as the competition to JPA. Main reason to use it instead of JPA is performance and absolute control over SQL.
- Daos are only created as interfaces and XML configuration files provide the implementation.
- Realm – a series of users, groups etc.
- Application – declares relations between users, groups etc. Exact way of mapping roles to groups differs between application servers.
- Methods or entire classes can be annotated with @RolesAllowed(“...”) to limit which roles are allowed to access it. You can also use XML.
- When access is denied an Exception is thrown. You can catch the exception and deal with it – e.g. redirect to login page.