I want to make some file operations (copy) in stateless EJB Method. I know about not recommndig to do it. But it could be possible for some special EJB implementation. What is the best thing for Wildfly ?
EDIT Some disturbing old links:
"Sun blueprint: EJB Restrictions"
EJB Bad Practices: Use of Java I/O
Stackoverflow
What is the best thing for Wildfly ?
Just doing the file operation (seriously). It's not as-if there's a security manager installed to prevent you from doing this.
And a stateless EJB is not different from many other types of methods in beans in Java EE. It's not the case, as some people think, that it's not allowed in EJB methods but is allowed in CDI bean methods. This is simply not the case.
There's some old information out there, where the spec said that "EJB was not allowed to". But what was actually meant is that Java EE was not allowed to. At the time EJB was seen as equivalent to Java EE, so that's the origin of this wide spread confusion.
Later this myth was starting a life of its own where people dreamed up scenarios where it was supposedly allowed to do IO in Servlets, but not from an EJB, so they designed all kinds of crazy architectures to delegate IO (or threading, another favorite) from an EJB to a Servlet. Absolutely ludicrous!
The restriction (as mentioned above, intended for the whole of Java EE, not just EJB) was also put in too eagerly. There's simply no reason to absolutely forbid it.
Some of the answers that you quote are more retroactive reasons. People just make up reasons for a rule to somehow justify their world, even though the reason and the rule don't match.
For this reason, the rule has been removed from the EJB spec.
That's right, in the current EJB spec you will not longer find that it's forbidden to use IO from an EJB (which, again, never meant to say "EJB", but should be read as "Java EE").
See:
https://blogs.oracle.com/marina/entry/ejb_3_2_news
https://blogs.oracle.com/arungupta/entry/what_s_new_in_ejb
Of course, as with many things, you may or may not have to be cautious when using IO, but this is completely unrelated to Java EE or EJB and holds for almost any application, and is more dependent on the kind of IO, the kind of application you're coding and your situation.
Two small extreme examples:
Your very own personal Java EE application of which you are the only developer that you installed at home on your raspberry pi and that reads a small configuration file at startup from an external location -> pretty much always okay.
Large clustered enterprise application being developed by many different teams, integrated separately, deployed separately, highly transactional that wants to write temporary data to a filesystem but that has to be cleanedup again when the transaction ends -> likely not such a good idea.
Between those two that are literally an infinite amount of variations. We had for example a larger enterprise application that did IO to an external folder from a Singleton in a very controlled and specific way. The app served millions of users under intense load and there was never a problem with the IO. So even "enterprise" and "transactional" do not necessarily have to mean "no IO". It really depends.
Related
In order to favor certain service implementations over others, I wrote a customizable version of java.util.ServiceLoader (adds priority and enabled/disabled flag to implementations via preference files for non-OSGi code).
The client was pleased and wanted the same customization for OSGi service implementations.
The devised solution is based on calling getServiceReferences(Class<S> clazz, String filter) on BundleContext and uses a null filter to retrieve all implementations.
Nevertheless, fiddling around with OSGi on such a low level leaves a bad taste. There's much boilerplate code (e.g. mandatory subtypes of BundleActivator) and the used approach will also hinder an smooth upgrade to declarative services and some point in time.
I also read about the SERVICE_RANKING property, but compared to the preference files from the approach above, it has the drawback that each implementation sets its own ranking property and it's not possible to change the ranking afterwards.
So my question is: What are good arguments against this low-level approach? Why should declarative services be used instead?
At the core OSGi is a dynamic environment. Bundles and services can come and go at every moment (theoretically). So the only way to cope with this environment is to react on changes compared to waiting for something to happen.
For example a declarative services component will come up once all its mandatory services are present and will vanish if one goes away.
A solution based on service loader or similar will actively get the services that are available if such a service is mandatory then you will have to block until it is available. This can easily lead to deadlocks in the application.
Of course in practice the application is normally not so dynamic. In most cases this only affects the startup of the application. So in many cases the blocking behaviour can work but it will produce an application that is inherently fragile.
On the other hand if you have the problem that your application needs to run inside and outside of OSGi then DS is problematic as it relies on OSGi to be present.
Typical examples are Aapache CXF and Apache Camel. Both do not use DS and instead invented different abstractions for usage in OSGi and both sometimes have problems in OSGi exactly because of this. Still it would be difficult to improve this as they need to work outside of OSGi too.
If JPA does not depend on EJB and it has its own spec. Why do I need EJB ?
What I cannot without EJB ?
I have read the following discussions but I really do not point out why it is still required ?
Why should we use EJB?
https://stackoverflow.com/questions/4464338/why-ejb-is-used-in-enterprise-applications
All of the above answers add important information to the question but misses on one critical point. The main selling point of EJB architecture was distributed component (apart from all
other services such as container managed,transactional, secure etc.). The idea was to enable the business logic to run in distributed environment piggybacking on RMI/IIOP. Although over the years this architectural style proved bad. For distributed computing there were more successfull architecture based on webservices. Distributed components though were made look easy by EJB, had their own share of inherent complexities and performance woes and were later avoided whenever possible. An old but very interesting read on this matter by Martin Fowler can be read here where he is scathing in his attack on the lure of distributed architecture typically being promoted by the likes of EJB. Later people seems to have followed this wisdom and avoided the temptation to jump onto the "distributed architecture" bandwagon. In Java landscape, this was marked by the rise of Spring framework and Rod Johnson's famous book "Expert One-on-One J2EE Development without EJB". People and the likes of me have never missed EJB's since then :-)
P.S. To be fair to EJB specs and the guys working hard on it to improve, they certainly have made fair progress in the past decade and they are much modern and developer friendly. However their "distributed" nature has taken a back seat for good
EJB is just a server side component that servers the request of the user. Each enterprise bean runs in a container which do some maintenance (transaction management, security management, bean life cycle etc.,) on behalf of the user/programmer. Thus it makes the developer to focus on the core job instead of reinventing all alone.
So we can conclude that EJB just reduces the amount of coding done by programmer and let the programmer to focus on the core business logic.
We can do the same without EJBs with some good amount of coding.
Thanks,
JK
EJBs, or enterprise java beans are java classes that can be managed by Java EE container that guarantees services like
bean life cycle
thread management
transaction management etc
Yes, JPA is not a part of Java EE spec now. It moved to JSE. However in past when Entity Beans provided the "standard" bridge between java and relational databases world.
What you cannot do without EJB? I'd say nothing. I mean you can do everything without EJB. And the reason is that there are alternative solutions like Spring or Guice.
And as always you can write lower level code without any framework.
Let me preface this by saying this is not an actual situation of mine but I'm asking this question more for my own knowledge and to get other people's inputs here.
I've used both Spring and EJB3/JBoss, and for the smaller types of applications I've built, Spring (+Tomcat when needed) has been much simpler to use. However, when scaling up to larger applications that require things like load balancing and clustering, is Spring still a viable solution? Or is it time to turn to a solution like EJB3/JBoss when you start to get big enough to need that? I'm not sure if I've scoped the problem well enough to get a good answer, so please let me know.
Thanks,
Jeff
Tomcat can be clustered.
Load balancing is usually a hardware solution (e.g., a BigIP or Cisco ACE) that's independent of app server.
Spring can be enterprise, just like EJB. There's no dividing line that says Spring can't handle it.
I could say that in our project which quite large (~500K LOC) we've got rid of JBoss in favour of Spring/Tomcat for a performance sake.
One of J2EE Application container (and JBoss, as an implementation) key features is a possibility of transparent distributed transactions among different kind of transactional resources. That is great idea and it simplifies coordination of, let's say, JMS messenging and database operations a lot. But when it comes to a necessity of high throughout it becomes a problem. Unfortunately, distributed transactions are notable for its slow speed.
It isn't an easy task to migrate from JBoss to Spring, however it's possible and Spring/Tomcat could be considered, with quite rare exceptions, as fully functional replacement for JBoss.
I'm just implementing a JavaEE assignment I was given on an interview.
I have some prior experience with EJB, but nothing related to JMS and MDBs. So here's what I find through the numerous examples:
application servers bind their topics and queues to different JNDI names - for example topic/queue, jms
the activationConfig property is required on JBoss, while in the Sun tutorial it is not.
after starting my application, jboss warns me that my topic isn't bound (it isn't actually - I haven't bound it, but I expect it to be bound automatically - in fact, in an example for JBoss 4.0 automatic binding does seem to happen). A suggested solution is to map it in some jboss files or even use jboss-specific annotations.
This might be just JBoss, but since it is certified to implement to spec, it appears the spec doesn't specify these these things. And there all the alleged portability vanishes.
So I wonder - how come it is claimed that JavaEE is portable and you can take an ear and deploy it on another application server and it magically runs, if such extremely basic things don't appear to be portable at all.
P.S. sorry for the rant, but I'm assume I might be doing/getting something wrong, so state your opinions.
Java EE, like (almost?) any standard, is something that implementers strive to advertise adherence to but desperately don't want to adhere to.
Consider this question: how does Red hat make money? By giving things away or by selling them? If the code you wrote could be easily transferred to another Java EE application server, this would interfere with them making money from you. The solution to this is the venerable "embrace and extend" technique that has been attributed to Microsoft but in reality has been the tool of choice for commercial software vendors since the first standard was published.
If you stick strictly to the Java EE APIs in your code then JBoss (or Geronimo (or JonAS (or ...))) will run it as well as any other compliant application server with the only changes being required in the server-specific deployment descriptors. This is the embrace stage.
Each server -- the commercial ones (like JBoss) in particular! -- also tends to add extra stuff to the API to "make things easier". (To be fair these often do make things easier.) Developers -- especially those not intimately familiar with the standard APIs -- frequently fall into the trap of relying on these extra APIs without wrapping them in any way, thus allowing these extensions to inundate their code to the point that they're difficult to remove should you wish to change platforms. This is the extend stage.
Name a standard from any point in software history and you'll find people embracing and extending (to the point that when people talk about "deadly embrace" I have to forcibly move my thoughts away from vendor lock-in problems to the proper terminology). You'll also find end-users (developer or otherwise) falling for it. Java EE is no different than any other technology in this regard.
Then you factor in just how badly-worded most specifications are and ...
Joel says "all non-trivial abstractions are, to some degree, leaky." I have found this to be very applicable to JavaEE. Consider that a JMS exception may be something transient such as a full queue. This is a typical fast-producer/slow-consumer problem and ideally the producer will throttle down to match the consumer's speed. But the error may also be fatal such as an authorization failure. In the first case retries eventually succeed (usually) whereas in the second case no amount of retry will help until humans intervene to fix the authorization failure.
So what do you do in your portable program to address this? One approach is to treat every JMS exception as fatal. Close all your objects and reinitialize the program. Sort of like killing a fly with a sledgehammer but very portable. Alternatively, you can check the JMS exception to see if it's a transient or fatal error and take some appropriate action. This is much more efficient but since the JMS exceptions are provider-specific it is hardly portable. Some of my clients have taken the approach of writing vendor-specific shims which catch JMS exceptions and do vendor-appropriate things with them so that the code can be "portable" (think: software equivalent of the Hardware Abstraction Layer).
And of course, this is just exception handling. Similar issues exist across the board. Consider reconnection details. Some transports bubble up a connection failure to the application or container. Some hide it away with the idea that the code should not need to know about this. But the reality is that virtually all messaging applications will need to provide an alert or log entry if the network is permanently down. You would not want the app to just hang forever if the network failed, right? So ultimately even an app running on a transport that provides transparent reconnect needs to code for connection failures. The specific features and behavior of the transport provider will leak up through the abstraction of JMS.
For my money, JavaEE makes the skills portable across transport providers. The application needs to be aware enough of the underlying transport provider to deal with the abstractions that bubble up to the surface. To the extent that you can avoid the leaks the app is portable, but no further.
That's just a partial answer but Java EE 6, more precisely EJB 3.1, finally specifies Portable Global JNDI Names. Prior to Java EE 6, JNDI naming wasn't standardized and each app server vendor was using its own rules which was indeed bad for portability (a kind of vendor lock in). Consequently, in the J2EE 1.4 world, if you wanted to ease the portability of your enterprise application it was necessary to implement various strategies, typically in your ServiceLocator class. The introduction of dependency injection in Java EE 5 reduced the need for lookups and somehow "improved" the portability but still, no standard for when JNDI lookups are needed and polyglot ServiceLocator are still required.
The core EE application can run unchanged. The external configuration is application server specific.
To transfer data from one system to another, through data interface, by web services, we normally get a result set by SQL query, and format them as a web service endpoint, and allow it to be retrieved by another side.
With EJB 3.0, it seems we can replace the result set by stateless session bean. So are there any advantages over the SQL-based web services? And when should we use it?
This is a very broad question on the system architect level. I will try to answer with my best knowledge without starting a flame war (FYI, I have used both ejb and spring).
As you know, building a stable/robust software application requires many building blocks, such as logging, connection pool, etc. Usually, you can find libraries of these building blocks, but not all of them have common api, so they may require integration. In the worst case, you may have to lock into some vendors. The main idea of EJB 3 (or Java EE) is to provide a more complete set of building blocks (via API, annotation or config), so developers can start working on the core business logic right away with an industry standard API/spec/config without training on the proprietary APIs. Additionally, you can change vendor without changing your codes since API/config are really the industry standard (well, your mileage may vary a lot in the real life. hopefully, the new Java EE will fix it).
Your application may already have some of the main elements that EJB 3 already provides. However, EJB 3 promises to provide more such as ORM mapping, RMI, Load balancing, failover, transactions, dynamic redeployment, logging, system management, thread managing, resource pooling (db connection), security, caching.
As you have an working application already, you can really consider if it is worth of your efford to migrate your codes to a standard system to gain more functionality vs integrate new functionality individually. Additionally, EJB 3.0 (or Java EE) is not really the framework that you can pick. You can also look into other framework, such as Spring.
My suggestion is to really figure what your system requirements, and then pick the right technologies instead of picking up the coolest technologies first.
Good luck