Java EE Architecture & Development

December 16, 2009

Installing Squid 3.0 on Fredora 11

Filed under: Fedora — Tags: , , , , — Jonathan Wright @ 2:41 pm
  1. Install Squid in the normal fashion using yum or System -> Administration -> Add/Remove Software.
  2. Open the Squid configuration file by executing the following command:
    sudo gedit /etc/squid/squid.conf
  3. Change the value of the error_directory property so that it points to an actual directory. For example:
    error_directory /usr/share/squid/errors/English

    As opposed to

    error_directory /usr/share/squid/errors/en

    which didn’t exist on my system after the install had completed.

  4. If your current SELinux enforcing mode is set to "Enforcing" you’ll also need to perform the following steps.
  5. Create the following Type Enforcement file (the remaining steps assume the file name local.te):
    module local 1.0;
    
    require {
    	type var_run_t;
    	type unconfined_t;
    	type squid_t;
    	class file {open read getattr};
    	class process signal;
    }
    
    #============= squid_t ==============
    allow squid_t var_run_t:file {open read getattr};
    allow squid_t unconfined_t:process signal;

    N.B. The following steps will overwrite any existing module with the same name. To check if you already have a policy module called local go to System -> Administration -> SELinux Management, select "Policy Module" from the left-hand menu and enter "local" into the filter field. If you’ve already got a module called local simply edit the Type Enforcement file accordingly. For example:

    module mysquid 1.0;
  6. Edit accordingly, then execute the following script:
    dir=<your-dir-path>;
    sudo checkmodule -M -m -o $dir/local.mod $dir/local.te;
    sudo semodule_package -o $dir/local.pp -m $dir/local.mod;
    sudo semodule -i $dir/local.pp;

    N.B. The checkmodule command takes the Type Enforcement file, local.te, created in step 5 as its input.

  7. Got to System -> Administration -> Services. Start Squid.
  8. Cleanup any unwanted files created in steps 5 and 6.

December 4, 2009

Unit Testing HTTPS Clients with a Self-signed Certificate

Filed under: Java EE Development — Tags: , , , , , , , — Jonathan Wright @ 7:11 pm

Overview

A quick and easy way to eliminate javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target without making dangerous changes to your default trust store.

Steps

  1. Create a new keystore and associated key entry by executing the following command (N.B. The password values for the -keypass and -storepass options must be identical for Tomcat to work):
    keytool -genkey -alias tomcat -keyalg RSA -keypass <password> -keystore <user-home>/tomcat.jks -storepass <password>
    
  2. Enter and confirm your details.
  3. Uncomment the “SSL HTTP/1.1 Connector” entry in $CATALINA_BASE/conf/server.xml.
  4. Add keystoreFile and keystorePass attributes with the appropriate values. The result should now resemble the following:
    <!-- Define a SSL HTTP/1.1 Connector on port 8443
    	This connector uses the JSSE configuration, when using APR, the
    	connector should be using the OpenSSL style configuration
    	described in the APR documentation -->
    
    <Connector port="8443" protocol="HTTP/1.1" SSLEnabled="true"
    	maxThreads="150" scheme="https" secure="true"
    	keystoreFile="${user.home}/tomcat.jks" keystorePass="<password>"
    	clientAuth="false" sslProtocol="TLS" />
    
  5. Restart Tomcat and deploy your HTTPS constrained resources.
  6. Add a @BeforeClass method to any tests generating HTTPS requests. Use this method to set the javax.net.ssl.trustStore and javax.net.ssl.trustStorePassword system properties. For example:
    @BeforeClass
    public static void setUp() {
    	System.setProperty("javax.net.ssl.trustStore", "<user-home>/tomcat.jks");
    	System.setProperty("javax.net.ssl.trustStorePassword", "<password>");
    }
    
  7. JSSE now uses the new keystore created in steps 1 and 2 as opposed to the default, <java-home>/jre/lib/security/cacerts, trust store.

December 3, 2009

Scraping Sun Microsystems’ CertManager

Filed under: Uncategorized — Tags: , , , , , — Jonathan Wright @ 1:59 pm

Waiting for SCJD or SCEA results can be a bit of a pain. The lucky amongst you may get them in a couple of weeks. On the other hand, you could face a wait of up to six weeks.

To make life a little easier I decided to cobble together an HTML scraper to automate the checking process.

Figure 1. Screenshot

Although there are no binaries at this point in time, you can checkout the source code from SourceForge. For SVN details click the Develop tab.

Usage

According to the CertManager Test History page "tests are imported during regular business hours (GMT -07:00)".

Extending it

Adding your own service listener should be a pretty straightforward task: simply implement PropertyChangeListener and register with the service. As an example; if you live in a timezone other than GMT -07:00, and want to get notified ASAP, you could implement a listener to send an email, or SMS, once the specified test result has been found.

September 22, 2009

Rational Software Architect – Nested Node Instances

Section 10.3.7, Device (from Nodes), in the UML 2.2 specification contains the following deployment diagram (see page 206).

Figure 1 – Notation for a Device

Notation for a Device

Clearly, all the nodes in this diagram are instances. With this in mind, let’s try and recreate a similar diagram using Rational Software Architect 7.5.

Creating the AppServer and J2EEServer elements is pretty straightforward. A graphical representation of the model looks something like the following. In the example below I’ve added some attributes to the AppServer device to highlight the fact it’s an element specification, not an instance.

Figure 2 – Deployment Model

Deployment Model

If you selected the "Blank Deployment Package" template and default model capabilities in the model creation wizard, the ability to add node instances will be disabled. To remedy this you need to select the capabilities tab in the model properties panel and select the "UML Specific Instance Type 1" and "UML Specific Instance Type 2" options.

Figure 3 – Enabling Node Instances

Enabling Node Instances

Once this is done you can starting adding node instances to your deployment diagram. For example.

Figure 4 – Deployment Diagram

Deployment Diagram

The problems arise when you try and add nested nodes to the diagram because, basically, you can’t. As the following figure shows, the properties panel appearance tab options for showing textual and/or graphical nested node compartments are absent for node instances.

Figure 5 – Node Instance Properties

Node Instance Properties

Unfortunately, the help documentation is totally unhelpful as it contains the following section

Nesting nodes inside other nodes

In UML modelling, you can nest nodes within nodes to represent the hardware and software components in a system that contains other components.

A diagram must be open in the diagram editor, and the diagram must contain at least two nodes. The Nested Nodes compartment of the container node must be visible.

To nest a node in another node, in the diagram editor, click one node and drag it into the Nested Node compartment of another node.

As the following figure illustrates, a node named Node2 is displayed in the Nested Nodes Textual and Nested Nodes Graphical compartments of another node, named Node1.

Figure 6 – Rational Software Architect Help

Figure from Rational Software Architect Help

What they fail to mention is that none of this applies to node instances. I raised this with Rational Support and after a month’s deliberation they finally confirmed that nested node instances are not currently supported.

September 10, 2009

Rational Software Architect – Java to UML Transformations

Over the past few weeks I’ve been evaluating IBM’s Rational Software Architect (RSA) for WebSphere 7.5 . Whilst RSA is an incredibly powerful piece of software, there are a number of features that are conspicuous by their absence. Perhaps the most prominent of these is the inability of the Java to UML transformation to generate relationships other than Generalisation or Realisation. For example, it won’t generate Association or Usage elements. This makes it pretty useless when it comes to visualising the structure of existing code

You could argue that RSA’s raison d’etre is not the reverse engineering of UML models from Java code, but rather the architecture and development of new applications. This is true, but it misses the point as a number of RSA’s design contract management protocols (notably, "Reconciled Modelling" and "Conceptual Models Drive Development") rely on the reverse transformation of Java code.

According to Rational Support this issue has been logged as a request for enhancement, but when or if it makes it into a future release is anyone’s guess. In the meantime here’s an illustration of the problem.

Step 1 – Create a simple UML model with a composite aggregation navigable from both ends

Figure 1. Class diagram view

Class Diagram 1

Figure 2. Project explorer view

Model 1

Step 2 – Run a reconciled UML to Java transformation on the model

This produces the following java classes (minus the auto-generated comments):

Whole.java

package uml;

import java.util.Set;

public class Whole {

	private Set part;
}

Part.java

package uml;

public class Part {

	private Whole whole;
}

Step 3 – Comment out both private fields in the generated source and run the reverse transformation

As you’d expect, the composite aggregation relationship has now been deleted from the model.

Figure 3. Class diagram view

Class Diagram 2

Figure 4. Project explorer view

Model 2

Step 4 – Uncomment both fields and rerun the reverse transformation

Unfortunately this doesn’t produce the results you’d expect. Rather than explicitly creating an Association element in the UML model, the composite aggregation becomes implicit via the generated attributes for each class. By itself this isn’t a major drama, but it does introduce an inconsistency in your model if you have existing relationships that are modelled explicitly, as was originally the case. To visualise the recreated association you have to filter the attributes to "show as association". However, this only produces uni-directional associations which results in difficult to read diagrams full of unnecessary clutter and noise. The only workaround is to manually recreate the association in the model, which at best wastes time and at worst introduces errors.

Figure 4. Class diagram view (show as attribute)

Class Diagram 3

Figure 4. Class diagram view (show as association)

Class Diagram 4

Figure 5. Project explorer view

Model 3

September 3, 2009

The Kernel Package: Basic UML to Java

Filed under: UML — Tags: , , , , , — Jonathan Wright @ 1:10 pm

At first glance the UML specification can seem a little daunting. Java developers know all about classes, interfaces, and inheritance, but how do these concepts map to the UML? In Java terms, what are Elements, NamedElements, RedefinableElements, Classifiers, Features, etc.? This post aims to bridge the representational gap between some of the key UML Kernel package elements and the corresponding concepts that manifest themselves in a simple Java class.

The following code depicts a simple interface, abstract superclass, concrete subclass hierarchy in Java.

Operation.java

package math;

public interface Operation {
  double perform();
}

BinaryOperation.java

package math;

public abstract class BinaryOperation implements Operation {
  
  protected final double operand1;
  protected final double operand2;

  protected BinaryOperation(final double operand1, final double operand2) {
    this.operand1 = operand1;
    this.operand2 = operand2;
  }

  public abstract double perform();  
}

Addition.java

package math;

public final class Addition extends BinaryOperation {

  public Addition(final double operand1, final double operand2) {
    super(operand1, operand2);
  }

  public double perform() {
    return operand1 + operand2;
  }
}

Class Diagram

UML model class diagram

N.B. The remainder of this post assumes the elements are contained in model called "model".

Element

An element is a constituent of a model. The interface, classes, member variables, operations, parameters, etc. in the example code above are all elements. Elements can own other elements and have comments attached to them. The hierarchy of elements (listed outermost first) for the operand1 parameter of the BinaryOperation constructor is as follows:

  • <package> model
  • <package> math
  • <class> BinaryOperation
  • <operation> BinaryOperation
  • <parameter> operand1

NamedElement (extends Element)

A named element has a simple name, a qualified name, and an optional visibility. The perform method in the Operation interface has following named element attributes:

  • name = perform
  • qualifiedName = model::math::Operation::perform
  • visibility = public

PackageableElement (extends NamedElement)

The only difference between named elements and packageable elements is the requirement that packageable elements always have a visibility. For named elements the visibility attribute is optional. Classes and interfaces are both packageable elements.

Namespace (extends NamedElement)

A namespace is simply a container for named elements. In the code example, the following elements are also namespaces:

  • <package> math
  • <interface> Operation
  • <class> BinaryOperation
  • <class> Addition
  • <operation> perform
  • <operation> BinaryOperation
  • <operation> Addition

This is all pretty straightforward. Packages contain named elements such as sub-packages, classes, and interfaces; classes contain named member variables and methods, and operations contain named parameters.

Package (extends PackageableElement, Namespace)

A package is essentially a namespace with the additional constraint that its directly owned elements must also be packageable elements. Because a package is itself a packageable element it can be nested within other packages. In the example the package math contains the packageable elements <interface> Operation, <class> BinaryOperation, and <class> Addition.

RedefinableElement (extends NamedElement)

A redefinable element is an element that has the capacity to be overridden. It adds a single boolean attribute, isLeaf. Setting isLeaf to true is equivalent to applying the final modifier, as is the case in the Addition class.

Type (extends PackageableElement)

A type constrains the values that may be represented by a typed element. In Java terms this equates to a primitive type, interface, or class.

TypedElement (extends NamedElement)

A typed element extends a named element by adding an optional association to a type. For example, the operand1 instance member variable in the BinaryOperation class is a typed element with an association to the type double<PrimitiveType>. The value it represents must be no less than java.lang.Double.MIN_VALUE and no greater than java.lang.Double.MAX_VALUE. Similarly, if we declared a variable of type Operation in some client object it would be constrained to referencing the set of Objects that directly or indirectly realise the Operation interface. (See StructuralFeature below).

Classifier (extends Namespace, RedefinableElement, Type)

A classifier is a namespace that can contain features (see Feature below). Classifiers also have the capacity to own generalisations, which in effect means they can extend other classifiers. In the example code, Addition owns a Generalisation relationship that targets BinaryOperation. Classifier adds a single boolean attribute, isAbstract. This is semantically equivalent to the abstract modifier in Java. The value for the BinaryOperation classifier is true.

Feature (extends RedefinableElement)

Features define the behavioural or structural characteristics of classifier instances. They can also be static, in which case they define a feature of the classifier itself. The following elements, owned by the BinaryOperation classifier, are all examples of non-static features:

  • <property> operand1
  • <property> operand2
  • <operation> BinaryOperation
  • <operation> perform

StructuralFeature (extends Feature, MultiplicityElement, TypedElement)

The structure of a classifier is defined by its structural features. In Java, a structural feature is an interface constant or a class member variable (static or non-static). StructuralFeature defines a single boolean attribute, isReadOnly. Supplying a value of true is equivalent to applying the final modifier to a Java member variable. In the case of the BinaryOperation classifier the following elements are structural features:

  • <property> operand1
  • <property> operand2

BehaviouralFeature (extends Feature, Namespace)

By defining a behavioural feature, a Classifier states that it will respond to a designated request by invoking a behaviour. A behavioural feature is also a Namespace in the sense that it may own zero or more named parameters. BehaviouralFeature defines an association to zero or more Types representing the exceptions that may be raised during its execution.

Interface (extends Classifier)

The UML concept of an interface and the Java concept of an interface are pretty much identical. As with Java, all the features of a UML interface must have public visibility.

Class (extends Classifier)

As in Java, a UML class defines a set of objects that share the same specification of features, constraints, and semantics. A class owns a set of attributes and a set of operations. These are represented by instances of Property and Operation respectively.

MultiplicityElement, Property, Operation, Parameter, and other elements

Like Interface and Class, many of these elements are self explanatory. The aim of this post has been to focus on the more abstract elements of the Kernel package, so I won’t list their details here. If you’d like further information, please consult the UML specification.

August 12, 2009

JMS Patterns – Generic Message Handler

Filed under: Java EE Development — Tags: , , , , , , — Jonathan Wright @ 7:47 pm

Refactoring some JMS code got me thinking about message validation, type casting, and payload extraction. Having recently read Adam Bien’s excellent book “Real World Java EE Patterns – Rethinking Best Practices” I decided to implement the “Payload Extractor” pattern. However, I couldn’t help feeling there’s something not quite right about it. In particular I didn’t like having to implement an empty onMessage method, and some of the reflection overhead seemed unnecessary. Don’t get me wrong; EJB 3 interceptors are great for extracting cross-cutting concerns, but in this case the implementation of the bean is entirely dependent upon the presence of the interceptor.

The alternative I came up with uses a generic abstract superclass and the Template Method pattern. In my opinion, this approach has several advantages:

  • The solution handles both message type checking and payload extraction.
  • Less reflective code. Determining the expected type happens once during object construction. Message type checking and payload extraction use simple instanceof and isAssignableFrom checks.
  • There’s no empty onMessage method in the concrete subclass.
  • Concrete subclasses can also access the dead letter handler if the need arises.
  • More robust compile time checks. The generic abstract method forces you to implement a correctly typed consume method. In the Payload Extractor pattern this check doesn’t happen until runtime, at which point any coding errors will simply masquerade as invalid messages.

You could argue that using an interceptor frees you from having to use inheritance. However, in this case, I don’t see this as a problem. It’s generally accepted best practice to not place business logic in your Message-Driven Beans, so scenarios in which your listener is required to inherit from another class should be rare.

GenericMessageHandler.java

public abstract class GenericMessageHandler<T> implements MessageListener {

    private final Class expectedType;
    @EJB
    private DeadLetterHandler deadLetterHandler;

    public GenericMessageHandler() {
        final ParameterizedType parameterizedType =
            (ParameterizedType) getClass().getGenericSuperclass();
        expectedType = (Class) parameterizedType.getActualTypeArguments()[0];
    }

    public void onMessage(final Message message) {
        if (matchesExpectedType(message)) {
            invokeConsume(message);
        } else {
            final Object payload = extractPayload(message);
            if (matchesExpectedType(payload)) {
                invokeConsume(payload);
            } else {
                deadLetterHandler.invalidMessageType(message);
            }
        }
    }

    protected DeadLetterHandler getDeadLetterHandler() {
        return deadLetterHandler;
    }

    protected abstract void consume(T obj);

    private boolean matchesExpectedType(final Object obj) {
        return obj != null && expectedType.isAssignableFrom(obj.getClass());
    }

    private Object extractPayload(final Message message) {
        try {
            if (message instanceof ObjectMessage) {
                return ((ObjectMessage) message).getObject();
            } else if (message instanceof TextMessage) {
                return ((TextMessage) message).getText();
            }
            return null;
        } catch (JMSException e) {
            throw new IllegalStateException("Error extracting payload", e);
        }
    }

    private void invokeConsume(final Object obj) {
        consume((T) obj);
    }
}

Payload Extraction Example – MailQueueHandlerBean.java

public class MailQueueHandlerBean extends GenericMessageHandler<Email> {

    @EJB
    private Mailer mailer;

    @Override
    public void consume(final Email email) {
        mailer.sendMessage(email);
    }
}

In the above example MailQueueHandlerBean expects messages of type ObjectMessage with a payload of type Email. As you can see, the implementation is super-lean and there’s no ambiguity about who’s performing what.

Message Type Check Example – RawDataQueueHandlerBean.java

public class RawDataQueueHandlerBean extends GenericMessageHandler<BytesMessage> {

    @EJB
    private DataProcessor dataProcessor;

    @Override
    public void consume(final BytesMessage bytesMessage) {
        try {
            if (bytesMessage.getBodyLength() == 0) {
                getDeadLetterHandler().invalidMessageContent(bytesMessage);
            } else {
                final byte[] data = // extract byte array
                dataProcessor.process(data);
            }
        } catch (JMSException e) {
            throw new IllegalStateException("Error extracting bytes", e);
        }
    }
}

Installing Rational Software Modeller 7.5 on Fedora 11

Filed under: Fedora, Java EE Development, UML — Tags: , , , , , — Jonathan Wright @ 1:07 pm
  1. Because the installer uses text relocations you’ll need to relax your SELinux settings. Go to System -> Administration -> SELinux Management -> Status and set the Current Enforcing Mode to Permissive.
  2. Launch the installer and follow the wizard to completion (the remaining steps assume you accepted the default installation and workspace locations).
  3. Rational Software Modeller also uses text relocations at runtime so you need to run the following command before setting your Current Enforcing Mode back to Enforcing:
    sudo chcon -R -t textrel_shlib_t /opt/IBM
  4. If you try and launch the application at this point eclipse will crash and display an error dialog telling you to check <HOME>/IBM/rationalsdp/workspace/.metadata/.log. This bug is the result of a change in the xulrunner SDK which is required to display the eclipse welcome screen.
  5. To disable the welcome screen run the following command:
    echo "org.eclipse.ui/showIntro=false" > /tmp/noWelcomeScreen.ini

    Now append the following option to the launch command:

    -pluginCustomization /tmp/noWelcomeScreen.ini

    For example:

    opt/IBM/SDP/eclipse -product com.ibm.rational.rsm.product.v75.ide -pluginCustomization /tmp/noWelcomeScreen.ini
  6. Go to Application -> IBM Software Delivery Platform -> IBM Software Modeller
  7. Happy modelling!

The Shocking Blue Green Theme Blog at WordPress.com.

Follow

Get every new post delivered to your Inbox.