Thứ Hai, 9 tháng 9, 2013

Book Review: JBoss Weld CDI for Java Platform

JBoss Weld CDI for Java Platform is a relatively short book (approximately 100 "main" pages) that introduces JBoss Weld, which it describes as "the open source reference implementation" of Java Contexts and Dependency Injection. Weld is the reference implementation of Java Specification Request 299 ("Contexts and Dependency Injection for the Java EE platform") and is not limited to use with JBoss Application Server. This post is my review of Packt Publishing's JBoss Weld CDI for Java Platform by Ken Finnigan.

Preface

The Preface of JBoss Weld CDI for Java Platform explains that the book is written for "anyone wanting to understand what CDI 1.0 is and how it can be used to benefit an application's architecture." This Preface also states that the latest version of Weld 1.x is required along with Maven and a "favorite runtime container" (out of JBoss AS7, GlassFish, and Tomcat).

Chapter 1: What is a Bean?

The opening chapter of JBoss Weld CDI for Java Platform provides a brief history of Java "beans" that includes mention of early JavaBeans, Enterprise JavaBeans, and JSF Managed Beans. There are, of course, many more types of "beans" in Java such as JMX Managed Beans (MBeans and MXBeans) and product-specific beans like Spring Framework's beans.

The initial chapter goes on to provide a definition of a CDI bean. Finnigan explains that a CDI bean generally "needs a non-private constructor with no parameters" to be "proxied by the container" before discussing use of the @Inject annotation for classes without a no-argument public constructor. There is a typo here as the text reads, "It is also possible for a bean to be proxied by the container if it does not have a constructor with any parameters," but I think the text should read, "It is also possible for a bean to be proxied by the container if it does not have a constructor without parameters" or "It is also possible for a bean to be proxied by the container if it does not have a constructor no parameters."

Chapter 1 of JBoss Weld CDI for Java Platform introduces several other annotations besides @Inject; these include @Dependent, @RequestScoped, @ApplicationScoped, @SessionScoped, @ConversationScoped, and @Alternative. The chapter includes coverage of the beans.xml file and discusses where it should be placed and what it should contain.

The first chapter continues its introduction to CDI beans by quoting the CDI specification of the characteristics required of a CDI bean and then focuses on each characteristic (bean types, qualifiers, scope, interceptor bindings, bean implementation, and optional bean expression language [EL]). These introductions to the characteristics of a CDI bean introduce more annotations such as @Typed, @Qualifier, and @Named.

The packed ten-page first chapter continues with coverage of CDI's @ManagedBean (not to be confused with JSF's @ManagedBean) and @Produces (on methods and fields).

Chapter 2: Dependency Injection and Lookup

The second chapter of JBoss Weld CDI for Java Platform begins with a deeper look at dependency injection using Weld. Finnigan describes the ability to inject dependencies at class level (via no-arguments constructor or constructor annotated with @Inject), at get/set method level, or at field level. I was happy to see that he specifically mentions constructor setting and field level setting of injection points as preferable to method level setting to support creation of immutable objects. (I think the importance and value of immutability (when possible) in Java objects is still under-appreciated.)

The second chapter provides more focus on qualifiers (including @Any and @Default annotations), alternatives, and client proxies, and injection point metadata.

I like that Finnigan talks about some likely errors (including error message output) that can occur when configuration problems exist. I wish more introductory books did this, focusing on things that often go wrong rather than simply covering the happy path of using the framework or tool being introduced. Finnigan includes a section in this chapter called "Resolving Weld deployment errors" that lists the common types of errors that can occur with Weld deployments (unsatisfied dependencies and ambiguous dependencies) and then lists multiple ways to resolve each.

Chapter 3: Deploying JBoss Weld

The third chapter of JBoss Weld CDI for Java Platform covers "installation of JBoss Weld into Java EE 6 and Servlet containers." Finnigan points out that "all Java EE 6 containers will come with an implementation of CDI preinstalled," but also makes the point that it's worth knowing how to install or deploy Weld because the version bundled with the container may be insufficient. The chapter talks about how to download Weld and mentions that the current version as of the book's writing was 1.1.10 (at the time of this blog post's writing, Weld 1.2 beta and Weld 2.0 are available for download).

Chapter 3 concludes with a useful discussion on upgrading of Weld versions within three containers: JBoss AS 7 (7.1.1) with bundled Weld 1.1.5Final, GlassFish 3 (3.1.2.2) with bundled Weld 1.1.8Final, and Apache Tomcat 7.0.35 (no bundled Weld implementation because Tomcat is a web servlet implementation).

Chapter 4: Scopes and Contexts

JBoss Weld CDI for Java Platform's fourth chapter delves deeper into the concepts of scopes and contexts introduced earlier in the first chapter. This fourth chapter introduces the concepts of normal and pseudo scopes. Finnigan explains that the differentiating factor between normal scope and pseudo scope is whether a client proxy is required or not. The chapter provides a relatively large section on the built-in scopes introduced earlier and describes the underlying respective lifecycles: request context, session context, application context, and conversation context. I liked that Finnigan wanrns about conversation scope in CDI 1.0 being specific to JSF, but mentioning that CDI 1.1 (JSR 346) is expected to make conversation scope more generally available.

The majority of Chapter 4 is spent on normal, built-in scopes and their associated contexts. In particular, a significant portion of the chapter is dedicated to coverage of using the conversational scope with JSF. The chapter, however, does briefly describe pseudo scopes and concludes with an example of writing custom scope and context.

Chapter 5: Producers

The fifth chapter in JBoss Weld CDI for Java Platform provides greater focus on another topic introduced in the first chapter: producers with @Produces and @Disposes. This chapter's coverage includes some more highly useful side notes with special emphasis that discuss the use of @New, but also mention that @New is deprecated in CDI 1.1 in favor of @Dependent at the injection point.

Chapter 6: Interceptors and Decorators

Chapter 6 of JBoss Weld CDI for Java Platform introduces interceptors and decorators and differentiates them, "Interceptors are perfect for separating concerns that are orthogonal to our application ... Decorators are well suited for solving business problems that apply to a hierarchy of classes of the same type."

This chapter provides relatively in-depth coverage of created interceptors and decorators. I like the fact that the examples, especially the interceptors examples, include some complicating issues to take the examples past "Hello World" status and to be more reflective of what one might do with these constructs.

Chapter 7: Events

The seventh chapter of JBoss Weld CDI for Java Platform covers "events within CDI" including "how they are fired" (javax.enterprise.event.Event.fire), "how we listen for new events" (@Observes), "what we can use as an event payload" (concrete Java classes), and "how we can narrow what events we can listen to and fire" (event qualifiers and conditional observers).

Chapter 8: Writing a Portable Extension

Chapter 8 is the last chapter of JBoss Weld CDI for Java Platform that focuses on detailed coverage of Weld concepts in an purely introductory fashion because Chapter 9 and Chapter 10 focus on an example book store application. This chapter's focus is use of CDI-exposed Service Provider Interfaces (SPIs) that allow extension and customization of CDI. The chapter outlines the development of portable CDI extensions by implementing javax.enterprise.inject.spi.Extension and registering the extension in META-INF/services/javax.enterprise.inject.spi.Extension. The chapter discusses the "core" role of BeanManager in allowing extensions to access the CDI lifecycle. Chapter 8 also mentions Apache DeltaSpike, a product which I had never heard of, but which its homepage advertises as "a number of portable CDI extensions that provide useful features for Java application developers."

Chapter 9: Book Store – CDI Services

JBoss Weld CDI for Java Platform's ninth chapter is the first of two chapters that use an online book store application as a CDI/Weld example intended to "provide a more indicative picture of how (Weld CDI) can be utilized," to "cover some of the CDI usage patterns that can be beneficial," and to "provide clear examples of topics that we have discussed in the previous chapters." Chapter 9 introduces the example application and demonstrates building its "back end" (services, interceptors, and events portions).

Chapter 10: Book Store – User Interfaces

The tenth and final chapter continues the example online bookstore application started in Chapter 9. This chapter focuses on the "front end" of the example application and demonstrates "how CDI services can be reused to create two distinct user interfaces." The two technologies used for the interfaces are AngularJS and JSF2/Rich Faces. In the book's example application, REST is used for communication between the user interfaces and the services.

Strengths
  • General CDI Specification (not just Weld) Resource - Although the book title and some of its content suggest focus on the CDI implementation Weld, the vast majority of the book is likely applicable to most common implementations of CDI (Chapter 3 being about the only significant exception that is highly Weld-specific rather than CDI-general). I find it often to be the case that books on reference implementations are good sources of information on the specification being implemented and that is definitely the case with JBoss Weld CDI for Java Platform; it can serve as simply "CDI for Java Platform."
  • Forward-looking - Technology books, especially those focused on new implementations of ongoing specifications, always come with great risk of being outdated quickly. Finnigan's mention of CDI 1.1 in several parts of the book helps to mitigate this risk at least a bit.
  • Appropriate Level of Detail - This is not a very lengthy book, but its length feels appropriate. There is nice introductory discussion along with discussion on some things to do and not do with CDI/Weld. There are several code examples, but most are short and easy to follow. The lengthy and more difficult to follow examples are reserved for the final two chapters on the sample application.
Conclusion

I really enjoyed JBoss Weld CDI for Java Platform and recommend it to anyone interested in learning about Java EE CDI in general or the Weld implementation of CDI in particular. Other than a few typos such as the one I mentioned in this post, the text is generally well-written. I particularly like the text's mixing of introductory material with forward-looking caveat statements and discussion of why certain practices are beneficial or detrimental in different circumstances.

Thứ Hai, 2 tháng 9, 2013

Better JUnit-based Unit Tests with NetBeans 7.4 beta Hints

In my last post, I wrote about hints provided in NetBeans 7.4 beta that improve a developer's ability to avoid nasty runtime issues with Java exception handling. In this post, I look at how two more hints provided by NetBeans 7.4 beta can be used to make unit tests more correct and more clear during unit test execution. These are the "Inconvertible parameters of Assert.assertEquals" and "Incorrect order of parameters of Assert.assertEquals" hints.

As far as I can tell from anecdotal evidence and from talking to other Java developers, JUnit remains the most widely used unit testing framework in the Java environment. Most of these JUnit users are intimately familiar with JUnit's Assert class and its many overloaded assertEquals methods. NetBeans 7.4 beta now provides two hints to make it easier to use these assertEquals methods appropriately.

Although many of the Assert.assertEquals() methods have very specific data types for the "expected" and "actual" parameters to be asserted as equal, there is a version that accepts two Objects and this means two parameters of different types that cannot possibly be considered "equal" can still be passed to that method. There is no way for the compiler to prevent that, but NetBeans 7.4 beta includes the "Inconvertible parameters of Assert.assertEquals" hint to address that particular case. Without such a hint, one is more likely to not realize the error of his or her ways until he or she runs the JUnit test and sees the failed assertion.

One of the most common issues I've run into with JUnit (and one of the reasons I love Hamcrest's fluent API) is that I just cannot seem to remember with confidence which order the parameters to the assertEquals methods are. I have a 50/50 chance of being correct by guessing. Modern Java IDEs such as NetBeans help greatly when writing new JUnit code because their method completion features will indicate that the "expected" parameter is specified first and the "actual" parameter is specified second. More commonly, this is a problem when reading code rather than when writing it because there is no method completion helping me read the code. NetBeans 7.4 beta addresses this by highlighting the situation in which I have mixed up the parameters' order via the "Incorrect order of parameters of Assert.assertEquals" hint. With that hint enabled (which it is by default), I can quickly recognize out-of-order parameters prior to runtime and even without method completion.

Both of the hints discussed above can be demonstrated in a very simple unit test class.

Portion of CalculatorTest.java

/**
* Test Calculator.sum(int ...).
*/
@Test
public void TestSumIntegers()
{
final Calculator calculator = new Calculator();
Assert.assertEquals(calculator.add(1, 2, 3, 4, 5), 15);
Assert.assertEquals("15", calculator.add(1, 2, 3, 4, 5));
}

The code the above unit test method is testing is not important for this discussion. Rather, the focus is on the use of Assert.assertEquals in two cases. Both cases as shown above are incorrect and force demonstration of the two previously discussed NetBeans hints. The first attempt at asserting two objects are equal places the parameters in the wrong order. The "expected" value (hard-coded 15) should be listed first followed by the "actual" value calculated by the method under test. The second attempt at asserting two objects are equal will always fail because the types don't match: the first parameter is a String and the second parameter is an integer. In both of these cases, the unit test code compiles without complaint. However, both assertions will ALWAYS fail when running the unit tests. In fact, these tests results may inadvertently be interpreted as problems with the code being tested until someone looks at the test failures in greater depth.

The next two screen snapshots demonstrate NetBeans 7.4 beta flagging both problematic unit testing assertion statements.

There is one caveat to note regarding the "Incorrect order of parameters of Assert.assertEquals" hint. It works well when the assertion statement is like the one shown in my example: a hard-coded expected value is provided as the "actual" value along with an obviously calculated value as the "expected" value. The next screen snapshot illustrates this point; only the statement I earlier showed is flagged by the hint and other ways of comparing actual to expected are not flagged, even when the order is incorrect.

The last shown screen snapshot demonstrates that the NetBeans hint is only able to detect an incorrect order of assertEquals parameters (should be expected before actual rather than actual before expected) in the case where those values are directly accessed in the statement (the actual calculation is performed for the first [expected] parameter and the expected hard-coded value is provided for the second [actual] parameter).

The two hints covered in this blog post make it easier to detect problems with the frequently used JUnit Assert.assertEquals methods that might not be detected until analysis of unit test run results without the hints. Although the two issues these hints warn developers about are typically fairly easy to detect and fix, detecting and fixing these problems is still more difficult and time-consuming than having the NetBeans IDE tell you they are wrong before you even run the test.

Thứ Bảy, 31 tháng 8, 2013

NetBeans 7.4 Beta Hints Warn of Ineffective Exception Handling

There are numerous examples of how Java exception handling can be more difficult than it might first appear and Josh Bloch devoted an entire chapter of Effective Java (both editions) to exception handling. The checked exception model in Java remains "controversial." I was pleased to see that the NetBeans 7.4 beta I recently downloaded has some hints to help with at least a few nuances of Java exception handling.

I recently downloaded NetBeans 7.4 beta and installed this latest version of NetBeans on my laptop. I downloaded the "All" NetBeans IDE Download Bundle (includes GlassFish Server Open Source Edition 4.0 and Apache Tomcat 7.0.41 and Groovy support) and installed it on my machine.

Two of the new hints in the "probable bugs" category that are in the "current development version" of NetBeans are "'finally' block suppresses exceptions" and "'throw' inside 'finally' block." In this blog post, I will demonstrate these hints and briefly discuss why the hints help improve exception handling.

'finally' block suppresses exceptions

As documented in posts such as James Stauffer's Don't return in a finally clause and in forums such as Java try-finally return design question, it is generally accepted that having a method return from a finally block is a bad idea. An example of this poor Java coding practice is shown next.

Example of finally Block Suppressing Exception

private void throwException() throws Exception
{
throw new Exception("A checked exception!");
}

/**
* Demonstrate NetBeans hint "The 'return' statement in the 'finally' block
* discards unhandled exceptions" by returning a value from the "finally"
* block.
*
* @return Integer value that is really meaningless in this case.
* @throws RuntimeException This exception is always thrown.
*/
public int demonstrateReturnFromFinallyBlock()
{
int value = 5;
try
{
value = 7;
throwException();
}
catch (Exception exception)
{
throw new RuntimeException(exception);
}
finally
{
return value;
}
}

When the method demonstrateReturnFromFinallyBlock() in the above code snippet is executed, the output appears as follows:

Returned Value: 7

Although one might expect the demonstrateReturnFromFinallyBlock() method to throw a Runtime exception instead of returning an integer value of 7 (as the Javadoc for that method even advertises!), the "always thrown" exception is actually discarded because of the return statement in the finally block. This is a potentially nasty issue that might only be obvious at runtime rather than at compile time. Fortunately, NetBeans 7.4 beta includes a hint about this potential issue as demonstrated in the next screen snapshot:

The above screen snapshot demonstrates NetBeans 7.4 beta warns of the condition of a return statement in a finally block by underlining it in yellow. It also shows that when one hovers over that yellow-underlined piece of code, the NetBeans editor hints "The 'return' statement in the 'finally' block discards unhandled exceptions."

One can also find out about this same condition by passing -Xlint:finally to the javac compiler. This can obviously be done on the command line as I previously blogged about in javac's -Xlint Options, but the next screen snapshot shows the same thing being done in NetBeans through specification of -Xlint:finally via project.properties setting javac.compilerargs=-Xlint:finally.

'throw' inside 'finally' block

Throwing an exception from inside of a finally block is generally a bad idea because it will hide any exception thrown in that finally block's associated try block. The next code listing shows an example of this bad form.


/**
* Demonstrate NetBeans hint warning that throwing an exception from a
* 'finally' block is a bad idea because it hides the original exception.
*/
public void demonstrateThrowFromFinallyBlock()
{
Integer twoDividedByZero = null;
try
{
twoDividedByZero = 2 / 0;
}
finally
{
if (twoDividedByZero == null)
{
throw new RuntimeException("Cannot calculate quotient with division.");
}
}
}

One might think that executing the above method would result in an ArithmeticException being thrown and might be a bit surprised when a more general (and parent) RuntimeException is thrown instead.

The next screen snapshot shows NetBeans 7.4 beta warning of this condition.

Hovering over the yellow underlined code leads to display of the NetBeans warning "The 'throw' statement in 'finally' block may hide the original exception." The above screen snapshot shows this to be exactly what happened in this case: the ArithmeticException and its stack trace were hidden by the RuntimeException thrown from the finally block.

If I comment out the line throwing the exception from the finally block, the original exception is available again. This is demonstrated in the next screen snapshot.

Enabling even -Xlint:all (or simply -Xlint) will not warn of the bad form of throwing an exception from a finally block. In this particular example, the -Xlint:devzero (or -Xlint:all or -Xlint) would have shown that a divide by zero occurs in the code, but in general there is no -Xlint warning to have javac warn you when throwing from a finally block is hiding an original exception. This makes this particular NetBeans hint particularly useful.

Conclusion

There are many nuances and corner cases in Java exception handling. NetBeans 7.4 beta introduces two new "probable bugs" hints that warn of dangerous practices in exception-related finally blocks. The two cases are particularly insidious because they are not generally caught by the compiler (although one can optionally be caught as a warning), will not be found until runtime, and are not likely to be discovered easily from reading and reviewing the code.

Thứ Tư, 28 tháng 8, 2013

Book Review: TestNG Beginner's Guide

I was happy to accept Packt Publishing's invitation to review the recently released (July 2013) book TestNG Beginner's Guide because I welcomed the opportunity to learn more about TestNG. I have read about and played a little bit with TestNG before, but the vast majority of my Java unit testing experience has been with JUnit.

Author Varun Menon opens TestNG Beginner's Guide with the following statement in the Preface, "Currently, TestNG is the most widely used testing framework in the software industry." This is definitely not what I've found in my experience where JUnit has been used far more than TestNG in the different Java projects that I've worked on. The Preface lists four things needed for getting most use out of TestNG Beginner's Guide: Java JDK, Eclipse, Linux or Windows, "basic knowledge of Java and testing."

Chapter 1: Getting Started

The first chapter of TestNG Beginner's Guide opens with a brief introduction to testing and automated testing. The chapter then introduces TestNG and provides a brief history and overview of the features of that open source unit testing framework. The chapter describes how to acquire TestNG via download (testng-6.8.jar in the book) and explains five ways it can be run: command line, Eclipse plugin, IntelliJ IDEA plugin, Ant, and Maven. The chapter spends multiple pages and several screen snapshots demonstrating configuration of TestNG within Eclipse via the plugin update site http://beust.com/eclipse. It demonstrates creating an Eclipse project, associating the TestNG library with the Eclipse project, writing a TestNG-based test class, and executing the TestNG test class in Eclipse. There are numerous screen snapshots in this Equinox-heavy portion of the chapter. Similar instructions on using TestNG with Eclipse can be found in the TestNG Eclipse documentation. The TestNG documentation includes a section on running TestNG from the command line.

Chapter 2: Understanding testng.xml

The second chapter of TestNG Beginner's Guide focuses on the testng.xml file, which it describes as "a configuration file for TestNG" that is "used to define test suites and tests in TestNG" and is "used to pass parameters to test methods." The chapter focuses on using testng.xml to specify test suites. It covers use of TestNG within Eclipse and from the command line. This chapter contains some of the concepts central to using TestNG. The examples shown are Eclipse-oriented, but XML snippets are shown as well, which is useful for those not using Eclipse. As testng.xml is a core part of TestNG, it is not surprising that Chapter 2 is a core part of TestNG Beginner's Guide.

Chapter 3: Annotations

The third chapter of TestNG Beginner's Guide, like the second chapter, focuses on a core part of TestNG. In this case, it's on TestNG's annotations. The chapter introduces Java annotations and standard Java annotations (@Override, @Deprecated, and @SuppressWarnings) before covering TestNG's specific annotations in a table with annotation name and brief description.

Chapter 3 of TestNG Beginner's Guide examines TestNG's annotations in more detail after the initial listing of them in the table with annotations names and descriptions. This more detailed examination includes code uses of these annotations. Annotations covered in this chapter include the @Test annotation (including specification of timeouts and expected exceptions), several of the wide variety of "before" and "after" TestNG annotations (such as @BeforeClass and @AfterMethod), @Optional, @Parameters, and @DataProvider. This, along with Chapter 2, is another "core" chapter of the book because annotations are core to TestNG. The third chapter also includes additional references to testng.xml.

Chapter 4: Groups

The fourth chapter of TestNG Beginner's Guide covers TestNG Groups. Coverage of test groups covers grouping of tests, running those groups of tests, specifying tests as parts of more than one group, using regular expressions to specify which groups to run, and grouping test groups within groups (metagroups). As with many of the other chapters, this chapter includes numerous screen snapshots showing Eclipse used with the different concepts, but code snippets are also included.

Chapter 5: Dependencies

TestNG Beginner's Guide's fifth chapter is on dependencies, a TestNG mechanism that allows tests to be executed in a particular order via expression of dependencies between tests and other tests or groups of tests. Screen snapshots of Eclipse and code listings are used to illustrate creating a dependency between one test on another, between one test on multiple other tests, between one test and a test in another class in the same inheritance hierarchy, and between a test and a group. The chapter also covers use of regular expressions with test dependencies and using XML to specify test dependencies.

Chapter 6: The Factory Annotation

The sixth chapter of TestNG Beginner's Guide introduces TestNG factories. The chapter explains the use of factories to "define and create tests dynamically at runtime." Through more screen snapshots of Eclipse and mode code listings, the chapter introduces the @Factory annotation and shows how it is used. This chapter also introduces the @DataProvider annotation and demonstrates using these two annotations together. The chapter also includes explanation of how @Factory and @DataProvider differ and when each is most appropriate.

Chapter 7: Parallelism

The seventh chapter of TestNG Beginner's Guide covers parallelism, or running tests with multiple threads. The chapter includes a brief section describing two reasons why being able to run tests in parallel can be advantageous.

Chapter 8: Using Build Tools

The eighth chapter of TestNG Beginner's Guide begins by outlining the "advantages of automating a build" and highlights Ant, Maven, and Gradle as the "major build tools that are being used by the software industry when it comes to Java or Java related languages." The rest of the chapter focuses on incorporating TestNG with Ant and with Maven using TestNG's custom Ant task and Maven plug-ins.

Chapter 9: Logging and Reports

Chapter 9 of TestNG Beginner's Guide introduces TestNG support for reporting and logging with an introductory paragraph on how reporting and logging are generally beneficial. The chapter introduces the interfaces ITestListener and IReporter and very briefly differentiates between these and where each is more appropriate. Like several other chapters, the ninth chapter mixes screen snapshots of Eclipse with code listings to demonstrate how to write a custom logger implementing the ITestListener interface, how to write a custom reporter implementing the IReporter interface, using TestNG-provided XML and HTML reports, and generating a JUnit HTML report with Ant. This chapter also introduces ReportNG, which is described on its website as "a simple HTML reporting plug-in for the TestNG unit-testing framework" that "is intended as a replacement for the default TestNG HTML report." This chapter also introduces Reporty-ng, formerly known as TestNG-XSLT.

Chapter 10: Creating a Test Suite through Code

The tenth chapter of TestNG Beginner's Guide covers "how to configure and run [a] test suite through code" to help "in configuring and running tests at runtime." In short, this chapter covers how to run TestNG tests programmatically rather than via specification in a testng.xml file. The chapter introduces and describes "the API classes" XmlSuite, XmlTest, XmlClass, XmlPackage, XmlDependencies, and a few more. The chapter adapts examples that were used earlier in the book to demonstrate using testng.xml for configuration but instead specify configuration in the code itself.

Chapter 11: Migrating from JUnit

The eleventh chapter of TestNG Beginner's Guide was one that I most looked forward to as I scanned the table of contents of the book. I find documentation on migration of one product (or version) to another product (or version) useful for two reasons. First, if I know the product or version being migrated from, I can better understand how the product or version being migrated to implements the same functionality. It helps me to learn the new product or version. Second, if I decide to adopt the new product or version, the migration guide is helpful in transitioning to that new product or version.

The section of the TestNG documentation called Migrating from JUnit states, "TestNG can automatically recognize and run JUnit tests, so you can use TestNG as a runner for all your existing tests and write new tests using TestNG." TestNG Beginner's Guide begins Chapter 11 with coverage of executing JUnit tests in TestNG. The chapter continues with a demonstration of running JUnit and TestNG tests together via testng.xml specification and then demonstrates "running JUnit tests along with TestNG [tests] through Ant."

Chapter 11 also covers true migration of JUnit-based unit tests to TestNG-based unit tests (as opposed to simply running JUnit-based tests in TestNG). This section includes an extremely handy table that compares the feature of TestNG to use compared to the feature of JUnit 3 and JUnit 4 to fulfill the same use case. This table is one of my favorite features of TestNG Beginner's Guide. The table validated my own internal mapping that I had been creating in my mind of TestNG concepts to JUnit concepts. The chapter also discusses how assert statements are handled differently in JUnit versus TestNG and this reminded me of why I prefer Hamcrest-based assertions with their high readability over straight JUnit assertions in which I must remember which of the two is an expected value and which is the actual value.

Chapter 12: Unit and Functional Testing

The final chapter of TestNG Beginner's Guide focuses on using TestNG for unit and functional testing. The chapter provides basic definitions of unit testing and functional testing before examining each approach in more detail via examples.

The unit testing section of Chapter 12 provides a table of assertions supported by TestNG and demonstrates use of an assertion in a code sample. That section also focuses on mocking with TestNG. Although this chapter specifically mentions jMock, Mockito, EasyMock, PowerMock, and JMockit as a "few of the mocking utilities," the chapter's focus is on jMock and Mockito.

After contrasting functional testing against unit testing, Chapter 12 includes a "list of functional testing automation tools that are available in the market" including Selenium, Sikuli, and SilkTest. Selenium is the product in the functional test coverage that gets the same focus that jMock and Mockito got in the unit test coverage.

The final paragraph of the Summary of Chapter 12 is also the summary paragraph for the entire book.

Overall Positives
  • For Beginners - As its title TestNG For Beginners correctly advertises, this book is aimed at beginners. I found my experience with JUnit to make it very easy to understand the concepts covered in this book, but I think most Java developers, even with less JUnit experience, would find this book highly approachable.
  • Screen snapshots and Images - TestNG Beginner's Guide features numerous screen snapshots that can be helpful in learning how to use TestNG, particularly in conjunction with the Eclipse plugin. The one downside is that many of the images are Eclipse-specific. This is a positive for Eclipse users, but may be a bit of a negative for users of other IDEs.
  • Code Listings - TestNG Beginner's Guide includes numerous code examples and listings. Because they are listed for nearly every covered topic, users of IDEs other than Eclipse should still be able to use this book.
Overall Negatives
  • Editing and Polish - One of the weaknesses of several (not all) of the Packt titles I have reviewed has been occasional convoluted sentence structure and weird grammar and incorrect spelling. This particular book has some strange grammar in a couple places as well as several spelling errors. Examples of spelling errors include @SupressWarnings (only one "p") and "TestNg" rather than "TestNG" on the same page 52. The good news is that these are mostly just minor distractions or annoyances and rarely take away from understanding of the meaning.
  • For Beginners - This is an advantage for new Java developers and developers new to unit testing, but is a bit of a disadvantage for more experienced developers (especially with JUnit). The book does a sound job of covering the most important features of TestNG, but there is very little coverage of why these features are useful. The simplicity and clarity of the examples comes at the price of the examples not providing very realistic ideas of how these TestNG features might be used in real code.
  • Eclipse-centric - The book provides enough code listings to largely overcome this limitation and this is not a limitation, of course, for Eclipse users.
Other Observations

The title says it all: TestNG Beginner's Guide is for those new to TestNG.

As already mentioned this book is targeted most closely at Eclipse users. That stated, I think developers with at least some Java experience will find it easy to pick up the concepts and even implement the code listings in their favorite IDE even when that IDE is not Eclipse. Complete code examples are typically provided and most of the many Eclipse screen snapshots are showing reported results which will be shown on the command line or in other IDEs.

The ordering of the chapters is not the same order I'd have chosen, but this is not a big deal. For the most part, one could read the chapters in the order one prefers or even skip chapters on subjects that are not of interest or which the reader is already familiar. The chapters rely slightly on each other, but for the most part could be read fairly independently of one another. There are references to earlier parts of the book in several chapters, but these references are often not necessary to understand the newly covered topic.

Most of the material covered in TestNG Beginner's Guide is covered online in TestNG documentation and in blog post. I have linked to specific sections or pages of these resources several times in my review of this book. Cédric Beust's blog is another obvious source of information on TestNG. The TestNG site includes the More TestNG Reading page with links to numerous additional online TestNG resources. Although there is little in TestNG Beginner's Guide that is not available online, this book provides organization for the introductory material and can provide context that is especially helpful when accessing seemingly unrelated blog postings.

TestNG Beginner's Guide is close to 250 pages of content plus more pages for table of contents, index, and so forth. Much of the space on these pages consists of code listings and screen snapshots, so the overall prose content is well below 250 pages. The examples are very simple, making it easy to focus on the TestNG feature being demonstrated, but also meaning that more subtle understanding of when certain features would be useful might be missed, especially by those not familiar with unit testing.

Conclusion

TestNG Beginner's Guide is squarely aimed at developers new to TestNG. Its twelve chapters cover the basics of TestNG and are approachable for anyone with some basic Java ability, but are especially easy to understand with some Java and JUnit experience. The book is probably too introductory for advanced TestNG users, but its title suggests that this is intentional. The only caveat I'd offer to a person new to TestNG who is trying to decide whether to obtain this book is to consider whether the book helps fill a need that is not covered adequately by the broad TestNG documentation or blog posts such as those by mkyong. I personally find some advantages to learning from books in conjunction with online resources, but I understand that this is a matter of taste.

Thứ Hai, 26 tháng 8, 2013

Is Java Riskier than C/C++?

The following is a contributed article from Jon Jarboe of Coverity:


Is Java Riskier than C?
Jon Jarboe
Senior Technical Manager, Coverity

Lately, I’ve heard a number of folks discussing whether Java development is riskier than development in C/C++ (from here on out, I’ll just refer to "C"). They’re not rehashing the age-old discussion of which language is best, but are wondering whether teams developing in Java have unique risks compared to teams developing in C. They are particularly interested to learn how projects can better understand and manage risk.

For purposes of this post, I’ll ignore sources of risk that span languages—things like social engineering and configuration/training problems, which are presumably constant. What follows is based on my own experience - biases and all - with the understanding that this isn't a numbers discussion.

To my shame, I initially thought the answer was obvious: Java was designed to address many of the most important pitfalls of C, so it must be safer. Hackers have been exploiting C vulnerabilities like out of range memory accesses and null pointer dereferences for decades, circumventing controls and interrupting business-critical—and in some cases, mission- and life-critical—functions. (Activist hacker Barnaby Jack was planning to disclose lethal, exploitable vulnerabilities in implantable medical devices before his recent, untimely passing)

Java eliminates many of these vulnerabilities entirely, providing internal protections that automatically enforce buffer bounds and intercept and pass null and invalid memory references to the application for graceful handling. Whereas C programs need to navigate a maze of APIs like POSIX and Windows for threading and concurrency management capabilities, Java provides language primitives to enable developers to consistently manage concurrency.

While C memory management is notoriously tricky, Java provides a garbage collector to make resource management almost foolproof. While C applications are compiled to have direct hardware and OS access, Java programs are run in a virtual machine sandbox that tries to prevent them from interacting with the rest of the system. Surely that means that Java is less risky.

Of course, we regularly hear about data exposures and web site attacks—areas where Java is very commonly used. In fact, the vast majority of security vulnerabilities, such as injections, cross-site scripting, and authentication/session management, originate in faulty code—meaning that Java applications can’t be immune to these security problems. There are plenty of other types of risk that originate in the application code, impacting things like availability, data integrity and performance. When it comes down to it, this question is more complex than I initially realized.

After taking a step back, I realized that my initial reaction was focused on the risk inherent in the runtime environment. Java improves upon the weaknesses of C, especially in preventing application users from being able to gain control of the machine(s) upon which the application runs. But gaining control of the machine is rarely the goal—it is often just a means to gain access to, or interrupt the flow of, data. Considering the relevance of the application vulnerabilities that obviously still exist, those improvements are apparently just a step in the right direction.

To understand the implications, maybe I should consider the bigger picture. General purpose programming languages like Java and C are by definition designed to apply to a wide variety of programming tasks. They provide the toolbox that enables developers to implement their applications. It is the developer’s responsibility to craft a good logical model for the application, and to correctly implement that model using the available tools. From that perspective, the "riskier" language might be the one where developers have limited ability to effectively manage that risk.

Both C and Java have robust tools to manage application risk—from feature-rich IDEs to sophisticated analysis and debugging tools to testing frameworks and high-quality reusable components. I don’t think that either language is at a disadvantage for managing risk, so maybe the language isn't the source of risk. Maybe it's actually the applications or the developers.

I guess we have answered the original question: neither language is riskier than the other. But I don’t think we’re done yet; there is still the interesting question of managing risk. I don’t think it’s particularly important to characterize the source of the risk further. Suffice it to say, much of it originates in source code, with the nature of the application generally defining the major types of risk.

So where does that leave us as developers?

Above all, deeply understand your toolbox. What are the strengths and weaknesses of your languages/environments of choice? Do they insulate you from system-level concerns? Are there performance tradeoffs? For each project you undertake, understand the risks you’re facing with the application. Do you need to worry about concurrency, data security and/or resource constraints?

Java has a garbage collector that will free certain resources sometime after your program finishes using them but that doesn't mean that you should be lazy. Not all resources are handled automatically, and it can take a significant amount of time for resources to become available for reuse—impacting application availability and performance. By preparing for the worst case, you can minimize the chance it will happen. Actively manage as many resources as you can, to lessen the load on the garbage collector and reduce the chance of availability and performance problems.

Concurrency is tricky, even when you have the luxury of language primitives. If you want to get it right, you need to understand your application’s behavior on a deep level and you need to understand the intricacies of the concurrency tools you are using. Even sophisticated analysis and debugging tools have their limits—just because the code is valid doesn't mean that it’s correctly implementing your requirements.

Once you understand the risks, see whether you can find existing components and frameworks that have proven themselves in similar applications—it is often much harder to invent a better wheel than we anticipate. After understanding the risks of your application and the strengths and weaknesses of your tools, you can start to match up tool strengths to application needs and find the best way forward.

Ultimately, the question of which language is best – or riskiest – is just a distraction. To understand and manage risk, you need to ensure that your developers understand the intricacies of their tools, that you have a solid plan for attacking the challenges presented by your application, and that you have sufficient internal controls to recognize when you are off course.


The article above was contributed by Jon Jarboe of Coverity. I have published this contributed article because I think it brings up some interesting points of discussion. No payment or remuneration was received for publishing this article.

Thứ Ba, 20 tháng 8, 2013

Ant Properties Nuances

Every once in a while, I'm reminded of a few subtle nuances of Ant properties that can, when forgotten, lead to confusion when dealing with Ant. In particular, the fact that Ant properties are generally immutable (not counting local properties as of Ant 1.8) and are set "permanently" upon their first setting can lead to slightly surprising results.

The properties section of the Ant Manual states, "Normally property values can not be changed, once a property is set, most tasks will not allow its value to be modified." The section of that manual on the Property task adds, "Properties are immutable: whoever sets a property first freezes it for the rest of the build; they are most definitely not variables."

The order of definition of properties influences their setting. In general, once a property is set, its value cannot be changed by a later attempt at redefinition in the same build file or in called build files. Furthermore, there are a set of properties that are already defined that generally cannot be redefined within an Ant build file. These include Java System properties and the built-in Ant properties.

Although definition of properties within an Ant build file cannot override the values of the default Ant built-in properties or the Java system properties, these values for these properties' names can generally be set with the -D option on the Ant launcher. However, a small number of these cannot be reset even with the -D option. For example, ant.file cannot be changed from the path and name of the Ant build file even when passed as a parameter via the -D option. Of course, it's probably just as well because there seems to be no good reason to pretend that the Ant build file is any other than what it really is.

To demonstrate the above "rules" of Ant property resolution, the following simple Ant build file can be used.

build.xml Displaying Properties in Ant

<project name="Project" default="showProperties" basedir=".">

<property environment="env"/>

<target name="showProperties">
<!-- Java System Properties -->
<echo message="java.home: ${java.home}" />
<echo message="user.home: ${user.home}" />
<!-- Custom Properties -->
<echo message="name.last: ${name.last}" />
<echo message="name.first: ${name.first}" />
<!-- Ant Built-in Properties -->
<echo message="ant.file: ${ant.file}" />
<echo message="ant.version: ${ant.version}" />
<echo message="ant.java.version: ${ant.java.version}" />
</target>

</project>

There are a couple of Java system properties, a couple of custom properties, and a few Ant built-in properties in this example. These allow me to easily demonstrate how properties can be overridden or not overridden. The next screen snapshot shows the "default" settings of the properties without being overridden. The two custom ones are not defined at all, but the others (Java system and Ant built-in properties) have values automatically set for the Ant build.

The next screen snapshot shows an attempt to supply the values for the properties used in the build by passing them in via the -D parameters. As the example shows, even the system properties and Ant built-in properties can be overridden with the -D property setting, but the ant.file property is not overridden.

A common way to specify properties used in an Ant file are to specify them within the Ant build file using the Property task. The next code listing adds internally defined properties to the file shown above.

build.xml Defining Properties Internally

<project name="Project" default="showProperties" basedir=".">

<property environment="env"/>
<property name="user.home" value="/bin" />
<property name="java.home" value="java" />
<property name="name.last" value="Flintstone" />
<property name="name.first" value="Fred" />
<property name="ant.file" value="text.txt" />
<property name="ant.version" value="1.8." />
<property name="ant.java.version" value="6" />

<target name="showProperties">
<!-- Java System Properties -->
<echo message="java.home: ${java.home}" />
<echo message="user.home: ${user.home}" />
<!-- Custom Properties -->
<echo message="name.last: ${name.last}" />
<echo message="name.first: ${name.first}" />
<!-- Ant Built-in Properties -->
<echo message="ant.file: ${ant.file}" />
<echo message="ant.version: ${ant.version}" />
<echo message="ant.java.version: ${ant.java.version}" />
</target>

</project>

The next screen snapshot shows running this Ant file without any properties provided with the -D arguments. Note that the only properties which have been successfully set by the internal specification are the custom properties. The Java system properties and built-in Ant properties are unaffected by the attempts to internally set the properties.

There are advantages to Ant's properties generally being immutable. However, one must be cautious when assuming just because a property is declared in a particular Ant build file (or in a property file referenced by that build file), that it is actually the value to which that property is set for the build. If the property has already been set elsewhere, the local attempt at redefining the property has no effect other than to falsely advertise a value for that property which does not actually apply.

Thứ Tư, 14 tháng 8, 2013

Searching JARs for String (Linux)

I recently thought about writing a Groovy script to search JARs for a specific string, but decided to first look for an alternative rather than writing a script. The alternative needed to be easy to use, freely available, and not bogged down with a load of dependencies. I was glad I looked first, because the Linux-based approach provided by "jan61" satisfied my need nicely. In this blog post, I look at that example more closely.

As documented on the LinuxQuestions.org thread searching contents of .class file within jar (for strings), a single line command in Linux nicely does the job of searching JARs recursively from a given directory for a given String. This search isn't searching for the names of the entries themselves in the JAR, but rather is searching the contents of each searchable file in the JAR. Here is that simple line (the token <stringWithOrWithoutSpacesToFind> represents the string to search for):

Linux Command to Search Contents of .jar Files for Specific String

find . -iname '*.jar' -printf "unzip -c %p | grep -q '<stringWithOrWithoutSpacesToFind>' && echo %p\n" | sh

I like to have this in script form (or as an alias) because that name is easier to remember than typing in that entire command each time. Here is an example script that could be used.

Linux Script Form of Above Command

printf "Searching JARs for string '${1}'...\n"
find . -iname '*.jar' -printf "unzip -c %p | grep -q '${1}' && echo %p\n" | sh

The two versions of the command shown immediately above will work as-is and the rest of this blog post focuses on how the command works. I start analyzing the command from the inside and move outward.

The Linux unzip command "list[s], test[s] and extract[s] compressed files in a ZIP archive." The -c passed to the unzip command "extract[s] files to stdout" and includes the name of the extracted files with that standard output. The %p is associated with the Linux find command. More specifically, %p is a directive to the -printf flag of the find command that directs it to include the found file's name.

Each found file is unzipped and its content directed to standard output where it is piped to a grep command to search for the provided text String. The provided -q parameter specifies "quiet" mode in which nothing is written to standard output and the grep exits immediately with zero status code upon detecting a match. The && symbols indicate that the echo command will be run to print out the file name with content matching the grep-ed for String if (and only when) the grep command returns a successful status (0).

All of the above are only executed against files with .jar extension thanks to the find . -iname '*.jar' command. The whole thing is piped to a shell.

Thanks to jan61 for the elegant Linux command covered in this post that makes it easy to search contents of files in JARs for a given string.