Guys, I HAVE tried reading tons of stuff about EJB. And I don't get it. It seems that most of the authors have a superficial knowledge on it. They basically say it's the business-logic 'stuff'. They don't show it how it interacts with the AppServer and so on, what it does, how, and why?
It is a huge question, but not that huge. It is not like asking what is physics. You basically run your business code inside container which is handling all the connections, lookup, transactions etc. There are alternatives to ejb, e.g. spring.
The question is huge indeed. EJBs in a general sense try to enforce a design pattern that encapsulates all of your reusable code or "business logic" into a specific tier in your architecture. By doing this you can reuse this code for your web/presentation layer and web services for example. EJBs provide a way of persisting your data to a DB.
The trend in java development now a days is POJO driven architectures that leverage dependency injection. Spring is a popular tool to facilitate this design pattern and I would encourage you to explore this instead of EJB.
an enterprise bean is a server-side component that
encapsulates the business logic of an application. The business logic is the code that fulfills the
purpose of the application. In an inventory control application, for example, the enterprise
beans might implement the business logic in methods called checkInventoryLevel and
orderProduct. By invoking these methods, clients can access the inventory services provided
by the application.
Related
I was reading a topic about good practices on web development with Java and found that it is a bad practice to call the DAO from a Servlet. The topic itself did not explained why this is a bad practice, although it clearly explains that, following the best practices, we need a intermediate class (eg.: a service class) to call the DAO.
Why is this a bad practice? Is there any theorical and / or technical explanation to this?
The answer is for the sake of usability.
DAOs resolve access to database objects.
Servlets must be used merely as a facade to handle remote requests and responses (typically HTTP).
Servlets are aimed to do the parsing/formatting of parameters; but they must not know anything about business logic.
So, an intermediate level of business logic classes is necessary between servlets and DAOs. Classes from this level must know the business rules, the database schema and how to use it. This business logic must not be coupled to any deployment schema, so it can be used (and reused) from a number of facades:
servlets/jsps,
swing guis,
spring controllers,
Ant tasks,
etc.
I have been reading the book Spring in Action for a few weeks now to learn about the spring framework. I have about 2 years of programming experience mostly in java with some distractions here and there in Ruby and Python.
After reading the first few chapters, I didn't quite get what the big deal is about dependency injection in spring. I was expecting a AHAAA moment but didn't quite experience that yet. I'm sure I'm missing something important.
Why would I want to wire my beans in xml rather than instantiating them the good old way with the = new myclass();
I understand I can wire beans in the xml via constructor args and properties as well as configure datasources in spring so that I can hide away connection details in an xml file. But why? There is more to this especially when it comes to good software design. Can some one explain the big deal?
Three Words: INVERSION OF CONTROL
In a nutshell:
As soon as you instantaniate "the good old way" you create tight coupling, e.g.: your controller depends on a specific template engine, your entities on a concrete database layer, etc. And that's something you want to prevent and where the dependency injection container (DIC) comes in very handy. It manages your services and you don't really have to care anymore about specific implementations as long as those implement the same interface.
Imagine a simple storage layer class called InMemoryLayer that gets instantiated by you when need it. Now you want to switch it for an awesome new open-source github solution called SuperSecretRemoteCloudLayer. Normally you would now hit "Search and Replace" in your IDE of choice and replace all occurrences of InMemoryLayer with the SuperSecretRemoteCloudLayer. But that's not really handy and quite errorprone, why would you want to do all that hard work by hand? The DIC can do that for you and all you need to take care of, is that both *Layer implement the same interface (so your application won't break).
Spring's big deal is more about dependency injection, not XML-based configuration. As others have noted, Spring has been moving away from XML-based configuration. But DI is core to Spring.
The a-ha is that DI offers a different model for linking components together. Instead of components creating each other directly (and thus being tightly coupled), the components stop doing that, and you inject the linkages from a central location. It turns out that this helps with testing and transaction management in particular.
You don't truly appreciate Spring until you've had to do things the hard way. The hard way being maintaining multiple large projects without a coherent framework. If you have 4 big enterprise wide applications that all have their own way of starting themselves, and managing resources, you're in for a headache. If you know that each application uses spring, then just look for the application context xml! This also makes it incredibly easy to setup a new context for different environments, and test cases, all without mucking up your code base.
Haven't used EJB3, but by reading a tutorial, EJB3 looks like mostly for manipulating data in database through JPA (of course, it contains other business logic). Just curious, if no database is quired, is it still beneficial to use EJB3 or it just adds complexity to an application? Will POJO be a better choice for implementation?
Big part of EJB benefits is coming from transactions and persistence.
But even without them you may benefit from EJBs. It can give you a proven clustering and balancing model. It can give you the declarative security. It can give you MDBs which are a convenient way to listen to JMS queues/topics and timers.
All above can be done using third-party libraries, such as Spring. EJBs though are highly consistent, while to get, for instance, clustering and security you may need to combine two products, and it's not guaranteed they will work together well and won't need much glue.
EJBs are transactional, distributed components deployed on an app server that manages lifecycle, threading, and other services. Persistence is just one type of EJBs. You still might find stateless, stateful, or message EJBs useful, even if you don't want to use entity beans.
With that said, you can create POJO components that are stateful, stateless, persistent or message-driven. You don't need EJBs; something like Spring can be a good alternative.
I am currently struggling with whether or not I've achieved a good level of separation, or if I've missed the point somewhere, as I am relatively new to learning the disciplined side of development...
My goal when I started was to create a layer that was agnostic of any persistence mechanism - I called this data-api. I then implemented these interfaces using JDO, and called this project data-jdo. The logic layer ideally talks only is aware of data-api.
This is the point where I'm not sure what makes sense. The business logic layer has to be invoked somehow, right? So is the expectation that the implementation of the data-api (data-jdo, or something else depending on experimentation) is provided (appropriate to say/do injected?) by the invoker?
So the goal would be to (largely for experience and not for productivity) maybe, implement a data-jpa package that could be substituted in place of data-jdo. So the topmost layer (a web service, generic main method as part of a tool, unit tests, whatever) are the ones to make the choice which implementation to use.
Should I be using some framework like Spring to allow me to choose which implementation of my data-api is used, via XML?
Sorry if that's a little vague... I guess the root question is, at what point does the consumer of an API depend on, supply, or become paired with, the implementation of that API? If the answer is or should be "never" then what is used to make sure everything is available at runtime and how does the consumer get an instance of whatever the "API" is describing with only interfaces?
I come from a .net background - not a Java one, so I'm afraid I can't help you with Java specifics.
The business logic layer has to be invoked somehow, right? So is the expectation that the implementation of the data-api (data-jdo, or something else depending on experimentation) is provided (appropriate to say/do injected?) by the invoker?
Yes. In the .Net world I use a Factory (as in an instance of the Factory Pattern) that dynamically returns the data provider implementation (which one of those to use is set by config). The data provider is returned by the factory as an 'object' and it's up to the calling business logic code to cast it to the correct type - as specificed by the interface that the business logic is working against.
I'v egot (another!) article on Dependency Injection for .Net which might help explain with some of the issues, but I'm sure there are good java based ones around somewhere.
Should I be using some framework like Spring to allow me to choose which implementation of my data-api is used, via XML?
Probably. I'd say spend your time getting to grips with the concepts first, worry about "best practice" after that. FYI, I learnt AJAX the hard way - by writting all the code myself. These days I'd run straight to a good framework, but I only think I have the confidence to do that after having really grokked the basics by doing some hard graft at the coal-face :)
... If the answer is or should be "never" then what...
Yeah - it's never. Use a Factory.
Your data-api is a DAO interface layer, that's all your business (aka service) layer should know about persistence. And the presentation layer or any other layer above the business layer shouldn't have any "knowledge" of the DAO layer underneath.
To achieve that, relying on a framework like Spring is a good idea. The top level layer loads an application context which contains all the information for the framework to load the appropriate implementation.
For example, you could load applicationContext.xml from the front-end to use data-jdo, and load testApplicationContext.xml from the unit tests to use data-jpa.
I'm wondering if anyone has any experience in "isolating" framework objects from each other (Spring, Hibernate, Struts). I'm beginning to see design "problems" where an object from one framework gets used in another object from a different framework. My fear is we're creating tightly coupled objects.
For instance, I have an application where we have a DynaActionForm with several attributes...one of which is a POJO generated by the Hibernate Tools. This POJO gets used everywhere...the JSP populates data to it, the Struts Action sends it down to a Service Layer, the DAO will persist it...ack!
Now, imagine that someone decides to do a little refactoring on that POJO...so that means the JSP, Action, Service, DAO all needs to be updated...which is kind of painful...There has got to be a better way?!
There's a book called Core J2EE Patterns: Best Practices and Design Strategies (2nd Edition)...is this worth a look? I don't believe it touches on any specific frameworks, but it looks like it might give some insight on how to properly layer the application...
Thanks!
For instance, I have an application where we have a DynaActionForm with several attributes...one of which is a POJO generated by the Hibernate Tools. This POJO gets used everywhere...the JSP populates data to it, the Struts Action sends it down to a Service Layer, the DAO will persist it...ack!
To me, there is nothing wrong with having Domain Objects as a "transveral" layer in a web application (after all, you want their state to go from the database to the UI and I don't see the need to map them into intermediate structures):
Now, imagine that someone decides to do a little refactoring on that POJO...so that means the JSP, Action, Service, DAO all needs to be updated...which is kind of painful...There has got to be a better way?!
Sure, you could read "Beans" from the database at the DAO layer level, map them into "Domain Objects" at the service layer and map the Domain Objects into "Value Objects" for the presentation layer and you would have very low coupling. But then you'll realize that:
Adding a column in a database usually means adding some information on the view and vice-versa.
Duplication of objects and mappings are extremely painful to do and to maintain.
And you'll forget this idea.
There's a book called Core J2EE Patterns: Best Practices and Design Strategies (2nd Edition)...is this worth a look? I don't believe it touches on any specific frameworks, but it looks like it might give some insight on how to properly layer the application...
This book was a "showcase" of how to implement (over engineered) applications using the whole J2EE stack (with EJB 2.x) and has somehow always been considered as too complicated (too much patterns). On top of that, it is today clearly outdated. So it is interesting but must be taken with a giant grain of salt.
In other words, I wouldn't recommend that book (at least certainly not as state of the art). Instead, have a look at Real World Java EE Patterns - Rethinking Best Practices (see Chapter 3 - Mapping of the Core J2EE patterns into Java EE) and/or the Spring literature if you are not using Java EE.
First, avoid Struts 1. Having to extend a framework class (like DynaActionForm) is one of the reasons this framework is no longer a good choice.
You don't use spring classes in the usual scenarios. Spring is non-invasive - it just wires your objects. You depend on it only if using some interfaces like ApplicationContextAware, or if you are using the hibernate or jdbc extensions. Using these extensions together with hibernate/jdbc completely fine and it is not an undesired coupling.
Update: If you are forced to work with Struts 1 (honestly, try negotiating for Struts 2, Struts 1 is obsolete!), the usual way to go was to create a copy of the Form class, that contained the exact same fields, but did not extend the framework class. There would be a factory method that takes the form class and returns the simple POJO. This is duplication of code, but I've seen it in practice and is not that bad (compared to the use of Struts 1 :) )
I think your problem is not so big as it seems.
Let's imagine, what can you really change in your POJO:
1) name of its class: any IDE with refactoring support will automatically make all necessary changes for you
2) add some field/method: it almost always means adding new functionality what is always should be done manually and carefully. It usually cause to some changes in your service layer, very seldom in DAO, and usually in your view (jsp).
3) change methods implementation: with good design this should cause any changes in other classes.
That's all, imho.
Make a decision about technology for implementing busyness-logic (EJB or Spring) and use its facilities of dependency injection. Using DI will make different parts of your program communicate to each other through interfaces. It should be enough for reaching necessary (small enough) level of coupling.
It's always nice to keep things clear if you can and separate the layers etc. But don't go overboard. I've seen systems where the developers were so intent on strictly adhering to their adopted patterns and practices that they ended up with a system worse than the imaginary one they were trying to avoid.
The art of good design is understanding the good practices and patterns, knowing when and how to apply them, but also knowing when it's appropriate to break or ignore them.
So take a good look at how you can achieve what you are after, read up on the patterns. Then do a trial on a separate proof of concept or a small part of your system to see your ideas in practice. My experience is that only once you actually put some code in place, do you really see the pros and cons of the idea. Once you have done that, you will be able to make an informed decision about what you will or will not introduce.
Finally, it's possible to build a system which does handle all the issues you are concerned about, but be pragmatic - is each goal you are attempting to reach worth the extra code and APIs you will have to introduce to reach it.
I'd say that Core J2EE Patterns: Best Practices and Design Strategies (2nd Edition) addresses EJB 2.0 concerns, some of which would be considered anti-patterns today. Knowledge is never wasted, but I wouldn't make this my first choice.
The problem is that it's impossible to decouple all the layers. Refactoring the POJO means modifying the problem you're solving, so all the layers DO have to be modified. There's no way around that.
Pure decoupling of layers that have no knowledge of each other requires a lot of duplication, translation, and mapping to occur. Don't fall for the idea that loose coupling means this work goes away.
One thing you can do is have a service layer that's expressed in terms of XML requests and responses. It forces you to map the XML to objects on the service side, but it does decouple the UI from the rest.