Featured FREE Whitepapers

What's New Here?

java-logo

Guava’s Objects Class: Equals, HashCode, and ToString

If you are fortunate enough to be using JDK 7, the newly available Objects class is the obvious (at least to me) choice for implementing the ‘common’ Java object methods such as equals(Object) [with Objects.equals(Object,Object)], hashCode() [with Objects.hashCode(Object) or Objects.hash(Object…)], and toString() [with Objects.toString(Object)] to appropriately override the default Object implementations. I have written posts about using Objects class: JDK 7: The New Objects Class and Java 7 Objects-Powered Compact Equals. If you’re not yet using Java 7, your best choices might be the Apache Commons builders ToStringBuilder and EqualsBuilder and HashCodeBuilder (if you’re using a version of Java prior to J2SE 5) or Guava (if you’re using J2SE 5 or later). In this post, I look at using Guava‘s Objects class to implement the three common methods equals, hashCode, and toString(). Without Guava or other library to help, the three common methods discussed in this post are often highlighted as shown in the next code listing. These methods were generated with NetBeans 7.1 beta. TraditionalEmployee   package dustin.examples;import java.util.Calendar;/** * Simple employee class using NetBeans-generated 'common' methods * implementations that are typical of many such implementations created * without Guava or other library. * * @author Dustin */ public class TraditionalEmployee { public enum Gender{ FEMALE, MALE };private final String lastName; private final String firstName; private final String employerName; private final Gender gender;/** * Create an instance of me. * * @param newLastName The new last name my instance will have. * @param newFirstName The new first name my instance will have. * @param newEmployerName The employer name my instance will have. * @param newGender The gender of my instance. */ public TraditionalEmployee( final String newLastName, final String newFirstName, final String newEmployerName, final Gender newGender) { this.lastName = newLastName; this.firstName = newFirstName; this.employerName = newEmployerName; this.gender = newGender; }public String getEmployerName() { return this.employerName; }public String getFirstName() { return this.firstName; }public Gender getGender() { return this.gender; }public String getLastName() { return this.lastName; }/** * NetBeans-generated method that compares provided object to me for equality. * * @param obj Object to be compared to me for equality. * @return {@code true} if provided object is considered equal to me or * {@code false} if provided object is not considered equal to me. */ @Override public boolean equals(Object obj) { if (obj == null) { return false; } if (getClass() != obj.getClass()) { return false; } final TraditionalEmployee other = (TraditionalEmployee) obj; if ((this.lastName == null) ? (other.lastName != null) : !this.lastName.equals(other.lastName)) { return false; } if ((this.firstName == null) ? (other.firstName != null) : !this.firstName.equals(other.firstName)) { return false; } if ((this.employerName == null) ? (other.employerName != null) : !this.employerName.equals(other.employerName)) { return false; } if (this.gender != other.gender) { return false; } return true; }/** * NetBeans-generated method that provides hash code of this employee instance. * * @return My hash code. */ @Override public int hashCode() { int hash = 3; hash = 19 * hash + (this.lastName != null ? this.lastName.hashCode() : 0); hash = 19 * hash + (this.firstName != null ? this.firstName.hashCode() : 0); hash = 19 * hash + (this.employerName != null ? this.employerName.hashCode() : 0); hash = 19 * hash + (this.gender != null ? this.gender.hashCode() : 0); return hash; }/** * NetBeans-generated method that provides String representation of employee * instance. * * @return My String representation. */ @Override public String toString() { return 'TraditionalEmployee{' + 'lastName=' + lastName + ', firstName=' + firstName + ', employerName=' + employerName + ', gender=' + gender + '}'; } } Although NetBeans 7.1 beta did the heavy lifting here, this code still must be maintained and can be made more readable. The next class is the same class, but with Guava-powered common methods instead of the NetBeans-generated ‘typical’ implementations shown above. GuavaEmployee   package dustin.examples;/** * Simple employee class using Guava-powered 'common' methods implementations. * * I explicitly scope the com.google.common.base.Objects class here to avoid the * inherent name collision with the java.util.Objects class. * * @author Dustin */ public class GuavaEmployee { public enum Gender{ FEMALE, MALE };private final String lastName; private final String firstName; private final String employerName; private final TraditionalEmployee.Gender gender;/** * Create an instance of me. * * @param newLastName The new last name my instance will have. * @param newFirstName The new first name my instance will have. * @param newEmployerName The employer name my instance will have. * @param newGender The gender of my instance. */ public GuavaEmployee( final String newLastName, final String newFirstName, final String newEmployerName, final TraditionalEmployee.Gender newGender) { this.lastName = newLastName; this.firstName = newFirstName; this.employerName = newEmployerName; this.gender = newGender; }public String getEmployerName() { return this.employerName; }public String getFirstName() { return this.firstName; }public TraditionalEmployee.Gender getGender() { return this.gender; }public String getLastName() { return this.lastName; }/** * Using Guava to compare provided object to me for equality. * * @param obj Object to be compared to me for equality. * @return {@code true} if provided object is considered equal to me or * {@code false} if provided object is not considered equal to me. */ @Override public boolean equals(Object obj) { if (obj == null) { return false; } if (getClass() != obj.getClass()) { return false; } final GuavaEmployee other = (GuavaEmployee) obj;return com.google.common.base.Objects.equal(this.lastName, other.lastName) && com.google.common.base.Objects.equal(this.firstName, other.firstName) && com.google.common.base.Objects.equal(this.employerName, other.employerName) && com.google.common.base.Objects.equal(this.gender, other.gender); }/** * Uses Guava to assist in providing hash code of this employee instance. * * @return My hash code. */ @Override public int hashCode() { return com.google.common.base.Objects.hashCode( this.lastName, this.firstName, this.employerName, this.gender); }/** * Method using Guava to provide String representation of this employee * instance. * * @return My String representation. */ @Override public String toString() { return com.google.common.base.Objects.toStringHelper(this) .addValue(this.lastName) .addValue(this.firstName) .addValue(this.employerName) .addValue(this.gender) .toString(); } } As the code above proves, the use of Guava improves the readability of the implementations of the three common methods. The only thing that’s not so nice is the need to explicitly scope Guava’s Objects class in the code to avoid a naming collision with Java SE 7’s Objects class. Of course, if one is not using Java 7, then this is not an issue and if one is using Java 7, it’s most likely that the standard version should be used instead anyway. Conclusion Guava provides a nice approach for building safer and more readable common methods via its Objects class. Although I’ll use the new java.util.Objects class instead for JDK 7 projects, Guava’s com.google.common.base.Objects class provides a nice alternative for working in versions of Java prior to JDK 7.   Reference: Guava’s Objects Class: Equals, HashCode, and ToString from our JCG partner Dustin Marx at the Inspired by Actual Events blog. ...
groovy-logo

Scripted Reports with Groovy

Groovy has become my favorite scripting language and in this blog I look at some of Groovy’s features that make it particularly attractive for presenting text-based reports. The post will show how custom text-based reports of data stored in the database can be easily presented with Groovy. I will highlight several attractive features of Groovy along the way. I use the Oracle Database 11g Express Edition (XE) for the data source in my example in this post, but any data source could be used. This example does make use of Groovy’s excellent SQL/JDBC support and uses the Oracle sample schema (HR). A visual depiction of that sample schema is available in the sample schema documentation. My example of using Groovy to write a reporting script involves retrieving data from the Oracle HR sample schema and presenting that data via a text-based report. One portion of the script needs to acquire this data from the database and Groovy adds only minimal ceremony to the SQL statement needed to do this. The following code snippet from the script shows use of Groovy’s multi-line GString to specify the SQL query string in a user-friendly format and to process the results of that query. def employeeQueryStr = '''SELECT e.employee_id, e.first_name, e.last_name, e.email, e.phone_number, e.hire_date, e.job_id, j.job_title, e.salary, e.commission_pct, e.manager_id, e.department_id, d.department_name, m.first_name AS mgr_first_name, m.last_name AS mgr_last_name FROM employees e, departments d, jobs j, employees m WHERE e.department_id = d.department_id AND e.job_id = j.job_id AND e.manager_id = m.employee_id(+)'''def employees = new TreeMap<Long, Employee>() import groovy.sql.Sql def sql = Sql.newInstance('jdbc:oracle:thin:@localhost:1521:xe', 'hr', 'hr', 'oracle.jdbc.pool.OracleDataSource') sql.eachRow(employeeQueryStr) { def employeeId = it.employee_id as Long def employee = new Employee(employeeId, it.first_name, it.last_name, it.email, it.phone_number, it.hire_date, it.job_id, it.job_title, it.salary, it.commission_pct, it.manager_id as Long, it.department_id as Long, it.department_name, it.mgr_first_name, it.mgr_last_name) employees.put(employeeId, employee) } The Groovy code above only adds a small amount of code on top of the Oracle SQL statement. The specified SELECT statement joins multiple tables and includes an outer join as well (outer join needed to include the President in the query results despite that position not having a manager). The vast majority of the first part of the code is the SQL statement that could be run as-is in SQL*Plus or SQL Developer. No need for verbose exception catching and result set handling with Groovy’s SQL support! There are more Groovy-specific advantages to point out in the code snippet above. Note that the import statement to import groovy.sql.Sql was allowed when needed and did not need to be at the top of the script file. The example also used Sql.newInstance and Sql.eachRow(GString,Closure). The latter method allows for easy application of a closure to the results of the query. The it special word is the default name for items being processed in the closure. In this case,it can be thought of a a row in the result set. Values in each row are accessed by the underlying database columns’ names (or aliases in the case of mgr_first_name and mgr_last_name). One of the advantages of Groovy is its seamless integration with Java. The above code snippet also demonstrated this via Groovy’s use of TreeMap, which is advantageous because it means that the new Employee instances placed in the map based on data retrieved from the database will always be available in order of employee ID. In the code above, the information retrieved from the database and processed via the closure is stored for each row in a newly instantiated Employee object. This Employee object provides another place to show off Groovy’s brevity and is shown next. Employee.groovy @groovy.transform.Canonical class Employee { Long employeeId String firstName String lastName String emailAddress String phone_number Date hireDate String jobId String jobTitle BigDecimal salary BigDecimal commissionPercentage Long managerId Long departmentId String departmentName String managerFirstName String managerLastName } The code listing just shown is the entire class! Groovy’s property supports makes getter/setter methods automatically available for all the defined class attributes. As I discussed in a previous blog post, the @Canonical annotation is a Groovy AST (transformation) that automatically creates several useful common methods for this class [equals(Object), hashCode(), and toString()]. There is no explicit constructor because @Canonical also handles this, providing a constructor that accepts that class’s arguments in the order they are specified in their declarations. It is difficult to image a scenario in which it would be easier to easily and quickly create an object to store retrieved data values in a script. A JDBC driver is needed for this script to retrieve this data from the Oracle Database XE and the JAR for that driver could be specified on the classpath when running the Groovy script. However, I like my scripts to be as self-contained as possible and this makes Groovy’s classpath root loading mechanism attractive. This can be used within this script (rather than specifying it externally when invoking the script) as shown next: this.class.classLoader.rootLoader.addURL( new URL('file:///C:/oraclexe/app/oracle/product/11.2.0/server/jdbc/lib/ojdbc6.jar')) Side Note: Another nifty approach for accessing the appropriate dependent JAR or library is use of Groovy’s Grape-provided @Grab annotation. I didn’t use that here because Oracle’s JDBC JAR is not available in any legitimate Maven central repositories that I am aware of. An example of using this approach when a dependency is available in the Maven public repository is shown in my blog post Easy Groovy Logger Injection and Log Guarding. With the data retrieved from the database and placed in a collection of simple Groovy objects built for holding this data and providing easy access to it, it is almost time to start presenting this data in a text report. Some constants defined in the script are shown in the next excerpt from the script code. int TOTAL_WIDTH = 120 String HEADER_ROW_SEPARATOR = '='.multiply(TOTAL_WIDTH) String ROW_SEPARATOR = '-'.multiply(TOTAL_WIDTH) String COLUMN_SEPARATOR = '|' int COLUMN_SEPARATOR_SIZE = COLUMN_SEPARATOR.size() int COLUMN_WIDTH = 22 int TOTAL_NUM_COLUMNS = 5 int BALANCE_COLUMN_WIDTH = TOTAL_WIDTH-(TOTAL_NUM_COLUMNS-1)*COLUMN_WIDTH-COLUMN_SEPARATOR_SIZE*(TOTAL_NUM_COLUMNS-1)-2 The declaration of constants just shown exemplify more advantages of Groovy. For one, the constants are statically typed, demonstrating Groovy’s flexibility to specifying types statically as well as dynamically. Another feature of Groovy worth special note in the last code snippet is the use of the String.multiply(Number) method on the literal Strings. Everything, even Strings and numerics, are objects in Groovy. The multiply method makes it easy to create a String of that number of the same repeating character. The first part of the text output is the header. The following lines of the Groovy script write this header information to standard output. println '\n\n${HEADER_ROW_SEPARATOR}' println '${COLUMN_SEPARATOR}${'HR SCHEMA EMPLOYEES'.center(TOTAL_WIDTH-2*COLUMN_SEPARATOR_SIZE)}${COLUMN_SEPARATOR}' println HEADER_ROW_SEPARATOR print '${COLUMN_SEPARATOR}${'EMPLOYEE ID/HIRE DATE'.center(COLUMN_WIDTH)}${COLUMN_SEPARATOR}' print '${'EMPLOYEE NAME'.center(COLUMN_WIDTH)}${COLUMN_SEPARATOR}' print '${'TITLE/DEPARTMENT'.center(COLUMN_WIDTH)}${COLUMN_SEPARATOR}' print '${'SALARY INFO'.center(COLUMN_WIDTH)}${COLUMN_SEPARATOR}' println '${'CONTACT INFO'.center(BALANCE_COLUMN_WIDTH)}${COLUMN_SEPARATOR}' println HEADER_ROW_SEPARATOR The code above shows some more addictive features of Groovy. One of my favorite aspects of Groovy’s GString support is the ability to use Ant-like ${} expressions to provide executable code inline with the String. The code above also shows off Groovy’s GDK String’s support for the center(Number) method that automatically centers the given String withing the specified number of characters. This is a powerful feature for easily writing attractive text output. With the data retrieved and available in our data structure and with the constants defined, the output portion can begin. The next code snippet shows use of Groovy’s standard collections each method to allow iteration over the previously populated TreeMap with a closure applied to each iteration. employees.each { id, employee -> // first line in each output row def idStr = id as String print '${COLUMN_SEPARATOR}${idStr.center(COLUMN_WIDTH)}${COLUMN_SEPARATOR}' def employeeName = employee.firstName + ' ' + employee.lastName print '${employeeName.center(COLUMN_WIDTH)}${COLUMN_SEPARATOR}' def jobTitle = employee.jobTitle.replace('Vice President', 'VP').replace('Assistant', 'Asst').replace('Representative', 'Rep') print '${jobTitle.center(COLUMN_WIDTH)}${COLUMN_SEPARATOR}' def salary = '$' + (employee.salary as String) print '${salary.center(COLUMN_WIDTH)}${COLUMN_SEPARATOR}' println '${employee.phone_number.center(BALANCE_COLUMN_WIDTH)}${COLUMN_SEPARATOR}'// second line in each output row print '${COLUMN_SEPARATOR}${employee.hireDate.getDateString().center(COLUMN_WIDTH)}' def managerName = employee.managerFirstName ? 'Mgr: ${employee.managerFirstName[0]}. ${employee.managerLastName}' : 'Answers to No One' print '${COLUMN_SEPARATOR}${managerName.center(COLUMN_WIDTH)}${COLUMN_SEPARATOR}' print '${employee.departmentName.center(COLUMN_WIDTH)}${COLUMN_SEPARATOR}' String commissionPercentage = employee.commissionPercentage ?: 'No Commission' print '${commissionPercentage.center(COLUMN_WIDTH)}${COLUMN_SEPARATOR}' println '${employee.emailAddress.center(BALANCE_COLUMN_WIDTH)}${COLUMN_SEPARATOR}' println ROW_SEPARATOR } The last code snippet is where the data retrieved from the database is output in a relatively attractive text format. The example shows how handles in a closure can be named to be more meaningful. In this case, they are named id and employee and represent the key (Long) and value (Employee) of each entry in the TreeMap. There are other Groovy features in the last code snippet worth special mention. The presentation of commission uses Groovy’s Elvis operator (?:), which makes even Java’s conditional ternary look verbose. In this example, if the employee’s commission percentage meets Groovy truth standards, that percentage is used; otherwise, ‘No Commission’ is printed. The handling of the hire date provides another opportunity to tout Groovy’s GDK benefits. In this case, Groovy GDK Date.getDateString() is used to easily access the date-only portion of the Date class (time not desired for hire date) without explicit use of a String formatter. Nice! The last code example also demonstrates use of the as keyword to coerce (cast) variables in a more readable way and also demonstrates more leverage of Java features, in this case taking advantage of Java String’s replace(CharSequence, CharSequence) method. Groovy adds some more goodness to String again in this example, however. The example demonstrates Groovy’s supporting extracting the first letter only of the manager’s first name using subscript (array) notation ([0]) to get only the first character out of the string. So far in this post, I’ve shown snippets of the overall script as I explained the various features of Groovy that are demonstrated in each snippet. The entire script is shown next and that code listing is followed by a screen snapshot of how the output appears when the script is executed. The complete code for the Groovy Employee class was shown previously. generateReport.groovy: The Complete Script #!/usr/bin/env groovy// Add JDBC driver to classpath as part of this script's bootstrapping. // See http://marxsoftware.blogspot.com/2011/02/groovy-scripts-master-their-own.html. // WARNING: This location needs to be adjusted for specific user environment. this.class.classLoader.rootLoader.addURL( new URL('file:///C:/oraclexe/app/oracle/product/11.2.0/server/jdbc/lib/ojdbc6.jar'))int TOTAL_WIDTH = 120 String HEADER_ROW_SEPARATOR = '='.multiply(TOTAL_WIDTH) String ROW_SEPARATOR = '-'.multiply(TOTAL_WIDTH) String COLUMN_SEPARATOR = '|' int COLUMN_SEPARATOR_SIZE = COLUMN_SEPARATOR.size() int COLUMN_WIDTH = 22 int TOTAL_NUM_COLUMNS = 5 int BALANCE_COLUMN_WIDTH = TOTAL_WIDTH-(TOTAL_NUM_COLUMNS-1)*COLUMN_WIDTH-COLUMN_SEPARATOR_SIZE*(TOTAL_NUM_COLUMNS-1)-2// Get instance of Groovy's Sql class // See http://marxsoftware.blogspot.com/2009/05/groovysql-groovy-jdbc.html import groovy.sql.Sql def sql = Sql.newInstance('jdbc:oracle:thin:@localhost:1521:xe', 'hr', 'hr', 'oracle.jdbc.pool.OracleDataSource')def employeeQueryStr = '''SELECT e.employee_id, e.first_name, e.last_name, e.email, e.phone_number, e.hire_date, e.job_id, j.job_title, e.salary, e.commission_pct, e.manager_id, e.department_id, d.department_name, m.first_name AS mgr_first_name, m.last_name AS mgr_last_name FROM employees e, departments d, jobs j, employees m WHERE e.department_id = d.department_id AND e.job_id = j.job_id AND e.manager_id = m.employee_id(+)'''def employees = new TreeMap<Long, Employee>() sql.eachRow(employeeQueryStr) { def employeeId = it.employee_id as Long def employee = new Employee(employeeId, it.first_name, it.last_name, it.email, it.phone_number, it.hire_date, it.job_id, it.job_title, it.salary, it.commission_pct, it.manager_id as Long, it.department_id as Long, it.department_name, it.mgr_first_name, it.mgr_last_name) employees.put(employeeId, employee) }println '\n\n${HEADER_ROW_SEPARATOR}' println '${COLUMN_SEPARATOR}${'HR SCHEMA EMPLOYEES'.center(TOTAL_WIDTH-2*COLUMN_SEPARATOR_SIZE)}${COLUMN_SEPARATOR}' println HEADER_ROW_SEPARATOR print '${COLUMN_SEPARATOR}${'EMPLOYEE ID/HIRE DATE'.center(COLUMN_WIDTH)}${COLUMN_SEPARATOR}' print '${'EMPLOYEE NAME'.center(COLUMN_WIDTH)}${COLUMN_SEPARATOR}' print '${'TITLE/DEPARTMENT'.center(COLUMN_WIDTH)}${COLUMN_SEPARATOR}' print '${'SALARY INFO'.center(COLUMN_WIDTH)}${COLUMN_SEPARATOR}' println '${'CONTACT INFO'.center(BALANCE_COLUMN_WIDTH)}${COLUMN_SEPARATOR}' println HEADER_ROW_SEPARATORemployees.each { id, employee -> // first line in each row def idStr = id as String print '${COLUMN_SEPARATOR}${idStr.center(COLUMN_WIDTH)}${COLUMN_SEPARATOR}' def employeeName = employee.firstName + ' ' + employee.lastName print '${employeeName.center(COLUMN_WIDTH)}${COLUMN_SEPARATOR}' def jobTitle = employee.jobTitle.replace('Vice President', 'VP').replace('Assistant', 'Asst').replace('Representative', 'Rep') print '${jobTitle.center(COLUMN_WIDTH)}${COLUMN_SEPARATOR}' def salary = '$' + (employee.salary as String) print '${salary.center(COLUMN_WIDTH)}${COLUMN_SEPARATOR}' println '${employee.phone_number.center(BALANCE_COLUMN_WIDTH)}${COLUMN_SEPARATOR}'// second line in each row print '${COLUMN_SEPARATOR}${employee.hireDate.getDateString().center(COLUMN_WIDTH)}' def managerName = employee.managerFirstName ? 'Mgr: ${employee.managerFirstName[0]}. ${employee.managerLastName}' : 'Answers to No One' print '${COLUMN_SEPARATOR}${managerName.center(COLUMN_WIDTH)}${COLUMN_SEPARATOR}' print '${employee.departmentName.center(COLUMN_WIDTH)}${COLUMN_SEPARATOR}' String commissionPercentage = employee.commissionPercentage ?: 'No Commission' print '${commissionPercentage.center(COLUMN_WIDTH)}${COLUMN_SEPARATOR}' println '${employee.emailAddress.center(BALANCE_COLUMN_WIDTH)}${COLUMN_SEPARATOR}' println ROW_SEPARATOR }In this blog post, I’ve attempted to show how Groovy provides numerous features and other syntax support that make it easier to write scripts for generating readable and relatively attractive output. For more general Groovy scripts that provide text output support, see Formatting simple tabular text data. Although these are nice general solutions, an objective of my post has been to show that it is easy and does not take much time to write customized scripts for generating custom text output with Groovy. Small Groovy-isms such as easily centering a String, easily converting a Date to a String, extracting any desired character from a string based on array position notation, and easily accessing database data make Groovy a powerful tool in generating text-based reports.   Reference: Scripted Reports with Groovy from our JCG partner Dustin Marx at the Inspired by Actual Events blog. ...
apache-hadoop-logo

Hadoop Single Node Set Up

With this post I am hoping to share the procedure to set up Apache Hadoop in single node. Hadoop is used in dealing with Big Data sets where deployment is happening on low-cost commodity hardware. It is a map-reduce framework which map segments of a job among the nodes in a cluster for execution. Though we will not see the exact power of Hadoop running it on single node, it is the first step towards the multi-node cluster. Single node set up is useful in getting familiar with the operations and debugging applications for accuracy, but the performance may be far low than what is achievable. I am sharing the steps to be followed on a Linux system, as it is supported as both a development and a production platform for Hadoop. Win32 is supported only as a development platform and equivalent commands for the given Linux commands need to be followed. This Hadoop document includes the details for setting up Hadoop, in brief. I am here sharing a detailed guidance for the set up process with the following line up.Pre-requisites Hadoop Configurations Running the Single Node Cluster Running a Map-reduce job  Pre-requisites Java 1.6.X Java needs to be installed in your node, in order to run Hadoop as it is a java based framework. We can check the Java installation of node by, pushpalanka@pushpalanka-laptop:~$ java -version java version '1.6.0_23' Java(TM) SE Runtime Environment (build 1.6.0_23-b05) Java HotSpot(TM) Server VM (build 19.0-b09, mixed mode) If it is not giving an intended output, we need to install Java by running, pushpalanka@pushpalanka-laptop:~$ sudo apt-get install sun-java6-jdk or running a downloaded binary java installation package. Then set the environment variable JAVA_HOME in the relevant configuration file(.bashrc for Linux bash shell users). Create a Hadoop User At this step we create a user account dedicated for Hadoop installation. This not a ‘must do’ step, but recommended for security reasons and ease of managing the nodes. So we create a group called ‘hadoop’ and add a new user to the group called ‘hpuser'(the names can be of our choice) with the following commands. pushpalanka@pushpalanka-laptop:~$ sudo addgroup hadoop pushpalanka@pushpalanka-laptop:~$ sudo adduser --ingroup hadoop hpuser pushpalanka@pushpalanka-laptop:~$ su hpuser hpuser@pushpalanka-laptop:~$ Now on we will work as hpuser, with the last command. Enable SSH Access Hadoop requires SSH(Secure Shell) access to the machines it uses as nodes. This is to create a secured channel to exchange data. So even in single node the localhost need SSH access for the hpuser in order to exchange data for Hadoop operations. Refer this documentation if you need more details on SSH. We can install SSH with following command. hpuser@pushpalanka-laptop:~$ sudo apt-get install ssh Now let’s try to SSH the localhost without a pass-phrase. hpuser@pushpalanka-laptop:~$ ssh localhost Linux pushpalanka-laptop 2.6.32-33-generic #72-Ubuntu SMP Fri Jul 29 21:08:37 UTC 2011 i686 GNU/Linux Ubuntu 10.04.4 LTSWelcome to Ubuntu! ................................................ If it does not give something similar to the above, we have to enable SSH access to the localhost as following. Generate a RSA key pair without a password. (We do not use a password only because then it will prompt us to provide password in each time Hadoop communicate with the node.) hpuser@pushpalanka-laptop:~$ssh-keygen -t rsa -P '' Then we need to concatenate the generated public key in the authorized keys list of the localhost. It is done as follows. Then make sure ‘ssh localhost’ is successful. hpuser@pushpalanka-laptop:~$ cat $HOME/.ssh/id_rsa.pub >> $HOME/.ssh/authorized_keys Now we are ready to move onto Hadoop. :) Use the latest stable release from Hadoop site and I used hadoop-1.0.3. Hadoop Configurations Set Hadoop Home As we set JAVA_HOME at the beginning of this post we need to set HADOOP_HOME too. Open the same file (.bashrc) and add the following two lines at the end. export HADOOP_HOME=<absolute path to the extracted hadoop distribution> export PATH=$PATH:$HADOOP_HOME/bin   Disable IPv6 As there will not be any practical need to go for IPv6 addressing inside Hadoop cluster, we are disabling this to be less error-prone. Open the file HADOOP_HOME/conf/hadoop-env.sh and add the following line. export HADOOP_OPTS=-Djava.net.preferIPv4Stack=true   Set Paths and Configuration In the same hadoop-env.sh file add the JAVA_HOME too. export JAVA_HOME=<path to the java installation> Then we need create a directory to be used as HDFS (Hadoop Distributed File System).Make directory at a place of your choice and make sure the owner of the directory is ‘hpuser’. I ll refer this as ‘temp_directory’. We can do it by, hpuser@pushpalanka-laptop:~$ sudo chown hpuser:hadoop <absolute path to temp_directory> Now we add the following property segments in the relevant file inside the <configuration>……</configuration> tags. conf/core-site.xml <property> <name>hadoop.tmp.dir</name> <value>path to temp_directory</value> <description>Location for HDFS.</description> </property><property> <name>fs.default.name</name> <value>hdfs://localhost:54310</value> <description>The name of the default file system. A URI whose scheme and authority determine the FileSystem implementation. </description> </property> conf/mapred-site.xml <property> <name>mapred.job.tracker</name> <value>localhost:54311</value> <description>The host and port that the MapReduce job tracker runs at. </description> </property> conf/hdfs-site.xml <property> <name>dfs.replication</name> <value>1</value> <description>Default number of block replications. </description> </property> The above value needs to be decided on the priority on speed, space and fault tolerance factors. Format HDFS This operation is needed every time we create a new Hadoop cluster. If we do this operation on a running cluster all the data will be lost.What this basically do is creating the Hadoop Distributed File System over the local file system of the cluster. hpuser@pushpalanka-laptop:~$ <HADOOP_HOME>/bin/hadoop namenode -format 12/09/20 14:39:56 INFO namenode.NameNode: STARTUP_MSG: /************************************************************ STARTUP_MSG: Starting NameNode STARTUP_MSG: host = pushpalanka-laptop/127.0.1.1 STARTUP_MSG: args = [-format] STARTUP_MSG: version = 1.0.3 STARTUP_MSG: build = https://svn.apache.org/repos/asf/hadoop/common/branches/branch-1.0 -r 1335192; compiled by 'hortonfo' on Tue May 8 20:31:25 UTC 2012 ************************************************************/ ... 12/09/20 14:39:57 INFOnamenode.NameNode: SHUTDOWN_MSG: /************************************************************ SHUTDOWN_MSG: Shutting down NameNode at pushpalanka-laptop/127.0.1.1 ************************************************************/ If the output is something as above HDFS is formatted successfully. Now we are almost done and ready to see the action. Running the Single Node Cluster hpuser@pushpalanka-laptop:~/hadoop-1.0.3/bin$ ./start-all.sh and you will see, hpuser@pushpalanka-laptop:~/hadoop-1.0.3/bin$ ./start-all.sh starting namenode, logging to /home/hpuser/hadoop-1.0.3/libexec/../logs/hadoop-hpuser-namenode-pushpalanka-laptop.out localhost: starting datanode, logging to /home/hpuser/hadoop-1.0.3/libexec/../logs/hadoop-hpuser-datanode-pushpalanka-laptop.out localhost: starting secondarynamenode, logging to /home/hpuser/hadoop-1.0.3/libexec/../logs/hadoop-hpuser-secondarynamenode-pushpalanka-laptop.out starting jobtracker, logging to /home/hpuser/hadoop-1.0.3/libexec/../logs/hadoop-hpuser-jobtracker-pushpalanka-laptop.out localhost: starting tasktracker, logging to /home/hpuser/hadoop-1.0.3/libexec/../logs/hadoop-hpuser-tasktracker-pushpalanka-laptop.out which starts several nodes and trackers. We can observe these Hadoop processes using jps tool from Java. hpuser@pushpalanka-laptop:~/hadoop-1.0.3/bin$ jps 5767 NameNode 6619 Jps 6242 JobTracker 6440 TaskTracker 6155 SecondaryNameNode 5958 DataNode Also we can check the ports Hadoop is configured to listen on, hpuser@pushpalanka-laptop:~/hadoop-1.0.3/bin$ sudo netstat -plten | grep java [sudo] password for hpuser: tcp 0 0 0.0.0.0:33793 0.0.0.0:* LISTEN 1001 175415 8164/java .... tcp 0 0 0.0.0.0:60506 0.0.0.0:* LISTEN 1001 174566 7767/java tcp 0 0 0.0.0.0:50075 0.0.0.0:* LISTEN 1001 176269 7962/java There are several web interfaces available to observe inside behavior, job completion, memory consumption etc. as follows.http://localhost:50070/– web UI of the NameNodehttp://localhost:50030/– web UI of the JobTrackerhttp://localhost:50060/– web UI of the TaskTracker At the moment this will not show any information as we have not put any job for execution to observe the progress.We can stop the cluster at any time with the following command. hpuser@pushpalanka-laptop:~/hadoop-1.0.3/bin$ ./stop-all.sh stopping jobtracker localhost: stopping tasktracker stopping namenode localhost: stopping datanode localhost: stopping secondarynamenode   Running a Map-reduce Job Let’s try to get some work done using Hadoop. We can use the word count example distributed with Hadoop as explained here atHadoop wiki. In brief what it does is take some text files as inputs, count the number of repetitions of distinct words mapping each line to a mapper and output the reduced result as a text file. first create a folder and copy some .txt files having several 10000s of words. We are going to count the distinct words’ repetitions of those. hpuser@pushpalanka-laptop:~/tempHadoop$ ls -l total 1392 -rw-r--r-- 1 hpuser hadoop 1423810 2012-09-21 02:10 pg5000.txt Then restart the cluster, using start-all.sh file as done before. Copy the sample input file to HDFS. hpuser@pushpalanka-laptop:~/hadoop-1.0.3$ bin/hadoop dfs -copyFromLocal /home/hpuser/tempHadoop/ /user/hpuser/testHadoop Let’s check whether it is correctly copied HDFS, hpuser@pushpalanka-laptop:~/hadoop-1.0.3$ bin/hadoop dfs -ls /user/hpuser/testHadoop Found 1 items -rw-r--r-- 1 hpuser supergroup 1423810 2012-09-21 02:17 /user/hpuser/testHadoop/pg5000.txt Now inputs are ready. Let’s run the map reduce job. For this we use a jar distributed with Hadoop which is written to do the needful, which can later refer and learn how the things are done. hpuser@pushpalanka-laptop:~/hadoop-1.0.3$ bin/hadoop jar hadoop*examples*.jar wordcount /user/hpuser/testHadoop /user/hpuser/testHadoop-output 12/09/21 02:24:34 INFO input.FileInputFormat: Total input paths to process : 1 12/09/21 02:24:34 INFO util.NativeCodeLoader: Loaded the native-hadoop library 12/09/21 02:24:34 WARN snappy.LoadSnappy: Snappy native library not loaded 12/09/21 02:24:34 INFO mapred.JobClient: Running job: job_201209210216_0003 12/09/21 02:24:35 INFO mapred.JobClient: map 0% reduce 0% 12/09/21 02:24:51 INFO mapred.JobClient: map 100% reduce 0% 12/09/21 02:25:06 INFO mapred.JobClient: map 100% reduce 100% 12/09/21 02:25:11 INFO mapred.JobClient: Job complete: job_201209210216_0003 12/09/21 02:25:11 INFO mapred.JobClient: Counters: 29 12/09/21 02:25:11 INFO mapred.JobClient: Job Counters 12/09/21 02:25:11 INFO mapred.JobClient: Launched reduce tasks=1 12/09/21 02:25:11 INFO mapred.JobClient: SLOTS_MILLIS_MAPS=17930 12/09/21 02:25:11 INFO mapred.JobClient: Total time spent by all reduces waiting after reserving slots (ms)=0 12/09/21 02:25:11 INFO mapred.JobClient: Total time spent by all maps waiting after reserving slots (ms)=0 12/09/21 02:25:11 INFO mapred.JobClient: Launched map tasks=1 12/09/21 02:25:11 INFO mapred.JobClient: Data-local map tasks=1 12/09/21 02:25:11 INFO mapred.JobClient: SLOTS_MILLIS_REDUCES=14153 12/09/21 02:25:11 INFO mapred.JobClient: File Output Format Counters 12/09/21 02:25:11 INFO mapred.JobClient: Bytes Written=337639 12/09/21 02:25:11 INFO mapred.JobClient: FileSystemCounters 12/09/21 02:25:11 INFO mapred.JobClient: FILE_BYTES_READ=466814 12/09/21 02:25:11 INFO mapred.JobClient: HDFS_BYTES_READ=1423931 12/09/21 02:25:11 INFO mapred.JobClient: FILE_BYTES_WRITTEN=976811 12/09/21 02:25:11 INFO mapred.JobClient: HDFS_BYTES_WRITTEN=337639 12/09/21 02:25:11 INFO mapred.JobClient: File Input Format Counters 12/09/21 02:25:11 INFO mapred.JobClient: Bytes Read=1423810 12/09/21 02:25:11 INFO mapred.JobClient: Map-Reduce Framework 12/09/21 02:25:11 INFO mapred.JobClient: Map output materialized bytes=466814 12/09/21 02:25:11 INFO mapred.JobClient: Map input records=32121 12/09/21 02:25:11 INFO mapred.JobClient: Reduce shuffle bytes=466814 12/09/21 02:25:11 INFO mapred.JobClient: Spilled Records=65930 12/09/21 02:25:11 INFO mapred.JobClient: Map output bytes=2387668 12/09/21 02:25:11 INFO mapred.JobClient: CPU time spent (ms)=9850 12/09/21 02:25:11 INFO mapred.JobClient: Total committed heap usage (bytes)=167575552 12/09/21 02:25:11 INFO mapred.JobClient: Combine input records=251352 12/09/21 02:25:11 INFO mapred.JobClient: SPLIT_RAW_BYTES=121 12/09/21 02:25:11 INFO mapred.JobClient: Reduce input records=32965 12/09/21 02:25:11 INFO mapred.JobClient: Reduce input groups=32965 12/09/21 02:25:11 INFO mapred.JobClient: Combine output records=32965 12/09/21 02:25:11 INFO mapred.JobClient: Physical memory (bytes) snapshot=237834240 12/09/21 02:25:11 INFO mapred.JobClient: Reduce output records=32965 12/09/21 02:25:11 INFO mapred.JobClient: Virtual memory (bytes) snapshot=778846208 12/09/21 02:25:11 INFO mapred.JobClient: Map output records=251352 While the job is running if we try out the previously mentioned web interfaces we can observe the progress and utilization of the resources in a summarized way. As given in the command the output file that carries the word counts is written to the ‘/user/hpuser/testHadoop-output’. hpuser@pushpalanka-laptop:~/hadoop-1.0.3$ bin/hadoop dfs -ls /user/hpuser/testHadoop-output Found 3 items -rw-r--r-- 1 hpuser supergroup 0 2012-09-21 02:25 /user/hpuser/testHadoop-output/_SUCCESS drwxr-xr-x - hpuser supergroup 0 2012-09-21 02:24 /user/hpuser/testHadoop-output/_logs -rw-r--r-- 1 hpuser supergroup 337639 2012-09-21 02:25 /user/hpuser/testHadoop-output/part-r-00000 To see what is inside the file, let’s get it copied to the local file system. hpuser@pushpalanka-laptop:~/hadoop-1.0.3$ bin/hadoop dfs -getmerge /user/hpuser/testHadoop-output /home/hpuser/tempHadoop/out 12/09/21 02:38:10 INFO util.NativeCodeLoader: Loaded the native-hadoop library Here getmerge option is used to merge if there are several files, then the HDFS location of output folder and the desired place for output in local file system are given. Now you can browse to the given output folder and open of the result file, which will something as follows, according to your input file. "1 1 '1,' 1 '35' 1 '58,' 1 'AS'. 1 'Apple 1 'Abs 1 'Ah! 1 Now we have completed setting up a single node cluster with Apache Hadoop and running a map-reduce job. In a next post I ll share how to set up a multi node cluster. Original Source  Hadoop Single Node Set-up – Guchex. By Pushpalanka Jayawardhana   Reference: Hadoop Single Node Set Up from our JCG partner Pushpalanka at the Pushpalanka’s Blog blog. ...
java-interview-questions-answers

Database Encryption Using JPA Listeners

I recently had to add database encryption to a few fields and discovered a lot of bad advice out there. Architectural Issues The biggest problem is architectural. If your persistence manager quietly handles your encryption then, by definition, your architecture demands a tight and unnecessary binding between your persistence and security designs. You can’t touch one without also touching the other. This might seem to be unavoidable but there is a respected school of thought that the best architecture is one where you have independent teams of app developers and security developers. The app developers can’t be sloppy but overall their sole focus is feature completion. The security developers are responsible for designing and implementing the security. The only places where both pieces are considered is at the architectural and top-level design. In the past this wasn’t very practical but Aspect-Oriented Programming (AOP) and similar concepts have changed that. Now it’s entirely reasonable to inject an interceptor between the service and persistence layer so values the caller isn’t authorized to see are quietly dropped. A list of 10 items might be cut to 7, or an update might throw an exception instead of modifying a read-only value. It’s a little more complicated when persisting collections but the general approach should be clear. The key thing here is that the app developers never need to see the security code. It can all be handled by AOP injection added via configuration files at the time of deployment. More importantly it can be changed at any time without requiring modification of the application itself. (You may need to perform an update process that will change values in the database.) An interceptor can even prevent calls to undocumented methods – one less worry about rogue programmers. In practice many sites will have several developers wear both hats instead of having a dedicated security team. That’s not a problem as long as they can keep their distinct responsibilities in mind. Transparent encryption in JPA or Hibernate fields is definitely better than putting the encryption/decryption code in your POJO but it still imposes a high level of unnecessary binding between the security and persistence layers. It also has serious security issues. Security Issues There is a critical question any time you’re dealing with encryption – can this object be written to disk? The most obvious threat is serialization, e.g., by an appserver that is passivating data to free up memory or to migrate it to a different server. In practice this means that your keys and plaintext content must be marked ‘transient’ (for the serialization engine) and ‘@Transient’ (for JPA or Hibernate). If you’re really paranoid you’ll even override the implicit serialization method writeObject so you can absolutely guarantee that these fields are never written to disk. This works… but it blows the transparent encryption/decryption out of the water since the entire point of that code is to make these fields look like just another field. You must maintain two fields – a persistent encrypted value and a transient unencrypted value – and have some way to keep them in sync. All done without putting any crypto code into your pojo. A more subtle problem is that your objects may still be written to disk if an attacker can trigger a core dump by crashing the appserver. Careful site administrators will disable core dumps but many overlook it. It’s harder to work around this but it’s possible if the AOP decrypts/encrypts values immediately around the methods that need the decrypted values. Your application shouldn’t care where the decryption occurs as long as it’s decrypted when it needs it. This is the type of decision that should be left to the security team. A third way objects can be written to disk is via OS swap files but that should be a non-issue since swap files are usually encrypted now. JPA EntityListeners A solution is JPA EntityListeners or the corresponding Hibernate class. These are Listener classes that can provide methods called before or after database object creation, deletion or modification. Sample Code This is easiest to see with some sample code. Consider a situation where we must keep a user’s password for a third-party site. In this case we must use encryption, not hashing. (Note: I doubt this is the actual information required by Twitter for third-party apps – it’s solely for the purpose of illustration.) The entity /** * Conventional POJO. Following other conventions the sensitive * information is written to a secondary table in addition to being * encrypted. */ @Entity @Table(name='twitter') @SecondaryTable(name='twitter_pw', pkJoinColumns=@PrimaryKeyJoinColumn(name='twitter_id')) @EntityListeners(TwitterUserPasswordListener.class) public class TwitterUser { private Integer id; private String twitterUser private String encryptedPassword; transient private String password;@Id @GeneratedValue(strategy = GenerationType.IDENTITY) public Integer getId() { return id; }@Column(name = 'twitter_user') public String getTwitterUser() { return twitterUser; }@Column(name = 'twitter_pw', table = 'twitter_pw') @Lob public String getEncryptedPassword() { return encryptedPassword; }@Transient public String getPassword() { return password; }// similar definitions for setters.... }   The DAO /** * Conventional DAO to access login information. */ @LocalBean @Stateless public class TwitterDao { @PersistenceContext private EntityManager em;/** * Read an object from the database. */ @TransactionAttribute(TransactionAttributeType.SUPPORTS) public TwitterUser getUserById(Integer id) { return em.find(TwitterUser.class, id); }/** * Create a new record in the database. */ @TransactionAttribute(TransactionAttributeType.REQUIRED) public saveTwitterUser(TwitterUser user) { em.persist(user); }/** * Update an existing record in the database. * * Note: this method uses JPA semantics. The Hibernate * saveOrUpdate() method uses slightly different semantics * but the required changes are straightforward. */ @TransactionAttribute(TransactionAttributeType.REQUIRED) public updateTwitterUser(TwitterUser user) { TwitterUser tw = em.merge(user);// we need to make one change from the standard method - // during a 'merge' the old data read from the database // will result in the decrypted value overwriting the new // plaintext value - changes won't be persisted! This isn't // a problem when the object is eventually evicted from // the JPA/Hibernate cache so we're fine as long as we // explicitly copy any fields that are hit by the listener. tw.setPassword(user.getPassword());return tw; }   The EntityListener To keep a clean separation between the persistence and security layers the listener does nothing but call a service that handles the encryption. It is completely ignorant of the encryption details. public class TwitterUserPasswordListener { @Inject private EncryptorBean encryptor;/** * Decrypt password after loading. */ @PostLoad @PostUpdate public void decryptPassword(Object pc) { if (!(pc instanceof TwitterUser)) { return; }TwitterUser user = (TwitterUser) pc; user.setPassword(null);if (user.getEncryptedPassword() != null) { user.setPassword( encryptor.decryptString(user.getEncryptedPassword()); } }/** * Decrypt password before persisting */ @PrePersist @PreUpdate public void encryptPassword(Object pc) { if (!(pc instanceof TwitterUser)) { return; }TwitterUser user = (TwitterUser) pc; user.setEncryptedPassword(null);if (user.getPassword() != null) { user.setEncryptedPassword( encryptor.encryptString(user.getPassword()); } } }   The EncryptorBean The EncryptorBean handles encryption but does not know what’s being encrypted. This is a minimal implementation – in practice we’ll probably want to pass a keyId in addition to the ciphertext/plaintext. This would allow us to quietly rotate encryption keys with minimal disruption – something that is definitely not possible with the usual ‘easy encryption’ approaches. This class uses OWASP/ESAPI for encryption since 1) it should already be used by your application and 2) the portable format allows other applications to use our database as long as they also use the OWASP/ESAPI library. The implementation only covers Strings – a robust solution should have methods for all primitive types and possibly domain-specific classes such as credit cards. import org.owasp.esapi.ESAPI; import org.owasp.esapi.Encryptor; import org.owasp.esapi.codecs.Base64; import org.owasp.esapi.crypto.CipherText; import org.owasp.esapi.crypto.PlainText; import org.owasp.esapi.errors.EncryptionException; import org.owasp.esapi.reference.crypto.JavaEncryptor;@Stateless public class EncryptorBean { private static final String PBE_ALGORITHM = 'PBEWITHSHA256AND128BITAES-CBC-BC'; private static final String ALGORITHM = 'AES';// hardcoded for demonstration use. In production you might get the // salt from the filesystem and the password from a appserver JNDI value. private static final String SALT = 'WR9bdtN3tMHg75PDK9PoIQ=='; private static final char[] PASSWORD = 'password'.toCharArray();// the key private transient SecretKey key;/** * Constructor creates secret key. In production we may want * to avoid keeping the secret key hanging around in memory for * very long. */ public EncryptorBean() { try { // create the PBE key KeySpec spec = new PBEKeySpec(PASSWORD, Base64.decode(SALT), 1024); SecretKey skey = SecretKeyFactory.getInstance(PBE_ALGORITHM).generateSecret(spec); // recast key as straightforward AES without padding. key = new SecretKeySpec(skey.getEncoded(), ALGORITHM); } catch (SecurityException ex) { // handle appropriately... } }/** * Decrypt String */ public String decryptString(String ciphertext) { String plaintext = null;if (ciphertext != null) { try { Encryptor encryptor = JavaEncryptor.getInstance(); CipherText ct = CipherText.from PortableSerializedBytes(Base64.decode(ciphertext)); plaintext = encryptor.decrypt(key, ct).toString(); } catch (EncryptionException e) { // handle exception. Perhaps set value to null? } }return plaintext; }/** * Encrypt String */ public String encryptString(String plaintext) { String ciphertext= null;if (plaintext!= null) { try { Encryptor encryptor = JavaEncryptor.getInstance(); CipherText ct = encryptor.encrypt(key, new PlaintText(plaintext)); ciphertext = Base64.encodeBytes(ct.asPortableSerializedByteArray()); } catch (EncryptionException e) { // handle exception. Perhaps set value to null? } }return ciphertext; } }   Final Thoughts There is no reason why you must have a one-to-one relationship between unencrypted and encrypted fields. It is perfectly reasonable to bundle related fields into a single value – in fact it is probably preferable to encrypting each field individually. The values could be represented in CSV, XML, JSON, or even a properties file.   Reference: Database Encryption Using JPA Listeners from our JCG partner Bear Giles at the Invariant Properties blog. ...
spring-security-logo

Ten Things You Can Do With Spring Security

One You can specify the authorisation provider of your choice in your Spring XML config file. You do this by configuring an authentication-manager as defined in Spring’s http://www.springframework.org/schema/security/spring-security-3.1.xsd schema. The simplified authentication-manager element definition looks something like this:           <xs:element name='authentication-manager'> <xs:complexType> <xs:choice minOccurs='0' maxOccurs='unbounded'> <xs:element name='authentication-provider'> <xs:complexType> <xs:choice minOccurs='0' maxOccurs='unbounded'> <xs:element ref='security:any-user-service'/> <xs:element name='password-encoder'>...</xs:element> </xs:choice> <xs:attributeGroup ref='security:ap.attlist'/> </xs:complexType> </xs:element> <!-- This is BIG --> <xs:element name='ldap-authentication-provider'>...</xs:element> </xs:choice> <xs:attributeGroup ref='security:authman.attlist'/> </xs:complexType> </xs:element> This means that, for example, you can use any number of authentication providers including basic authentication and JDBC authentication as shown in the snippet below:<authentication-manager alias='authenticationManager'> <authentication-provider> <user-service> <user authorities='ROLE_GUEST' name='guest' password=''/> </user-service> </authentication-provider> <authentication-provider> <jdbc-user-service data-source-ref='dataSource'/> </authentication-provider> </authentication-manager>   Two You can configure authorisation rules in your Spring XML file by linking URLs to user roles using the intercept-url element. The intercept-url element is a child element of the http element, whose abridged definition looks like this: <xs:element name='http'> <xs:complexType> <xs:choice minOccurs='0' maxOccurs='unbounded'> <xs:element name='intercept-url'> <xs:complexType> <xs:attributeGroup ref='security:intercept-url.attlist'/> </xs:complexType> </xs:element> <!-- Details omitted for clarity --> <xs:element name='access-denied-handler'>...</xs:element> <xs:element name='form-login'>...</xs:element> <xs:element name='openid-login'>...</xs:element> <xs:element name='x509'>...</xs:element> <xs:element ref='security:jee'/> <xs:element name='http-basic'>...</xs:element> <xs:element name='logout'>...</xs:element> <xs:element name='session-management'>...</xs:element> <xs:element name='remember-me'>...</xs:element> <xs:element name='anonymous'>...</xs:element> <xs:element name='port-mappings'>...</xs:element> <xs:element ref='security:custom-filter'/> <xs:element ref='security:request-cache'/> <xs:element name='expression-handler'>...</xs:element> </xs:choice> <xs:attributeGroup ref='security:http.attlist'/> </xs:complexType> </xs:element>Example usage: <security:http> <security:intercept-url pattern='/admin/**' access='hasRole('ROLE_ADMIN')'/> <security:intercept-url pattern='/account/**' access='hasRole('ROLE_USER')' /> <security:intercept-url pattern='/**' access='hasRole('ROLE_ANONYMOUS')' /> <!-- other elements removed for clarity --> </security:http>   Three You can encode and validate passwords using several classes that implement Spring’s org.springframework.security.authentication.encoding.PasswordEncoder interface. This only has two methods: encodePassword and isPasswordValid. Its many implementations include:BaseDigestPasswordEncoder BasePasswordEncoder LdapShaPasswordEncoder Md4PasswordEncoder, Md5PasswordEncoder MessageDigestPasswordEncoder MessageDigestPasswordEncoder PlaintextPasswordEncoder ShaPasswordEncoder  Four You can restrict access to page elements using Spring Security’s tag library. To use this library you include the following taglib definition in your JSP: <%@ taglib prefix='sec' uri='http://www.springframework.org/security/tags' %> The taglib contains three useful tags:authorize authentication accesscontrollistThe most useful seems to be the authorize tag, which, taking examples from the Spring documentation, can be used in two ways. Firstly, you can authorize against roles: <sec:authorize access='hasRole('supervisor')'> This content will only be visible to users who have the 'supervisor' authority in their list of <tt>GrantedAuthority</tt>s. </sec:authorize> …and secondly you can authorize against URLs <sec:authorize url='/admin'> This content will only be visible to users who are authorized to send requests to the '/admin' URL. </sec:authorize> The URL specified must tie in with the intercept-url tag described in item 2. Five You can perform method level authorization using Spring’s in-house annotations@PreAuthorize('spEL expression') @PostAuthorize('spEL expression') @Securewhere the spEL expression can be anything, but is usually something like: hasRole('ROLE_USER'). To enable @PreAuthorize(...) and @PostAuthorize(...) add the following to your XML config file: <global-method-security pre-post-annotations='enabled' /> @PreAuthorize(...) is used as shown in the following example: <span class='java0'><br /> </span><span class='java16'>@PreAuthorize</span><span class='java8'>(</span><span class='java5'>'hasRole('ROLE_ADMIN')'</span><span class='java8'>) <br /> </span><span class='java4'>public </span><span class='java9'>void </span><span class='java10'>deleteUser</span><span class='java8'>(</span><span class='java10'>String username</span><span class='java8'>)</span><span class='java10'>;<br /> </span> To enable @Secure add the following to your Spring config file: <global-method-security pre-post-annotations='enabled' />   Six You can perform method level security using Spring’s JSR-250 implementation by adding the following to your Spring config file: <global-method-security jsr250-annotations=”enabled”/> The JSR-250 security annotations are a sub set of the JSR-250 annotations and include:@RolesAllowed({“ROLE_USER”,”ROLE_ADMIN”}) @PermitAll @DenyAllWhen used, a JSR-250 annotation looks something like this:@RolesAllowed({"ROLE_ADMIN","ROLE_USER"}) public void deleteUser(String username);  Seven You can integrate Spring Security with OpenID authentication with a few simple steps. The first of these is writing a simple JSP form where the action value is set to j_spring_openid_security_check, which at its most minimal looks something like this: <form action='j_spring-openid-security-check' method='post'> <label for='openid_idenifier'>Login</label>: <input id='openid_identifier' name='openid_identifier' type='text'/> <input type='submit' value='Login' /> </form> The next step is add the openid-login element to http: <xs:element name='http'> <xs:complexType> <xs:choice minOccurs='0' maxOccurs='unbounded'> <xs:element name='openid-login'> <xs:annotation> <xs:documentation> Sets up form login for authentication with an Open ID identity </xs:documentation> </xs:annotation> <xs:complexType> <xs:sequence> <xs:element minOccurs='0' maxOccurs='unbounded' ref='security:attribute-exchange' /> </xs:sequence> <xs:attributeGroup ref='security:form-login.attlist' /> <xs:attribute name='user-service-ref' type='xs:token'> <xs:annotation> <xs:documentation> A reference to a user-service (or UserDetailsService bean) Id </xs:documentation> </xs:annotation> </xs:attribute> </xs:complexType> </xs:element> <!-- Other elements omitted for clarity --> </xs:choice> </xs:complexType> </xs:element> As all of openid-login child elements are optional, the simplest way to enable OpenID is to write: <http auto-config='true'> <openid-login/> <!-- other tags and attributes omitted for clarity --> </http> Lastly, you’ll need to add the spring-security-openid.jar to your project. Eight You can configure your app to authenticate users with an embedded LDAP (Lightweight Directory Access Protocol) Server using XML config. This is described in the abridged XML schema show below: <xs:element name='ldap-server'> <xs:complexType> <xs:attributeGroup ref='security:ldap-server.attlist' /> </xs:complexType> </xs:element> <xs:attributeGroup name='ldap-server.attlist'> <xs:attribute name='id' type='xs:token'> <xs:annotation> <xs:documentation> A bean identifier, used for referring to the bean elsewhere in the context. </xs:documentation> </xs:annotation> </xs:attribute> <xs:attribute name='port' type='xs:positiveInteger'/> <xs:attribute name='ldif' type='xs:string'> <xs:annotation> <xs:documentation> Explicitly specifies an ldif file resource to load into an embedded LDAP server. The default is classpath*:*.ldiff </xs:documentation> </xs:annotation> </xs:attribute> <xs:attribute name='root' type='xs:string'> <xs:annotation> <xs:documentation> Optional root suffix for the embedded LDAP server. Default is 'dc=springframework,dc=org' </xs:documentation> </xs:annotation> </xs:attribute> </xs:attributeGroup> The LDIF file, where LDIF stands for LDAP Interchange Format, is a plain text file format used to describe a set of LDAP records. An example of the ldap-server element usage would be: <ldap-server ldif='classpath:my-ldif-file.ldif' id='localserver' /> To use Spring Security LDAP integration, remember to include the spring-security-ldap.jar jar in your project’s POM.XML. Nine You can configure your app to authenticate users with remote LDAP (Lightweight Directory Access Protocol) Server using XML config. This is described in the abridged XML schema show below: <xs:element name='ldap-server'> <xs:complexType> <xs:attributeGroup ref='security:ldap-server.attlist' /> </xs:complexType> </xs:element> <xs:attributeGroup name='ldap-server.attlist'> <xs:attribute name='id' type='xs:token'> <xs:annotation> <xs:documentation> A bean identifier, used for referring to the bean elsewhere in the context. </xs:documentation> </xs:annotation> </xs:attribute> <xs:attribute name='url' type='xs:token'/> <xs:attribute name='port' type='xs:positiveInteger'/> <xs:attribute name='manager-dn' type='xs:string'> <xs:annotation> <xs:documentation> Username (DN) of the 'manager' user identity which will be used to authenticate to a (non-embedded) LDAP server. If omitted, anonymous access will be used. </xs:documentation> </xs:annotation> </xs:attribute> <xs:attribute name='manager-password' type='xs:string'> <xs:annotation> <xs:documentation> The password for the manager DN. This is required if the manager-dn is specified. </xs:documentation> </xs:annotation> </xs:attribute> </xs:attributeGroup> The documentation states that the ldap-server element “Defines an LDAP server location or starts an embedded server. The url indicates the location of a remote server. If no url is given, an embedded server will be started, listening on the supplied port number. The port is optional and defaults to 33389. A Spring LDAP ContextSource bean will be registered for the server with the id supplied”. This is an example of a really minimal configuration: <ldap-server url='ldap://myServer/dc=captaindebug,dc=com:389' id='ldapExternal' manager-dn='uid=admin,ou=users,ou=systems' manager-password='s3cret'/> Having configured the server, you also need to configure the LDAP authentication provider. There seem to be several methods of doing this and it’s not so straightforward, so more on that later, possibly… Ten You can add the requires-channel='https' attribute to your Spring Security Config’s <intercept-url /> element to force any matching URL to use HTTPS. For example, if you wanted to ensure that password were always encrypted before being sent, then you could add this abridged XML to your config: <http auto-config='true' use-expressions='true'> <intercept-url pattern='/login' requires-channel='https'/> <!-- Other attributes and elements omitted --> </https> There are another couple of things to do here, but more on that later… You may have noticed that I’ve used the Spring Security XML schema file ( http://www.springframework.org/schema/security/spring-security-3.1.xsd) to explain some of the features in my list of things you can do with Spring Security. That’s because I always treat the Spring XSDs as the definitive reference point for all things Spring. In November 2011 I wrote a blog on Spring’s JSR-250’s @PostConstruct Annotation that contained a mistake (Yes, it true it does happen), which was quite rightly pointed out by Spring’s Chris Beams – @CBeams, who left a comment on the JavaLobby Version of this blog. I decided to check the schemas and found that we were both wrong (although I was a lot more wrong than Chris) – the Captain Debug article is now, so far as I can tell, correct. Application security is a pretty complex subject and if it’s something you’ll be looking at in depth then I suggest that you get a copy of Spring Security 3 by Peter Mularien – it’s also recommended by the Guys at Spring. Finally, if there’s one key idea to appreciate about Spring Security is that, as an application bolt-on, it provides a really rich security feature set. You should therefore try to let Spring Security handle as much possible of your app’s security details rather than diving in and unnecessarily writing your own code.   Reference: Ten Things You Can Do With Spring Security from our JCG partner Roger Hughes at the Captain Debug’s Blog blog. ...
java-logo

Java Heap Dump: Are you up to the task?

If you are as much enthusiasm as I am on Java performance, heap dump analysis should not be a mystery to you. If it is then the good news is that you have an opportunity to increase your Java troubleshooting skills and JVM knowledge. The JVM has now evolve to a point that it is much easier today to generate and analyze a JVM heap dump vs. the old JDK 1.0 – JDK 1.4 days. Heap dump analysis should not be seen as a replacement for profiling & JVM analysis tools such as JProfiler or Plumbr but complementary. It is particularly useful when troubleshooting Java heap memory leaks and java.lang.OutOfMemoryError problems. This post will provide you with an overview of a JVM heap dump and what to expect out of it. It will also provide recommendations on how and when you should spend time analyzing a heap dump. Future articles will include tutorials on the analysis process itself. Java Heap Dump overview A JVM heap dump is basically a “snapshot” of the Java heap memory at a given time. It is quite different than a JVM thread dump which is a snapshot of the threads. Such snapshot contains low level detail about the java objects and classes allocated on the Java heap such as:Java objects such as Class, fields, primitive values and references Classloader related data including static fields (important for classloader leak problems) Garbage collection roots or objects that are accessible from outside the heap (System classloader loaded resources such as rt.jar, JNI or native variables, Threads, Java Locals and more…) Thread related data & stacks (very useful for sudden Java heap increase problems, especially when combined with thread dump analysis)Please note that it is usually recommended to generate a heap dump following a full GC in order to eliminate unnecessary “noise” from non-referenced objects. Analysis reserved for the Elite? One common misperception I have noticed over the last 10 years working with production support teams is the impression that deeper analysis tasks such as profiling, heap dump or thread dump analysis are reserved for the “elite” or the product vendor (Oracle, IBM…). I could not disagree more. As a Java developer, you write code potentially running in a highly concurrent thread environment, managing hundreds and hundreds of objects on the JVM. You do have to worry not only about concurrency issues but also on garbage collection and the memory footprint of your application(s). You are in the best position to perform this analysis since you are the expert of the application.Find below typical questions you should be able to answer:How much concurrent threads are needed to run my application concurrently as per load forecast? How much memory each active thread is consuming before they complete their tasks? What is the static memory footprint of my application? (libraries, classloader footprint, in-memory cache data structures etc.) What is the dynamic memory footprint of my application under load? (sessions footprint etc.) Did you profile your application for any memory leak?Load testing, profiling your application and analyzing Java heap dumps (ex: captured during a load test or production problem) will allow you to answer the above questions. You will then be in position to achieve the following goals:Reduce risk of performance problems post production implementation Add value to your work and your client by providing extra guidance & facts to the production and capacity management team; allowing them to take proper IT improvement actions Analyze the root cause of memory leak(s) or footprint problem(s) affecting your client IT production environment Increase your technical skills by learning these performance analysis principles and techniques Increase your JVM skills by improving your understanding of the JVM, garbage collection and Java object life cyclesThe last thing you want to reach is a skill “plateau”. If you are not comfortable with this type of analysis then my recommendations are as per below:Ask a more senior member of your team to perform the heap dump analysis and shadow his work and approach Once you are more comfortable, volunteer yourself to perform the same analysis (from a different problem case) and this time request a more experienced member to shadow your analysis work Eventually the student (you) will become the mentor  When to use Analyzing JVM heap dumps should not be done every time you are facing a Java heap problem such as OutOfMemoryError. Since this can be a time consuming analysis process, I recommend this analysis for the scenarios below:The need to understand & tune your application and / or surrounding API or Java EE container itself memory footprint Java heap memory leak troubleshooting Java classloader memory leaks Sudden Java heap increase problems or trigger events (has to be combined with thread dump analysis as a starting point)Now find below some limitations associated with heap dump analysis:JVM heap dump generation is an intensive computing task which will hang your JVM until completed. Proper due diligence is required in order to reduce impact to your production environment Analyzing the heap dump will not give you the full Java process memory footprint e.g. native heap. For this purpose, you will need to rely on other tools and OS commands for that purpose You may face problems opening & parsing heap dumps generated from older version of JDK’s such as 1.4 or 1.5  Heap dump generation techniques JVM heap dumps are typically generated as a result of 2 actions:Auto-generated or triggered as a result of a java.lang.OutOfMemoryError (e.g. Java Heap, PermGen or native heap depletion) Manually generated via the usage of tools such as jmap, VisualVM (via JMX) or OS level command  # Auto-triggered heap dumps If you are using the HotSpot Java VM 1.5+ or JRockit R28+ then you will need to add the following parameter below at your JVM start-up:-XX:+HeapDumpOnOutOfMemoryErrorThe above parameter will enable to HotSpot VM to automatically generate a heap dump following an OOM event. The heap dump format for those JVM types is HPROF (*.hprof). If you are using the IBM JVM 1.4.2+, heap dump generation as a result of an OOM event is enabled by default. The heap dump format for the IBM JVM is PHD (*.phd). # Manually triggered heap dumps Manual JVM heap dumps generation can be achieved as per below:Usage of jmap for HotSpot 1.5+ Usage of VisualVM for HotSpot 1.6+ * recommended *** Please do your proper due diligence for your production environment since JVM heap dump generation is an intrusive process which will hang your JVM process until completion ** If you are using the IBM JVM 1.4.2, you will need to add the following environment variables from your JVM start-up:export IBM_HEAPDUMP=true export IBM_HEAP_DUMP=trueFor IBM JVM 1.5+ you will need to add the following arguments at the Java start-up:-Xdump:heapEX:java -Xdump:none -Xdump:heap:events=vmstop,opts=PHD+CLASSIC JVMDUMP006I Processing Dump Event 'vmstop', detail '#00000000' - Please Wait. JVMDUMP007I JVM Requesting Heap Dump using 'C:\sdk\jre\bin\heapdump.20050323.142011.3272.phd' JVMDUMP010I Heap Dump written to C:\sdk\jre\bin\heapdump.20050323.142011.3272.phd JVMDUMP007I JVM Requesting Heap Dump using 'C:\sdk\jre\bin\heapdump.20050323.142011.3272.txt' JVMDUMP010I Heap Dump written to C:\sdk\jre\bin\heapdump.20050323.142011.3272.txt JVMDUMP013I Processed Dump Event 'vmstop', detail '#00000000'.Please review the Xdump documentation for IBM JVM1.5+. For Linux and AIX®, the IBM JVM heap dump signal is sent via kill –QUIT or kill -3. This OS command will trigger JVM heap dump generation (PHD format). I recommend that you review the MAT summary page on how to acquire JVM heap dump via various JVM & OS combinations. Heap dump analysis tools My primary recommended tool for opening and analyzing a JVM heap dump is Eclipse Memory Analyzer (MAT). This is by far the best tool out there with contributors such as SAP & IBM. The tool provides a rich interface and advanced heap dump analysis capabilities, including a “leak suspect” report. MAT also supports both HPROF & PHD heap dump formats. I recommend my earlier post for a quick tutorial on how to use MAT and analyze your first JVM heap dump. I have also a few heap dump analysis case studies useful for your learning process.  Final words I really hope that you will enjoy JVM heap dump analysis as much as I do. Future articles will provide you with generic tutorials on how to analyze a JVM heap dump and where to start. Please feel free to provide your comments.   Reference: Java Heap Dump: Are you up to the task? from our JCG partner Pierre-Hugues Charbonneau at the Java EE Support Patterns & Java Tutorial blog. ...
software-development-2-logo

How to be Big Data-native?

Big data has spawned a set of tools that deliver results beyond the buzz. It has started delivering real insights for companies, which result in more effective decisions. When middleware natively supports big data, big data becomes more than just another option. It becomes the default. Let’s examine this idea: 1.Big Data Storage Whenever you think of storage, (almost) everyone thinks of an RDBMS mysql, postgres, mariaDB, Oracle, etc. If you convert to supporting native Big Data, you turn into to NoSQL options that sacrifices SQL for scale. You start storing everything in Cassandra, HBase, mongoDB, redis, etc. You don’t have to dread the day your data volume becomes too big to handle. When it does all you do now is configure a new node and maybe tune the cluster a bit and you are done. 2.Big Data Analytics If you are not looking at analytics, you should (Google for innovate or die). All analytics support for big data. If you thought about running some SQL or spread sheet macros, it’s time to move on. Start thinking Hadoop, Big Query, Drill, etc. Natively supporting Big Data analytics allows anyone who sets up the middleware to instantly enable their departments and teams to harvest their data silos, no matter how big they are. 3.Big Data Speed There is no point of BigData storage and Big Data Analytics if you can’t collect big data fast enough. Looking at web scale transactions it is not unusual to have millions a second. Before middleware vendors start advocating they need to make sure the middleware is up to par. Computers are definitely fast enough so that even a single node can handle around 10,000 TPS. The biggest concern I’ve seen is many companies claiming to be able to adapt to Big Data without actually supporting it natively. It is a nightmare to allow to scale for Big Data after choosing incompatible technologies. The concepts differ, the trade offs are different and the effectiveness is very low. Big data has reached the importance level to for middleware evaluators to add another section to their RFPs. And, yes that’s whether the middleware is “Big Data native”.   Reference: How to be Big Data-native? from our JCG partner Mackie Mathew at the dev_religion blog. ...
git-logo

Introduction To Git Concepts

This post is an introduction/reminder to Git concepts. It aims at facilitating the learning curve for those coming from a Subversion (or other) background. For more details, there is nothing like the official book. ConceptsGit operates on repositories which contain a local database of files and corresponding file revisions. Repositories contain files which can have 3 states:Committed – The file is stored in the database. Modified – The file has been modified, but has not been stored in the database. Staged – The file has been modified and flagged as to be committed in the database.A file can also be considered as untracked by Git. It has no status, until it is added to the working directory. The add function can be used to stage a file. When cloning or creating a Git repository to a local directory, this directory will contain:A Git directory containing the local database and all meta information corresponding to the repository. A staging area file containing information about what will be included in the next commit. The remaining content is called the working directory, which contains files (extracted from the database) corresponding to a specific version of modification stored in the database.Typically, files are modified in the working directory, then staged from commit, then committed into the repository database. One can skip the staging step when committing files, all modified tracked files are taken into account. It is possible to ignore files in a repository by marking them as such in the working directory. They will not be stored in the local database. It is possible to remove files from the Git repository, or to move them around in the working directory. When cloning a repository locally, its origin (i.e., the original repository) is registered in the local repository as a remote repository. More remote repository can be attached (added) and detached (deleted) to your local Git repository. One can fetch all data from a remote repository (including for branches). This operation will not merge it with your local work though. One can also pull all data from a remote repository, which is like a fetch with automatic merging. Pushing your repository content to a remote repository is like a pull, but the other way round. All modifications transmitted and merged on the remote repository. One can create tags (i.e. of content at a specific version). Eventually, this tag can be annotated with tagger, email, etc… It is possible to sign tags too (in a cryptographic way). Signed tags can be verified. One can create branches too. Technically speaking, these are pointers to a specific version in the database repository. The default branch is called Master. In order to remember which branch you are working on, Git has a specific pointer called HEAD. One can use the Git checkout command to switch back and forth between branches. This will update the content of the working directory accordingly. Modifications made to files in different branches are recorded separately. Once a branch has reached a stable level, it can be merged back to Master (or any other branch it came from). Then, it can be deleted. Eventually, a branch can be closed and deleted without merging modified content. This content is lost forever. Branches can evolve independently. If so, a merge operation will first find a common ancestor and create a new version in the Master (or any other target branch). This version will contain both the modifications of the target and merging branches. It is possible to work with remote branches from remote repositories too. Rebasing is about merging the content of a branch back to Master (for example). When there is only one branch, it is not different than a simple merge, except that the log history will not contain the entries (versions) of the rebased branch anymore. This functionality is mostly useful when there are multiple branches created from multiple branches in a Git repository. You may want to merge a branch while keeping alive others having common ancestors. Be careful with rebasing, because if other people were working on that branch (i.e. it is public) or any sub-branches, the continuous integration continuity will be broken for them. Fast Forwarding is the process of moving a branch pointer forward. For example, a branch A is created from Master. Work is performed on A and merged back to Master. The Master pointer may lag behind to an earlier version not containing the merged changes. It can be fast forwarded to the version containing those merged changes. Stashing is the practice of saving unfinished work aside without committing it yet. This allows one to switch branches without committing work in progress. Submodules is a mean to import another Git project into your Git project, but with keeping the commits separated. This is useful when that other project is about developing a library which will be used in several Git projects.  Reference: Introduction To Git Concepts from our JCG partner Jerome Versrynge at the Technical Notes blog. ...
apache-tomcat-logo

Standalone web application with executable Tomcat

When it comes to deploying your application, simplicity is the biggest advantage. You’ll understand that especially when project evolves and needs some changes in the environment. Packaging up your whole application in one, standalone and self-sufficient JAR seems like a good idea, especially compared to installing and upgrading Tomcat in target environment. In the past I would typically include Tomcat JARs in my web application and write thin command-line runner using Tomcat API. Luckily there is a tomcat7:exec-war maven goal that does just that. It takes your WAR artifact and packages it together with all Tomcat dependencies. At the end it also includes Tomcat7RunnerCli Main-class to manifest. Curious to try it? Take your existing WAR project and add the following to your pom.xml: <plugin> <groupId>org.apache.tomcat.maven</groupId> <artifactId>tomcat7-maven-plugin</artifactId> <version>2.0</version> <executions> <execution> <id>tomcat-run</id> <goals> <goal>exec-war-only</goal> </goals> <phase>package</phase> <configuration> <path>/standalone</path> <enableNaming>false</enableNaming> <finalName>standalone.jar</finalName> <charset>utf-8</charset> </configuration> </execution> </executions> </plugin> Run mvn package and few seconds later you’ll find shiny standalone.jar in your target directory. Running your web application was never that simple: $ java -jar target/standalone.jar …and you can browse localhost:8080/standalone. Although the documentation of path parameter says (emphasis mine): The webapp context path to use for the web application being run. The name to store webapp in exec jar. Do not use / just between the two of us, <path>/</path> seems to work after all. It turns out that built in main class is actually a little bit more flexible. For example you can say (I hope it’s self-explanatory): $ java -jar standalone.jar -httpPort=7070 What this runnable JAR does is it first unpacks WAR file inside of it to some directory (.extract by default1) and deploys it to Tomcat – all required Tomcat JARs are also included. Empty standalone.jar (with few KiB WAR inside) weights around 8.5 MiB - not that much if you claim that pushing whole Tomcat with every release alongside your application is wasteful. Talking about Tomcat JARs, you should wonder how to choose Tomcat version included in this runnable? Unfortunately I couldn’t find any simple option, so we must fall back to explicitly redefining plugin dependencies (version 2.0 has hardcoded 7.0.30 Tomcat). It’s quite boring, but not that complicated and might be useful for future reference: <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <tomcat7Version>7.0.33</tomcat7Version> </properties><build> <plugins> <plugin> <groupId>org.apache.tomcat.maven</groupId> <artifactId>tomcat7-maven-plugin</artifactId> <version>2.0</version> <executions> <execution> <id>tomcat-run</id> <goals> <goal>exec-war-only</goal> </goals> <phase>package</phase> <configuration> <path>/standalone</path> <enableNaming>false</enableNaming> <finalName>standalone.jar</finalName> <charset>utf-8</charset> </configuration> </execution> </executions> <dependencies> <dependency> <groupId>org.apache.tomcat.embed</groupId> <artifactId>tomcat-embed-core</artifactId> <version>${tomcat7Version}</version> </dependency> <dependency> <groupId>org.apache.tomcat</groupId> <artifactId>tomcat-util</artifactId> <version>${tomcat7Version}</version> </dependency> <dependency> <groupId>org.apache.tomcat</groupId> <artifactId>tomcat-coyote</artifactId> <version>${tomcat7Version}</version> </dependency> <dependency> <groupId>org.apache.tomcat</groupId> <artifactId>tomcat-api</artifactId> <version>${tomcat7Version}</version> </dependency> <dependency> <groupId>org.apache.tomcat</groupId> <artifactId>tomcat-jdbc</artifactId> <version>${tomcat7Version}</version> </dependency> <dependency> <groupId>org.apache.tomcat</groupId> <artifactId>tomcat-dbcp</artifactId> <version>${tomcat7Version}</version> </dependency> <dependency> <groupId>org.apache.tomcat</groupId> <artifactId>tomcat-servlet-api</artifactId> <version>${tomcat7Version}</version> </dependency> <dependency> <groupId>org.apache.tomcat</groupId> <artifactId>tomcat-jsp-api</artifactId> <version>${tomcat7Version}</version> </dependency> <dependency> <groupId>org.apache.tomcat</groupId> <artifactId>tomcat-jasper</artifactId> <version>${tomcat7Version}</version> </dependency> <dependency> <groupId>org.apache.tomcat</groupId> <artifactId>tomcat-jasper-el</artifactId> <version>${tomcat7Version}</version> </dependency> <dependency> <groupId>org.apache.tomcat</groupId> <artifactId>tomcat-el-api</artifactId> <version>${tomcat7Version}</version> </dependency> <dependency> <groupId>org.apache.tomcat</groupId> <artifactId>tomcat-catalina</artifactId> <version>${tomcat7Version}</version> </dependency> <dependency> <groupId>org.apache.tomcat</groupId> <artifactId>tomcat-tribes</artifactId> <version>${tomcat7Version}</version> </dependency> <dependency> <groupId>org.apache.tomcat</groupId> <artifactId>tomcat-catalina-ha</artifactId> <version>${tomcat7Version}</version> </dependency> <dependency> <groupId>org.apache.tomcat</groupId> <artifactId>tomcat-annotations-api</artifactId> <version>${tomcat7Version}</version> </dependency> </dependencies> </plugin> </plugins> </build> In the next article we will learn how to tame these pesky Tomcat internal logs appearing in the terminal (java.util.logging…) In the meantime I discovered and reported MTOMCAT-186 Closing executable JAR does not call ServletContextListener.contextDestroyed() – have look if this is a deal breaker for you. 1 – it might be a good idea to specify different directory using -extractDirectory and clean it before every restart with -resetExtract.   Reference: Standalone web application with executable Tomcat from our JCG partner Tomasz Nurkiewicz at the Java and neighbourhood blog. ...
java-logo

Guava Preconditions Class

Anyone who’s written much Java has probably written methods that begin with conditionals that verify either the provided parameters or the state of the object being acted upon before proceeding with the remainder of the method’s implementation. These can add verbosity to the method and sometimes, especially if there are multiple checks, can almost drown out the interesting business logic of the method. One way to reduce this clutter is to use Java assertions, but these are disabled at runtime by default. In fact, it is advised to ‘not use assertions for argument checking in public methods’ for this reason and to use appropriate runtime exceptions instead. Guava provides a handy Preconditions class with aesthetic advantages of assertions, but which uses the normal Java exception mechanism and is not disabled at runtime. This post provides some illustrative examples of Guava’s Preconditions class in action. The next code listing shows contrived examples using Guava‘s Preconditions class. The example demonstrate use of static methods on the Preconditions class to check a parameter for null, check a parameter’s placement in a provided array, check to ensure a valid value has been provided for a parameter, and to check that the state of the object on which the method is invoked is appropriate for that method’s execution. Note also that I made use of the static import for the Preconditions class so that I am able to call its static methods without need to scope each call with the class name. GuavaPreconditionsDemo.java   package dustin.examples;import static java.lang.System.err; import static com.google.common.base.Preconditions.*;/** * Simple demonstration of Guava's Preconditions support. * * @author Dustin */ public class GuavaPreconditionsDemo { private final boolean initialized = false;/** * Demonstrate Guava's Preconditions.checkNotNull methods. * * @param parameter Parameter that is checked for null-ness. */ public void testForNonNullArgument(final String parameter) { final String localParameter = checkNotNull(parameter, 'Provided parameter is unacceptably null.'); }public void testDivisorNotZero(final int divisor) { checkArgument(divisor != 0, 'Zero divisor not allowed.'); }public void testArrayElement(final String[] strArray, final int indexNumber) { final int index = checkElementIndex(indexNumber, strArray.length, 'String array index number'); }public void testArrayPosition(final String[] strArray, final int indexNumber) { final int index = checkPositionIndex(indexNumber, strArray.length, 'String array index number'); }public void testState() { checkState(this.initialized, 'Cannot perform action because not initialized.'); }public static void printHeader(final String newHeaderText) { err.println('\n=========================================================='); err.println('== ' + newHeaderText); err.println('=========================================================='); }/** * Main function for executing demonstrations of Guava's Preconditions. */ public static void main(final String[] arguments) { final GuavaPreconditionsDemo me = new GuavaPreconditionsDemo();printHeader('Preconditions.checkNotNull'); try { me.testForNonNullArgument(null); } catch (NullPointerException npe) { npe.printStackTrace(); }printHeader('Preconditions.checkArgument'); try { me.testDivisorNotZero(0); } catch (IllegalArgumentException illArgEx) { illArgEx.printStackTrace(); }printHeader('Preconditions.checkElementIndex'); try { me.testArrayElement(new String[]{'Dustin', 'Java'}, 3); } catch (IndexOutOfBoundsException ioobEx) { ioobEx.printStackTrace(); }printHeader('Preconditions.checkPositionIndex'); try { me.testArrayPosition(new String[]{'Dustin', 'Java'}, 3); } catch (IndexOutOfBoundsException ioobEx) { ioobEx.printStackTrace(); }printHeader('Preconditions.checkState'); try { me.testState(); } catch (IllegalStateException illStateEx) { illStateEx.printStackTrace(); } } } Each of the cases demonstrated in the code listing above checked for preconditions on the method parameters or on the state of the object against which the method was being invoked without use of ‘noisy’ conditional statements. Use of the static import allowed very concise expression of the conditions to be checked, Much of the class is the ‘main’ function, used as a ‘test driver’ in this case. I placed the calls within try-catch block to make sure all demonstrations are executed. The output of running the above is shown next. Output From Executing Above Class   ========================================================== == Preconditions.checkNotNull ========================================================== java.lang.NullPointerException: Provided parameter is unacceptably null. at com.google.common.base.Preconditions.checkNotNull(Preconditions.java:204) at dustin.examples.GuavaPreconditionsDemo.testForNonNullArgument(GuavaPreconditionsDemo.java:22) at dustin.examples.GuavaPreconditionsDemo.main(GuavaPreconditionsDemo.java:62)========================================================== == Preconditions.checkArgument ========================================================== java.lang.IllegalArgumentException: Zero divisor not allowed. at com.google.common.base.Preconditions.checkArgument(Preconditions.java:88) at dustin.examples.GuavaPreconditionsDemo.testDivisorNotZero(GuavaPreconditionsDemo.java:27) at dustin.examples.GuavaPreconditionsDemo.main(GuavaPreconditionsDemo.java:72)========================================================== == Preconditions.checkElementIndex ========================================================== java.lang.IndexOutOfBoundsException: String array index number (3) must be less than size (2) at com.google.common.base.Preconditions.checkElementIndex(Preconditions.java:301) at dustin.examples.GuavaPreconditionsDemo.testArrayElement(GuavaPreconditionsDemo.java:32) at dustin.examples.GuavaPreconditionsDemo.main(GuavaPreconditionsDemo.java:82)========================================================== == Preconditions.checkPositionIndex ========================================================== java.lang.IndexOutOfBoundsException: String array index number (3) must not be greater than size (2) at com.google.common.base.Preconditions.checkPositionIndex(Preconditions.java:351) at dustin.examples.GuavaPreconditionsDemo.testArrayPosition(GuavaPreconditionsDemo.java:37) at dustin.examples.GuavaPreconditionsDemo.main(GuavaPreconditionsDemo.java:92)========================================================== == Preconditions.checkState ========================================================== java.lang.IllegalStateException: Cannot perform action because not initialized. at com.google.common.base.Preconditions.checkState(Preconditions.java:145) at dustin.examples.GuavaPreconditionsDemo.testState(GuavaPreconditionsDemo.java:42) at dustin.examples.GuavaPreconditionsDemo.main(GuavaPreconditionsDemo.java:102) The different static Preconditions methods throw different types of runtime exceptions when a specified condition is violated. They throw exceptions that tend to be appropriate for the particular case that is violated. This means that in most cases the result of a Preconditions static method call is the same as one would likely throw explicitly for that condition, but with much less code to make the check and throw the exception. I did not show it in this post, but overloaded versions of these static methods also allow for string arguments to be provided to fill placeholders in a patterned String. This is helpful for placing values associated with the errant condition in the exception message. Conclusion Guava eases the coding and improves the fluency and readability of contract checking in methods. It offers the advantages of assertions’ concise syntax coupled with the advantages of traditional throwing of runtime exceptions.   Reference: Guava Preconditions Class from our JCG partner Dustin Marx at the Inspired by Actual Events blog. ...
Java Code Geeks and all content copyright © 2010-2014, Exelixis Media Ltd | Terms of Use | Privacy Policy | Contact
All trademarks and registered trademarks appearing on Java Code Geeks are the property of their respective owners.
Java is a trademark or registered trademark of Oracle Corporation in the United States and other countries.
Java Code Geeks is not connected to Oracle Corporation and is not sponsored by Oracle Corporation.
Do you want to know how to develop your skillset and become a ...
Java Rockstar?

Subscribe to our newsletter to start Rocking right now!

To get you started we give you two of our best selling eBooks for FREE!

Get ready to Rock!
You can download the complementary eBooks using the links below:
Close