Skip to content

Instantly share code, notes, and snippets.

@mojavelinux
Created January 19, 2012 03:10
  • Star 6 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
Star You must be signed in to star a gist
Save mojavelinux/1637464 to your computer and use it in GitHub Desktop.
JBoss Java EE workshop

JBoss Java EE 6 Workshop

This tutorial steps through creating, testing and deploying an application using the JBoss Java EE tools and runtimes. You can show up with nothing but Java and a passion to learn. By the end, you’ll have a full application running in the cloud provided by OpenShift.

Here’s the development stack we’ll be using:

  • OpenShift

  • git

  • JBoss Forge

  • JBoss Tools

  • JBoss AS 7

  • Arquillian

Hang on, cause it’s going to move fast.

OpenShift Introduction

Why Java EE on OpenShift?

You’ve probably been hearing a lot about cloud (“to the cloud!”). But, if you’re like me, you just haven’t been that motivated to try it, or it just seemed like too much effort. After all, taking a Java EE application to the cloud typically meant:

  • Breaking out a credit card (I hate being restricted from exploring)

  • Implementing tons of hacks to get a Java EE application running on a cloud provider

  • Not knowing how Java EE development is even compatible with cloud

  • Lack of crystal clear documentation and examples

All that has changed. I assure you, you’re in for a pleasant surprise.

OpenShift provides a free, cloud-based application platform for Java, Perl, PHP, Python, and Ruby applications using a shared-hosting model. Exploring the cloud has never been simpler. You can deploy a Java EE compliant application without requiring any hacks or workarounds. Best of all, take as much time as you like, because it’s all free. (Oh, and you can show off your applications to your friends, or even run applications for your own purposes).

It’s time to get going!

Creating an OpenShift account

Creating an OpenShift account is very straightforward.

  1. Go to the OpenShift homepage

  2. Click on the "Signup and try it" button to open the registration form

  3. Enter a valid email address, a password (twice) and pass the Captcha (I know, it’s tough)

  4. Check your email and follow instructions in the welcome email

Welcome to OpenShift!

Installing Ruby-based OpenShift client tools

To interact with the OpenShift Platform-as-a-Service (PaaS), you’ll need one of the available OpenShift client tools installed. We’ll be using the Ruby-based commandline tool, rhc, in this tutorial.

To install the Ruby-based OpenShift client tools, you first need to install git and Ruby Gems.

On a Debian-based Linux distribution, it’s as easy as:

$> sudo apt-get install ruby rubygems

On a rpm-based Linux distribution, it’s as easy as:

$> sudo yum install ruby rubygems

Next, install the Red Hat Cloud (rhc) gem:

$> sudo gem install rhc

This will add a set of commands to your shell prefixed with rhc- (e.g., rhc-create-domain).

Tip
On some distributions the gem installation directory is not automatically added to the path. Find the location of your gems with gem environment and add it to you system’s PATH environment variable.

Creating a domain for your applications

Before actually deploying an app to OpenShift, you first need to create a domain. A domain hosts one or more applications. The name of the domain will be used in the URL of your apps according to the following scheme:

http://[application name]-[domain name].rhcloud.com

Create a domain using the following command:

$> rhc-create-domain -n [domain name] -l [openshift email]
Note
Use the same email address you used to register for your OpenShift account and enter your OpenShift password when prompted.
Tip
All OpenShift client tools prompt you for your OpenShift password (unless you supply it using the -p command flag)

The command will then create a pair of private and public keys as libra_id_rsa and libra_id_rsa.pub in your $HOME/.ssh/ directory. It will ask you for a password to access the private key. Don’t forget it!

Tip
If you want to use an existing ssh key file, you can specify it explicitly in the $HOME/.openshift/express.conf file. You’ll also discover that your email is cached in this file, which means you don’t have to specify it in subsequent commands.

You can see a summary of your domain using the following command:

$> rhc-domain-info

You can also go to the dashboard to see your newly minted domain. You now have your own, free cloud. Woot!

Creating your first Java EE application on OpenShift

We now want to create a new application that uses the JBoss AS 7 cartridge. This allows us to deploy Java EE-compliant applications to OpenShift.

We’ll assume you’ll be developing the application in the following folder: ~/demos/apps/sellmore

Next, use the following command to create a slot in your OpenShift domain in which to run the application and the location where the local project should be created:

$> rhc-create-app -a sellmore -t jbossas-7 -r ~/demos/apps/sellmore

You’ll be prompted for your ssh key password that you created in the previous step.

Behind the scenes, OpenShift has created a git repository for you and cloned it locally. That’s how you’re going to "push" your application to the cloud. The cloned repository contains a Maven-based project structure (which you don’t have to use):

Project layout
sellmore
|- .git/
|- .openshift/
|- deployments/
|- src/
|- .gitignore
|- pom.xml
`- README

The README describes all the special directories that pertain to OpenShift.

The OpenShift setup leaves behind a sample application which is going to get in our way later on. So first, let’s clear the path:

$> cd sellmore
$> git rm -r pom.xml src
$> git commit -m 'clear a path'
$> cd ..

If you’re working with another origin git repository (such as on github), we recommend renaming the OpenShift repository from origin to openshift:

$> cd sellmore
$> git remote rename origin openshift
$> cd ..

That separates the concern of managing your source code repository from deploying files to OpenShift.

You can see a summary of your application configuration using the following command:

$> rhc-domain-info

You can also go to the dashboard to see your application slot. If you click on the URL, you’ll see that a sample application is already running in the cloud. We’ll be replacing that soon enough.

If, for whatever reason, you need to delete your application, use this command:

$> rhc-ctl-app -a sellmore -c destroy

You’ll also want to delete your local .git repository (unless you mean to save it).

But now’s not the time to delete, it’s time to create!

JBoss Forge Introduction

Why JBoss Forge?

Because starting a project is hard. It doesn’t just take time, it takes mental energy. We want to save that energy for creating useful things. Trust me, even if copying and pasting 20 lines of build XML seems easy, somewhere along the line your going to find yourself roasting your brain. Let’s toss the complexity over the wall and let a tool like Forge deal with it.

Forge is your monkey, or 10,000 of them.

Setting up Forge

To create our application, we’re going to use JBoss Forge. Forge is a plugin-based framework for rapid development of standards-based Java applications.

Begin by grabbing Forge from the download area. Then, unpack the distribution:

$> unzip forge-distribution-1.0.0.Beta5.zip

Move the extracted folder to the location of your choice and change into that directory in your console:

$> cd ~/opt/forge

Finally, run Forge:

$> ./bin/forge

To be sure everything is working okay, run the about command in the Forge shell:

$forge> about

  _____
 |  ___|__  _ __ __ _  ___
 | |_ / _ \| `__/ _` |/ _ \  \\
 |  _| (_) | | | (_| |  __/  //
 |_|  \___/|_|  \__, |\___|
                 |___/

JBoss Forge, version [ 1.0.2.Final ] - JBoss, by Red Hat, Inc. [ http://jboss.org/forge ]
Note
Any command in this document prefixed with $forge> is intended to be run in the Forge shell.

Things look good. We’re ready to create an application.

Generating an application with Forge

Forge allows you to create a Java EE application from scratch. We’re going to generate a point of sale application step-by-step in the Forge shell using the commands below (make sure Forge is running):

Forge commands to create a Java EE web project
new-project; (1)

scaffold setup --scaffoldType faces; (2)
persistence setup --provider HIBERNATE --container JBOSS_AS7; (3)
validation setup --provider HIBERNATE_VALIDATOR; (4)

entity --named Customer --package ~.domain; (5)
field string --named firstName;
field string --named lastName;
field temporal --type DATE --named birthDate;
entity --named Item;
field string --named name;
field number --named price --type java.lang.Double;
field int --named stock;
cd ..;

entity --named ProductOrder; (6)
field manyToOne --named customer --fieldType ~.domain.Customer.java --inverseFieldName orders;
cd ../Customer.java;
entity --named Profile;
field string --named bio;
field string --named preferredName;
field string --named notes;
entity --named Address;
field string --named street;
field string --named city;
entity --named ZipCode;
field int --named code;
cd ../Address.java;

field manyToOne --named zip --fieldType ~.domain.ZipCode.java; (7)
cd ..;
cd Customer.java;
field manyToMany --named addresses --fieldType ~.domain.Address.java;
cd ..;
cd Address.java;
cd ../Customer.java;
field oneToOne --named profile --fieldType ~.domain.Profile.java;
cd ..;
cd ProductOrder.java;
field manyToMany --named items --fieldType ~.domain.Item.java;
cd ..;
cd ProductOrder.java;
field manyToOne --named shippingAddress --fieldType ~.domain.Address.java;
cd ..;

scaffold from-entity ~.domain.* --scaffoldType faces --overwrite; (8)
cd ~~;

rest setup; (9)
rest endpoint-from-entity ~.domain.*; (10)

build; (11)

cd ~~; (12)
echo "Project Info:"; project;
  1. Create a new project in the current directory

  2. Turn our Java project into a Web project with JSF[JavaServer Faces], CDI[Contexts & Dependency Injection], EJB[Enterprise JavaBeans]

  3. Setup JPA[Java Persistence API]

  4. Setup Bean Validation

  5. Create some JPA entities on which to base our application

  6. Create more entities, also add a relationship between Customer and their Orders

  7. Add more relationships between our entities

  8. Generate the UI for all of our entities at once

  9. Setup JAX-RS

  10. Generate CRUD[Create, Read, Update & Delete] endpoints

  11. Build the project

  12. Return to the project root directory and leave it in your hands

You’ve got a complete application, ready to deploy!

But wait! That sure seemed like a lot of typing. What’s really great about Forge is that it’s fine-grained enough to perform simple operations, but it can also compose those operations inside plugins or scripts!

You can take all of those commands and put them into a script ending in .fsh and run the script from the Forge shell.

If you’re going to try this approach, you should first wipe the slate clean.

$> rm -Rf src/ pom.xml

Then, copy all the Forge commands listed above into the file generate.fsh at the root of the project.

You may also want to wrap the following two lines around the contents so that the commands run without pausing:

Use as first line
set ACCEPT_DEFAULTS true; (1)
  1. Disables interactive commands

Use as last line
set ACCEPT_DEFAULTS false; (1)
  1. Reenables interactive commands

You can now build the application using a single command:

$forge> run generate.fsh

Alternatively, you can also run a prepared version of this script directly off the web

$forge> run-url https://raw.github.com/gist/1666087/1cd6032090f66f6aa18b7bd2ce55c569be8ac454/generate.fsh

That’s more like it! Now, let’s get the application running!

Application Deployment

Deploying the application to a local JBoss AS 7 instance

Before we get all cloud happy, it’s a good idea to make sure the application runs on our own machine. We want to make sure that we rule out any problems with the application before adding the cloud into the mix.

If you don’t have JBoss AS 7 yet, head on over to the JBoss AS 7 download page and grab the latest 7.1 version. When the download finishes, unpack the distribution

$> unzip jboss-as-7.1.1.Final.zip

Move the extracted folder to the location of your choice (we’ll assume it’s $HOME/opt/jboss-as) and change into that directory in your console:

$> cd $HOME/opt/jboss-as

Finally, run JBoss AS in standalone (single server) mode:

$> ./bin/standalone.sh

You shouldn’t have to wait long to see:

JBoss AS 7.1.1.Final "Brontes" started in 1933ms - Started 133 of 208 services...

Now that’s a speedy app server!

Let’s head back to Forge so we can give this eager server something to run. We’ll start by adding the Maven plugin for JBoss AS 7 to the project (yes, there is a decent Maven plugin finally):

$forge> setup as7

If you don’t have the as7 command yet, you can install it using this command, then go back and do the setup:

$forge> forge install-plugin as7

Okay, build the application and send it to JBoss AS:

$forge> build
$forge> as7 deploy

The first deployment is always the slowest, so give it a few seconds. Then, have a look around the application you generated:

$$http://localhost:8080/sellmore

If everything looks good, then the application is cleared for take off. Let’s now do the same deployment, but this time on OpenShift.

Deploying your first Java EE application to OpenShift

There are two ways to deploy an application to OpenShift:

  1. Deploy the source

    You can commit your source files and push them to the remote server using git, at which point the application will be built and deployed on the remote host. Alternatively, you can use a Jenkins slave to handle the build and deploy steps on the server. More on that later.

  2. Deploy a package

    You can copy a pre-built war into deployments/ (with the corresponding .dodeploy file for an exploded war) and use git to commit and push the file(s) to the remote server for deployment

In the first scenarios, you edit the files locally and let OpenShift build the app using Maven and deploy it to JBoss AS 7 once you push the changes using git. In the second scenario, you build the application locally and just push the final package to OpenShift, which it will deploy to JBoss AS 7.

We’re going to take the source route.

First, add the following profile to the end of the pom.xml file (inside the root element):

pom.xml (fragment)
<profiles>
  <profile>
   <!-- When built in OpenShift the 'openshift' profile will be used when invoking mvn. -->
   <!-- Use this profile for any OpenShift specific customization your app will need. -->
   <!-- By default that is to put the resulting archive into the 'deployments' folder. -->
   <!-- http://maven.apache.org/guides/mini/guide-building-for-different-environments.html -->
   <id>openshift</id>
   <build>
      <finalName>sellmore</finalName>
      <plugins>
        <plugin>
          <artifactId>maven-war-plugin</artifactId>
          <version>2.1.1</version>
          <configuration>
            <outputDirectory>deployments</outputDirectory>
            <warName>ROOT</warName>
          </configuration>
        </plugin>
      </plugins>
    </build>
  </profile>
</profiles>
Important
If you forget this profile, then the application will build on the OpenShift PaaS, but it will not be deployed to JBoss AS 7.
Caution
You may want to add the Eclipse project files to .gitignore so that they aren’t committed.

Next, we’ll add all the new files to git, commit them and push them to the server. You can perform these operations directly inside the Forge shell:

$forge> git add pom.xml src
$forge> git commit -a -m 'new project'
$forge> git push openshift master

You’ll see the OpenShift begin the build lifecycle on the server, which includes executing Maven and downloading the (nearby) internet. The console output you’re seeing is from the remote server being echoed into your local console.

OpenShift Build Lifecycle

The OpenShift build lifecycle comprises four steps:

  1. Pre-Receive

    Occurs when you run a git push command, but before the push is fully committed.

  2. Build

    Builds your application, downloads required dependencies, executes the .openshift/action_hooks/build script and prepares everything for deployment.

  3. Deploy

    Performs any required tasks necessary to prepare the application for starting, including running the .openshift/action_hooks/deploy script. This step occurs immediately before the application is issued a start command.

  4. Post-Deploy

    Allows for interaction with the running application, including running the .openshift/action_hooks/post_deploy script. This step occurs immediately after the application is started.

When the build is done, you’ll notice that the application is deployed to JBoss AS 7. You can now visit the application URL again to see the application running.

http://sellmore-[domain name].rhcloud.com

You should see the Forge welcome page and a list of items in the sidebar you can create, read, update and delete (CRUD).

If you want to push out a new change, simply update a file, then use git to commit and push again:

$forge> git commit -a -m 'first change'
$forge> git push openshift master

The OpenShift build lifecycle will kick off again. Shortly after it completes, the change will be visible in the application.

Application Management

Managing OpenShift applications from a shell environment

OpenShift isn’t just a black box (black cloud?), it’s Linux and it’s open! That means you can shell into your cloud just as you would any (decent) hosting environment.

So what’s the login? It’s embedded there in the git repository URL. Let’s find it.

$> git remote show -n openshift

You can also get the same information using:

$> rhc-domain-info -a

You are looking for the ssh username and host in the form username@hostname. Once you’ve got that, just pass it to ssh and the authentication will be handled by the ssh key you setup earlier. Here’s the syntax:

$> ssh [UUID]@[application name]-[domain name].rhcloud.com

There’s a lot of power in that shell environment. You can type help to get a list of speciality commands (such as starting, stopping or restarting your app), or use just about any Linux shell command you know. Be sure to pay attention to what you’re typing, though rest assured that the box is running on RHEL[Red Hat Enterprise Linux] secured with SELinux.

Viewing the log files

There are two ways to view (tail) the log files of your application. You can use the client tool:

$> rhc-tail-files -a sellmore

Or you can shell into the server and use the built-in tail command:

$> tail_all

You can also use the regular tail command in the remote shell environment.

Restarting or stopping your application

You can control your application directly without pushing files through git. One way is to use the client tool from your location machine:

$> rhc-ctl-app -c restart

You can also shell into your domain and execute a command using one of the special commands provided:

$> ctl_app restart

In addition to restart, you can use the commands start, stop, etc.

Persistence Storage

Preserving the database between restarts

You may have noticed that each time we restart the application, the data gets lost. There are two ways to resolve this:

  1. Update tables rather that dropping and recreating them on deployment

  2. Save the data to a safe location on disk

The first setting is a feature of Hibernate (or alternate JPA provider) and is changed using the following property in src/main/resources/META-INF/persistence.xml:

src/main/resources/META-INF/persistence.xml (fragment)
<property name="hibernate.hbm2ddl.auto" value="update"/>

The second feature depends on the database you are using. If you are using the provided H2 database, you’ll likely want to change the configuration in .openshift/config/standalone.xml to use the OpenShift data directory:

.openshift/config/standalone.xml (fragment)
<connection-url>jdbc:h2:${OPENSHIFT_DATA_DIR}/test;DB_CLOSE_DELAY=-1</connection-url>

The other approach is just to use a regular client-server database (e.g., MySQL or PostgreSQL), which we’ll do later.

Persisting data to a MySQL database

OpenShift provides us with several add-on services (cartridges) we can use. To see the list of available cartridges, issue the following command:

$> rhc-ctl-app -a sellmore -L

List of supported embedded cartridges:

  postgresql-8.4, metrics-0.1, mysql-5.1, jenkins-client-1.4,
  10gen-mms-agent-0.1, phpmyadmin-3.4, rockmongo-1.1, mongodb-2.0

Oh goody! Lots of options :)

Let’s install mysql-5.1 cartridge:

$> rhc-ctl-app -a sellmore -e add-mysql-5.1

Mysql 5.1 database added. Please make note of these credentials:

   Root User: admin
   Root Password: xxxxx
   Database Name: sellmore

Connection URL: mysql://127.1.47.1:3306/

You can manage your new Mysql database by also embedding phpmyadmin-3.4.
Note
The name of the database is the same as the name of the application.

OpenShift is telling us that the phpmyadmin cartridge is also available, so we’ll add it as well.

$> rhc-ctl-app -a sellmore -e add-phpmyadmin-3.4

phpMyAdmin 3.4 added. Please make note of these credentials:

   Root User: admin
   Root Password: xxxxx

URL: https://sellmore-[domain name].rhcloud.com/phpmyadmin/

Open a browser and go to the URL shown, then login as admin with the password reported by the previous command.

Caution
It’s a good idea to create another user with limited privileges (select, insert, update, delete, create, index and drop) on the same database.

You can also shell into the domain and control MySQL using the MySQL client. You’ll need to connect using the hostname provided when you added the cartridge since it’s running on a different interface (not through a local socket).

$> mysql -u $OPENSHIFT_DB_USERNAME -p$OPENSHIFT_DB_PASSWORD -h $OPENSHIFT_DB_HOST

Now we’ll configure our application to use OpenShift’s MySQL database when running in the cloud.

Switching the application datastore to MySQL

The JBoss AS 7 cartridge comes configured out of the box with datasources for H2 (embedded), MySQL and PostgreSQL. The datasources for MySQL and PostgreSQL are enabled automatically when the respective cartridges are added. You can find this configuration in .openshift/config/standalone.xml.

Here’s the datasource name that cooresponds to the MySQL connection pool:

java:jboss/datasources/MysqlDS

The connection URL uses values that are automatically populated via environment variables maintained by OpenShift.

jdbc:mysql://${OPENSHIFT_DB_HOST}:${OPENSHIFT_DB_PORT}/${OPENSHIFT_APP_NAME}

All you need to do is open up the src/main/resources/META-INF/persistence.xml and set the JTA datasource:

src/main/resources/META-INF/persistence.xml (fragment)
<jta-data-source>java:jboss/datasources/MysqlDS</jta-data-source>

If you want to use PostgreSQL, follow the steps above for setting up MySQL, but replace it with the PostgreSQL cartridge (postgresql-8.4). Then, you’ll use this datasource in your persistence.xml:

src/main/resources/META-INF/persistence.xml (fragment)
<jta-data-source>java:jboss/datasources/PostgreSQLDS</jta-data-source>

You can connect to the PostgreSQL prompt on the domain using this command:

$> psql -h $OPENSHIFT_DB_HOST -U $OPENSHIFT_DB_USERNAME -d $OPENSHIFT_APP_NAME

Advanced Deployment

Building with Jenkins

Jenkins is a continous integration (CI) server. When installed in an OpenShift environment, Jenkins takes over as the build manager for your application. You now have two options for how to build and deploy on OpenShift:

Building without Jenkins

Uses your application space as part of the build and test process. Because of this, the application is stopped to free memory while the build is running.

Building with Jenkins

Uses dedicated application space that can be larger then the application runtime space. Because the build happens in its own dedicated jail, the running application is not shutdown or changed in any way until after the build is a success.

Here are the benefits to using Jenkins:

  • Archived build information

  • No application downtime during the build process

  • Failed builds do not get deployed (leaving the previous working version in place).

  • Jenkins builders have additional resources like memory and storage

  • A large community of Jenkins plugins (300+)

To enable Jenkins to use with an existing application, you first create a dedicated jenkins application:

$> rhc-create-app -a builds -t jenkins-1.4

Then you add the Jenkins client to your own application:

$> rhc-ctl-app -a sellmore -e add-jenkins-client-1.4

Make a note of the admin account password for Jenkins and point your browser at the following URL:

http://builds-[domain name].rhcloud.com

Once you are there, you can click "log in" in the top right of the Jenkins window to sign in and start tweaking the Jenkins configuration.

Now you simply have to do a git push to remote branch and Jenkins will take over building and deploying your application.

The pre-Jenkins way of doing this was to fire off a command line build and dump the output to the screen. You’ll notice that this output is replaced with a URL where you can view the output and status of the build.

Integration Testing

Writing real cloud tests with Arquillian

Bring your tests to the runtime instead of managing the runtime from your test. Isn’t the cloud one of those runtimes? It sure is!

Let’s use Arquillian to write some tests that run on a local JBoss AS instance. Later, we’ll get them running on OpenShift.

Setting up Arquillian requires thought. Let’s put those 10,000 monkeys to work again. Open up Forge and see if it can find a plugin to help us get started with Arquillian.

$forge> forge find-plugin arquillian

Sure enough, there it is!

- arquillian (org.arquillian.forge:arquillian-plugin:::1.0.0-SNAPSHOT)
       Author: Paul Bakker <paul.bakker.nl@gmail.com>
       Website: http://www.jboss.org/arquillian
       Location: git://github.com/forge/plugin-arquillian.git
       Tags: arquillian, jboss, testing, junit, testng, integration testing, tests, CDI, java ee
       Description: Integration Testing Framework

Let’s snag it.

$forge> forge install-plugin arquillian

That will clone the plugin source, build it and install it into the Forge shell. Once it’s finished, we can get straight to the Arquillian setup.

We’ll first create a profile for testing on a running JBoss AS 7 instance on our own machine (here, the term remote refers to deployment protocol, not where the server is running).

$forge> setup arquillian --container JBOSS_AS_REMOTE_7.X
Note

At the time of writing, the plugin puts the Arquillian BOM[Bill of Materials] dependency in the wrong section. Move it into the dependencyManagement section below the others:

pom.xml
<dependencyManagement>
  <dependencies>
    <dependency>
      <groupId>org.jboss.arquillian</groupId>
      <artifactId>arquillian-bom</artifactId>
      <version>1.0.0.Final</version>
      <type>pom</type>
      <scope>import</scope>
    </dependency>
  </dependencies>
</dependencyManagement>

You can also remove the version from the arquillian-junit-container dependency. Both of these problems will be fixed in the next release of the plugin.

We can also use the Forge Arquillian plugin to create tests for us. Let’s create an integration test for one of the services created earlier:

$forge> arquillian create-test --class com.acme.sellmore.rest.ItemEndpoint --enableJPA

This test is going to read and write to a database. You probably don’t want to mix test data with application data, so first copy the JPA descriptor (persistence.xml) to the test classpath and prefix the file with test- so it doesn’t get mixed up:

$forge> cd ~~
$forge> cp src/main/resources/META-INF/persistence.xml src/test/resources/test-persistence.xml

Make sure the test-persistence.xml uses the ExampleDS datasource (or whatever you want to use for tests).

Next, open up the test in your editor so we can work it into a useful test. Begin by updating the ShrinkWrap archive builder to snag the JPA descriptor from the test classpath (instead of the production one):

src/test/java/com/acme/sellmore/rest/ItemEndpointTest.java (fragment)
.addAsManifestResource("test-persistence.xml", "persistence.xml")

Assign the @Test method a meaninful name and replace the contents with logic to validate that an item can be created in one transaction and retrieved in another:

src/test/java/com/acme/sellmore/rest/ItemEndpointTest.java (fragment)
@Test
public void should_insert_and_select_item() {
    Item item = new Item();
    item.setName("Widget");
    item.setPrice(5.0);
    item.setStock(100);
    item = itemendpoint.create(item);
    Long id = item.getId();
    Assert.assertNotNull(id);
    Assert.assertTrue(id > 0);
    Assert.assertEquals(item.getVersion(), 0);

    item = itemendpoint.findById(id);
    Assert.assertNotNull(item);
    Assert.assertEquals("Widget", item.getName());
}

The test is ready to run. First, start JBoss AS 7.

$> cd $JBOSS_HOME
$> ./bin/standalone.sh

Run the Arquillian test on this instance by activating the cooresponding profile when running the Maven test command:

$forge> test --profile JBOSS_AS_REMOTE_7.X

If things go we’ll, the tests will pass and you’ll see some Hibernate queries in the JBoss AS console. “Green bar!”

The previous test runs inside the container. Let’s write another test that acts as a client to the REST endpoint. To keep effort to a minimum, we’ll use the Apache HttpComponents HttpClient library to invoke the HTTP endpoints. We can get Forge to add it to our build:

$forge> project add-dependency org.apache.httpcomponents:httpclient:4.1.2:test

Let’s REST!

Sigh. There’s no better way to do this at the moment, so copy the previous test and rename it to ItemEndpointClientTest (rename both the file and the class name). Then, replace the class definition with the following source:

src/test/java/com/acme/sellmore/rest/ItemEndpointClientTest.java
@RunWith(Arquillian.class)
public class ItemEndpointClientTest {
    @ArquillianResource
    private URL deploymentUrl;

    @Deployment(testable = false)
    public static WebArchive createDeployment() {
        return ShrinkWrap.create(WebArchive.class, "test.war")
                .addClasses(Item.class, ItemEndpoint.class)
                .addAsResource("META-INF/persistence.xml")
                .addAsWebInfResource(EmptyAsset.INSTANCE, "beans.xml")
                .setWebXML(new File("src/main/webapp/WEB-INF/web.xml"));
    }

    @Test
    public void should_post_update_and_get_item() {
        DefaultHttpClient client = new DefaultHttpClient();
        String itemResourceUrl = deploymentUrl + "rest/item";

        String ITEM_XML = "<item>%1$s<name>Widget</name><price>5.0</price><stock>%3$d</stock>%1$s</item>";

        // POST new item
        HttpPost post = new HttpPost(itemResourceUrl);
        post.setEntity(createXmlEntity(String.format(ITEM_XML, "", "", 99)));

        String result = execute(post, client);
        assertEquals(String.format(ITEM_XML, "<id>1</id>", "<version>0</version>", 99), result);

        // PUT update to item 1
        HttpPut put = new HttpPut(itemResourceUrl + "/1");
        put.setEntity(createXmlEntity(String.format(ITEM_XML, "", "", 98)));

        execute(put, client);

        // GET item 1
        HttpGet get = new HttpGet(itemResourceUrl + "/1");
        get.setHeader("Accepts", MediaType.APPLICATION_XML);

        result = execute(get, client);
        assertEquals(String.format(ITEM_XML, "<id>1</id>", "<version>1</version>", 98), result);

        client.getConnectionManager().shutdown();
    }
}

Also add these two private helper methods (to hide away some of the boilerplate code):

src/test/java/com/acme/sellmore/rest/ItemEndpointClientTest.java (fragment)
private HttpEntity createXmlEntity(final String xml) {
    ContentProducer cp = new ContentProducer() {
        public void writeTo(OutputStream outstream) throws IOException {
            Writer writer = new OutputStreamWriter(outstream, "UTF-8");
            writer.write(xml);
            writer.flush();
        }
    };

    AbstractHttpEntity entity = new EntityTemplate(cp);
    entity.setContentType(MediaType.APPLICATION_XML);
    return entity;
}

private String execute(final HttpUriRequest request, final HttpClient client) {
    try {
        System.out.println(request.getMethod() + " " + request.getURI());
        return client.execute(request, new BasicResponseHandler())
                .replaceFirst("<\\?xml.*\\?>", "").trim();
    }
    catch (Exception e) {
        e.printStackTrace();
        Assert.fail(e.getMessage());
        return null;
    }
    finally {
        request.abort();
    }
}

Let’s see if these endpoints do what they claim to do.

$forge> test --profile JBOSS_AS_REMOTE_7.X

If you get a test failure, it may be because the type the endpoints are configured to consume is incorrect. Open the ItemEndpoint class and replace all instances of @Consumes with:

src/main/java/com/acme/sellmore/rest/ItemEndpoint.java
@Consumes(MediaType.APPLICATION_XML)

Run the tests again. With any luck, this time you’ll be chanting “Green bar!”

Running the Arquillian tests on OpenShift

Okay, now you can say it. "Let’s take it to the cloud!" If they work there, they’ll work anywhere :)

It’s up to you whether you want to run the tests on the same OpenShift application as the production application or whether you want to create a dedicated application. We’ll assume you’re going to create a dedicated application. Let’s call it ike.

$> rhc-create-app -t jbossas-7 -a ike

You’ll also need an Arquillian profile. The Forge plugin doesn’t honor the OpenShift adapter yet, so you’ll have splice this profile into the pom.xml by hand:

pom.xml (fragment)
<profile>
  <id>OPENSHIFT_1.X</id>
  <dependencies>
    <dependency>
      <groupId>org.jboss.arquillian.container</groupId>
      <artifactId>arquillian-openshift-express</artifactId>
      <version>1.0.0.Beta1</version>
      <scope>test</scope>
    </dependency>
  </dependencies>
</profile>

The Arquillian OpenShift adapter also uses git push to deploy the test archive. In order for that to work, it needs to know where it’s pushing. In other words, it needs a little configuration.

Seed an arquillian.xml descriptor using a known container (in this case, JBoss AS 7 remote):

$forge> arquillian configure-container --profile JBOSS_AS_REMOTE_7.X

Next, replace the container element with the following XML:

src/test/resources/arquillian.xml (fragment)
<container qualifier="OPENSHIFT_1.X">
  <configuration>
    <property name="namespace">mojavelinux</property>
    <property name="application">ike</property>
    <property name="sshUserName">02b0951a5ed54c98b54c41a7f2efbda8</property>
    <!-- Passphrase can be specified using the environment variable SSH_PASSPHRASE -->
    <!-- <property name="passphrase"></property> -->
    <property name="login">dan.j.allen@gmail.com</property>
  </configuration>
</container>

You can either put the passphrase for your SSH key in the descriptor or you can export the SSH_PASSPHRASE environment variable:

$> export SSH_PASSPHRASE=[libra_id_rsa passphrase]

To activate this container configuration, write the name of the qualifier to the arquillian.launch file (alternatively, you can select the configuration using the -Darquillian.launch flag when you run Maven):

$> echo "OPENSHIFT_1.X" > src/test/resources/arquillian.launch

Are you ready to see some tests run in the cloud?

$forge> test --profile OPENSHIFT_1.X

You may want to tail the log files in another terminal to moniter the progress:

$> rhc-tail-files -a ike

If you can’t see the green bar, look above you :)

Hosting Configuration

Making your application a top-level domain

Do we expect that you’ll use *.rhcloud.com for all of your public websites? Of course not! That’s where the alias feature comes in.

You can create a domain alias for any OpenShift application using this command:

$> rhc-ctl-app -a sellmore -c add-alias --alias sellmore.com

Next, you point the DNS for your domain name to the IP address of your OpenShift server (or you can cheat by putting it in /etc/hosts).

Now you can access the application from the following URL:

Congratulations! You’re OpenShift-hosted.

Summary

In this tutorial, we learned how to:

  • Register an account at OpenShift

  • Install the Ruby-based OpenShift client tools

  • Create our own OpenShift domain

  • Create an OpenShift application using the JBoss AS 7 cartridge on that domain

  • Add a remote OpenShift git repo to our own repo to deploy an existing app

  • Deploy a Java EE application to OpenShift

  • Work with the in-memory database

  • Configure H2 to persist the database file to the application’s data directory

  • Configure MySQL and phpmyadmin cartridges in OpenShift

  • Configure our Java EE application to use the MySQL database running on the OpenShift domain

Resources

@nurnberg
Copy link

Very good article!

I just get the following error when trying to install the Arquillian plugin:

Running test.integration.PluginTest
log4j:ERROR Could not create an Appender. Reported error follows.
java.lang.ClassNotFoundException: org.apache.log4j.rolling.RollingFileAppender
at java.net.URLClassLoader$1.run(URLClassLoader.java:202)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:190)
at java.lang.ClassLoader.loadClass(ClassLoader.java:306)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:301)
at java.lang.ClassLoader.loadClass(ClassLoader.java:247)
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Class.java:169)
at org.apache.log4j.helpers.Loader.loadClass(Loader.java:198)
at org.apache.log4j.xml.DOMConfigurator.parseAppender(DOMConfigurator.java:247)
at org.apache.log4j.xml.DOMConfigurator.findAppenderByName(DOMConfigurator.java:176)
at org.apache.log4j.xml.DOMConfigurator.findAppenderByReference(DOMConfigurator.java:191)
at org.apache.log4j.xml.DOMConfigurator.parseChildrenOfLoggerElement(DOMConfigurator.java:523)
at org.apache.log4j.xml.DOMConfigurator.parseRoot(DOMConfigurator.java:492)
at org.apache.log4j.xml.DOMConfigurator.parse(DOMConfigurator.java:1001)
at org.apache.log4j.xml.DOMConfigurator.doConfigure(DOMConfigurator.java:867)
at org.apache.log4j.xml.DOMConfigurator.doConfigure(DOMConfigurator.java:773)
at org.apache.log4j.helpers.OptionConverter.selectAndConfigure(OptionConverter.java:483)
at org.apache.log4j.LogManager.(LogManager.java:127)
at org.slf4j.impl.Log4jLoggerFactory.getLogger(Log4jLoggerFactory.java:73)
at org.slf4j.LoggerFactory.getLogger(LoggerFactory.java:249)
at org.slf4j.cal10n.LocLoggerFactory.getLocLogger(LocLoggerFactory.java:59)
at org.jboss.weld.logging.LoggerFactory.getLogger(LoggerFactory.java:47)
at org.jboss.weld.bootstrap.WeldBootstrap.(WeldBootstrap.java:124)
at org.jboss.arquillian.container.weld.ee.embedded_1_1.mock.TestContainer.(TestContainer.java:212)
at org.jboss.arquillian.container.weld.ee.embedded_1_1.WeldEEMockContainer.deploy(WeldEEMockContainer.java:66)
at org.jboss.arquillian.impl.handler.ContainerDeployer.callback(ContainerDeployer.java:62)
at org.jboss.arquillian.impl.handler.ContainerDeployer.callback(ContainerDeployer.java:50)
at org.jboss.arquillian.impl.event.MapEventManager.fire(MapEventManager.java:63)
at org.jboss.arquillian.impl.context.AbstractEventContext.fire(AbstractEventContext.java:115)
at org.jboss.arquillian.impl.EventTestRunnerAdaptor.beforeClass(EventTestRunnerAdaptor.java:96)
at org.jboss.arquillian.junit.Arquillian$2.evaluate(Arquillian.java:162)
at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:31)
at org.jboss.arquillian.junit.Arquillian$3$1.evaluate(Arquillian.java:186)
at org.jboss.arquillian.junit.Arquillian$MultiStatementExecutor.execute(Arquillian.java:297)
at org.jboss.arquillian.junit.Arquillian$3.evaluate(Arquillian.java:182)
at org.junit.runners.ParentRunner.run(ParentRunner.java:236)
at org.jboss.arquillian.junit.Arquillian.run(Arquillian.java:127)
at org.apache.maven.surefire.junit4.JUnit4TestSet.execute(JUnit4TestSet.java:35)
at org.apache.maven.surefire.junit4.JUnit4Provider.executeTestSet(JUnit4Provider.java:115)
at org.apache.maven.surefire.junit4.JUnit4Provider.invoke(JUnit4Provider.java:97)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.apache.maven.surefire.booter.ProviderFactory$ClassLoaderProxy.invoke(ProviderFactory.java:103)
at $Proxy0.invoke(Unknown Source)
at org.apache.maven.surefire.booter.SurefireStarter.invokeProvider(SurefireStarter.java:150)
at org.apache.maven.surefire.booter.SurefireStarter.runSuitesInProcess(SurefireStarter.java:91)
at org.apache.maven.surefire.booter.ForkedBooter.main(ForkedBooter.java:69)
log4j:WARN No appenders could be found for logger (org.jboss.weld.Version).
log4j:WARN Please initialize the log4j system properly.
log4j:WARN See http://logging.apache.org/log4j/1.2/faq.html#noconfig for more info.
Tests run: 46, Failures: 0, Errors: 43, Skipped: 3, Time elapsed: 11.451 sec <<< FAILURE!

@mojavelinux
Copy link
Author

I am also experiencing a problem installing the Arquillian Forge plugin in Forge 1.0.0.Beta5. Paul is looking into it. Feel free to file a JIRA: https://issues.jboss.org/browse/FORGE

@britztopher
Copy link

I've been getting this error _ERROR_ [scaffold from-entity] Error generating default scaffolding when i run the command scaffold from-entity ~.domain.* --scaffoldType faces --overwrite. However, when I remove the Customer.java class the error goes away. Being even more specific, I have run all the field entries for the Customer.java entity class, but when i get to issuing the first relationship on the Customer.java class involving the Address it throws the above errors. Also, FYI I am using the Eclipse plugin with the Beta5 forge release.

@mojavelinux
Copy link
Author

I'm not able to reproduce the problem you are reporting. Could you post this problem to the users mailinglist, including a bit more detail about the steps you took?

https://lists.jboss.org/mailman/listinfo/forge-users

I'm curious, does the forge script work for you when you run it from top to bottom (assuming you start with no project)?

@britztopher
Copy link

I am running it without openshift, so I am just starting on the forge part. The script works all the way till you get up to the scaffold command. I have run this manually and NOT using the script way because I wanted to learn the forge keywords. Is there a forge log anywhere? The error i am getting is very vague.

@lincolnthree
Copy link

Hi guys,

The error being reported when installing the Arquillian plugin should not actually cause any failures, but it's been resolved in the latest SNAPSHOT of Forge. (You can get it at http://jboss.org/forge - then look for Snapshot Downloads)

Regarding the scaffolding error. I'll look into it, but I have noticed some strange issues regarding executing this command from within scripts.

~Lincoln

@britztopher
Copy link

Thats the thing, I am not executing this from a script its when I run each command manually. Weird right? Anyways deleted old project, and now I am starting fresh. Ill let you know if everything goes as planned.

@lincolnthree
Copy link

Running this script directly with run-url seems to be working fine for me on the latest SNAPSHOT of Forge.

@lincolnthree
Copy link

lincolnthree commented Jan 24, 2012 via email

@britztopher
Copy link

same error Below is my exact commands:

[no project] tests $ new-project
? [named=The name of the new project (of type java.lang.String)]: arquilTest
? [topLevelPackage=The top-level java package for the project [e.g: "com.example.project"](of type java.lang.String)]: com.arquilTest.project
? Use [/home/cbritz/arquillian/tests/arquilTest] as project directory? [Y/n] y
_SUCCESS_ Created project [arquilTest] in new working directory [/home/cbritz/arquillian/tests/arquilTest]
Wrote /home/cbritz/arquillian/tests/arquilTest
Wrote /home/cbritz/arquillian/tests/arquilTest/pom.xml
Wrote /home/cbritz/arquillian/tests/arquilTest/src/main/java
Wrote /home/cbritz/arquillian/tests/arquilTest/src/test/java
Wrote /home/cbritz/arquillian/tests/arquilTest/src/main/resources
Wrote /home/cbritz/arquillian/tests/arquilTest/src/test/resources
Wrote /home/cbritz/arquillian/tests/arquilTest/src/main/resources/META-INF/forge.xml
[arquilTest] arquilTest $ scaffold setup --
--scaffoldType --overwrite --usingTemplate
[arquilTest] arquilTest $ scaffold setup --
--scaffoldType --overwrite --usingTemplate
[arquilTest] arquilTest $ scaffold setup --scaffoldType faces
? Scaffold provider [faces] is not installed. Install it? [Y/n] y
? Facet [forge.maven.WebResourceFacet] requires packaging type(s) [war], but is currently [jar]. Update packaging? (Note: this could deactivate other plugins in your project.) [Y/n] y
_SUCCESS_ Installed [forge.maven.WebResourceFacet] successfully.
Warning: The encoding 'UTF-8' is not supported by the Java runtime.
_SUCCESS_ Installed [forge.spec.jpa] successfully.
_SUCCESS_ Installed [forge.spec.cdi] successfully.
Warning: The encoding 'UTF-8' is not supported by the Java runtime.
_SUCCESS_ Installed [forge.spec.servlet] successfully.
_SUCCESS_ Installed [forge.spec.jsf] successfully.
_SUCCESS_ Installed [faces] successfully.
Warning: The encoding 'UTF-8' is not supported by the Java runtime.
Warning: The encoding 'UTF-8' is not supported by the Java runtime.
Wrote /home/cbritz/arquillian/tests/arquilTest/src/main/webapp
Wrote /home/cbritz/arquillian/tests/arquilTest/pom.xml
Wrote /home/cbritz/arquillian/tests/arquilTest/src/main/resources/META-INF/persistence.xml
Wrote /home/cbritz/arquillian/tests/arquilTest/src/main/webapp/WEB-INF/beans.xml
Wrote /home/cbritz/arquillian/tests/arquilTest/src/main/webapp/WEB-INF/web.xml
Wrote /home/cbritz/arquillian/tests/arquilTest/src/main/webapp/WEB-INF/faces-config.xml
Wrote /home/cbritz/arquillian/tests/arquilTest/src/main/webapp/favicon.ico
Wrote /home/cbritz/arquillian/tests/arquilTest/src/main/webapp/resources/scaffold/paginator.xhtml
Wrote /home/cbritz/arquillian/tests/arquilTest/src/main/webapp/resources/scaffold/page.xhtml
Wrote /home/cbritz/arquillian/tests/arquilTest/src/main/webapp/index.html
Wrote /home/cbritz/arquillian/tests/arquilTest/src/main/webapp/index.xhtml
Wrote /home/cbritz/arquillian/tests/arquilTest/src/main/webapp/error.xhtml
Wrote /home/cbritz/arquillian/tests/arquilTest/src/main/webapp/resources/background.gif
Wrote /home/cbritz/arquillian/tests/arquilTest/src/main/webapp/resources/favicon.ico
Wrote /home/cbritz/arquillian/tests/arquilTest/src/main/webapp/resources/forge-logo.png
Wrote /home/cbritz/arquillian/tests/arquilTest/src/main/webapp/resources/forge-style.css
Wrote /home/cbritz/arquillian/tests/arquilTest/src/main/webapp/resources/jboss-community.png
Wrote /home/cbritz/arquillian/tests/arquilTest/src/main/webapp/resources/search.png
[arquilTest] arquilTest $ scaffold setup --
--scaffoldType --overwrite --usingTemplate
[arquilTest] arquilTest $ scaffold setup --scaffoldType faces
? [/home/cbritz/arquillian/tests/arquilTest/src/main/webapp/resources/scaffold/paginator.xhtml] File exists, overwrite? [Y/n] y
? [/home/cbritz/arquillian/tests/arquilTest/src/main/webapp/resources/scaffold/page.xhtml] File exists, overwrite? [Y/n] y
? [/home/cbritz/arquillian/tests/arquilTest/src/main/webapp/index.html] File exists, overwrite? [Y/n] y
? [/home/cbritz/arquillian/tests/arquilTest/src/main/webapp/index.xhtml] File exists, overwrite? [Y/n] y
? [/home/cbritz/arquillian/tests/arquilTest/src/main/webapp/error.xhtml] File exists, overwrite? [Y/n] y
? [/home/cbritz/arquillian/tests/arquilTest/src/main/webapp/resources/background.gif] File exists, overwrite? [Y/n] y
? [/home/cbritz/arquillian/tests/arquilTest/src/main/webapp/resources/favicon.ico] File exists, overwrite? [Y/n] y
? [/home/cbritz/arquillian/tests/arquilTest/src/main/webapp/resources/forge-logo.png] File exists, overwrite? [Y/n] y
? [/home/cbritz/arquillian/tests/arquilTest/src/main/webapp/resources/forge-style.css] File exists, overwrite? [Y/n] y
? [/home/cbritz/arquillian/tests/arquilTest/src/main/webapp/resources/jboss-community.png] File exists, overwrite? [Y/n] y
? [/home/cbritz/arquillian/tests/arquilTest/src/main/webapp/resources/search.png] File exists, overwrite? [Y/n] y
? Your web.xml already contains an error page for 404 status codes, replace it? [Y/n] y
? Your web.xml already contains an error page for 500 status codes, replace it? [Y/n] y
Warning: The encoding 'UTF-8' is not supported by the Java runtime.
Warning: The encoding 'UTF-8' is not supported by the Java runtime.
Wrote /home/cbritz/arquillian/tests/arquilTest/src/main/webapp/resources/scaffold/paginator.xhtml
Wrote /home/cbritz/arquillian/tests/arquilTest/src/main/webapp/resources/scaffold/page.xhtml
Wrote /home/cbritz/arquillian/tests/arquilTest/src/main/webapp/index.html
Wrote /home/cbritz/arquillian/tests/arquilTest/src/main/webapp/index.xhtml
Wrote /home/cbritz/arquillian/tests/arquilTest/src/main/webapp/error.xhtml
Wrote /home/cbritz/arquillian/tests/arquilTest/src/main/webapp/resources/background.gif
Wrote /home/cbritz/arquillian/tests/arquilTest/src/main/webapp/resources/favicon.ico
Wrote /home/cbritz/arquillian/tests/arquilTest/src/main/webapp/resources/forge-logo.png
Wrote /home/cbritz/arquillian/tests/arquilTest/src/main/webapp/resources/forge-style.css
Wrote /home/cbritz/arquillian/tests/arquilTest/src/main/webapp/resources/jboss-community.png
Wrote /home/cbritz/arquillian/tests/arquilTest/src/main/webapp/resources/search.png
Wrote /home/cbritz/arquillian/tests/arquilTest/src/main/webapp/WEB-INF/web.xml
[arquilTest] arquilTest $ y
_ERROR_ No such command: y
[arquilTest] arquilTest $ persistence setup --provider
--provider --provider-version
[arquilTest] arquilTest $ persistence setup --provider HIBERNATE --container JBOSS_AS
JBOSS_AS6 JBOSS_AS7
[arquilTest] arquilTest $ persistence setup --provider HIBERNATE --container JBOSS_AS7
_INFO_ Setting transaction-type="JTA"
_INFO_ Using example data source [java:jboss/datasources/ExampleDS]
Warning: The encoding 'UTF-8' is not supported by the Java runtime.
? The JPA provider [HIBERNATE], also supplies extended APIs. Install these as well? [y/N] y
Install which version of [org.hibernate:hibernate-entitymanager:::]?

1 - [org.hibernate:hibernate-entitymanager:::3.3.1.ga]
2 - [org.hibernate:hibernate-entitymanager:::3.3.2.Beta1]
3 - [org.hibernate:hibernate-entitymanager:::3.3.2.GA]
4 - [org.hibernate:hibernate-entitymanager:::3.4.0.CR1]
5 - [org.hibernate:hibernate-entitymanager:::3.4.0.CR2]
6 - [org.hibernate:hibernate-entitymanager:::3.4.0.GA]
7 - [org.hibernate:hibernate-entitymanager:::3.5.0-Beta-2]
8 - [org.hibernate:hibernate-entitymanager:::3.5.0-Beta-3]
9 - [org.hibernate:hibernate-entitymanager:::3.5.0-Beta-4]
10 - [org.hibernate:hibernate-entitymanager:::3.5.0-CR-1]
11 - [org.hibernate:hibernate-entitymanager:::3.5.0-CR-2]
12 - [org.hibernate:hibernate-entitymanager:::3.5.0.Beta-1]
13 - [org.hibernate:hibernate-entitymanager:::3.5.0-Final]
14 - [org.hibernate:hibernate-entitymanager:::3.5.1-Final]
15 - [org.hibernate:hibernate-entitymanager:::3.5.2-Final]
16 - [org.hibernate:hibernate-entitymanager:::3.5.3-Final]
17 - [org.hibernate:hibernate-entitymanager:::3.5.4-Final]
18 - [org.hibernate:hibernate-entitymanager:::3.5.5-Final]
19 - [org.hibernate:hibernate-entitymanager:::3.5.6-Final]
20 - [org.hibernate:hibernate-entitymanager:::3.6.0.Beta1]
21 - [org.hibernate:hibernate-entitymanager:::3.6.0.Beta2]
22 - [org.hibernate:hibernate-entitymanager:::3.6.0.Beta3]
23 - [org.hibernate:hibernate-entitymanager:::3.6.0.Beta4]
24 - [org.hibernate:hibernate-entitymanager:::3.6.0.CR1]
25 - [org.hibernate:hibernate-entitymanager:::3.6.0.CR2]
26 - [org.hibernate:hibernate-entitymanager:::3.6.0.Final]
27 - [org.hibernate:hibernate-entitymanager:::3.6.1.Final]
28 - [org.hibernate:hibernate-entitymanager:::3.6.2.Final]
29 - [org.hibernate:hibernate-entitymanager:::3.6.3.Final]
30 - [org.hibernate:hibernate-entitymanager:::3.6.4.Final]
31 - [org.hibernate:hibernate-entitymanager:::3.6.5-SNAPSHOT]
32 - [org.hibernate:hibernate-entitymanager:::3.6.5.Final]
33 - [org.hibernate:hibernate-entitymanager:::3.6.6-SNAPSHOT]
34 - [org.hibernate:hibernate-entitymanager:::3.6.6.Final]
35 - [org.hibernate:hibernate-entitymanager:::3.6.7-SNAPSHOT]
36 - [org.hibernate:hibernate-entitymanager:::3.6.7.Final]
37 - [org.hibernate:hibernate-entitymanager:::3.6.8-SNAPSHOT]
38 - [org.hibernate:hibernate-entitymanager:::3.6.8.Final]
39 - [org.hibernate:hibernate-entitymanager:::3.6.9-SNAPSHOT]
40 - [org.hibernate:hibernate-entitymanager:::3.6.9.Final]
41 - [org.hibernate:hibernate-entitymanager:::3.6.10-SNAPSHOT]
42 - [org.hibernate:hibernate-entitymanager:::4.0.0-SNAPSHOT]
43 - [org.hibernate:hibernate-entitymanager:::4.0.0.Alpha1]
44 - [org.hibernate:hibernate-entitymanager:::4.0.0.Alpha2]
45 - [org.hibernate:hibernate-entitymanager:::4.0.0.Alpha3]
46 - [org.hibernate:hibernate-entitymanager:::4.0.0.Beta1]
47 - [org.hibernate:hibernate-entitymanager:::4.0.0.Beta2]
48 - [org.hibernate:hibernate-entitymanager:::4.0.0.Beta3]
49 - [org.hibernate:hibernate-entitymanager:::4.0.0.Beta4]
50 - [org.hibernate:hibernate-entitymanager:::4.0.0.Beta5]
51 - [org.hibernate:hibernate-entitymanager:::4.0.0.CR1]
52 - [org.hibernate:hibernate-entitymanager:::4.0.0.CR2]
53 - [org.hibernate:hibernate-entitymanager:::4.0.0.CR3]
54 - [org.hibernate:hibernate-entitymanager:::4.0.0.CR4]
55 - [org.hibernate:hibernate-entitymanager:::4.0.0.CR5]
56 - [org.hibernate:hibernate-entitymanager:::4.0.0.CR6]
57 - [org.hibernate:hibernate-entitymanager:::4.0.0.CR7]
58 - [org.hibernate:hibernate-entitymanager:::4.0.0.Final]
59 - [org.hibernate:hibernate-entitymanager:::4.0.1-SNAPSHOT]
60 - [org.hibernate:hibernate-entitymanager:::4.0.1.Final]
61 - [org.hibernate:hibernate-entitymanager:::4.1.0-SNAPSHOT]*

? Choose an option by typing the number of the selection [_-default] [0] 60
Wrote /home/cbritz/arquillian/tests/arquilTest/src/main/resources/META-INF/persistence.xml
Wrote /home/cbritz/arquillian/tests/arquilTest/pom.xml
[arquilTest] arquilTest $ validation setup --provider HIBERNATE_VALIDATOR
Warning: The encoding 'UTF-8' is not supported by the Java runtime.
_SUCCESS* Installed [forge.spec.validation] successfully.
Which version of hibernate-validator would you like to use?

1 - [org.hibernate:hibernate-validator:::4.1.0.Final]
2 - [org.hibernate:hibernate-validator:::4.2.0-SNAPSHOT]
3 - [org.hibernate:hibernate-validator:::4.2.0.Beta1]
4 - [org.hibernate:hibernate-validator:::4.2.0.Beta2]
5 - [org.hibernate:hibernate-validator:::4.2.0.CR1]
6 - [org.hibernate:hibernate-validator:::4.2.0.Final]
7 - [org.hibernate:hibernate-validator:::4.3.0-SNAPSHOT]*

? Choose an option by typing the number of the selection [*-default] [0] 6
Warning: The encoding 'UTF-8' is not supported by the Java runtime.
Wrote /home/cbritz/arquillian/tests/arquilTest/src/main/resources/META-INF/validation.xml
Wrote /home/cbritz/arquillian/tests/arquilTest/pom.xml
[arquilTest] arquilTest $ entity --named Customer --package ~.domain
Created @entity [com.arquilTest.project.domain.Customer]
Picked up type : com.arquilTest.project.domain.Customer
Wrote /home/cbritz/arquillian/tests/arquilTest/src/main/java/com/arquilTest/project/domain/Customer.java
[arquilTest] Customer.java $ field string --named firstName
Added field to com.arquilTest.project.domain.Customer: @column private String firstName;

Wrote /home/cbritz/arquillian/tests/arquilTest/src/main/java/com/arquilTest/project/domain/Customer.java
[arquilTest] Customer.java $ field string --named lastName
Added field to com.arquilTest.project.domain.Customer: @column private String lastName;

Wrote /home/cbritz/arquillian/tests/arquilTest/src/main/java/com/arquilTest/project/domain/Customer.java
[arquilTest] Customer.java $ field temporal --type DATE --named birthDate
Added field to com.arquilTest.project.domain.Customer: private @TeMPOraL(TemporalType.DATE) Date birthDate;

Wrote /home/cbritz/arquillian/tests/arquilTest/src/main/java/com/arquilTest/project/domain/Customer.java
[arquilTest] Customer.java $ entity --named Item
Created @entity [com.arquilTest.project.domain.Item]
Picked up type : com.arquilTest.project.domain.Item
Wrote /home/cbritz/arquillian/tests/arquilTest/src/main/java/com/arquilTest/project/domain/Item.java
[arquilTest] Item.java $ fi
fingerprint find field
[arquilTest] Item.java $ field string --named name
Added field to com.arquilTest.project.domain.Item: @column private String name;

Wrote /home/cbritz/arquillian/tests/arquilTest/src/main/java/com/arquilTest/project/domain/Item.java
[arquilTest] Item.java $ field number --named price --type java.lang.Double
Added field to com.arquilTest.project.domain.Item: @column private Double price;

Wrote /home/cbritz/arquillian/tests/arquilTest/src/main/java/com/arquilTest/project/domain/Item.java
[arquilTest] Item.java $ field int --named stock
Added field to com.arquilTest.project.domain.Item: @column private int stock;

Wrote /home/cbritz/arquillian/tests/arquilTest/src/main/java/com/arquilTest/project/domain/Item.java
[arquilTest] Item.java $ cd ..
[arquilTest] domain $ entity --named ProductOrder
Created @entity [com.arquilTest.project.domain.ProductOrder]
Picked up type : com.arquilTest.project.domain.ProductOrder
Wrote /home/cbritz/arquillian/tests/arquilTest/src/main/java/com/arquilTest/project/domain/ProductOrder.java
[arquilTest] ProductOrder.java $ field manyTo
manyToMany manyToOne
[arquilTest] ProductOrder.java $ field manyToOne --named customer --fieldType ~.domain.Customer.java --inverseFieldName orders
Wrote /home/cbritz/arquillian/tests/arquilTest/src/main/java/com/arquilTest/project/domain/Customer.java
Wrote /home/cbritz/arquillian/tests/arquilTest/src/main/java/com/arquilTest/project/domain/ProductOrder.java
[arquilTest] ProductOrder.java $ cd ../Customer.java
[arquilTest] Customer.java $ entity --named Profile
Created @entity [com.arquilTest.project.domain.Profile]
Picked up type : com.arquilTest.project.domain.Profile
Wrote /home/cbritz/arquillian/tests/arquilTest/src/main/java/com/arquilTest/project/domain/Profile.java
[arquilTest] Profile.java $ field string --named bio
Added field to com.arquilTest.project.domain.Profile: @column private String bio;

Wrote /home/cbritz/arquillian/tests/arquilTest/src/main/java/com/arquilTest/project/domain/Profile.java
[arquilTest] Profile.java $ field string --named preferredName
Added field to com.arquilTest.project.domain.Profile: @column private String preferredName;

Wrote /home/cbritz/arquillian/tests/arquilTest/src/main/java/com/arquilTest/project/domain/Profile.java
[arquilTest] Profile.java $ field string --named notes
Added field to com.arquilTest.project.domain.Profile: @column private String notes;

Wrote /home/cbritz/arquillian/tests/arquilTest/src/main/java/com/arquilTest/project/domain/Profile.java
[arquilTest] Profile.java $ entity --named Address
Created @entity [com.arquilTest.project.domain.Address]
Picked up type : com.arquilTest.project.domain.Address
Wrote /home/cbritz/arquillian/tests/arquilTest/src/main/java/com/arquilTest/project/domain/Address.java
[arquilTest] Address.java $ field string --named street
Added field to com.arquilTest.project.domain.Address: @column private String street;

Wrote /home/cbritz/arquillian/tests/arquilTest/src/main/java/com/arquilTest/project/domain/Address.java
[arquilTest] Address.java $ field string --named city
Added field to com.arquilTest.project.domain.Address: @column private String city;

Wrote /home/cbritz/arquillian/tests/arquilTest/src/main/java/com/arquilTest/project/domain/Address.java
[arquilTest] Address.java $ entity --named ZipCode
Created @entity [com.arquilTest.project.domain.ZipCode]
Picked up type : com.arquilTest.project.domain.ZipCode
Wrote /home/cbritz/arquillian/tests/arquilTest/src/main/java/com/arquilTest/project/domain/ZipCode.java
[arquilTest] ZipCode.java $ field int --named code
Added field to com.arquilTest.project.domain.ZipCode: @column private int code;

Wrote /home/cbritz/arquillian/tests/arquilTest/src/main/java/com/arquilTest/project/domain/ZipCode.java
[arquilTest] ZipCode.java $ cd ../Address.java
[arquilTest] Address.java $ field manyTo
manyToMany manyToOne
[arquilTest] Address.java $ field manyToOne --named zip --fieldType ~.domain.Address.java
Wrote /home/cbritz/arquillian/tests/arquilTest/src/main/java/com/arquilTest/project/domain/Address.java
[arquilTest] Address.java $ cd ..
[arquilTest] domain $ cd Address.java
[arquilTest] Address.java $ cd ../Customer.java
[arquilTest] Customer.java $ field oneTo
oneToMany oneToOne
[arquilTest] Customer.java $ field oneTo
oneToMany oneToOne
[arquilTest] Customer.java $ field oneToOne --named profile --fieldType ~.domain.Pro
ProductOrder.java Profile.java
[arquilTest] Customer.java $ field oneToOne --named profile --fieldType ~.domain.Profile.java
Added field to com.arquilTest.project.domain.Customer: @OnetoOne private Profile profile;

Wrote /home/cbritz/arquillian/tests/arquilTest/src/main/java/com/arquilTest/project/domain/Customer.java
[arquilTest] Customer.java $ cd ..
[arquilTest] domain $ cd ProductOrder.java
[arquilTest] ProductOrder.java $ field manyTo
manyToMany manyToOne
[arquilTest] ProductOrder.java $ field manyToMany --
--named --fieldType --inverseFieldName
[arquilTest] ProductOrder.java $ field manyToMany --named shippingAddress --fieldType ~.domain.Address.java
Wrote /home/cbritz/arquillian/tests/arquilTest/src/main/java/com/arquilTest/project/domain/ProductOrder.java
[arquilTest] ProductOrder.java $ cd ..
[arquilTest] domain $ scaffold
templates from-entity setup indexes
[arquilTest] domain $ scaffold from-entity ~.domain.* --
--scaffoldType --overwrite --usingTemplate
[arquilTest] domain $ scaffold from-entity ~.domain.* --
--scaffoldType --overwrite --usingTemplate
[arquilTest] domain $ scaffold from-entity ~.domain.* --
--scaffoldType --overwrite --usingTemplate
[arquilTest] domain $ scaffold from-entity ~.domain.* --
--scaffoldType --overwrite --usingTemplate
[arquilTest] domain $ scaffold from-entity ~.domain.* --scaffoldType faces --overwrite
_SUCCESS_ Generated UI for [com.arquilTest.project.domain.Address]
Wrote /home/cbritz/arquillian/tests/arquilTest/src/main/java/com/arquilTest/project/view/AddressBean.java
Wrote /home/cbritz/arquillian/tests/arquilTest/src/main/webapp/scaffold/address/create.xhtml
Wrote /home/cbritz/arquillian/tests/arquilTest/src/main/webapp/scaffold/address/view.xhtml
Wrote /home/cbritz/arquillian/tests/arquilTest/src/main/webapp/scaffold/address/search.xhtml
Wrote /home/cbritz/arquillian/tests/arquilTest/src/main/webapp/resources/scaffold/page.xhtml
Wrote /home/cbritz/arquillian/tests/arquilTest/src/main/java/com/arquilTest/project/view/ViewUtils.java
Wrote /home/cbritz/arquillian/tests/arquilTest/src/main/webapp/WEB-INF/classes/META-INF/forge.taglib.xml
_ERROR_ [scaffold from-entity] Error generating default scaffolding.

@britztopher
Copy link

Ok, so I went ahead and ran this in the actual Forge window in the terminal and it ran fine. So this must be an eclipse issue. Also, which i thought was wierd, was that i had to run the scaffold setup command again because Forge said it was missing faces. However, when i ran "scaffold setup --scaffoldType faces" I got this error "_ERROR_ [scaffold setup] Failed to create required [home/myhome/arquillian/tests/arquilTest/src/main/webapp/WEB-INF/faces-config.xml]" To resolve this error I had to remove the faces-config.xml file then run the scaffold setup command again.

@mojavelinux
Copy link
Author

I've tried it a bunch of times using the Forge Console in JBoss Tools and it always works for me (if I do all the steps in proper order). I'm using the development version of JBoss Tools for Eclipse Indigo.

Forge Tools - 1.0.0.v20111208-2108-H31-M5

It may just be the result of having an older version of the tooling installed.

You last error seems to be the result of your project just getting into a messed up state and Forge being confused as to what to do.

The most important thing about reporting an error is to be able to reproduce it consistently (I know that's not always possible, but it's very helpful). That way, you can explain the exact steps to get from a blank slate (no project) to the error.

Thanks!

@opensas
Copy link

opensas commented Feb 7, 2012

Excellent article!!!

Should be part of official openshift documentation...

@michako
Copy link

michako commented Mar 2, 2012

Hello,

I have a problem with arquillian. I dont get the arquillian container JBOSS_AS_REMOTE_7.X in forge console.

[test] test $ arquillian setup --container JBOSS_AS_REMOTE_7.X
_ERROR_ [arquillian setup] org.jboss.forge.project.facets.DependencyFacet.getDirectDependency(Lorg/jboss/forge/project/dependencies/Dependency;)Lorg/jboss/forge/project/dependencies/Dependency;

What is the solve? Someone can help me?

Thank very much

best regards =)

michako

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment