Tuesday, June 19, 2012

Software Architects Need Not Apply

I saw an online job posting several years ago that listed a set of desired software development and programming skills and concluded with the statement, "Architects Need Not Apply." Joe Winchester has written that Those Who Can, Code; Those Who Can't, Architect (beware an extremely obnoxious Flash-based popup) and has stated that part of his proposed Hippocratic Oath for Programmers would be to "swear that my desire to enter the computing profession is not to become an architect." Andriy Solovey has written the post Do We Need Software Architects? 10 Reasons Why Not and Sergey Mikhanov has proclaimed Why I don’t believe in software architects. More recent posts have talked of Frustration with the Role and Purpose of Architects on Software Projects and The frustrated architect. In this post, I look at some of the reasons software architects are often held in low esteem in the software development community.

I have been (and am) a software architect at times and a software developer at times. Often, I must move rapidly between the two roles. This has allowed me to see both sides of the issue and I believe that the best software architects are those who do architecture work, design work, and lower level implementation coding and testing.

In Chapter 5 ("The Second-System Effect") The Mythical Man-Month, Frederick P. Brooks, Jr., wrote of the qualities and characteristics of a successful architect. These are listed next:

  • An architect "suggests" ("not dictates") implementation because the programmer/coder/builder has the "inventive and creative responsibility."
  • An architect should have an idea of how to implement his or her architecture, but should be "prepared to accept any other way that meets the objectives as well."
  • An architect should be "ready to forego credit for suggested improvements."
  • An architect should "listen to the builder's suggestions for architecture improvements."
  • An architect should strive for work to be "spare and clean," avoiding "functional ornamentation" and "extrapolation of functions that are obviated by changes in assumptions and purposes."

Although the first edition of The Mythical Man-Month was published more than 35 years ago in 1975, violations of Brooks's suggestions for being a successful architect remain, in my opinion, the primary reason why software architecture as a discipline has earned some disrespect in the software development community.

One of the problems developers often have with software architects is the feeling that the software architect is micromanaging their technical decisions. As Brooks suggests, successful architects need to listen to the developers' alternative suggestions and recommendations for improvements. Indeed, in some cases, the open-minded architect might even be willing to go with a significant architectural change if the benefits outweigh the costs. In my opinion, good architects (like good software developers) should be willing to learn and even expect to learn from others (including developers).

A common complaint among software developers regarding architects is that architects are so high-level that they miss important details or ignore important concerns with their idealistic architectures. I have found that I'm a better architect when I have recently worked with low-level software implementation. The farther and longer removed I am from design and implementation, the less successful I can be in helping architect the best solutions. Software developers are more confident in the architect's vision when they know that the architect is capable of implementing the architecture himself or herself if needed. An architect needs to be working among the masses and not lounging in the ivory tower. Indeed, it would be nice if the title "software architect" was NOT frequently seen as an euphemism for "can no longer code."

The longer I work in the software development industry, the more convinced I am that "spare and clean" should be the hallmarks of all good designs and architectures. Modern software principles seem to support this. Concepts like Don't Repeat Yourself (DRY) and You Ain't Gonna Need It (YAGNI) have become popular for good reason.

Some software architects have an inflated opinion of their own value due to their title or other recognition. For these types, it is very difficult to follow Brooks's recommendation to "forego credit" for architecture and implementation improvements. Software developers are much more likely to embrace the architect who shares credit as appropriate and does not take credit for the developers' ideas and work.

I think there is a place for software architecture, but a portion of our fellow software architects have harmed the reputation of the discipline. Following Brooks's suggestions can begin to improve the reputation of software architects and their discipline, but, more importantly, can lead to better and more efficient software solutions.

Monday, June 18, 2012

Moving Beyond Core Hamcrest in JUnit

In the post Improving On assertEquals with JUnit and Hamcrest I introduced use of Hamcrest with JUnit. I then looked at JUnit's Built-in Hamcrest Core Matcher Support. In this post, I look at how to apply Hamcrest's non-core matchers with JUnit. These non-core matchers are NOT included with JUnit by default, but are available by including a Hamcrest JAR in the classpath.

Although JUnit's inclusion of Hamcrest core matchers makes them easier to use if one only wants to use the core matchers, this inclusion can make use of the non-core matchers more difficult and is a well-known issue.

Because the non-core Hamcrest matchers are not included with JUnit, the Hamcrest JAR needs to be downloaded. For my examples in this post, I am using hamcrest-all-1.2.jar.

The next screen snapshot indicates the problems with combining the hamcrest-all JAR with the normal JUnit library (JUnit 4.10 as provided by NetBeans 7.2 beta in my example). As the screen snapshot indicates, when the junit-4.10.jar is included in the NetBeans libraries BEFORE the hamcrest-all-1.2.jar, the previously working code (from my previous post) breaks. Both NetBeans and the command-line compiler show this breakage in this screen snapshot.

Switching the order of the test libraries so that the Hamcrest library is listed first and the JUnit JAR listed after it, makes the compiler break on the test code go away. This is shown in the next screen snapshot.

Although switching the order of the dependent libraries so that the Hamcrest JAR is included before the JUnit JAR does prevent the build problem, this is not typically a satisfactory approach. This approach is too fragile for long-term maintainability. Fortunately, there is a better approach that JUnit directly supports to deal with this issue.

A special Hamcrest-less JUnit JAR can be downloaded. The next screen snapshot shows the one I use in this example: junit-dep-4.10.jar. The -dep in the JAR name is the clue that it's Hamcrest-free. The notation next to the JAR on the download page (screen snapshot shown next) points this out as well ("Jar without hamcrest").

With the Hamcrest-free "dep" version of the JUnit JAR, I can include it in the test libraries at any point I like with relation to the Hamcrest JAR and will still be able to build the test code. This is a much more favorable approach than relying on a specific order of test libraries. The next image shows the screen snapshot of NetBeans and the command-line build being successful even with the JUnit JAR listed first.

With the appropriate libraries in use (JUnit-dep JAR and the Hamcrest "all" JAR), all of Hamcrest's matchers can be used with JUnit-based tests. Hamcrest provides numerous matchers beyond the core matches that are now bundled with JUnit. One way to get an idea of the additional matchers available is to look at the classes in the Hamcrest JAR. The following is output from running a jar tvf command against the Hamcrest JAR and removing many of the entries to leave some of the most interesting ones. The "core" matchers tend to be based on the classes in the "core" package and the non-core matchers tend to be based on the classes in all the other packages without "core" in their name.

  4029 Thu May 21 23:21:20 MDT 2009 org/hamcrest/core/AllOf.java
  3592 Thu May 21 23:21:20 MDT 2009 org/hamcrest/core/AnyOf.java
  1774 Thu May 21 23:21:20 MDT 2009 org/hamcrest/core/CombinableMatcher.java
  1754 Thu May 21 23:21:20 MDT 2009 org/hamcrest/core/DescribedAs.java
  1104 Thu May 21 23:21:20 MDT 2009 org/hamcrest/core/Every.java
  2088 Thu May 21 23:21:20 MDT 2009 org/hamcrest/core/Is.java
  1094 Thu May 21 23:21:20 MDT 2009 org/hamcrest/core/IsAnything.java
  2538 Thu May 21 23:21:20 MDT 2009 org/hamcrest/core/IsCollectionContaining.java
  1862 Thu May 21 23:21:20 MDT 2009 org/hamcrest/core/IsEqual.java
  2882 Thu May 21 23:21:20 MDT 2009 org/hamcrest/core/IsInstanceOf.java
  1175 Thu May 21 23:21:20 MDT 2009 org/hamcrest/core/IsNot.java
  1230 Thu May 21 23:21:20 MDT 2009 org/hamcrest/core/IsNull.java
   960 Thu May 21 23:21:20 MDT 2009 org/hamcrest/core/IsSame.java
   675 Thu May 21 23:21:20 MDT 2009 org/hamcrest/core/StringContains.java
   667 Thu May 21 23:21:20 MDT 2009 org/hamcrest/core/StringEndsWith.java
   678 Thu May 21 23:21:20 MDT 2009 org/hamcrest/core/StringStartsWith.java
   
  2557 Thu May 21 23:21:20 MDT 2009 org/hamcrest/collection/IsArray.java
  1805 Thu May 21 23:21:20 MDT 2009 org/hamcrest/collection/IsArrayContaining.java
  1883 Thu May 21 23:21:20 MDT 2009 org/hamcrest/collection/IsArrayContainingInAnyOrder.java
  1765 Thu May 21 23:21:20 MDT 2009 org/hamcrest/collection/IsArrayContainingInOrder.java
  1388 Thu May 21 23:21:20 MDT 2009 org/hamcrest/collection/IsArrayWithSize.java
  1296 Thu May 21 23:21:20 MDT 2009 org/hamcrest/collection/IsCollectionWithSize.java
   812 Thu May 21 23:21:20 MDT 2009 org/hamcrest/collection/IsEmptyCollection.java
   866 Thu May 21 23:21:20 MDT 2009 org/hamcrest/collection/IsEmptyIterable.java
  1086 Thu May 21 23:21:20 MDT 2009 org/hamcrest/collection/IsIn.java
  3426 Thu May 21 23:21:20 MDT 2009 org/hamcrest/collection/IsIterableContainingInAnyOrder.java
  3479 Thu May 21 23:21:20 MDT 2009 org/hamcrest/collection/IsIterableContainingInOrder.java
   993 Thu May 21 23:21:20 MDT 2009 org/hamcrest/collection/IsIterableWithSize.java
  1899 Thu May 21 23:21:20 MDT 2009 org/hamcrest/collection/IsMapContaining.java
  1493 Thu May 21 23:21:20 MDT 2009 org/hamcrest/collection/IsMapContainingKey.java
  1421 Thu May 21 23:21:20 MDT 2009 org/hamcrest/collection/IsMapContainingValue.java

  1380 Thu May 21 23:21:20 MDT 2009 org/hamcrest/number/IsCloseTo.java
  2878 Thu May 21 23:21:20 MDT 2009 org/hamcrest/number/OrderingComparison.java

  1082 Thu May 21 23:21:20 MDT 2009 org/hamcrest/object/HasToString.java
   918 Thu May 21 23:21:20 MDT 2009 org/hamcrest/object/IsCompatibleType.java
  2080 Thu May 21 23:21:20 MDT 2009 org/hamcrest/object/IsEventFrom.java

  1164 Thu May 21 23:21:20 MDT 2009 org/hamcrest/text/IsEmptyString.java
  1389 Thu May 21 23:21:20 MDT 2009 org/hamcrest/text/IsEqualIgnoringCase.java
  2058 Thu May 21 23:21:20 MDT 2009 org/hamcrest/text/IsEqualIgnoringWhiteSpace.java
  1300 Thu May 21 23:21:20 MDT 2009 org/hamcrest/text/StringContainsInOrder.java

  4296 Thu May 21 23:21:20 MDT 2009 org/hamcrest/xml/HasXPath.java

JUnit's providing of a JAR without Hamcrest automatically built in (the "dep" JAR) allows developers to more carefully building up their classpaths if Hamcrest matchers above and beyond the "core" matchers are desired for use with JUnit.

Wednesday, June 13, 2012

JavaOne 2012 Content Catalog Available

It appears that a version of the JavaOne 2012 Content Catalog is available from the JavaOne site under Tools | Content Catalog. In this post, I look at a subset of the presentations described in this Content Catalog that appear interesting to me.

Core Java
  • Dynamic Class Reloading in the Wild with Javeleon (CON3160)
  • Why Should I Switch to Java SE 7? (CON7357)
  • Lambda: A Peek Under the Hood (CON6080)
  • The Road to Lambda (CON4862)
  • Jump-Starting Lambda Programming (CON5089)
  • Why There’s No Future in Java Futures (CON6385)
  • Uncovering Hidden Power Tools in the JDK (CON7059) [Neo Technology]
  • The Good, Bad, and Ugly of Java Generics (CON3468)
  • Advanced JVM Tuning (CON7236)
  • Mastering Java Deployment Skills (CON7797)
  • Are Your Garbage Collection Logs Speaking to You? (CON5405)
  • JMX: Much More Than Just Application Monitoring (CON4863)
  • Concurrency Without Pain in Pure Java (CON3454) [Akka]
  • Code Inspection with the javac (TUT4285)
Java Virtual Machine
  • JVM JIT for Dummies (CON7263)
  • From Java Code to Java Heap: Understanding the Memory Usage of Your Application (CON5135)
JVM Languages
  • Polyglot for Dummies (CON6575)
  • Type-Safe, Efficient, Low-Level Programming for the JVM (CON6037)
  • The Groovy Ecosystem (CON5100)
  • Design Patterns in Groovy (CON3469)
  • What’s New in Groovy 2.0? (CON6505)
  • What’s New in Grails 2.0? (CON7945)
  • Griffon, Up Close and Personal (CON5106)
  • Kotlin: Practical Aspects of JVM Language Implementation (CON5759)
  • Introduction to Ceylon (CON4025)
  • Design Patterns in Modern JVM Languages (CON3455)
  • What’s New in Scala 2.10 (CON6338)
  • What Is the Best Way to Embed Your Scripting Language in Java? (CON3978)
JavaFX
  • What’s New in JavaFX (CON4616)
  • Building Amazing Applications with JavaFX (CON4606)
  • JavaFX Graphics Tips and Tricks (CON6784)
  • Moving to the Client: JavaFX and HTML5 (CON3362)
  • Visualizing the JVM Runtime Environment with JavaFX (CON6265)
  • GroovyFX: Making JavaFX Groovy (CON2813)
  • The Ins and Outs of Text for JavaFX: The Graphic Details (CON3138)
  • Audio and Video Processing in JavaFX (CON7146)
  • JavaFX and Scala, Like Milk and Cookies (CON5329)
  • Scala, JavaFX, Java EE 7, and Enterprise Integration (CON4648)
  • Contemporary User Interface Design Patterns in JavaFX 2.2 (CON4643)
  • JavaFX Meets Metro (CON4996)
  • New Image Operations in JavaFX (CON4440)
  • Do It Yourself: Custom JavaFX Controls (CON2425)
  • JavaFX CSS Is Awesome (CON6419)
  • A Tour of JavaFX Scene Builder (CON4348)
  • JavaFX Mashups (CON6224)
Java EE
  • 50 Tips in 50 Minutes for GlassFish Fans (CON4701)
  • Tooling Support for Enterprise Development (CON5247)
  • Tools for Java EE 7: Evolution or Revolution? (BOF3967)
  • Enterprise JavaBeans Today and Tomorrow (CON4654)
  • Unlocking the Java EE 6 Platform (CON2987)
  • What’s New in Servlet 3.1: An Overview (CON6793)
HTTP / REST / JSON
  • Future HttpClient: A Sneak Peek into a New HttpClient API (CON6789)
  • How RESTful Is Your REST? (CON7573)
  • Effective HATEOAS with JAX-RS (CON3383)
  • JSR 353: Java API for JSON Processing (CON3566)
NoSQL
    What’s What in NoSQL? (CON7065)
  • The Rise of NoSQL and Polyglot Persistence (BOF8049)
Play Framework
  • Introduction to the Play Framework (CON3845)
  • Modern Java Web Development with Play Framework 2.0 (CON6008)
General Software Development
  • Modern Software Development Antipatterns (CON6152)
  • The Social Developer (BOF2717)

Tuesday, June 12, 2012

Quickly Viewing Oracle Database Constraints

When I am working with an Oracle database, I still find myself using SQL*Plus for many quick and dirty database queries. In particular, I often look up constraints in SQL*Plus. In this post, I look at the Oracle database views and queries that I use most to get an idea what constraints I am dealing with.

I have found the two most important views for determining basic database constraints are ALL_CONSTRAINTS (USER_CONSTRAINTS) and ALL_CONS_COLUMNS (or USER_CONS_COLUMNS). In this post, I look at some queries I like to use that take advantage of these views from the Oracle Data Dictionary.

The ALL_CONSTRAINTS view is great for finding basic constraint details. The next SQL*Plus snippet demonstrates this in use.

displayConstraintInfo.sql
set linesize 180
set verify off
accept constraintName prompt "Constraint Name: "
SELECT constraint_name, constraint_type, r_constraint_name, table_name,
       search_condition
  FROM all_constraints
 WHERE constraint_name = '&constraintName';

The above snippet will prompt for a constraint name and then provide some fundamental characteristics of that constraint provided by the ALL_CONSTRAINTS view. One of these characteristics is CONSTRAINT_TYPE, which is one of the following values: 'C' (Check Constraint), 'P' (Primary Key), 'R' (Referential/Foreign Key), 'U' (Unique), 'V' (with check option on a view), 'O' (with read only on a view). The above query requires one to know the constraint name. The next query will show similar information for constraints on a given table.

displayConstraintsOnTable.sql
set linesize 180
set verify off
accept tableName prompt "Table Name: "
SELECT constraint_name, constraint_type, r_constraint_name, table_name,
       search_condition
  FROM all_constraints
 WHERE table_name = '&tableName';

The above query provides the constraints on a given table, but it is often useful to know which columns in particular on the table have constraints. This is easily done by joining the ALL_CONS_COLUMNS view to the ALL_CONSTRAINTS view.

displayConstraintsOnTableColumns.sql
set linesize 180
set verify off
accept tableName prompt "Table Name: "
SELECT c.constraint_name, c.constraint_type, c.r_constraint_name,
       c.table_name, cc.column_name, cc.position, c.search_condition
  FROM all_constraints c, all_cons_columns cc
 WHERE c.table_name = '&tableName'
   AND c.constraint_name = cc.constraint_name;

Other useful queries using these two constraints-related views are those that provide information on referential integrity constraints (CONSTRAINT_TYPE of R). In particular, the new two simple queries show the constraints for a given table that are foreign key constraints and which primary key constraints they depend on. The scripts only differ in substance in which version of the table_name is provided to the script (the primary or the referencing table). The majority of these scripts are exactly the same other than the comment, the prompt for the table name, and the all_constraints.table_name that is joined to the provided table name. I also use the UPPER() function in this example so that the input table_name could be provided in any case. Because I always have my tables in all uppercase, this will always work for me. Anyone who uses case sensitivity with their table names should not do this. I could have used UPPER() in my above examples as well.

displayForeignKeyConstraintsForPrimaryTable.sql
-- displayForeignKeyConstraintsForPrimaryTable.sql
--
-- Display the foreign key dependencies on a provided
-- PRIMARY table. In other words, show tables and their
-- foreign key constraints that reference the table whose
-- name is provided to the script.
--
set linesize 180
set verify off
column "PRIMARY COLUMN" format a25
accept tableName prompt "PRIMARY Table Name: "
SELECT cf.table_name "FK TABLE", 
       cf.constraint_name "FOREIGN KEY",
       cp.constraint_name "DEPENDS ON",
       cp.table_name "PK TABLE",
       ccp.column_name "PRIMARY COLUMN",
       ccp.position
  FROM all_constraints cp, all_cons_columns ccp, all_constraints cf
 WHERE cp.table_name = UPPER('&tableName')
   AND cp.constraint_name = ccp.constraint_name
   AND cf.r_constraint_name = cp.constraint_name
   AND cf.r_constraint_name = ccp.constraint_name;
displayForeignKeyConstraintsForReferencingTable.sql
-- displayForeignKeyConstraintsForReferencingTable.sql
--
-- Display the foreign key dependencies of a provided
-- table on other tables. In other words, show tables
-- upon which the provided table has foreign key
-- constraints.
--
set linesize 180
set verify off
column "REFERENCING COLUMN" format a25
accept tableName prompt "REFERENCING Table Name: "
SELECT cf.table_name "FK TABLE", 
       cf.constraint_name "FOREIGN KEY",
       cp.constraint_name "DEPENDS ON",
       cp.table_name "PK TABLE",
       ccp.column_name "PRIMARY COLUMN",
       ccp.position
  FROM all_constraints cp, all_cons_columns ccp, all_constraints cf
 WHERE cf.table_name = UPPER('&tableName')
   AND cp.constraint_name = ccp.constraint_name
   AND cf.r_constraint_name = cp.constraint_name
   AND cf.r_constraint_name = ccp.constraint_name;

In this post I've summarized some of the useful queries one can construct from the Oracle Data Dictionary views ALL_CONSTRAINTS and ALL_USER_CONS_COLUMNS.

Friday, June 8, 2012

Early JavaOne 2012 Abstract Acceptances

An early look at the types of sessions we can expect at JavaOne 2012 is now available with news getting out about which abstracts have been accepted and which have been declined. In this post, I look at some of the early announcements from people who have reported their abstracts being accepted. Twitter #JavaOne is one of the best sources for early information on accepted (and declined) JavaOne presentations and much of the early details are available there.

Mobile development seems to be a big theme for JavaOne 20212. @MichaelSamarin announced that "Java for Mobile Devices: New Horizons with Fantastic New Devices" has been accepted. Jay Balunas announced acceptance of "Front-to-Back Security for Mobile, HTML5, and Java EE Applications." Vinicius tweeted that his session "about using your old Java ME phone to build robots and cool hacking" was accepted.

Adam Bien reports on four Java EE-related sessions accepted for JavaOne 2012: "Interactive On-Stage Java EE Overengineering," "Stress-Testing Java EE 6 Applications Without Stress," "Building Serious JavaFX 2 Applications," and "Java EE 6/7: The Lean Parts." Andrew Lee Rubinger will be presenting two sessions on Java EE. Lincoln Baxter III will be presenting on JBossForge. Marc Teutelink has announced acceptance of "Enterprise Search in Action."

Mohamed Taman writes that two Java SE 7/NIO presentations and a JavaFX presentation have been accepted. Andres Almiray and Peter Pilgrim have announced the selection of three presentations on JavaFX and rich clients.

Marcus Lagergren will be speaking on "dynamic languages on the JVM" and promises the talk to be advanced.

The Java REST framework Forest will be the subject of a presentation at JavaOne 2012. A session on Eclipse DBWS will be presented by Lonneke Dikmans. Scala and Play fans will be pleased to hear that the abstract "Modern Java Web Development with Play Framework 2.0" was accepted.

At JavaOne 2011, I attended several sessions related to Java performance and Java command-line options. Staffan Larsen reports that "Diagnosing Your Application on the JVM" has been accepted for JavaOne 2012.

Mark Stephens has blogged about the BOF "Lessons Learned in Writing a PDF-to-JavaFX Converter for NetBeans" being accepted. Cross-build injection attacks is the subject of another accepted JavaOne 2012 abstract.

Of course, you cannot have a software development conference in 2012 without talk of the cloud and it has been announced that there will be a session "How we took our server-side application to the Cloud and liked what we got."

With only a small subset of JavaOne 2012 acceptances being publicly announced at this time, there is already a wide variety of interesting topics available.

Monday, June 4, 2012

Recent Software Development Posts of Interest - Early June 2012

There has recently been a large number of posts on some of my favorite topics and I summarize and reference a few of them here.

Why Developers Should Blog

I devoted a post to why I believe more software developers should write blogs. Ron Gross's post Why you should write a blog post today provides five reasons to write technical blog posts and contrasts blogs to other social media to demonstrate technical memento advantages of blogs.

NetBeans 7.2 Search Capability

There has been significant coverage of NetBeans 7.2 beta in recent weeks. Much of the focus has been on its improved performance, its greater helpfulness and its TestNG support. Geertjan Wielenga focuses on improved searching capability in NetBeans 7.2 beta in his post Beefed Up Code Navigation Tools in NetBeans IDE 7.2.

Running Common Java Development Tools with Ant

Modern Java IDEs often make it easy to integrate Java tools. An example is the NetBeans SQE plugin. However, not all Java development and execution necessarily occurs in the IDE. In addition, some projects may use more than one IDE. In such cases, command-line approaches have their advantages. These can be even easier to use when run as Ant targets. The post How to run Findbugs, Pmd, Checkstyle, JUnit and Cobertrua with an Ant Build-Script? covers using Ant to run popular Java development tools FindBugs, PMD, Checkstyle, JUnit, and Cobertura.

Upgrading Gradle

I think that Gradle has a lot of potential for being a very popular build tool if it can gain enough early traction. The post Upgrading Gradle demonstrates how easy it is to upgrade one's Gradle installation ("It’s basically the same as upgrading ant.").

SVG, FXML, and NetBeans

The post SVG to FXML using NetBeans comprehensively covers issues related to transforming SVG to FXML and ends with a link to another post showing how to use NetBeans to demonstrate the transformation.

Conclusion

There have been numerous posts in recent weeks on some of my favorite topics: NetBeans, blogging, Gradle, and JavaFX. This post has referenced a sample of these posts.