The Bean Class for Java Programming

      17 Comments on The Bean Class for Java Programming

In the courses that you take with me I define a bean as a class used to aggregate or collect both primitive data types and other classes for modelling data in a program. Most programs require the definition of multiple elements or values to describe the data that they interact with. Rather than list each element individually, these elements are grouped together into a single class.

The original concept of a bean called a JavaBean dates to 1996. It was intended to be a component model for visual elements of a program. These components could then be easily manipulated by a visual modelling tool. You can read the current specification at http://tinyurl.com/ybzwmldq that was last updated in 1997.

I require you to use a subset of this original concept that I refer to as a bean class in the programs that you write for the courses you are taking with me. Here is the rundown of the rules for a bean in my courses:

Mandatory:

  • All fields, also called instance variables or properties, can only be private.
  • There must be a default constructor.
  • Methods to read or write the instance variable must begin with the prefixes set or get.
  • The bean class should implement the serializable interface

Optional:

  • The bean class should have a toString method.
  • The bean class should have a hashCode and an equals method
  • The bean class should implement the Comparable interface and have a compareTo method.

Bonus:

  • The companion Comparable object for when you need to have more than one possible comparison
  • The Java 8 lambda implementation of of a Comparator
  • The Java 8 functional implementation of a Comparator

For example, consider a problem where it is necessary to model a book. Here is the basic bean.

[pastacode lang=”java” manual=”public%20class%20Book%20implements%20Serializable%7B%0A%0A%C2%A0%C2%A0%C2%A0%20private%20String%20isbn%3B%0A%C2%A0%C2%A0%C2%A0%20private%20String%20title%3B%0A%C2%A0%C2%A0%C2%A0%20private%20String%20author%3B%0A%C2%A0%C2%A0%C2%A0%20private%20String%20publisher%3B%0A%C2%A0%C2%A0%C2%A0%20private%20int%20pages%3B%0A%0A%C2%A0%C2%A0%C2%A0%20%2F**%0A%C2%A0%C2%A0%C2%A0%C2%A0%20*%20Default%20constructor%0A%C2%A0%C2%A0%C2%A0%C2%A0%20*%2F%0A%C2%A0%C2%A0%C2%A0%20public%20Book()%20%7B%0A%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%20this.isbn%20%3D%20%22%22%3B%0A%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%20this.title%20%3D%20%22%22%3B%0A%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%20this.author%20%3D%20%22%22%3B%0A%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%20this.publisher%20%3D%20%22%22%3B%0A%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%20this.pages%20%3D%200%3B%0A%C2%A0%C2%A0%C2%A0%20%7D%0A%0A%C2%A0%C2%A0%C2%A0%20public%20String%20getIsbn()%20%7B%0A%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%20return%20isbn%3B%0A%C2%A0%C2%A0%C2%A0%20%7D%0A%0A%C2%A0%C2%A0%C2%A0%20public%20void%20setIsbn(final%20String%20isbn)%20%7B%0A%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%20this.isbn%20%3D%20isbn%3B%0A%C2%A0%C2%A0%C2%A0%20%7D%0A%0A%C2%A0%C2%A0%C2%A0%20public%20String%20getTitle()%20%7B%0A%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%20return%20title%3B%0A%C2%A0%C2%A0%C2%A0%20%7D%0A%0A%C2%A0%C2%A0%C2%A0%20public%20void%20setTitle(final%20String%20title)%20%7B%0A%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%20this.title%20%3D%20title%3B%0A%C2%A0%C2%A0%C2%A0%20%7D%0A%0A%C2%A0%C2%A0%C2%A0%20public%20String%20getAuthor()%20%7B%0A%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%20return%20author%3B%0A%C2%A0%C2%A0%C2%A0%20%7D%0A%0A%C2%A0%C2%A0%C2%A0%20public%20void%20setAuthor(final%20String%20author)%20%7B%0A%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%20this.author%20%3D%20author%3B%0A%C2%A0%C2%A0%C2%A0%20%7D%0A%0A%C2%A0%C2%A0%C2%A0%20public%20String%20getPublisher()%20%7B%0A%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%20return%20publisher%3B%0A%C2%A0%C2%A0%C2%A0%20%7D%0A%0A%C2%A0%C2%A0%C2%A0%20public%20void%20setPublisher(final%20String%20publisher)%20%7B%0A%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%20this.publisher%20%3D%20publisher%3B%0A%C2%A0%C2%A0%C2%A0%20%7D%0A%0A%C2%A0%C2%A0%C2%A0%20public%20int%20getPages()%20%7B%0A%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%20return%20pages%3B%0A%C2%A0%C2%A0%C2%A0%20%7D%0A%0A%C2%A0%20%C2%A0%C2%A0public%20void%20setPages(final%20int%20pages)%20%7B%0A%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%20this.pages%20%3D%20pages%3B%0A%C2%A0%C2%A0%C2%A0%20%7D%0A%7D” message=”Basic Bean 1″ highlight=”” provider=”manual”/]

The methods for reading and writing must adhere to the naming convention. They must begin with set, get or is all in lower case. The is prefix is an alternative to get when the type of value returned is a boolean. They must be followed by a capital letter. They usually correspond to the private fields in the class. You may also add any additional methods that your logic may require.

You now have a class that models a book. Any part of your code now requires only a single reference to an object of type Book to represent all the data points or fields for a book. Reading or writing to any field must now go through a method. The serializable interface allows the state of the object to be preserved by writing it to disk. For distributed applications, such as web services, this allows the object to be transmitted over the internet. Review the documentation on serialization as not every class type can be serialized without additional code. Primitives and Strings can be serialized without additional code.


Special Note 1:

I had a paragraph here that incorrectly stated that a serializable object required a default constructor and set methods but it was pointed out by Michael Simons‏ @rotnroll666 that this is incorrect. I should have reviewed the documentation that I recommended that you review. Serialization does not require a default constructor or set methods.


[pastacode lang=”java” manual=”public%20class%20Book%20implements%20Serializable%7B%0A%0A%C2%A0%C2%A0%C2%A0%20private%20String%20isbn%3B%0A%C2%A0%C2%A0%C2%A0%20private%20String%20title%3B%0A%C2%A0%C2%A0%C2%A0%20private%20String%20author%3B%0A%C2%A0%C2%A0%C2%A0%20private%20String%20publisher%3B%0A%C2%A0%C2%A0%C2%A0%20private%20int%20pages%3B%0A%0A%C2%A0%C2%A0%C2%A0%20%2F**%0A%C2%A0%C2%A0%C2%A0%C2%A0%20*%20Default%20constructor%0A%C2%A0%C2%A0%C2%A0%C2%A0%20*%2F%0A%C2%A0%C2%A0%C2%A0%20public%20Book()%20%7B%0A%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%20this.isbn%20%3D%20%22%22%3B%0A%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%20this.title%20%3D%20%22%22%3B%0A%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%20this.author%20%3D%20%22%22%3B%0A%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%20this.publisher%20%3D%20%22%22%3B%0A%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%20this.pages%20%3D%200%3B%0A%C2%A0%C2%A0%C2%A0%20%7D%0A%0A%C2%A0%C2%A0%C2%A0%20%2F**%0A%C2%A0%C2%A0%C2%A0%C2%A0%20*%20Non-default%20constructor%0A%C2%A0%C2%A0%C2%A0%C2%A0%20*%0A%C2%A0%C2%A0%C2%A0%C2%A0%20*%20%40param%20isbn%0A%C2%A0%C2%A0%C2%A0%C2%A0%20*%20%40param%20title%0A%C2%A0%C2%A0%C2%A0%C2%A0%20*%20%40param%20author%0A%C2%A0%C2%A0%C2%A0%C2%A0%20*%20%40param%20publisher%0A%C2%A0%C2%A0%C2%A0%C2%A0%20*%20%40param%20pages%0A%C2%A0%C2%A0%C2%A0%C2%A0%20*%2F%0A%C2%A0%C2%A0%C2%A0%20public%20Book(final%20String%20isbn%2C%20final%20String%20title%2C%20final%20String%20author%2C%20final%20String%20publisher%2C%20final%20int%20pages)%20%7B%0A%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%20this.isbn%20%3D%20isbn%3B%0A%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%20this.title%20%3D%20title%3B%0A%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%20this.author%20%3D%20author%3B%0A%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%20this.publisher%20%3D%20publisher%3B%0A%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%20this.pages%20%3D%20pages%3B%0A%C2%A0%C2%A0%C2%A0%20%7D” message=”Basic Bean 2″ highlight=”” provider=”manual”/]

Notice that all the parameters in the methods are final. A final variable cannot have its value changed. If you pass a reference as an argument to any method that does not declare its parameter as final you can change the address that the argument points to and this can result in an unintended side effect. Bean classes must never change an argument.


An argument is a value or reference passed to a method. A parameter is the place holder in the method signature that will represent the argument’s value in the method.


Primitive argument types such as int or double have no connection to the original value from the caller so final is not required. However, it is a best practice to declare it final as you should not be changing it.

toString

We now have a proper bean class. There are four additional methods that can be added that will make the bean more useful in certain circumstances. The first of these circumstances is when you need to represent the bean as a string. The most common reason is to support debugging by allowing you to examine the value of each field in the bean in a log statement. This is the job of the toString method.

[pastacode lang=”java” manual=”%C2%A0%C2%A0%C2%A0%20%40Override%0A%C2%A0%C2%A0%C2%A0%20public%20String%20toString()%20%7B%0A%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%20return%20%22Book%7B%22%20%2B%20%22isbn%3D%22%20%2B%20isbn%20%2B%20%22%2C%20title%3D%22%20%2B%20title%20%2B%20%22%2C%20author%3D%22%20%2B%20author%20%2B%20%22%2C%20publisher%3D%22%20%2B%20publisher%20%2B%20%22%2C%20pages%3D%22%20%2B%20pages%20%2B%20’%7D’%3B%0A%C2%A0%C2%A0%C2%A0%20%7D%0A%0A” message=”toString” highlight=”” provider=”manual”/]

The toString method is inherited from the superclass Object that every class in Java extends. The annotation @Override, while optional, makes it clear that you are overriding a superclass method. What you put into the string is up to you. For example, when placing an object into GUI tree, the toString method is the default for what should appear on screen in the tree and so may return the value of a single field.

hashCode and equals

The next two methods are hashCode and equals. These should always go together whenever your code must test if two objects have identical values in their fields. It may appear that equals is all you need but there is a performance issue here. Our Book class has 4 String fields. When comparing two Book objects it will be necessary to compare every character in every string to determine if they are equal. The hashCode method creates an integer value called a hash code that represents all the values in the object. This value can be compared to the corresponding value in the object we are comparing to. If the value of the hash code is not the same then we know with certainty that they do not possess the same values.

Hash codes are not unique. It is possible that two objects with different values may return the same hash code. Therefore, if hash codes are equal we must call upon the equals method to be certain they are the same. Hash codes are used in Java collections data structures. If you intend to use such a structure, such as a HashMap or a HashSet then you must have hashCode and equals in the bean.

[pastacode lang=”java” manual=”%20%20%20%20%40Override%0A%C2%A0%C2%A0%C2%A0%20public%20int%20hashCode()%20%7B%0A%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%20int%20hash%20%3D%207%3B%0A%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%20hash%20%3D%2061%20*%20hash%20%2B%20Objects.hashCode(this.isbn)%3B%0A%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%20hash%20%3D%2061%20*%20hash%20%2B%20Objects.hashCode(this.title)%3B%0A%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%20hash%20%3D%2061%20*%20hash%20%2B%20Objects.hashCode(this.author)%3B%0A%C2%A0%C2%A0%C2%A0%C2%A0%20%C2%A0%C2%A0%C2%A0hash%20%3D%2061%20*%20hash%20%2B%20Objects.hashCode(this.publisher)%3B%0A%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%20hash%20%3D%2061%20*%20hash%20%2B%20this.pages%3B%0A%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%20return%20hash%3B%0A%C2%A0%C2%A0%C2%A0%20%7D%0A%0A%C2%A0%C2%A0%C2%A0%20%40Override%0A%C2%A0%C2%A0%C2%A0%20public%20boolean%20equals(Object%20obj)%20%7B%0A%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%20if%20(this%20%3D%3D%20obj)%20%7B%0A%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%20return%20true%3B%0A%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%20%7D%0A%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%20if%20(obj%20%3D%3D%20null)%20%7B%0A%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%20return%20false%3B%0A%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%20%7D%0A%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%20if%20(getClass()%20!%3D%20obj.getClass())%20%7B%0A%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%20return%20false%3B%0A%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%20%7D%0A%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%20final%20Book%20other%20%3D%20(Book)%20obj%3B%0A%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%20if%20(this.pages%20!%3D%20other.pages)%20%7B%0A%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%20return%20false%3B%0A%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%20%C2%A0%7D%0A%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%20if%20(!Objects.equals(this.isbn%2C%20other.isbn))%20%7B%0A%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%20return%20false%3B%0A%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%20%7D%0A%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%20if%20(!Objects.equals(this.title%2C%20other.title))%20%7B%0A%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%20return%20false%3B%0A%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%20%7D%0A%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%20if%20(!Objects.equals(this.author%2C%20other.author))%20%7B%0A%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%20return%20false%3B%0A%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%20%7D%0A%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%20if%20(!Objects.equals(this.publisher%2C%20other.publisher))%20%7B%0A%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%20return%20false%3B%0A%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%20%7D%0A%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%20return%20true%3B%0A%C2%A0%C2%A0%C2%A0%20%7D%0A%0A” message=”hashCode and equals” highlight=”” provider=”manual”/]

These two methods were generated by the IDE that I use, NetBeans. Most IDEs such as Eclipse and IntelliJ will generate these methods. You may choose to exclude certain fields from these methods but the fields you are using must be the same in hashCode and equals.


Special Note 2:

It has been mentioned in the comments that as presented this hashCode method is problematic when used in  a Hash data structure. The fields in the class are mutable/changeable and this could result in an object placed in the hash structure that can never be found if a field is changed. This is a type of memory leak. The solution is to make all fields used to construct the hash code final/immutable. 



Special Note 3:

This next section has been rewritten from the first version of this article based on comments from Michael Simons‏ @rotnroll666, Originally I proposed multiple Comparable interfaces and multiple compareTo methods in the bean. Michael pointed out that this will result in code bloat as the bean will keep getting longer with each additional compareTo method. He recommended Comparable objects that exist outside the bean.


Comparable Interface and compareTo

You have two choices for how you can order objects when using sort methods or self sorting collections such as a Map. The first choice is to implement a compareTo method in the bean. This method is required when you implement the Comparable interface. This sorted order that results is called the natural ordering and the compareTo method is referred to as the natural ordering method. You must decide which fields will contribute to the sort order criteria. I wish to be able to sort the books by their title.

[pastacode lang=”java” manual=”%20%20%20%20%2F**%0A%20%20%20%20%20*%20Natural%20comparison%20method%20for%20Title%0A%20%20%20%20%20*%0A%20%20%20%20%20*%20%40param%20book%0A%20%20%20%20%20*%20%40return%20negative%20value%2C%200%2C%20or%20positive%20value%0A%20%20%20%20%20*%2F%0A%20%20%20%20%40Override%0A%20%20%20%20public%20int%20compareTo(Book%20book)%20%7B%0A%20%20%20%20%20%20%20%20return%20this.title.compareTo(book.title)%3B%0A%20%20%20%20%7D%0A” message=”compareTo method” highlight=”” provider=”manual”/]

I am taking advantage of the fact that String objects implement the Comparable interface. If my title, this.title, comes before the title in the Book parameter then the difference in the ASCII codes for the first differing characters is returned as a negative value. If the strings are identical then 0 is returned. If my title comes after the title in the Book parameter then the difference in the ASCII code for the first differing characters is returned as a positive value

Comparator

You can have only one compareTo method that overrides the Comparable interface requirement. This leads to the second approach to comparisons. If you need multiple comparisons each with different fields as the criteria then your best solution is to create Comparable objects. This way you can compare any parts of the objects. You just need a Comparable object for each comparison and the original bean does not change.

[pastacode lang=”java” manual=”package%20com.kenfogel.book%3B%0A%0Aimport%20java.util.Comparator%3B%0A%0Apublic%20class%20BookPageComparator%20implements%20Comparator%3CBook%3E%20%7B%0A%0A%20%20%20%20%2F**%0A%20%20%20%20%20*%20The%20interface%20mandated%20compare%20method%0A%20%20%20%20%20*%0A%20%20%20%20%20*%20%40param%20book1%0A%20%20%20%20%20*%20%40param%20book2%0A%20%20%20%20%20*%20%40return%20negative%20value%2C%200%2C%20or%20positive%20value%0A%20%20%20%20%20*%2F%0A%20%20%20%20%40Override%0A%20%20%20%20public%20int%20compare(Book%20book1%2C%20Book%20book2)%20%7B%0A%20%20%20%20%20%20%20%20return%20book1.getPages()%20-%20book2.getPages()%3B%0A%20%20%20%20%7D%0A%7D%0A” message=”Comparator Class” highlight=”” provider=”manual”/]

Comparator lambda

The Comparable interface lends itself to the use of lambda expressions that is demonstrated in the test code. This eliminates the need for a Comparable object. However, if the logic to determine the sorting order is more than three lines long you might be better off with a Comparator object instead. Here is what the the two comparison approaches look like when used to sort an array.

[pastacode lang=”java” manual=”Arrays.sort(myBooks)%3B%20%2F%2F%20uses%20the%20Comparable%20compareTo%20in%20the%20bean%0AArrays.sort(myBooks%2C%20bookPageComparator)%3B%20%2F%2F%20uses%20the%20Comparator%20object%0AArrays.sort(myBooks%2C%20(s1%2C%20s2)%20-%3E%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20s1.getPublisher().compareTo(s2.getPublisher())%3B%0A%20%20%20%20%20%20%20%20%7D)%3B%20%2F%2F%20uses%20a%20Comparator%20lambda%0A” message=”Sorting an array” highlight=”” provider=”manual”/]

Java 8 Functional Comparator

Java 8 introduced new methods in the Comparator interface that simplifies comparisons with objects. I wish to sort my books based on the ISBN number. As a String has a natural order, I can inform the sorting method what Comparator to use by the following.

[pastacode lang=”java” manual=”%20%20%20%20%20%20%20%20Arrays.sort(myBooks%2C%20comparing(Book%3A%3AgetIsbn))%3B%20%2F%2F%20Comparable%20function%0A” message=”” highlight=”” provider=”manual”/]

See the test program just below to see how Comparable and Comparator work.

The Complete Bean

Here is the final version of the Book bean.

[pastacode lang=”java” manual=”mport%20java.io.Serializable%3B%0Aimport%20java.util.Objects%3B%0A%0Apublic%20class%20Book%20implements%20Serializable%2C%20Comparable%3CBook%3E%20%7B%0A%0A%20%20%20%20private%20String%20isbn%3B%0A%20%20%20%20private%20String%20title%3B%0A%20%20%20%20private%20String%20author%3B%0A%20%20%20%20private%20String%20publisher%3B%0A%20%20%20%20private%20int%20pages%3B%0A%0A%20%20%20%20%2F**%0A%20%20%20%20%20*%20Default%20constructor%0A%20%20%20%20%20*%2F%0A%20%20%20%20public%20Book()%20%7B%0A%20%20%20%20%20%20%20%20this.isbn%20%3D%20%22%22%3B%0A%20%20%20%20%20%20%20%20this.title%20%3D%20%22%22%3B%0A%20%20%20%20%20%20%20%20this.author%20%3D%20%22%22%3B%0A%20%20%20%20%20%20%20%20this.publisher%20%3D%20%22%22%3B%0A%20%20%20%20%20%20%20%20this.pages%20%3D%200%3B%0A%20%20%20%20%7D%0A%0A%20%20%20%20%2F**%0A%20%20%20%20%20*%20Non-default%20constructor%0A%20%20%20%20%20*%0A%20%20%20%20%20*%20%40param%20isbn%0A%20%20%20%20%20*%20%40param%20title%0A%20%20%20%20%20*%20%40param%20author%0A%20%20%20%20%20*%20%40param%20publisher%0A%20%20%20%20%20*%20%40param%20pages%0A%20%20%20%20%20*%2F%0A%20%20%20%20public%20Book(final%20String%20isbn%2C%20final%20String%20title%2C%20final%20String%20author%2C%20final%20String%20publisher%2C%20final%20int%20pages)%20%7B%0A%20%20%20%20%20%20%20%20this.isbn%20%3D%20isbn%3B%0A%20%20%20%20%20%20%20%20this.title%20%3D%20title%3B%0A%20%20%20%20%20%20%20%20this.author%20%3D%20author%3B%0A%20%20%20%20%20%20%20%20this.publisher%20%3D%20publisher%3B%0A%20%20%20%20%20%20%20%20this.pages%20%3D%20pages%3B%0A%20%20%20%20%7D%0A%0A%20%20%20%20public%20String%20getIsbn()%20%7B%0A%20%20%20%20%20%20%20%20return%20isbn%3B%0A%20%20%20%20%7D%0A%0A%20%20%20%20public%20void%20setIsbn(final%20String%20isbn)%20%7B%0A%20%20%20%20%20%20%20%20this.isbn%20%3D%20isbn%3B%0A%20%20%20%20%7D%0A%0A%20%20%20%20public%20String%20getTitle()%20%7B%0A%20%20%20%20%20%20%20%20return%20title%3B%0A%20%20%20%20%7D%0A%0A%20%20%20%20public%20void%20setTitle(final%20String%20title)%20%7B%0A%20%20%20%20%20%20%20%20this.title%20%3D%20title%3B%0A%20%20%20%20%7D%0A%0A%20%20%20%20public%20String%20getAuthor()%20%7B%0A%20%20%20%20%20%20%20%20return%20author%3B%0A%20%20%20%20%7D%0A%0A%20%20%20%20public%20void%20setAuthor(final%20String%20author)%20%7B%0A%20%20%20%20%20%20%20%20this.author%20%3D%20author%3B%0A%20%20%20%20%7D%0A%0A%20%20%20%20public%20String%20getPublisher()%20%7B%0A%20%20%20%20%20%20%20%20return%20publisher%3B%0A%20%20%20%20%7D%0A%0A%20%20%20%20public%20void%20setPublisher(final%20String%20publisher)%20%7B%0A%20%20%20%20%20%20%20%20this.publisher%20%3D%20publisher%3B%0A%20%20%20%20%7D%0A%0A%20%20%20%20public%20int%20getPages()%20%7B%0A%20%20%20%20%20%20%20%20return%20pages%3B%0A%20%20%20%20%7D%0A%0A%20%20%20%20public%20void%20setPages(final%20int%20pages)%20%7B%0A%20%20%20%20%20%20%20%20this.pages%20%3D%20pages%3B%0A%20%20%20%20%7D%0A%0A%20%20%20%20%40Override%0A%20%20%20%20public%20String%20toString()%20%7B%0A%20%20%20%20%20%20%20%20return%20%22Book%7B%22%20%2B%20%22isbn%3D%22%20%2B%20isbn%20%2B%20%22%2C%20title%3D%22%20%2B%20title%20%2B%20%22%2C%20author%3D%22%20%2B%20author%20%2B%20%22%2C%20publisher%3D%22%20%2B%20publisher%20%2B%20%22%2C%20pages%3D%22%20%2B%20pages%20%2B%20’%7D’%3B%0A%20%20%20%20%7D%0A%0A%20%20%20%20%40Override%0A%20%20%20%20public%20int%20hashCode()%20%7B%0A%20%20%20%20%20%20%20%20int%20hash%20%3D%207%3B%0A%20%20%20%20%20%20%20%20hash%20%3D%2061%20*%20hash%20%2B%20Objects.hashCode(this.isbn)%3B%0A%20%20%20%20%20%20%20%20hash%20%3D%2061%20*%20hash%20%2B%20Objects.hashCode(this.title)%3B%0A%20%20%20%20%20%20%20%20hash%20%3D%2061%20*%20hash%20%2B%20Objects.hashCode(this.author)%3B%0A%20%20%20%20%20%20%20%20hash%20%3D%2061%20*%20hash%20%2B%20Objects.hashCode(this.publisher)%3B%0A%20%20%20%20%20%20%20%20hash%20%3D%2061%20*%20hash%20%2B%20this.pages%3B%0A%20%20%20%20%20%20%20%20return%20hash%3B%0A%20%20%20%20%7D%0A%0A%20%20%20%20%40Override%0A%20%20%20%20public%20boolean%20equals(Object%20obj)%20%7B%0A%20%20%20%20%20%20%20%20if%20(this%20%3D%3D%20obj)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20true%3B%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20if%20(obj%20%3D%3D%20null)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20false%3B%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20if%20(getClass()%20!%3D%20obj.getClass())%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20false%3B%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20final%20Book%20other%20%3D%20(Book)%20obj%3B%0A%20%20%20%20%20%20%20%20if%20(this.pages%20!%3D%20other.pages)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20false%3B%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20if%20(!Objects.equals(this.isbn%2C%20other.isbn))%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20false%3B%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20if%20(!Objects.equals(this.title%2C%20other.title))%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20false%3B%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20if%20(!Objects.equals(this.author%2C%20other.author))%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20false%3B%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20if%20(!Objects.equals(this.publisher%2C%20other.publisher))%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20false%3B%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20return%20true%3B%0A%20%20%20%20%7D%0A%0A%20%20%20%20%2F**%0A%20%20%20%20%20*%20Natural%20comparison%20method%20for%20Title%0A%20%20%20%20%20*%0A%20%20%20%20%20*%20%40param%20book%0A%20%20%20%20%20*%20%40return%20negative%20value%2C%200%2C%20or%20positive%20value%0A%20%20%20%20%20*%2F%0A%20%20%20%20%40Override%0A%20%20%20%20public%20int%20compareTo(Book%20book)%20%7B%0A%20%20%20%20%20%20%20%20return%20this.title.compareTo(book.title)%3B%0A%20%20%20%20%7D%0A%7D%0A” message=”Complete Bean” highlight=”” provider=”manual”/]

The Bean Tester

Here is a test program that demonstrates the two ways that comparisons can be made, The comments describe which approach is used.

[pastacode lang=”java” manual=”%2F%2F%20Required%20for%20Arrays.sort%0Aimport%20java.util.Arrays%3B%0A%2F%2F%20Required%20by%20the%20Comparator%20function%0Aimport%20static%20java.util.Comparator.comparing%3B%0A%0Apublic%20class%20BeanTester%20%7B%0A%0A%20%20%20%20%2F**%0A%20%20%20%20%20*%20Here%20is%20where%20I%20am%20testing%20my%20comparisons%0A%20%20%20%20%20*%0A%20%20%20%20%20*%2F%0A%20%20%20%20public%20void%20perform()%20%7B%0A%20%20%20%20%20%20%20%20%2F%2F%20Lets%20create%20four%20books%0A%20%20%20%20%20%20%20%20Book%20b0%20%3D%20new%20Book(%22200%22%2C%20%22Xenon%22%2C%20%22Hamilton%22%2C%20%22Harcourt%22%2C%2099)%3B%0A%20%20%20%20%20%20%20%20Book%20b1%20%3D%20new%20Book(%22500%22%2C%20%22Boron%22%2C%20%22Bradbury%22%2C%20%22Prentice%22%2C%20108)%3B%0A%20%20%20%20%20%20%20%20Book%20b2%20%3D%20new%20Book(%22300%22%2C%20%22Radon%22%2C%20%22Heinlein%22%2C%20%22Thompson%22%2C%2098)%3B%0A%20%20%20%20%20%20%20%20Book%20b3%20%3D%20new%20Book(%22404%22%2C%20%22Argon%22%2C%20%22Campbell%22%2C%20%22Hachette%22%2C%20102)%3B%0A%0A%20%20%20%20%20%20%20%20%2F%2F%20Using%20Comparable%20to%20compare%20two%20books%0A%20%20%20%20%20%20%20%20System.out.println(%22Value%20returned%20by%20Comparable%22)%3B%0A%20%20%20%20%20%20%20%20System.out.println(b0.getTitle()%20%2B%20%22%20compared%20to%20%22%20%2B%20b1.getTitle()%20%2B%20%22%3A%20%22%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%2B%20b0.compareTo(b1))%3B%0A%20%20%20%20%20%20%20%20System.out.println()%3B%0A%0A%20%20%20%20%20%20%20%20%2F%2F%20Using%20Comparator%20to%20compare%20two%20books%0A%20%20%20%20%20%20%20%20System.out.println(%22Value%20returned%20by%20Comparator%22)%3B%0A%20%20%20%20%20%20%20%20BookPageComparator%20bookPageComparator%20%3D%20new%20BookPageComparator()%3B%0A%20%20%20%20%20%20%20%20System.out.println(b0.getPages()%20%2B%20%22%20compared%20to%20%22%20%2B%20b1.getPages()%20%2B%20%22%3A%20%22%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%2B%20bookPageComparator.compare(b0%2C%20b1))%3B%0A%20%20%20%20%20%20%20%20System.out.println()%3B%0A%0A%20%20%20%20%20%20%20%20%2F%2F%20Create%20an%20array%20we%20can%20sort%0A%20%20%20%20%20%20%20%20Book%5B%5D%20myBooks%20%3D%20new%20Book%5B4%5D%3B%0A%20%20%20%20%20%20%20%20myBooks%5B0%5D%20%3D%20b0%3B%0A%20%20%20%20%20%20%20%20myBooks%5B1%5D%20%3D%20b1%3B%0A%20%20%20%20%20%20%20%20myBooks%5B2%5D%20%3D%20b2%3B%0A%20%20%20%20%20%20%20%20myBooks%5B3%5D%20%3D%20b3%3B%0A%20%20%20%20%20%20%20%20System.out.println(%22Unsorted%22)%3B%0A%20%20%20%20%20%20%20%20displayBooks(myBooks)%3B%0A%0A%20%20%20%20%20%20%20%20System.out.println(%22Sorted%20with%20Comparable%20Interface%20on%20Title%22)%3B%0A%20%20%20%20%20%20%20%20Arrays.sort(myBooks)%3B%20%2F%2F%20uses%20the%20Comparable%20compareTo%20in%20the%20bean%0A%20%20%20%20%20%20%20%20displayBooks(myBooks)%3B%0A%0A%20%20%20%20%20%20%20%20System.out.println(%22Sorted%20with%20Comparable%20Object%20on%20Pages%22)%3B%0A%20%20%20%20%20%20%20%20Arrays.sort(myBooks%2C%20bookPageComparator)%3B%20%2F%2F%20uses%20the%20Comparator%20object%0A%20%20%20%20%20%20%20%20displayBooks(myBooks)%3B%0A%0A%20%20%20%20%20%20%20%20System.out.println(%22Sorted%20with%20Comparable%20lambda%20expression%20on%20Publishers%22)%3B%0A%20%20%20%20%20%20%20%20Arrays.sort(myBooks%2C%20(s1%2C%20s2)%20-%3E%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20s1.getPublisher().compareTo(s2.getPublisher())%3B%0A%20%20%20%20%20%20%20%20%7D)%3B%20%2F%2F%20uses%20the%20Comparator%20lambda%0A%20%20%20%20%20%20%20%20displayBooks(myBooks)%3B%0A%0A%20%20%20%20%20%20%20%20System.out.println(%22Sorted%20with%20Comparable%20lambda%20function%20on%20ISBN%22)%3B%0A%20%20%20%20%20%20%20%20Arrays.sort(myBooks%2C%20comparing(Book%3A%3AgetIsbn))%3B%20%2F%2F%20Comparable%20function%0A%20%20%20%20%20%20%20%20displayBooks(myBooks)%3B%0A%20%20%20%20%7D%0A%0A%20%20%20%20%2F**%0A%20%20%20%20%20*%20Print%20the%20contents%20of%20each%20Book%20object%20in%20the%20array%0A%20%20%20%20%20*%0A%20%20%20%20%20*%20%40param%20theBooks%0A%20%20%20%20%20*%2F%0A%20%20%20%20private%20void%20displayBooks(Book%5B%5D%20theBooks)%20%7B%0A%20%20%20%20%20%20%20%20for%20(Book%20b%20%3A%20theBooks)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20System.out.print(b.getIsbn()%20%2B%20%22%5Ct%22)%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20System.out.print(b.getTitle()%20%2B%20%22%5Ct%22)%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20System.out.print(b.getAuthor()%20%2B%20%22%5Ct%22)%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20System.out.print(b.getPublisher()%20%2B%20%22%5Ct%22)%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20System.out.println(b.getPages())%3B%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20System.out.println()%3B%0A%20%20%20%20%7D%0A%0A%20%20%20%20%2F**%0A%20%20%20%20%20*%20Where%20it%20all%20begins%0A%20%20%20%20%20*%0A%20%20%20%20%20*%20%40param%20args%0A%20%20%20%20%20*%2F%0A%20%20%20%20public%20static%20void%20main(String%5B%5D%20args)%20%7B%0A%20%20%20%20%20%20%20%20BeanTester%20bt%20%3D%20new%20BeanTester()%3B%0A%20%20%20%20%20%20%20%20bt.perform()%3B%0A%20%20%20%20%20%20%20%20System.exit(0)%3B%0A%20%20%20%20%7D%0A%7D%0A” message=”Bean Tester” highlight=”” provider=”manual”/]

The output of this program will be:

[pastacode lang=”java” manual=”Value%20returned%20by%20Comparable%0AXenon%20compared%20to%20Boron%3A%2022%0A%0AValue%20returned%20by%20Comparator%0A99%20compared%20to%20108%3A%20-9%0A%0AUnsorted%0A200%09Xenon%09Hamilton%09Harcourt%0999%0A500%09Boron%09Bradbury%09Prentice%09108%0A300%09Radon%09Heinlein%09Thompson%0998%0A404%09Argon%09Campbell%09Hachette%09102%0A%0ASorted%20with%20Comparable%20Interface%20on%20Title%0A404%09Argon%09Campbell%09Hachette%09102%0A500%09Boron%09Bradbury%09Prentice%09108%0A300%09Radon%09Heinlein%09Thompson%0998%0A200%09Xenon%09Hamilton%09Harcourt%0999%0A%0ASorted%20with%20Comparable%20Object%20on%20Pages%0A300%09Radon%09Heinlein%09Thompson%0998%0A200%09Xenon%09Hamilton%09Harcourt%0999%0A404%09Argon%09Campbell%09Hachette%09102%0A500%09Boron%09Bradbury%09Prentice%09108%0A%0ASorted%20with%20Comparable%20lambda%20expression%20on%20Publishers%0A404%09Argon%09Campbell%09Hachette%09102%0A200%09Xenon%09Hamilton%09Harcourt%0999%0A500%09Boron%09Bradbury%09Prentice%09108%0A300%09Radon%09Heinlein%09Thompson%0998%0A%0ASorted%20with%20Comparable%20lambda%20functions%20based%20on%20ISBN%0A200%09Xenon%09Hamilton%09Harcourt%0999%0A300%09Radon%09Heinlein%09Thompson%0998%0A404%09Argon%09Campbell%09Hachette%09102%0A500%09Boron%09Bradbury%09Prentice%09108″ message=”Output” highlight=”” provider=”manual”/]

Bean classes are required when using several libraries in Java such as Context Dependency Injection (CDI) and Bean Validation. You will also use bean classes to represent data from a database when using Java Database Connectivity (JDBC). Beans that back JavaFX controls are coded differently but are 100% backward compatible with simple bean classes. See my next article on JavaFX beans.

Java EE 7 Web Profile Maven pom.xml Using Arquillian, Selenium, MySQL, Primefaces and EclipseLink

  1. Update: Removed unnecessary eclipselink dependency 2017-02-27 14:46
  2. Update: Changed skipTests value to false in Surefire dependency in the complete pom file 2017-02-27 15:18

If you are not using Maven then you should. If you are using Maven then you are likely cutting and pasting snippets of pom.xml file examples and hoping for the best. In this article I will present the pom.xml file that I require my students to use in an e-commerce project course. Not everything in it is required and you likely have libraries you need that are not in my example. After reviewing my pom.xml you should be able to make all the changes you need. You can find the complete file at the end of this article.

This is my third article on the pom.xml file that I have written. The last time I wrote about it was two years ago and while Maven has not changed I have learned more about the pom.xml. If you are not using Maven because a practical explanation of the elements required in the real world are rare, then hopefully this will change your mind.

Whether you work from the command line or with an IDE such as NetBeans (my favourite) one issue comes up over and over again. How do I make sure all the libraries I need get included in my project? It used to be for me that I needed to track down the web site for every library I wanted to use, download the jar and manually paste it into a location on the classpath or a specific folder in IDE. Packaging an application for distribution was also an issue because I needed to ensure that all the right jars were included in the uber archive, jar or war, I planned to distribute.

There is more to Maven than just including libraries. I use it to upload Java programs to my Raspberry Pi and execute them. I use Maven to control when I want unit testing to occur. There is much, much more it can do. The one task that drives my continual writing about Maven is that I use it in the classroom. I teach software development at Dawson College in the final year of the program. I like teaching coding but I am not fond of teaching the necessary plumbing to make systems work. I use NetBeans in my courses because it does not need to be managed the way Eclipse or IntelliJ needs to be. I use Maven for the same reason. I provide my students with a standard Maven pom.xml file that ensures that they all begin from the same baseline. Here is that pom.xml file.

[pastacode lang=”markup” manual=”%3C%3Fxml%20version%3D%221.0%22%20encoding%3D%22UTF-8%22%3F%3E” message=”” highlight=”” provider=”manual”/]

 Every XML document should begin with an XML declaration. While the version has remained 1.0, it is the encoding attribute that is important. UTF-8 means that this document is encoded using the Unicode standard in which the first 128 characters map to Unicode. For more information on UTF-8 I recommend http://www.fileformat.info/info/unicode/utf8.htm


[pastacode lang=”markup” manual=”%20%3Cproject%20xmlns%3D%22http%3A%2F%2Fmaven.apache.org%2FPOM%2F4.0.0%22%20xmlns%3Axsi%3D%22http%3A%2F%2Fwww.w3.org%2F2001%2FXMLSchema-instance%22%20xsi%3AschemaLocation%3D%22http%3A%2F%2Fmaven.apache.org%2FPOM%2F4.0.0%20http%3A%2F%2Fmaven.apache.org%2Fxsd%2Fmaven-4.0.0.xsd%22%3E” message=”” highlight=”” provider=”manual”/]

  This is the root tag for this XML document. An XML document must be well formed and valid. Well formed means that all tags are properly nested and have a matching closing tag. Valid means that the tags and attributes you are using are part of this specific XML language. Testing for validity requires a schema and that is what is referred to in the root project tag. The schema is also used by the IDE to validate while you enter the tags into the file.


[pastacode lang=”markup” manual=”%20%20%20%20%20%3C!–%20Maven%20version%20of%20the%20xml%20document%20currently%20only%204.0.0%20is%20valid%20–%3E%0A%20%20%20%20%3CmodelVersion%3E4.0.0%3C%2FmodelVersion%3E%0A%20″ message=”” highlight=”” provider=”manual”/]

      As the comment says, its always 4.0.0.


[pastacode lang=”markup” manual=”%20%20%20%20%20%3C!–%20The%20GAV%20consists%20of%20an%20arbitrary%20descriptor%20that%20is%20usually%20in%20the%0A%20%20%20%20form%20of%20a%20reverse%20domain%20name.%20–%3E%0A%20%20%20%20%3CgroupId%3Ecom.kfwebstandard%3C%2FgroupId%3E%0A%20%0A%20%20%20%20%3C!–%20This%20is%20the%20name%20given%20to%20the%20packaged%20build%20–%3E%0A%20%20%20%20%3CartifactId%3EKFWebStandardProject%3C%2FartifactId%3E” message=”” highlight=”” provider=”manual”/]

 Maven manages the thousands of libraries available by using the combination of the groupId and artifactId as a unique identifier for each library. This is commonly called the GAV. These are usually expressed using the naming convention for Java packages or as a reverse domain name but they can be anything. You’ll see a non-package name for the MySQL dependency. When a library is a dependency for a project it is identified by this combination. This is also the directory in your local repository where this jar or other file type is stored.


[pastacode lang=”markup” manual=”%20%20%20%20%3C!–%20The%20version%20of%20the%20build.%20Any%20value%20is%20valid%20though%20a%20number%20and%20a%0A%20%20%20%20string%20are%20common.%20SNAPSHOT%20means%20a%20project%20under%20development.%20FINAL%20is%20commonly%0A%20%20%20%20used%20to%20refer%20to%20stable%20production%20version%20–%3E%0A%20%20%20%20%3Cversion%3E%200.0.1-SNAPSHOT%3C%2Fversion%3E” message=”” highlight=”” provider=”manual”/]

   The version number for a project is an important piece of data that you should be updating during development. Over time there may may be many versions of a project and other developers may depend on a specific version. The most recent version may contain changes that could break the work of other developers who have a dependency on your work. Two special optional terms are SNAPSHOT for a project in development and FINAL for a production ready project.


[pastacode lang=”markup” manual=”%20%20%20%20%3C!–%20Default%20value%20is%20jar%20but%20may%20be%20war%20or%20ear%20–%3E%0A%20%20%20%20%3Cpackaging%3Ewar%3C%2Fpackaging%3E” message=”” highlight=”” provider=”manual”/]

 Select the appropriate archive packaging type, either jar, war or ear.


[pastacode lang=”markup” manual=”%20%20%20%20%3C!–%20The%20name%20given%20to%20the%20project.%20Unlike%20groupId%20and%20artifactId%20a%20name%0A%20%20%20%20may%20have%20spaces%20–%3E%0A%20%20%20%20%3Cname%3E%24%7Bproject.artifactId%7D%3C%2Fname%3E” message=”” highlight=”” provider=”manual”/]

I like to use the artifactId for the project name but you can use any name you want. Notice that you can refer to a tag in the file using substitution notation and by appending it to the term ‘project’.


[pastacode lang=”markup” manual=”%20%20%20%20%3C!–%20A%20description%20of%20the%20program%20–%3E%0A%20%20%20%20%3Cdescription%3EStandard%20starting%20point%20for%20a%20JEE%20Web%20Profile%20application%20using%20Java%20Server%20Faces%0A%20%20%20%20%20%20%20%20for%20students%20of%20Ken%20Fogel%3C%2Fdescription%3E%0A%0A%20%20%20%20%3C!–%20Identifies%20the%20programmer%20or%20programmers%20who%20worked%20on%20the%20project%20–%3E%0A%20%20%20%20%3Cdevelopers%3E%0A%20%20%20%20%20%20%20%20%3Cdeveloper%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3Cid%3EEnter%20your%20school%20id%3C%2Fid%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3Cname%3EEnter%20your%20name%3C%2Fname%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3Cemail%3EEnter%20your%20email%20address%3C%2Femail%3E%0A%20%20%20%20%20%20%20%20%3C%2Fdeveloper%3E%0A%20%20%20%20%3C%2Fdevelopers%3E%0A%0A%20%20%20%20%3C!–%20The%20company%20or%20organization%20that%20the%20programmer(s)%20work%20for%20–%3E%0A%20%20%20%20%3Corganization%3E%0A%20%20%20%20%20%20%20%20%3Cname%3EEnter%20school%20name%3C%2Fname%3E%0A%20%20%20%20%3C%2Forganization%3E” message=”” highlight=”” provider=”manual”/]

 The three sections above are used to identify you. They are optional if you are an amateur. If you are a professional they are mandatory. 


[pastacode lang=”markup” manual=”%20%20%20%20%3C!–%20Global%20settings%20for%20the%20project.%20Settings%20can%20be%20accessed%20in%20the%20pom%0A%20%20%20%20by%20placing%20the%20tag%20name%20in%20%24%7B…%7D%20ex.%20%24%7Bendorsed.dir%7D%20–%3E%0A%20%20%20%20%3Cproperties%3E%0A%20%20%20%20%20%20%20%20%3Cendorsed.dir%3E%24%7Bproject.build.directory%7D%2Fendorsed%3C%2Fendorsed.dir%3E%0A%20%20%20%20%20%20%20%20%3Cproject.build.sourceEncoding%3EUTF-8%3C%2Fproject.build.sourceEncoding%3E%0A%20%20%20%20%20%20%20%20%3Cmaven.compiler.source%3E1.8%3C%2Fmaven.compiler.source%3E%0A%20%20%20%20%20%20%20%20%3Cmaven.compiler.target%3E1.8%3C%2Fmaven.compiler.target%3E%0A%20%20%20%20%3C%2Fproperties%3E” message=”” highlight=”” provider=”manual”/]

 Properties represent data that another section of the pom may need access to. This way this data can be stored in one place and not repeated where it is needed. Endorsed represents a directory where files with the same name and type as those present in the Java installation are stored. This way the file in the endorsed folder will be used rather than the one supplied in the Java installation. The encoding of the project appears here as does the version of Java you will be using.


[pastacode lang=”markup” manual=”%20%20%20%20%3C!–%20Dependencies%20listed%20here%20are%20usually%20bom%20or%20bill%20of%20materials–%3E%0A%20%20%20%20%3C!–%20The%20bom%20lists%20all%20the%20child%20dependencies%20that%20could%20be%20used%20and%20–%3E%0A%20%20%20%20%3C!–%20lists%20the%20current%20version%20number%20for%20each%20–%3E%0A%20%20%20%20%3CdependencyManagement%3E%0A%20%20%20%20%20%20%20%20%3Cdependencies%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3Cdependency%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3CgroupId%3Eorg.jboss.arquillian%3C%2FgroupId%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3CartifactId%3Earquillian-bom%3C%2FartifactId%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Cversion%3E1.1.12.Final%3C%2Fversion%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Cscope%3Eimport%3C%2Fscope%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Ctype%3Epom%3C%2Ftype%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3C%2Fdependency%3E%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%3Cdependency%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3CgroupId%3Eorg.jboss.shrinkwrap.resolver%3C%2FgroupId%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3CartifactId%3Eshrinkwrap-resolver-bom%3C%2FartifactId%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Cversion%3E2.2.6%3C%2Fversion%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Ctype%3Epom%3C%2Ftype%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Cscope%3Eimport%3C%2Fscope%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3C%2Fdependency%3E%0A%20%20%20%20%20%20%20%20%3C%2Fdependencies%3E%0A%20%20%20%20%3C%2FdependencyManagement%3E” message=”” highlight=”” provider=”manual”/]

 When using Arquillian there are numerous libraries that may be required. Exactly what they are may change from version to version. A dependencyManagement section refers to special files classifid as bill of materials that in turn will include the necessary Arquillian libraries. 


[pastacode lang=”markup” manual=”%20%20%20%20%3C!–%20Dependencies%20are%20libraries%20that%20either%20must%20be%20included%20in%20the%20–%3E%0A%20%20%20%20%3C!–%20jar%2Fwar%20file%20or%20are%20expected%20to%20be%20found%20in%20the%20container%20such%20as%20–%3E%0A%20%20%20%20%3C!–%20GlassFish%20–%3E” message=”” highlight=”” provider=”manual”/]

 As my comment above says, the dependencies are libraries that must be available to your project. They will all be downloaded to your local repository. This will allow your IDE to ensure you are using classes and methods from these libraries correctly. They are further classified by the scope tag. If there is no scope tag then the file associated with the dependency will be added to your final archive file. If the scope tag shows ‘provided’ then the required files are in the container you will be running in, such as Glassfish/Payara, and do not need to be added to your archive. If the scope is ‘test’ then the files are only added to an archive used for testing such as what Arquillian produces.


[pastacode lang=”markup” manual=”%20%20%20%20%3Cdependencies%3E%0A%20%20%20%20%20%20%20%20%3C!–%20These%20dependencies%20are%20required%20to%20run%20the%20project%20on%20the%20server%20–%3E%0A%20%20%20%20%20%20%20%20%3C!–%20Java%20EE%207.0%20Web%20profile%20dependency%20–%3E%0A%20%20%20%20%20%20%20%20%3Cdependency%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CgroupId%3Ejavax%3C%2FgroupId%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CartifactId%3Ejavaee-web-api%3C%2FartifactId%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3Cversion%3E7.0%3C%2Fversion%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3Cscope%3Eprovided%3C%2Fscope%3E%0A%20%20%20%20%20%20%20%20%3C%2Fdependency%3E%0A%0A%20%20%20%20%20%20%20%20%3C!–%20MySQL%20dependency%20–%3E%0A%20%20%20%20%20%20%20%20%3Cdependency%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CgroupId%3Emysql%3C%2FgroupId%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CartifactId%3Emysql-connector-java%3C%2FartifactId%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3Cversion%3E5.1.40%3C%2Fversion%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3Cscope%3Eprovided%3C%2Fscope%3E%0A%20%20%20%20%20%20%20%20%3C%2Fdependency%3E%0A%0A%20%20%20%20%20%20%20%20%3C!–%20PrimeFaces%20dependency%20–%3E%0A%20%20%20%20%20%20%20%20%3Cdependency%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CgroupId%3Eorg.primefaces%3C%2FgroupId%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CartifactId%3Eprimefaces%3C%2FartifactId%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3Cversion%3E6.0%3C%2Fversion%3E%0A%20%20%20%20%20%20%20%20%3C%2Fdependency%3E%0A%0A%20%20%20%20%20%20%20%20%3C!–%20EclipseLink%20dependency%20for%20the%20static%20metamodel%20generator%20–%3E%0A%20%20%20%20%20%20%20%20%3Cdependency%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CgroupId%3Eorg.eclipse.persistence%3C%2FgroupId%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CartifactId%3Eorg.eclipse.persistence.jpa.modelgen.processor%3C%2FartifactId%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3Cversion%3E2.6.4%3C%2Fversion%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3Cscope%3Eprovided%3C%2Fscope%3E%0A%20%20%20%20%20%20%20%20%3C%2Fdependency%3E” message=”” highlight=”” provider=”manual”/]

 The metamodel generator dependency invokes a process to create meta model classes dynamically. This will allow you to use identifiers rather than strings in certain types of JPA queries so that refactoring (renaming) is supported.

Thanks to BillyTheKid for pointing out that the dependency for eclipselink, now removed, is not needed, only the metamodel dependency is required.


[pastacode lang=”markup” manual=”%20%20%20%20%20%20%20%20%3C!–%20These%20dependencies%20are%20required%20for%20testing%20only%20–%3E%0A%20%20%20%20%20%20%20%20%3C!–%20Arquillian%20dependency%20for%20running%20tests%20on%20a%20remote%20GlassFish%20server%20–%3E%0A%20%20%20%20%20%20%20%20%3Cdependency%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CgroupId%3Eorg.jboss.arquillian.container%3C%2FgroupId%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CartifactId%3Earquillian-glassfish-remote-3.1%3C%2FartifactId%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3Cversion%3E1.0.0.Final%3C%2Fversion%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3Cscope%3Etest%3C%2Fscope%3E%0A%20%20%20%20%20%20%20%20%3C%2Fdependency%3E%0A%0A%20%20%20%20%20%20%20%20%3C!–%20Resolves%20dependencies%20from%20the%20pom.xml%20when%20explicitly%20referred%20to%0A%20%20%20%20%20%20%20%20in%20the%20Arquillian%20deploy%20method%20–%3E%0A%20%20%20%20%20%20%20%20%3Cdependency%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CgroupId%3Eorg.jboss.shrinkwrap.resolver%3C%2FgroupId%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CartifactId%3Eshrinkwrap-resolver-depchain%3C%2FartifactId%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3Ctype%3Epom%3C%2Ftype%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3Cscope%3Etest%3C%2Fscope%3E%0A%20%20%20%20%20%20%20%20%3C%2Fdependency%3E” message=”” highlight=”” provider=”manual”/]

 Not every required Arquillian dependency that my students need is in one of the two bom dependencyManagement entries so we need to add these two dependencies. If you are using Arquillian then you need these too.


[pastacode lang=”markup” manual=”%20%20%20%20%20%20%20%20%3C!–%20Connects%20Arquillian%20to%20JUnit%20–%3E%0A%20%20%20%20%20%20%20%20%3Cdependency%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CgroupId%3Eorg.jboss.arquillian.junit%3C%2FgroupId%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CartifactId%3Earquillian-junit-container%3C%2FartifactId%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3Cscope%3Etest%3C%2Fscope%3E%0A%20%20%20%20%20%20%20%20%3C%2Fdependency%3E%0A%20%0A%20%20%20%20%20%20%20%20%3C!–%20JUnit%20dependency%20–%3E%0A%20%20%20%20%20%20%20%20%3Cdependency%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CgroupId%3Ejunit%3C%2FgroupId%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CartifactId%3Ejunit%3C%2FartifactId%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3Cversion%3E4.12%3C%2Fversion%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3Cscope%3Etest%3C%2Fscope%3E%0A%20%20%20%20%20%20%20%20%3C%2Fdependency%3E%0A%0A%20%20%20%20%20%20%20%20%3C!–%20Selenium%20dependencies%20–%3E%0A%20%20%20%20%20%20%20%20%3Cdependency%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CgroupId%3Eorg.seleniumhq.selenium%3C%2FgroupId%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CartifactId%3Ehtmlunit-driver%3C%2FartifactId%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3Cversion%3E2.25%3C%2Fversion%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3Cscope%3Etest%3C%2Fscope%3E%0A%20%20%20%20%20%20%20%20%3C%2Fdependency%3E%0A%0A%20%20%20%20%20%20%20%20%3C!–%20You%20will%20need%20a%20driver%20dependency%20for%20every%20browser%20you%20use%20in%0A%20%20%20%20%20%20%20%20testing.%20You%20can%20find%20the%20meven%20dependencies%20at%0A%20%20%20%20%20%20%20%20https%3A%2F%2Fmvnrepository.com%2Fartifact%2Forg.seleniumhq.selenium%20–%3E%0A%20%20%20%20%20%20%20%20%3Cdependency%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CgroupId%3Eorg.seleniumhq.selenium%3C%2FgroupId%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CartifactId%3Eselenium-chrome-driver%3C%2FartifactId%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3Cversion%3E3.2.0%3C%2Fversion%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3Cscope%3Etest%3C%2Fscope%3E%0A%20%20%20%20%20%20%20%20%3C%2Fdependency%3E%0A%0A%20%20%20%20%20%20%20%20%3C!–%20Normally%20you%20must%20download%20an%20exe%20for%20each%20browser.%20This%20library%0A%20%20%20%20%20%20%20%20will%20retrieve%20the%20the%20necessary%20file%20and%20place%20it%20in%20the%20classpath%20for%0A%20%20%20%20%20%20%20%20selenium%20to%20use%20–%3E%0A%20%20%20%20%20%20%20%20%3Cdependency%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CgroupId%3Eio.github.bonigarcia%3C%2FgroupId%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CartifactId%3Ewebdrivermanager%3C%2FartifactId%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3Cversion%3E1.6.0%3C%2Fversion%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3Cscope%3Etest%3C%2Fscope%3E%0A%20%20%20%20%20%20%20%20%3C%2Fdependency%3E” message=”” highlight=”” provider=”manual”/]

 For the first time I will be having my students use Selenium as part of their testing. Selenium is actually an independent system that can even be placed in a Java desktop application. Here it will be run as a unit test. Selenium requires, in addition to the Java library, a standalone executable program to connect it to a specific browser. I found this extremely convenient library, webdrivermanager, that will download all the required executables and run them as required.


[pastacode lang=”markup” manual=”%20%20%20%20%20%20%20%20%3C!–%20A%20better%20way%20to%20write%20assertions%20–%3E%0A%20%20%20%20%20%20%20%20%3Cdependency%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CgroupId%3Eorg.assertj%3C%2FgroupId%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CartifactId%3Eassertj-core%3C%2FartifactId%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3Cversion%3E1.7.1%3C%2Fversion%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3Cscope%3Etest%3C%2Fscope%3E%0A%20%20%20%20%20%20%20%20%3C%2Fdependency%3E%0A%0A%20%20%20%20%20%20%20%20%3C!–%20Selenium%20uses%20SLF4J%20and%20log4j%20so%20these%20dependencies%20are%20needed%0A%20%20%20%20%20%20%20%20but%20just%20for%20test%20scope%20–%3E%0A%20%20%20%20%20%20%20%20%3Cdependency%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CgroupId%3Eorg.slf4j%3C%2FgroupId%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CartifactId%3Eslf4j-api%3C%2FartifactId%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3Cversion%3E1.7.23%3C%2Fversion%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3Cscope%3Etest%3C%2Fscope%3E%0A%20%20%20%20%20%20%20%20%3C%2Fdependency%3E%0A%20%20%20%20%20%20%20%20%3Cdependency%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CgroupId%3Eorg.apache.logging.log4j%3C%2FgroupId%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CartifactId%3Elog4j-slf4j-impl%3C%2FartifactId%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3Cversion%3E2.8%3C%2Fversion%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3Cscope%3Etest%3C%2Fscope%3E%0A%20%20%20%20%20%20%20%20%3C%2Fdependency%3E%0A%20%20%20%20%20%20%20%20%3Cdependency%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CgroupId%3Eorg.apache.logging.log4j%3C%2FgroupId%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CartifactId%3Elog4j-api%3C%2FartifactId%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3Cversion%3E2.8%3C%2Fversion%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3Cscope%3Etest%3C%2Fscope%3E%0A%20%20%20%20%20%20%20%20%3C%2Fdependency%3E%0A%20%20%20%20%20%20%20%20%3Cdependency%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CgroupId%3Eorg.apache.logging.log4j%3C%2FgroupId%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CartifactId%3Elog4j-core%3C%2FartifactId%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3Cversion%3E2.8%3C%2Fversion%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3Cscope%3Etest%3C%2Fscope%3E%0A%20%20%20%20%20%20%20%20%3C%2Fdependency%3E%0A%20%20%20%20%3C%2Fdependencies%3E%0A” message=”” highlight=”” provider=”manual”/]

 Selenium uses slf4j as the interface to log4j. That is why these dependencies are all listed as test scope. A student recently ran into a problem when a library they were using in their project also needed slf4j. The solution was to remove scope so that the libraries were added to both the production and test archive files. 


[pastacode lang=”markup” manual=”%20%20%20%20%3C%2F!–%20Information%20for%20compiling%2C%20testing%20and%20packaging%20are%20define%20here%20–%3E%0A%20%20%20%20%3Cbuild%3E%0A%20%20%20%20%20%20%20%20%3CtestResources%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3C!–%20Folders%20in%20the%20project%20required%20during%20testing%20–%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CtestResource%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Cdirectory%3Esrc%2Ftest%2Fresources%3C%2Fdirectory%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3C%2FtestResource%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CtestResource%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Cdirectory%3Esrc%2Ftest%2Fresources-glassfish-remote%3C%2Fdirectory%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3C%2FtestResource%3E%0A%20%20%20%20%20%20%20%20%3C%2FtestResources%3E” message=”” highlight=”” provider=”manual”/]

 Here in the build section of the pom.xml. Here you can identify filesor folders folders that are required but are not part of a standard Maven project. 


[pastacode lang=”markup” manual=”%20%20%20%20%20%20%20%20%3C!–%20Plugins%20are%20components%20that%20Maven%20uses%20for%20specific%20purposes%20beyond%0A%20%20%20%20%20%20%20%20the%20basic%20tasks%20–%3E%0A%20%20%20%20%20%20%20%20%3Cplugins%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3C!–%20Presence%20of%20this%20plugin%20suppress%20a%20warning%20about%20the%20existence%20%0A%20%20%20%20%20%20%20%20%20%20%20%20of%20the%20web.xml%20file%20–%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3Cplugin%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3CgroupId%3Eorg.apache.maven.plugins%3C%2FgroupId%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3CartifactId%3Emaven-war-plugin%3C%2FartifactId%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Cversion%3E3.0.0%3C%2Fversion%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3C%2Fplugin%3E” message=”” highlight=”” provider=”manual”/]

Plugins are modules that add features to Maven. The Maven war plugin is used when we wish to modify how the war file is built. It is not required for the projects my students build. Unfortunately, leaving this plugin out results in a warning that reads “Warning: selected war files include a WEB-INF/web.xml which will be ignored”. This statement is false and the project’s web.xml is properly processed. Adding this plugin without any settings eliminates the warning message. 


[pastacode lang=”markup” manual=”%20%20%20%20%20%20%20%20%20%20%20%20%3Cplugin%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3C!–%20Executes%20JUnit%20tests%20and%20writes%20the%20results%20as%20an%20xml%20and%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20txt%20file%20Test%20classes%20must%20include%20one%20of%20the%20following%20in%20their%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20name%3A%20Test*%20*Test%20*TestCase%20–%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3CgroupId%3Eorg.apache.maven.plugins%3C%2FgroupId%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3CartifactId%3Emaven-surefire-plugin%3C%2FartifactId%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Cversion%3E2.19.1%3C%2Fversion%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Cconfiguration%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3CargLine%3E-Dfile.encoding%3D%24%7Bproject.build.sourceEncoding%7D%3C%2FargLine%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3CskipTests%3Efalse%3C%2FskipTests%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3C%2Fconfiguration%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3C%2Fplugin%3E%0A%20%20%20%20%20%20%20%20%3C%2Fpluginn%3E%0A%20%20%20%20%3C%2Fbuild%3E%0A%3C%2Fproject%3E” message=”” highlight=”” provider=”manual”/]

The Surefire pligin controls running tests and it allows me to easily turn on or off testing with the skipTests tag.

Final Word

In preparing this article I removed two plugins that proved to be redundant and removed unnecessary tags from a third. These plugins were there because the articles that I read in researching Maven showed them. These Maven entries continue to appear on StackOverflow and in other articles. May I suggest that when writing about Maven or answering a question you consider testing your code by removing plugins. Otherwise we will propagate inflated Maven pom.xml files.

Here is the full pom.xml.

[pastacode lang=”markup” manual=”%3C%3Fxml%20version%3D%221.0%22%20encoding%3D%22UTF-8%22%3F%3E%0A%3Cproject%20xmlns%3D%22http%3A%2F%2Fmaven.apache.org%2FPOM%2F4.0.0%22%20xmlns%3Axsi%3D%22http%3A%2F%2Fwww.w3.org%2F2001%2FXMLSchema-instance%22%20xsi%3AschemaLocation%3D%22http%3A%2F%2Fmaven.apache.org%2FPOM%2F4.0.0%20http%3A%2F%2Fmaven.apache.org%2Fxsd%2Fmaven-4.0.0.xsd%22%3E%0A%20%20%20%20%3C!–%20pom.xml%20February%202017%20version%201.0%20–%3E%0A%0A%20%20%20%20%3C!–%20Maven%20version%20of%20the%20xml%20document%20currently%20only%204.0.0%20is%20valid%20–%3E%0A%20%20%20%20%3CmodelVersion%3E4.0.0%3C%2FmodelVersion%3E%0A%0A%20%20%20%20%3C!–%20The%20GAV%20consists%20of%20an%20arbitrary%20descriptor%20that%20is%20usually%20in%20the%0A%20%20%20%20form%20of%20a%20reverse%20domain%20name.%20–%3E%0A%20%20%20%20%3CgroupId%3Ecom.kfwebstandard%3C%2FgroupId%3E%0A%0A%20%20%20%20%3C!–%20This%20is%20the%20name%20given%20to%20the%20packaged%20build%20–%3E%0A%20%20%20%20%3CartifactId%3EKFWebStandardProject%3C%2FartifactId%3E%0A%0A%20%20%20%20%3C!–%20The%20version%20of%20the%20build.%20Any%20value%20is%20valid%20though%20a%20number%20and%20a%0A%20%20%20%20string%20are%20common.%20SNAPSHOT%20means%20a%20project%20under%20development.%20FINAL%20is%20commonly%0A%20%20%20%20used%20to%20refer%20to%20stable%20production%20version%20–%3E%0A%20%20%20%20%3Cversion%3E0.1%3C%2Fversion%3E%0A%0A%20%20%20%20%3C!–%20Default%20value%20is%20jar%20but%20may%20be%20war%20or%20ear%20–%3E%0A%20%20%20%20%3Cpackaging%3Ewar%3C%2Fpackaging%3E%0A%0A%20%20%20%20%3C!–%20The%20name%20given%20to%20the%20project.%20Unlike%20groupId%20and%20artifactId%20a%20name%0A%20%20%20%20may%20have%20spaces%20–%3E%0A%20%20%20%20%3Cname%3E%24%7Bproject.artifactId%7D%3C%2Fname%3E%0A%0A%20%20%20%20%3C!–%20A%20description%20of%20the%20program%20–%3E%0A%20%20%20%20%3Cdescription%3EStandard%20starting%20point%20for%20a%20JEE%20Web%20Profile%20application%20using%20Java%20Server%20Faces%0A%20%20%20%20%20%20%20%20for%20students%20of%20Ken%20Fogel%3C%2Fdescription%3E%0A%0A%20%20%20%20%3C!–%20Identifies%20the%20programmer%20or%20programmers%20who%20worked%20on%20the%20project%20–%3E%0A%20%20%20%20%3Cdevelopers%3E%0A%20%20%20%20%20%20%20%20%3Cdeveloper%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3Cid%3EEnter%20your%20school%20id%3C%2Fid%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3Cname%3EEnter%20your%20name%3C%2Fname%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3Cemail%3EEnter%20your%20email%20address%3C%2Femail%3E%0A%20%20%20%20%20%20%20%20%3C%2Fdeveloper%3E%0A%20%20%20%20%3C%2Fdevelopers%3E%0A%0A%20%20%20%20%3C!–%20The%20company%20or%20organization%20that%20the%20programmer(s)%20work%20for%20–%3E%0A%20%20%20%20%3Corganization%3E%0A%20%20%20%20%20%20%20%20%3Cname%3EEnter%20school%20name%3C%2Fname%3E%0A%20%20%20%20%3C%2Forganization%3E%0A%0A%20%20%20%20%3C!–%20Global%20settings%20for%20the%20project.%20Settings%20can%20be%20accessed%20in%20the%20pom%0A%20%20%20%20by%20placing%20the%20tag%20name%20in%20%24%7B…%7D%20ex.%20%24%7Bendorsed.dir%7D%20–%3E%0A%20%20%20%20%3Cproperties%3E%0A%20%20%20%20%20%20%20%20%3Cendorsed.dir%3E%24%7Bproject.build.directory%7D%2Fendorsed%3C%2Fendorsed.dir%3E%0A%20%20%20%20%20%20%20%20%3Cproject.build.sourceEncoding%3EUTF-8%3C%2Fproject.build.sourceEncoding%3E%0A%20%20%20%20%20%20%20%20%3Cmaven.compiler.source%3E1.8%3C%2Fmaven.compiler.source%3E%0A%20%20%20%20%20%20%20%20%3Cmaven.compiler.target%3E1.8%3C%2Fmaven.compiler.target%3E%0A%20%20%20%20%3C%2Fproperties%3E%0A%0A%20%20%20%20%3C!–%20Dependencies%20listed%20here%20are%20usually%20bom%20or%20bill%20of%20materials–%3E%0A%20%20%20%20%3C!–%20The%20bom%20lists%20all%20the%20child%20dependencies%20that%20could%20be%20used%20and%20–%3E%0A%20%20%20%20%3C!–%20lists%20the%20current%20version%20number%20for%20each%20–%3E%0A%20%20%20%20%3CdependencyManagement%3E%0A%20%20%20%20%20%20%20%20%3Cdependencies%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3Cdependency%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3CgroupId%3Eorg.jboss.arquillian%3C%2FgroupId%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3CartifactId%3Earquillian-bom%3C%2FartifactId%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Cversion%3E1.1.12.Final%3C%2Fversion%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Cscope%3Eimport%3C%2Fscope%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Ctype%3Epom%3C%2Ftype%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3C%2Fdependency%3E%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%3Cdependency%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3CgroupId%3Eorg.jboss.shrinkwrap.resolver%3C%2FgroupId%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3CartifactId%3Eshrinkwrap-resolver-bom%3C%2FartifactId%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Cversion%3E2.2.6%3C%2Fversion%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Ctype%3Epom%3C%2Ftype%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Cscope%3Eimport%3C%2Fscope%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3C%2Fdependency%3E%0A%20%20%20%20%20%20%20%20%3C%2Fdependencies%3E%0A%20%20%20%20%3C%2FdependencyManagement%3E%0A%0A%20%20%20%20%3C!–%20Dependencies%20are%20libraries%20that%20either%20must%20be%20included%20in%20the%20–%3E%0A%20%20%20%20%3C!–%20jar%2Fwar%20file%20or%20are%20expected%20to%20be%20found%20in%20the%20container%20such%20as%20–%3E%0A%20%20%20%20%3C!–%20GlassFish%20–%3E%0A%20%20%20%20%3Cdependencies%3E%0A%20%20%20%20%20%20%20%20%3C!–%20These%20dependencies%20are%20required%20to%20run%20the%20project%20on%20the%20server%20–%3E%0A%0A%20%20%20%20%20%20%20%20%3C!–%20Java%20EE%207.0%20Web%20profile%20dependency%20–%3E%0A%20%20%20%20%20%20%20%20%3Cdependency%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CgroupId%3Ejavax%3C%2FgroupId%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CartifactId%3Ejavaee-web-api%3C%2FartifactId%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3Cversion%3E7.0%3C%2Fversion%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3Cscope%3Eprovided%3C%2Fscope%3E%0A%20%20%20%20%20%20%20%20%3C%2Fdependency%3E%0A%0A%20%20%20%20%20%20%20%20%3C!–%20MySQL%20dependency%20–%3E%0A%20%20%20%20%20%20%20%20%3Cdependency%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CgroupId%3Emysql%3C%2FgroupId%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CartifactId%3Emysql-connector-java%3C%2FartifactId%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3Cversion%3E5.1.40%3C%2Fversion%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3Cscope%3Eprovided%3C%2Fscope%3E%0A%20%20%20%20%20%20%20%20%3C%2Fdependency%3E%0A%0A%20%20%20%20%20%20%20%20%3C!–%20PrimeFaces%20dependency%20–%3E%0A%20%20%20%20%20%20%20%20%3Cdependency%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CgroupId%3Eorg.primefaces%3C%2FgroupId%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CartifactId%3Eprimefaces%3C%2FartifactId%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3Cversion%3E6.0%3C%2Fversion%3E%0A%20%20%20%20%20%20%20%20%3C%2Fdependency%3E%0A%0A%20%20%20%20%20%20%20%20%3C!–%20EclipseLink%20dependency%20for%20the%20static%20metamodel%20generator%20–%3E%0A%20%20%20%20%20%20%20%20%3Cdependency%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CgroupId%3Eorg.eclipse.persistence%3C%2FgroupId%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CartifactId%3Eorg.eclipse.persistence.jpa.modelgen.processor%3C%2FartifactId%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3Cversion%3E2.6.4%3C%2Fversion%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3Cscope%3Eprovided%3C%2Fscope%3E%0A%20%20%20%20%20%20%20%20%3C%2Fdependency%3E%0A%0A%20%20%20%20%20%20%20%20%3C!–%20These%20dependencies%20are%20required%20for%20testing%20only%20–%3E%0A%0A%20%20%20%20%20%20%20%20%3C!–%20Arquillian%20dependency%20for%20running%20tests%20on%20a%20remote%20GlassFish%20server%20–%3E%0A%20%20%20%20%20%20%20%20%3Cdependency%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CgroupId%3Eorg.jboss.arquillian.container%3C%2FgroupId%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CartifactId%3Earquillian-glassfish-remote-3.1%3C%2FartifactId%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3Cversion%3E1.0.0.Final%3C%2Fversion%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3Cscope%3Etest%3C%2Fscope%3E%0A%20%20%20%20%20%20%20%20%3C%2Fdependency%3E%0A%0A%20%20%20%20%20%20%20%20%3C!–%20Resolves%20dependencies%20from%20the%20pom.xml%20when%20explicitly%20referred%20to%0A%20%20%20%20%20%20%20%20in%20the%20Arquillian%20deploy%20method%20–%3E%0A%20%20%20%20%20%20%20%20%3Cdependency%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CgroupId%3Eorg.jboss.shrinkwrap.resolver%3C%2FgroupId%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CartifactId%3Eshrinkwrap-resolver-depchain%3C%2FartifactId%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3Ctype%3Epom%3C%2Ftype%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3Cscope%3Etest%3C%2Fscope%3E%0A%20%20%20%20%20%20%20%20%3C%2Fdependency%3E%0A%0A%20%20%20%20%20%20%20%20%3C!–%20Connects%20Arquillian%20to%20JUnit%20–%3E%0A%20%20%20%20%20%20%20%20%3Cdependency%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CgroupId%3Eorg.jboss.arquillian.junit%3C%2FgroupId%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CartifactId%3Earquillian-junit-container%3C%2FartifactId%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3Cscope%3Etest%3C%2Fscope%3E%0A%20%20%20%20%20%20%20%20%3C%2Fdependency%3E%0A%0A%20%20%20%20%20%20%20%20%3C!–%20JUnit%20dependency%20–%3E%0A%20%20%20%20%20%20%20%20%3Cdependency%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CgroupId%3Ejunit%3C%2FgroupId%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CartifactId%3Ejunit%3C%2FartifactId%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3Cversion%3E4.12%3C%2Fversion%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3Cscope%3Etest%3C%2Fscope%3E%0A%20%20%20%20%20%20%20%20%3C%2Fdependency%3E%0A%0A%20%20%20%20%20%20%20%20%3C!–%20Selenium%20dependencies%20–%3E%0A%20%20%20%20%20%20%20%20%3Cdependency%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CgroupId%3Eorg.seleniumhq.selenium%3C%2FgroupId%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CartifactId%3Ehtmlunit-driver%3C%2FartifactId%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3Cversion%3E2.25%3C%2Fversion%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3Cscope%3Etest%3C%2Fscope%3E%0A%20%20%20%20%20%20%20%20%3C%2Fdependency%3E%0A%0A%20%20%20%20%20%20%20%20%3C!–%20You%20will%20need%20a%20driver%20dependency%20for%20every%20browser%20you%20use%20in%0A%20%20%20%20%20%20%20%20testing.%20You%20can%20find%20the%20meven%20dependencies%20at%0A%20%20%20%20%20%20%20%20https%3A%2F%2Fmvnrepository.com%2Fartifact%2Forg.seleniumhq.selenium%20–%3E%0A%20%20%20%20%20%20%20%20%3Cdependency%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CgroupId%3Eorg.seleniumhq.selenium%3C%2FgroupId%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CartifactId%3Eselenium-chrome-driver%3C%2FartifactId%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3Cversion%3E3.2.0%3C%2Fversion%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3Cscope%3Etest%3C%2Fscope%3E%0A%20%20%20%20%20%20%20%20%3C%2Fdependency%3E%0A%0A%20%20%20%20%20%20%20%20%3C!–%20Normally%20you%20must%20download%20an%20exe%20for%20each%20browser.%20This%20library%0A%20%20%20%20%20%20%20%20will%20retrieve%20the%20the%20necessary%20file%20and%20place%20it%20in%20the%20classpath%20for%0A%20%20%20%20%20%20%20%20selenium%20to%20use%20–%3E%0A%20%20%20%20%20%20%20%20%3Cdependency%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CgroupId%3Eio.github.bonigarcia%3C%2FgroupId%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CartifactId%3Ewebdrivermanager%3C%2FartifactId%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3Cversion%3E1.6.0%3C%2Fversion%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3Cscope%3Etest%3C%2Fscope%3E%0A%20%20%20%20%20%20%20%20%3C%2Fdependency%3E%0A%0A%20%20%20%20%20%20%20%20%3C!–%20A%20better%20way%20to%20write%20assertions%20–%3E%0A%20%20%20%20%20%20%20%20%3Cdependency%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CgroupId%3Eorg.assertj%3C%2FgroupId%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CartifactId%3Eassertj-core%3C%2FartifactId%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3Cversion%3E1.7.1%3C%2Fversion%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3Cscope%3Etest%3C%2Fscope%3E%0A%20%20%20%20%20%20%20%20%3C%2Fdependency%3E%0A%0A%20%20%20%20%20%20%20%20%3C!–%20Selenium%20uses%20SLF4J%20and%20log4j%20so%20these%20dependencies%20are%20needed%0A%20%20%20%20%20%20%20%20but%20just%20for%20test%20scope%20–%3E%0A%20%20%20%20%20%20%20%20%3Cdependency%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CgroupId%3Eorg.slf4j%3C%2FgroupId%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CartifactId%3Eslf4j-api%3C%2FartifactId%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3Cversion%3E1.7.23%3C%2Fversion%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3Cscope%3Etest%3C%2Fscope%3E%0A%20%20%20%20%20%20%20%20%3C%2Fdependency%3E%0A%20%20%20%20%20%20%20%20%3Cdependency%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CgroupId%3Eorg.apache.logging.log4j%3C%2FgroupId%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CartifactId%3Elog4j-slf4j-impl%3C%2FartifactId%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3Cversion%3E2.8%3C%2Fversion%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3Cscope%3Etest%3C%2Fscope%3E%0A%20%20%20%20%20%20%20%20%3C%2Fdependency%3E%0A%20%20%20%20%20%20%20%20%3Cdependency%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CgroupId%3Eorg.apache.logging.log4j%3C%2FgroupId%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CartifactId%3Elog4j-api%3C%2FartifactId%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3Cversion%3E2.8%3C%2Fversion%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3Cscope%3Etest%3C%2Fscope%3E%0A%20%20%20%20%20%20%20%20%3C%2Fdependency%3E%0A%20%20%20%20%20%20%20%20%3Cdependency%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CgroupId%3Eorg.apache.logging.log4j%3C%2FgroupId%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CartifactId%3Elog4j-core%3C%2FartifactId%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3Cversion%3E2.8%3C%2Fversion%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3Cscope%3Etest%3C%2Fscope%3E%0A%20%20%20%20%20%20%20%20%3C%2Fdependency%3E%0A%0A%20%20%20%20%3C%2Fdependencies%3E%0A%0A%20%20%20%20%3C!–%20Information%20for%20compiling%2C%20testing%20and%20packaging%20are%20define%20here%20–%3E%0A%20%20%20%20%3Cbuild%3E%0A%20%20%20%20%20%20%20%20%3C!–%20Folders%20in%20the%20project%20required%20during%20testing%20–%3E%0A%20%20%20%20%20%20%20%20%3CtestResources%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CtestResource%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Cdirectory%3Esrc%2Ftest%2Fresources%3C%2Fdirectory%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3C%2FtestResource%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CtestResource%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Cdirectory%3Esrc%2Ftest%2Fresources-glassfish-remote%3C%2Fdirectory%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3C%2FtestResource%3E%0A%20%20%20%20%20%20%20%20%3C%2FtestResources%3E%0A%0A%20%20%20%20%20%20%20%20%3C!–%20Plugins%20are%20components%20that%20Maven%20uses%20for%20specific%20purposes%20beyond%0A%20%20%20%20%20%20%20%20the%20basic%20tasks%20–%3E%0A%20%20%20%20%20%20%20%20%3Cplugins%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3C!–%20Presence%20of%20this%20plugin%20suppress%20a%20warning%20about%20the%20existence%0A%20%20%20%20%20%20%20%20%20%20%20%20of%20the%20web.xml%20file%20–%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3Cplugin%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3CgroupId%3Eorg.apache.maven.plugins%3C%2FgroupId%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3CartifactId%3Emaven-war-plugin%3C%2FartifactId%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Cversion%3E3.0.0%3C%2Fversion%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3C%2Fplugin%3E%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%3Cplugin%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3C!–%20Executes%20JUnit%20tests%20and%20writes%20the%20results%20as%20an%20xml%20and%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20txt%20file%20Test%20classes%20must%20include%20one%20of%20the%20following%20in%20their%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20name%3A%20Test*%20*Test%20*TestCase%20–%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3CgroupId%3Eorg.apache.maven.plugins%3C%2FgroupId%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3CartifactId%3Emaven-surefire-plugin%3C%2FartifactId%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Cversion%3E2.19.1%3C%2Fversion%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Cconfiguration%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3CargLine%3E-Dfile.encoding%3D%24%7Bproject.build.sourceEncoding%7D%3C%2FargLine%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3CskipTests%3Efalse%3C%2FskipTests%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3C%2Fconfiguration%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3C%2Fplugin%3E%0A%0A%20%20%20%20%20%20%20%20%3C%2Fplugins%3E%0A%20%20%20%20%3C%2Fbuild%3E%0A%3C%2Fproject%3E%0A%0A” message=”” highlight=”” provider=”manual”/]