The Java EE 6 Example – Galleria Part 2
Preparation
Get yourself in the mood for some configuration. You already have the latest NetBeans 7.1 installed and you are going to download the WebLogic 12c ZIP distribution in a second. After you have downloaded the wls1211_dev.zip put it to a location of choice and unzip it. From now on we are going to call this folder the %MW_HOME% folder. Open a command line and setup %JAVA_HOME%, %JAVA_VENDOR% and %MW_HOME% variables in it:
set JAVA_HOME=D:\jdk1.7.0_04 set MW_HOME=D:\temp\wls12zip set JAVA_VENDOR=Sun
After you have done this one final step is to run the installation configuration script configure.cmd in the MW_HOME directory. This is a one time thing to do.
Setup your WebLogic Domain
Next thing we need is a WebLogic domain. Open a new command line prompt. Setup your environment in the current shell by running the %MW_HOME%\wlserver\server\bin\setWLSEnv.cmd script. Execute the %MW_HOME%\wlserver\common\bin\config.cmd and follow the wizard to create a basic WebLogic Server Domain called test-domain in a folder of your choice (e.g. D:\temp\test-domain). Give a username and password of your choice (e.g. system/system1) and click through the wizard until you have a “finish” button down there. WebLogic needs the Derby client jar file in order to configure and use the database. Copy the derbyclient-10.8.2.2.jar from your m2 repository to the test-domain\lib folder. Now lets start the newly created domain manually by running the startWebLogic.cmd in your newly created domain directory. Verify that everything is up and running by navigating to http://localhost:7001/console and logging in with the credentials from above. Navigate to “Services > Data Sources” and select the “New” button from above the table. Select a “Generic Datasource” and enter a name of your choice (e.g. GalleriaPool) and enter jdbc/galleriaDS as the JNDI-Name. Select Derby as the Database Type and click “next”. Select Derby’s Driver (Type 4) and click “Next” and “Next” and enter the connection properties (Database: GALLERIATEST, Host: localhost. User and Password: APP” and click “Next”. If you like to, you can hit the “Test Configuration” button on top and make sure everything is setup in the right way.
Next the most tricky part. We need a JDBC realm like the one we configured for GlassFish. First difference here is, that we don’t actually create a new realm but add an authentication mechanism to the available one. There is a nasty limitation with WebLogic. You can configure as many security realms as you like, but only one can be active at a given time. This stopped myself for a while until I got the tip from Michel Schildmeijer (thanks, btw!). Navigate to “Security Realms” and select “myrealm” from the table. Switch to the Providers tab. Select “New” above the table of the Authentication Providers. Enter “GalleriaAuthenticator” as the name and select “SQLAuthenticator” from the dropdow-box as a type. Click ok. Select the GalleriaAuthenticator and set the Control Flag: SUFFICIENT and save. After that switch to the “Provider Specific” tab. Enter the following:
Data Source Name: GalleriaPool Password Style Retained: unchecked Password Algorithm: SHA-512 Password Style: SALTEDHASHED SQL Get Users Password: SELECT PASSWORD FROM USERS WHERE USERID = ? SQL Set User Password: UPDATE USERS SET PASSWORD = ? WHERE USERID = ? SQL User Exists: SELECT USERID FROM USERS WHERE USERID = ? SQL List Users: SELECT USERID FROM USERS WHERE USERID LIKE ? SQL Create User: INSERT INTO USERS VALUES ( ? , ? ) SQL Remove User: DELETE FROM USERS WHERE USERID = ? SQL List Groups: SELECT GROUPID FROM GROUPS WHERE GROUPID LIKE ? SQL Group Exists: SELECT GROUPID FROM GROUPS WHERE GROUPID = ? SQL Create Group: INSERT INTO GROUPS VALUES ( ? ) SQL Remove Group: DELETE FROM GROUPS WHERE GROUPID = ? SQL Is Member: SELECT USERID FROM USERS_GROUPS WHERE GROUPID = ? AND USERID = ? SQL List Member Groups: SELECT GROUPID FROM USERS_GROUPS WHERE USERID = ? SQL List Group Members: SELECT USERID FROM USERS_GROUPS WHERE GROUPID = ? AND USERID LIKE ? SQL Remove Group Memberships: DELETE FROM USERS_GROUPS WHERE GROUPID = ? OR GROUPID = ? SQL Add Member To Group: INSERT INTO USERS_GROUPS VALUES( ?, ?) SQL Remove Member From Group: DELETE FROM USERS_GROUPS WHERE GROUPID = ? AND USERID = ? SQL Remove Group Member: DELETE FROM USERS_GROUPS WHERE GROUPID = ? Descriptions Supported: unchecked
Save your changes. and go back to the “Providers” tab. Click on the “Reorder” button and push the GalleriaAuthenticator to the top of the list. Click “ok”, when done and stop your WebLogic instance. You are free to restart it at any time.
Configure your Projects
Java EE is portable. Right. And you should be able to run the same deployment without any changes on the WebLogic 12c. That is theory. In practice you will have to touch the deployment. Because WebLogic has some issues with Hibernate. And it is a lot more crotchety when it comes to deployments than GlassFish is. First of all you have to create a “galleria-ear\src\main\application\META-INF” folder. Put a blank weblogic-application.xml there and put the following code in it:
<?xml version='1.0' encoding='UTF-8'?> <weblogic-application xmlns="http://xmlns.oracle.com/weblogic/weblogic-application" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.oracle.com/weblogic/weblogic-application http://xmlns.oracle.com/weblogic/weblogic-application/1.4/weblogic-application.xsd"> <prefer-application-packages> <package-name>antlr.*</package-name> </prefer-application-packages> </weblogic-application>
That tells WebLogic to prefer the application packaged libraries over those already present in the server. Let’s go ahead. We need to add the Hibernate dependencies to the ear. With GlassFish we skipped that step, because we installed the Hibernate package with the server. Here we go. Open the galleria-ear pom.xml and add the following to the dependencies section:
<dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-entitymanager</artifactId> <version>4.0.1.Final</version> </dependency> <dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-core</artifactId> <version>4.0.1.Final</version> </dependency> <dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-validator</artifactId> <version>4.2.0.Final</version> </dependency> <dependency> <groupId>org.jboss.logging</groupId> <artifactId>jboss-logging</artifactId> <version>3.1.0.CR2</version> </dependency>
You also need to look at the maven-ear-plugin and add the following to the <configuration>:
<defaultLibBundleDir>lib</defaultLibBundleDir>
And if you are there already, remove the commons-codec jarModule. It doesn’t hurt, but it get’s packaged into the ear/lib folder, so you can skip it.
Next navigate to the galleria-jsf project and open the web.xml. The <login-config> is incomplete and should look like this:
<login-config> <auth-method>FORM</auth-method> <form-login-config> <form-login-page>/Login.xhtml</form-login-page> <form-error-page>/Login.xhtml</form-error-page> </form-login-config> </login-config>
<security-role> <description>All registered Users belong to this Group</description> <role-name>RegisteredUsers</role-name> </security-role>
You need to define the possible roles, too otherwise the WebLogic security stuff will start to complain.
Add a blank weblogic.xml to the galleria-jsf\src\main\webapp\WEB-INF folder and add the following lines to it:
<?xml version="1.0" encoding="UTF-8"?> <weblogic-web-app xmlns="http://xmlns.oracle.com/weblogic/weblogic-web-app" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.oracle.com/weblogic/weblogic-web-app http://xmlns.oracle.com/weblogic/weblogic-web-app/1.4/weblogic-web-app.xsd"> <security-role-assignment> <role-name>RegisteredUsers</role-name> <principal-name>RegisteredUsers</principal-name> </security-role-assignment> <session-descriptor> <timeout-secs>3600</timeout-secs> <invalidation-interval-secs>60</invalidation-interval-secs> <cookie-name>GalleriaCookie</cookie-name> <cookie-max-age-secs>-1</cookie-max-age-secs> <url-rewriting-enabled>false</url-rewriting-enabled> </session-descriptor> </weblogic-web-app>
We are mapping the web.xml role to a WebLogic role here. You could have skipped this, but I like it this way so you don’t get confused. The session-descriptor element is taking care of the JSESSION cookie name. If you wouldn’t change it, you would get into trouble with signed in users to the admin console.
Move on the the galleria-ejb project. Create a blank weblogic-ejb-jar.xml in the “galleria-ejb\src\main\resources\META-INF” folder. Put the following code in it:
<?xml version="1.0" encoding="UTF-8"?> <weblogic-ejb-jar xmlns="http://xmlns.oracle.com/weblogic/weblogic-ejb-jar" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.oracle.com/weblogic/weblogic-ejb-jar http://xmlns.oracle.com/weblogic/weblogic-ejb-jar/1.0/weblogic-ejb-jar.xsd"> <security-role-assignment> <role-name>RegisteredUsers</role-name> <principal-name>RegisteredUsers</principal-name> </security-role-assignment> </weblogic-ejb-jar>
Comparable to the web.xml/weblogic.xml this also tells WebLogic how to map the ejb-jar.xml security roles to WebLogic roles. Fine, open the persistence.xml and add the following lines:
<property name="hibernate.dialect" value="org.hibernate.dialect.DerbyDialect" /> <property name="hibernate.transaction.jta.platform" value="org.hibernate.service.jta.platform.internal.WeblogicJtaPlatform" />
The first one explicitly selects the Derby dialect for Hibernate. The second one tells Hibernate where and how to look for the transactions. All done. Now you should be able to build the project again and deploy it. Use the admin console or NetBeans to deploy it. Thanks for taking the time to follow this lengthy post. I hope it was helpful!
Want to know what it takes to get the unit and integration tests up and running? Read on!
Time to move on with Vineet’s Java EE 6 Galleria Example. After some introduction, a basic getting started guide on GlassFish and the WebLogic 12c deployment it finally is time to dive into testing. I skipped this part in the earlier posts because of two reasons. The first one obviously was that I wanted to write a separate post about it. The second one was that there was work to do to get this up and running on latest GlassFish 3.1.2. Vineet and team did a great job releasing Arquillian GlassFish Remote Container CR3 a few days back which now also covers GlassFish 3.1.2. Time to get you started with testing the Galleria Example.
What you are going to test
The Galleria was build to achieve comprehensive test coverage through the use of both unit and integration tests, written in JUnit 4. The unit and integration tests for EJBs and the domain model rely on the EJB 3.1 container API. The integration tests for the presentation layer relies on the Arquillian project and its Drone extension (for execution of Selenium tests).
Please make sure to update to the latest sources from the Galleria Project because Vineet updated the Arquillian GlassFish container to CR3 and the Selenium stuff to support latest FireFox browser.
Unit-Testing the Domain Layer
The tests for the domain layer fall into five separate categories. The first three (Bean Verification tests, Mutual Registration verification tests, Tests for the Constructor, equals and hashcode methods) cover the basic needs for nearly any JPA based application. If you take a walk down the galleria-ejb\src\test sources you can see them covered in the info.galleria.domain package. Every domain object is covered by a suite class which includes all three kinds of unit tests.
Lets start with looking at the Bean Verification tests. The behavior associated with the getters and setters in the properties of JavaBeans are fairly easy to verify. All one needs to do, is to invoke the setter first, then the getter, and verify whether the instance returned by the getter is equal to the instance passed to the setter. The project uses the
BeanVerifier class (under the src/tests/java root of the galleria-ejb module) for this. The AlbumBeanVerifier test simply is a parameterized test which tests every single property. The only exception in this case is the coverPhoto property which has a special behavior beyond the simple JavaBean pattern.
Next on the list are the tests for the constructor, equals and hashcode methods. Constructors for the domain entities are tested by merely creating new instances of the classes, while asserting the validity of the properties that would be set by the constructor. The equals and hashcode methods are verified via the use of the EqualsVerifier class from the EqualsVerifier project.
The last category of the more basic tests are the mutual registration (PDF) verification tests. You simply want to check if modifications to the relationships between the entities, actually result in changes to both the parent and the child properties. See the comprehensive wiki page for more details about the implementation. All these are executed during the unit-testing phase and are covered by **/*Suite.java classes.
In addition to the basic tests you also find one-off tests written for specific cases where the basic test-models are insufficient or unsuitable. In such instances, the one-off tests verify such behavior through hand-written assertions. You find them in **/*Tests.java classes in the same package.
The domain layer tests finish with the JPA repository tests. Each of the *RepositoryTest.java classes test the CRUD behavior of the handled domain objects. The common AbstractRepositoryTest handles the test data and resets the database after every test-run. The database creation itself is handled by the maven-dbdeploy-plugin. Looking at the pom.xml you can see, that it is bound to two Maven lifecycle phases (process-test-resources and pre-integration-test) which makes sure it gets called twice. First time before the unit-tests and second before the integration testing (compare below).
All those unit-tests are executed with surefire. If you issue a mvn test on the galleria-ejb project you can see a total of 138 tests passing. These are the four **/*Suite tests, the four **/*RepositoryTests and two additional tests. If you briefly look at the console output you see, that this is all happening in a Java SE environment. No container tests have been done until now.
Integration Testing the Domain Layer
So this really only covered the basics which everybody should do and probably knows. Doing integration testing is another story. This is done by the **/*IntegrationSuite tests. The name intentionally does not use the default naming conventions in order to prevent them from running during Maven’s unit-testing phase. To hook into the integration-test phases of Maven the Galleria example makes use of the Maven Failsafe Plugin. You can find the integration test Suite in the info.galleria.service.ejb package. The AbstractIntegrationTest takes care about handling the test data (comparable what the AbstractRepositoryTest) did for the unit-tests. The Suite contains a *ServiceIntegrationTest for every domain object. You can walk through the single tests in every *IntegrationTest and get a feeling for what is happening here. The ServicesIntegrationSuite takes care of starting and stopping the EJBContainer by using the AbstractIntegrationTest.startup();. This method is comparably unspectacular and simple:
logger.info("Starting the embedded container."); Map<String, Object> props = new HashMap<String, Object>(); props.put("org.glassfish.ejb.embedded.glassfish.installation.root", "./glassfish-integrationtest-install/glassfish"); container = EJBContainer.createEJBContainer(props); context = container.getContext(); datasource = (DataSource) context.lookup("jdbc/galleriaDS");
The most important point here is, that the embeddable EJBContainer is configured via an existing GlassFish domain which can be found directly in the galleria-ejb\glassfish-integrationtest-install folder. If you look at the glassfish\domains\domain1\config\domain.xml you can see, that all the configuration is already done for you. But where does the deployment come from? This is easy to answer. By default the embeddable EJBContainer searches your classpath for ejb-jar jarfiles or folders and deploys them. If you want to see a little bit more verbose output from the EJBContainer you have to provide a customlogging.properties file in src/test/resources and add some simple lines to it:
handlers=java.util.logging.ConsoleHandler java.util.logging.ConsoleHandler.formatter=java.util.logging.SimpleFormatter java.util.logging.ConsoleHandler.level=FINEST #add some more packages if you need them info.galleria.service.ejb.level=FINE
add the following to the maven-failsafe-plugin configuration section of your pom.xml:
<systemPropertyVariables> <java.util.logging.config.file>${basedir}/src/test/resources/customlogging. properties</java.util.logging.config.file> </systemPropertyVariables>
The integration tests should finish successfully and maven should print something comparable to the following:
Tests run: 49, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 61.726 sec
Notice, that the integration tests take significantly longer than the normal unit-tests. This is no surprise at all and you should make sure to only execute them when needed so you are not slowed down with your development.
Integration Testing the Presentation Layer
The domain layer is covered with tests. What is missing is the presentation layer. You can find the presentation layer tests in the galleria-jsf project. Start with examining the pom.xml. You find a couple of new dependencies here. Namely Arquillian, Selenium and Drone.
First some configuration again. Scroll down to the profile section you can see a integration-test profile which makes use of the maven-glassfish-plugin and controls a container which is configured with a couple of properties. Add the definition to the properties section on the top of the pom:
<galleria.glassfish.testDomain.user>admin</galleria.glassfish. testDomain.user> <galleria.glassfish.testDomain.passwordFile>D:/glassfish-3.1.2-b22/glassfish3/glassfish/domains/ test-domain/config/local-password</galleria.glassfish.testDomain.passwordFile> <galleria.glassfish.testDomain.glassfishDirectory>D:/glassfish-3.1.2-b22/glassfish3/glassfish/</galleria.glassfish.testDomain.glassfishDirectory> <galleria.glassfish.testDomain.domainName>test-domain</galleria.glassfish.testDomain.domainName> <galleria.glassfish.testDomain.adminPort>10048</galleria.glassfish.testDomain.adminPort> <galleria.glassfish.testDomain.httpPort>10080</galleria.glassfish.testDomain.httpPort> <galleria.glassfish.testDomain.httpsPort>10081</galleria.glassfish.testDomain.httpsPort>
You can copy this from the development profile of the galleria-ejb project as described in part 2. You also should already have the domain in place. Next down to the maven-surefire-plugin you can see, that it follows the same conventions that the galleria-ejb project has. But looking at the test-classes you can see, that there isn’t a single unit-test here. So you can directly move on to the maven-failsafe-plugin which handles the integration tests. There is one single AllPagesIntegrationTest which covers the complete testing. Let’s go there.
It is an Arquillian Testcase which is executed as a client against a remote instance. Beside the definition of the deployment (@Deployment) you also again see a couple of setUp and tearDown methods which do some initialization and destruction. One thing has to be handled separately. You also see a writeCoverageData() method in there which obviously connects to some kind of Socket and reads data from it. This is the JaCoCo (Java Code Coverage Library) hook which can produce a coverage data set of the tests. To make this work you will have to download the package and extract it to a place of you choice. Next go to your GlassFish test-domain\config\domain.xml and open it. Find the server-config – java-config and add the following there:
<jvm-options>-javaagent:D:\path\to\jacoco-0.5.6.201201232323\lib\jacocoagent.jar=output=tcpserver</jvm-options>
This enables the coverage agent for GlassFish. All configuration done now. Back to NetBeans, select the integration-test profile (in NetBeans you can do this by selecting the entry from the dropdown box next the the little hammer in the icon area or by using -Pintegration-test as a maven command line switch. The console output tells you, that the GlassFish domain is started and the info.galleria.view.AllPagesIntegrationTest is running. Be warned, a FireFox instance is popping up during this run and the Arquillian Drone extension is driving your Selenium Tests.
Seeing a browser remote controlled in this way looks and feels weird if you haven’t seen this before. If everything works you should now see this in the console output:
Tests run: 30, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 138.014 sec
If you are using another locale than en for your browser you may have completely failed tests. So there is additional need to configure Drone to support it. Drone allows you to specify a Firefox profile via arquillian.xml. You can create a Firefox profile that is configure to send accept-language headers with en/en-US as the value.
To create a new profile, start Firefox Profile manager with the following command (you might need to close all running instances): firefox -profilemanager (on Windows you need to execute the command “d:\complete\path\to\firefox.exe” -profilemanager) in a cmd shell. Remember the location on the disc where this profile is created – you’ll need it later. To configure the created profile, in Firefox, go to Options (menu) -> Content (tab) -> Languages (fieldset) -> Choose to add the English language (and move it top, as the preferred one). Now navigate the galleria-jsf\src\test\resources\arquillian.xml, you can then add a property:
<extension qualifier="webdriver"> <property name="implementationClass">org.openqa.selenium.firefox.FirefoxDriver</property> <property name="firefoxProfile">location of the Firefox profile for English</property> </extension>
All done now. You should be able to run the complete clean and build process now without any test failing. A big “green bar” :)
Reference: The Java EE 6 Example – Running Galleria on WebLogic 12 – Part 3 ,The Java EE 6 Example – Testing Galleria – Part 4 from our JCG partner Markus Eisele at the Markus Eisele blog.