I've recently begun working with a large, legacy enterprise Java application. It's primarily built on Websphere Commerce 6. It contains a mix of EJB 1.x and 2.x along with quite a bit of code that hooks directly into the Commerce API.
I've introduced the first unit tests while attempting to break dependancies and carefully refactor small portions of the code. We've been exploring the idea of using an integration testing framework to make the process of creating tests less fragile and time consuming.
Arquillian has been suggested as a very good option for integration testing. However, it looks geared towards more "modern" applications; most of the examples make use of Java EE 5+ and Maven. We're using J2EE and Ant. We're also currently tied to Java 1.4, and while it may be possible for us to move to Java 5, we won't be upgrading to EJB 3.x any time soon. We're also likely to stick with Ant.
With these constraints in mind, is it possible to use Arquillian? Or do better alternatives exist for integration testing legacy enterprise Java applications?
Arquillian has been suggested as a very good option for integration testing. However, it looks geared towards more "modern" applications; most of the examples make use of Java EE 5+ and Maven. We're using J2EE and Ant. We're also currently tied to Java 1.4, and while it may be possible for us to move to Java 5, we won't be upgrading to EJB 3.x any time soon. We're also likely to stick with Ant.
With these constraints in mind, is it possible to use Arquillian?
Note: I'm an Arquillian contributor. I've tried to be unbiased in my answer.
This would really depend on how your tests are executed. If you are attempting to use Arquillian's support for in-container tests, then you're unlikely to find a solution. WebSphere Commerce 6 uses WebSphere 6.0 as the underlying container, which is not supported by Arquillian at the moment. If you can hypothetically use a version of WebSphere Commerce that uses WAS 7.0 or 8.0 as the foundation, then most of my answer can be ignored, since these containers are supported.
You can attempt to run tests from the client using the #RunAsClient annotation, instead of the container, and this is more likely to succeed. Note that, you'll need to perform the deployment in some manner without a #Deployment annotated method, because of the afore-mentioned absence of support for WAS 6 in Arquillian.
If you intend to use Ant instead of Maven, then the only requirement is that all dependencies be present in the classpath. Unfortunately, there is no uber JAR or distribution for Arquillian, so for now, you'll need to know all the dependencies upfront.
Note - Building in WebSphere 6.0 support for Arquillian may not be a trivial activity, as compared to other more recent containers:
Firstly, there have to be means for deploying the archive. I'm not sure if the mechanism used in WebSphere 7 and 8 container support can be ported over.
Supporting in-container tests in Arquillian for WAS 6.0 may require supporting the Servlet 2.4 protocol for running tests. Currently, Arquillian supports Servlet Spec 2.5 and 3.0 for packaging it's ServletTestRunner. This is of course, necessary if the JMX protocol and the accompanying JMXTestRunner cannot be used.
Or do better alternatives exist for integration testing legacy enterprise Java applications?
I would normally advise folks to use a mix of Cargo and JUnit for functional testing legacy apps, but even Cargo does not appear to support WebSphere 6.0.
You might find JUnitEE to be a better fit for your needs if you are willing to package the JUnitEE TestRunner in your archive; note that JUnitEE's last release was in 2004, and the mailing list is a bit inactive, so YMMV.
Related
I am reviewing the migration path from Java 8 to Java 11 on Google App Engine, in the past the GAE environment offered excellent unit testing support and a local development environment.
But in the new Java 11 runtime, these seem to be missing, are they just not ready yet, or are they not coming to this new runtime?
The testing page says:
To test your application's functionality before deploying, run your application in your local environment with the development tools that you usually use.
That seems to punt the question back to the user - but when deploying to GAE having local runtime emulation for development and unit testing is really important. If it's not ever coming to Java 11, what's the best/right way to actually develop and test a Java 11 runtime GAE app?
After doing some research, the GAE local development environment for Java 8 is part of the standalone App Engine SDK and has been deprecated.
It doesn't look to me like a similar tool set will come for Java 11. At least for now.
I would say that for developing, as suggested in the Docs you referenced, you can use whatever development server of your preference.
As for unit testing. Because of how unit tests should be designed and implemented, it is actually best not to rely on other software to simulate the GAE behavior. Instead, mocks and stubs should be used to provide inputs to the tested modules that should make them return the response that is expected.
Their default local environment and gae runtime was based on Jetty. Since the Java 11 runtime you now need to pick your own application server which could be Jetty, Spring boot, Quarkus, Helidon or many others.
I picked the Grizzly HTTP server, as I wanted to use Jersey (the default JAX-RS implementation) and their example used Grizzly.
I wrote a blog post about how I made it work on Google App Engine:
https://medium.com/#Leejjon_net/migrate-a-jersey-based-micro-service-to-java-11-and-deploy-to-app-engine-7ba41a835992
If you want tests to work, I fixed the tests in the sample of my blog in this tag:
My full Java 11 sample with just one http request that can run locally and on app engine has a sample unit test:
https://github.com/Leejjon/SimpleJerseyService/tree/1.1.1
My task is to make a small a project for start my ee studies. Till now, I learned standard java, but i don't get what ee means exactly, how my project would be an enterprise stuff. Has it a different syntax or different setup in IDE? I know it's not a clever question, but I really don't know where to start. Do you have any idea for start a project?
Java EE is no different language or has no different syntax than Java SE. It's built on top of Java SE and comprises a set of standardized APIs and libraries that are helpful for solving problems in an enterprise context.
To name a few:
Web Applications (Servlets, JSPs, JSF, WAR-packaging)
RESTful- and WebServices (Jax-RS, Jax-WS)
Persistence (EJB, JPA)
Context Dependency Injection (CDI)
Security
Batch
Messaging
...
Further it defines a runtime environment - an Application Server - to run enterprise applications. Nevertheless, the classic application server model has become somewhat obsolet, nowadays you either run a single application in an application server or use only parts of the libraries and APIs and embedd those in your applications.
So basically, all you need is an IDE and the libraries. When you're using maven as build environment, all you need is the java-ee maven dependency, see Maven Central
Usually you don't need to know all the libraries and APIs of Java EE in detail, it's good to know what is available out-of-the-box (so you don't reinvent the wheel), but you hardly will need all of them in all of your projects.
I personally avoid JSF, hardly have to deal with JPA, only occasionally do something with Batch or EJBs. More common are CDI, Restful or WebServices and WebApps, and usually a bit of Security.
And a good example for a Java EE Projects, a simple one with some typical use cases and very little code is Adam Bien's Guestbook2.0, which only requires Docker to run.
I need to upgrade the source code for an existing Java EE 1.4 application to Java EE 7. What I need to do primarily? Any particular steps in order which I need to follow?
You are looking into a time difference of 10 years between 1.4 and 7, which in the IT is huge.
Replacing the old J2EE parts by Java EE code basically means rewrite the whole application - so it very much depends on what exactly needs to migrated and how much you can control this scenario.
From an own project where I had to deal with J2EE code I can recommend - if rewriting is not an option - to make the old application run on a new application server and only migrate small parts of it, if possible into a newly deployed application. This worked well, we still have J2EE code in the application and even add/fix small parts in the old code, but it runs together with Java EE code. One thing you have to take care about is the entity manager, because it leads you into trouble if you persist the same data via both ways.
Other than the obvious syntactical changes, I'd suggest looking at what libs you're using and seeing if those are now supported under 7.
When moving application code across versions, most of the time the jump is backwards compatible (I'd say in your case it won't be given such a massive jump) but one of the biggest factors will be if you're using legacy third party code, you'll need to find new supported versions of those products.
This includes say, if you're using a legacy application server and upgrading that. After all this then you can start to consider any syntactical changes that your IDE should help you with :)
I'd recommend WebSphere Migration Toolkit (an Eclipse plugin). Although it's primary usage is to look for a changes, when migrating from other platforms to WebSphere, it will scan your code, jsp pages, xml files and detect any Java, Java EE related issues also. So you will have rough idea what will need to be changed e.g. in relation to JDK changes.
See some info about that toolkit:
WebSphere Migration Toolkit
WebSphere Migration Toolkit download
Other WebSphere migration tools
Has anyone done this or attempted to do this for a preexisting project?
It seems there are two options to go with here, either using the embedded EJB API basically the following class
javax.ejb.embeddable.EJBContainer
Which expects a configured glassfish v3 install to be available (application scoped resources will make this easier).
The alternative is using the embedded glassfish jar files and the embedded glassfish API
I am looking for feedback from someone who has or who is in the process of doing this, links to blogs etc with a simple EJB & test case are dime a dozen.
If you've done this with any other EJB 3.1 container feel free to share.
Did you use any particular test framework for reasons other than it been your preferred tool?
Which JPA 2.0 implementation did you use, and was there a particular reason for doing so?
If you used glassfish which of the above strategies did you use? If not then which EJB 3.1 container did you use?
If you successfully did this, was it worth the effort and would you do this again for another existing project?
It seems there are two options to go with here, either using the embedded EJB API (...) which expects a configured glassfish v3 install to be available.
No, you can also use a minimal domain inside your project.
I am looking for feedback from someone who has or who is in the process of doing this, links to blogs etc with a simple EJB & test case are dime a dozen.
I've done integration testing of EJB 3.1 and JPA on my pet project (under Maven), inspired by Unit Testing EJBs and JPA with Embeddable GlassFish. Reading it is definitely worth it.
Did you use any particular test framework for reasons other than it been your preferred tool?
Nope.
Which JPA 2.0 implementation did you use, and was there a particular reason for doing so?
I used EclipseLink (because it was available at that time).
If you used glassfish which of the above strategies did you use? If not then which EJB 3.1 container did you use?
I used the Embedded EJB API, I was planning to run my code on other Java EE 6 containers when they'll be available.
If you successfully did this, was it worth the effort and would you do this again for another existing project?
Well, I think that integration / functional testing have value and find that the Embedded EJB API is really nice for that. It was not a pain to use it even if I don't consider my sample as a real life project.
For more complex scenarios, I keep an eye on the maven-embedded-glassfish-plugin (see also this answer).
I have written a small tutorial on my blog for using embedded glassfish 3.1 for unit-testing EJBs using javax.ejb.embeddable.EJBContainer. There are some pitfalls to it, which I got around by modifying the default embedded glassfish domain and putting some properties to createEJBContainer() call.
I want to ask for your prefered way to test Java EE code?
I found only three project, that are trying to help to code unit tests in Java EE environment:
http://jakarta.apache.org/cactus/ : Last Published: 2009-01-18
http://www.junitee.org/ : Last Release: 2004-12-11
http://ejb3unit.sourceforge.net/ : Last Release: 2008-05-17
So I wonder,
is there any framework helping to write (j) unit test for Java EE code?
do you use embedded Java EE servers like jboss or glassfish v3?
do you mockup and inject by yourself?
Thanks a lot...
If by Unit Testing you mean... unit testing (testing a unit in isolation), then you actually don't need any particular framework since EJB3.0 are nothing more than annotated POJOs and thus can be relatively easily tested without any special fixture.
Now, if you mean something else - like Integration Testing or Functional Testing - then, yes, tools can help and simplify things (but you should really start to use the right terminology :) I'll assume that this is what you have in mind.
First, JUnitEE seems dead and obsolete and I'm not even sure it has anything for EJB3.x. Second, I'm not impressed by the Java EE 5 support of Cactus and having to deploy Cactus tests is painful (I think that Cactus was nice for J2EE 1.4 but is a bit outdated now). So this leaves us with Ejb3Unit which is in my opinion the best option, especially if you want to run out of container tests i.e. without really deploying the application (much faster).
If you want to run in container tests, then you could indeed use an embedded container and my current preference goes to GlassFish v3, even for Java EE 5 (I may be wrong but I'm pretty disappointed by the starting time of the latest JBoss releases so it isn't getting much of my attention). See the post GlassFish Embedded Reloaded, an appserver in your pocket for sample code (that you could use from your tests) or Using maven plugin for v3 embedded glassfish (if you are using maven).
Another option would be to package and deploy your application with Cargo and then run some tests against the deployed application (with Selenium or a BDD tool for example). This could be useful if you want to run end-to-end tests with a container that doesn't provide any embedded API.
So, to answer your last question, I would indeed use available tools, maybe a combination of them, for tests that are not unit tests and wouldn't mock/inject stuff myself, except if they don't cover some needs that I can't think of right now.
As you are interested in unit testing, I recommend JUnit. You can unit test the methods in the core classes. If you have difficulty in writing unit test cases using JUnit, then probably the design is not modular and it is highly coupled. First focus on your core functionality and test it using JUnit.
I've been facing the same problem of running integration tests based on JUnit in a Java EE 6 container (Glassfish v3, to be precise), and after a lot of browsing and searching, I could not find a solution that really suited me needs, so I wrote my own, now published as jeeunit on Google Code.
I wouldn't call it a test framework, it is really just a handful of classes providing the glue between JUnit and Embedded Glassfish.
The general idea is similar to Cactus, your tests run in the container and get triggered by a servlet from outside.
jeeunit supports JUnit 4, Glassfish v3, CDI and generates the standard XML JUnit reports just like Ant or Maven Surefire (in fact, I reused some code from Ant for generating the reports).
I had a requirement to test a CDI application and wrote a custom JUnit runner that runs everything outside of the web container.
http://jglue.org/cdi-unit/
It is suitable for Java SE and also supports dummy Request, Session and Conversation scopes for testing web apps.
It's small and fast, which is great when you have lots of unit tests.