I recently re-read Martin Fowler’s essay ‘Mocks aren’t Stubs’ comparing the benefits and pitfalls of writing unit tests using either state verification or behavioural verification. He describes state verification as classical or regular unit testing, in that you run a test and check the state of your test object (as defined by the data a particular method call returns) using some kind of assert(…) method.
Java tips, observations, bugs and problems from the world of Spring, Weblogic, Oracle, MySQL and many other technologies...
Saturday, 29 January 2011
Wednesday, 26 January 2011
Upgrading to Spring 3
"It’s really about time I learnt all about Spring 3.0" I thought today. I’ve actually been putting it off for some time, after all Spring 2.5.x has been working well, without any problems, so putting it off seemed a good idea – as the old saying goes "if it ain’t broke don’t fix it".
This is a quick blog that provides a few pointers about converting your existing projects and providing a few links to some of the more detailed information.
This is a quick blog that provides a few pointers about converting your existing projects and providing a few links to some of the more detailed information.
Tuesday, 25 January 2011
Polymorphism Teaser
What would the output be from this piece of code?
/** * This represents any old super class with a print function **/ class SuperClass { private void printIt() { System.out.println("SuperClass"); }
Labels:
certification,
Java,
Polymorphism
Monday, 24 January 2011
From Use-Case to Coding
How do you go about writing software? Is it an art or a science? Are classes created from the imagination or are they in the requirements waiting to be discovered? This blog is a stab at figuring this out by attempting to document how I currently approach coding. I’m assuming a lot: you have your development environment, you know what tools you’re using, you know your target environment, you know the system’s architecture and probably lots more besides.
To illustrate the process, consider the following fragment taken from a hypothetical use-case:
To illustrate the process, consider the following fragment taken from a hypothetical use-case:
Sunday, 23 January 2011
A Definition of the SOLID Acronym
The SOLID acronym is an acronym of acronyms, drawing together five basic design principals:
Saturday, 22 January 2011
Arithmetic Promotion
In a calculation everything is promoted to an int or larger.
Line 1 will pass although strictly speaking an int is being assigned to a byte. (It's a fudge that makes literals work more easily).
1. byte b = 6; 2. b = b + 6;Line 2 will fail because b + 6 will create an int which is being assigned to a byte
Line 1 will pass although strictly speaking an int is being assigned to a byte. (It's a fudge that makes literals work more easily).
Labels:
certification,
Java
Friday, 21 January 2011
Using Java Assert
The idea of asserts was introduced to Java as part of the language in J2SE 1.4.
To allow the compiler to treat "assert" as a keyword you'll need to compile with the following amendment to the compile line:
To enable the assertion at runtime use the following command line option:
or
To allow the compiler to treat "assert" as a keyword you'll need to compile with the following amendment to the compile line:
javac -source 1.4 MyApp.java
To enable the assertion at runtime use the following command line option:
java -ea MyApp
or
Labels:
certification,
Java
Thursday, 20 January 2011
Java Automatic Type Conversion
The Java compiler will perform automatic type conversions for you so long as the receiving variable is wider that the sending variable. The diagram below shows the possible conversion routes...
Labels:
certification,
Java
Java Object Casting
Object casting rules compile time checks:
- When both OldType and NewType are classes, one class must be a subclass of the other.
- When both OldType and NewType are arrays, both arrays must contain reference types (not primitives) and it must be legal to cast an element of OldType to an element of NewType
- You can always cast between an interface and a non-final object.
Labels:
certification,
Java
Wednesday, 19 January 2011
Promotion and Reduction of Operands
Reduction of the right operand
If you use a shift number that is greater than the length of the variable type (ie for int this would be a number greater than 32) then the Java compiler will take the modulus of that number. For example: 2 >> 33 would become 2 >> (33 % 32) or 2 >> 1Promotion of Operands
When shifting number smaller than an int the results can be unexpected. for example consider:byte b = -64; byte c = b >>> 4;The original number will be:
Labels:
certification,
Java
Tuesday, 18 January 2011
Being in Perl...
As a contractor, there are those few times when you arrive at a client’s site and you get asked to do something for which you’re not remotely qualified. That happened to me a few months ago. I joined a new project as was asked to write a PL/SQL script triggered by a Perl script run using chron. Now, I’ve never done Perl, it’s not on my CV, but, as usual, you think: ‘how hard can it be?’ and get on with it. The sample scripts below are my notes on how to write Perl, they may not be the best notes in the world and they are incomplete, but they work for me…
Monday, 17 January 2011
A Three Tier Schema: Adding the Code and User Tiers
This is the last in a series of three blogs on creating a three tier schema in Oracle. The previous two blogs introduced the concept of the three tier schema, and creating the data layer. This blog covers the final two concepts: creating the code layer and giving the user access to the code.
Saturday, 15 January 2011
An Example 3 Tier Schema
Having introduced Three Tier Database Schemas in a previous blog, it's now time to return to the subject and discuss how to go about creating one.
Friday, 14 January 2011
PQ/SQL examples
This blog is a Java Programmer's answer for that moment when you're told to design a crucial piece of corporate PL/SQL that will hold the world together and save the empire. In this situation, as an ace developer your first response should be: "How hard can it be..."
So, introducing the Captain Debug PL/SQL quick reference guide, I'm going to demonstrate...
So, introducing the Captain Debug PL/SQL quick reference guide, I'm going to demonstrate...
- A simple PL/SQL Block
- A simple PL/SQL Block using a Cursor and while loop
- A simple PL/SQL Block using a Cursor and FOR loop
- A PL/SQL Block using SQL attributes.
- A simple procedure.
- A procedure with input and output parameters
- EXCEPTIONS
- Named EXCEPTIONs
- Unnamed EXCEPTIONs
- Functions
Introduction to 3 Tier Schemas in Oracle
The big idea behind the three tier approach is to enhance security by striving for a "least privileges" environment. The 3 tier approach places data objects (tables) in one schema, procedures to manipulate the data (PL/SQL) in a second and end-user(s) are the third.
This is a very conservative approach and requires the most maintenance but gives the most flexibility and is the most secure as it isolates the data from the SQL that manipulates it and the manipulation from external access.
This is a very conservative approach and requires the most maintenance but gives the most flexibility and is the most secure as it isolates the data from the SQL that manipulates it and the manipulation from external access.
Thursday, 13 January 2011
Unlocking an Oracle Database Account
This is a small but useful thing to know... often because you’ve type the wrong password into a configuration file that then locks you out of the database because you try to connect and fail – lots of times...
So here's how to lock or unlock Oracle database user accounts.
So here's how to lock or unlock Oracle database user accounts.
SQL> ALTER USER username ACCOUNT LOCK;
SQL> ALTER USER username ACCOUNT UNLOCK;
Not used very often, but useful to have on hand.
Wednesday, 12 January 2011
Non-XA and XA Transactions
Previous blogs have talked about MDBs and their use of transactions. This blog expands on the idea of transactions looking at the difference between XA and none-XA transactions and why they’re around...
A non-XA transaction, in basic terms, is something that wraps around a single resource that interacts with your code to co-ordinate your program’s access to that resource. When your code has finished accessing the resource, then the transaction will ensure that your code’s changes are committed. Resources generally include things like databases and JMS queues / topics.
An XA transaction takes this idea one step further and is, in the most general terms, a "global transaction" that may span multiple resources.
An XA transaction uses a coordinating transaction manager to co-ordinate access to one or more databases (or other resources, like JMS) that are all involved in the single global transaction. Non-XA transactions don’t use a transaction coordinator, and the single resource is doing all its transaction work itself. Tthis is sometimes referred to as a local transaction.
Most stuff in the world uses non-XA transactions: a Servlet or EJB or plain old JDBC in a Java application talking to a single database. XA gets involved in larger systems with multiple resources: two or more databases, a database and a JMS connection, all of those plus JCA resource, all in a single transaction. In this scenario, you'll use an application server like Websphere or Weblogic or JBoss, which acts as the Transaction Manager, and your various resources (Oracle, IBM MQ JMS, whatever) acting as transaction resources. Your code can then update/delete/publish/whatever across the many resources. When you say "commit", the results are committed across all of the resources. When you say "rollback", everything is rolled back across all resources.
The Transaction Manager coordinates all of this using a protocol called Two Phase Commit (2PC); however, remember that this protocol also has to be supported by the individual resources.
For more details - see the JTA pages on java.sun.com.
A non-XA transaction, in basic terms, is something that wraps around a single resource that interacts with your code to co-ordinate your program’s access to that resource. When your code has finished accessing the resource, then the transaction will ensure that your code’s changes are committed. Resources generally include things like databases and JMS queues / topics.
An XA transaction takes this idea one step further and is, in the most general terms, a "global transaction" that may span multiple resources.
An XA transaction uses a coordinating transaction manager to co-ordinate access to one or more databases (or other resources, like JMS) that are all involved in the single global transaction. Non-XA transactions don’t use a transaction coordinator, and the single resource is doing all its transaction work itself. Tthis is sometimes referred to as a local transaction.
Most stuff in the world uses non-XA transactions: a Servlet or EJB or plain old JDBC in a Java application talking to a single database. XA gets involved in larger systems with multiple resources: two or more databases, a database and a JMS connection, all of those plus JCA resource, all in a single transaction. In this scenario, you'll use an application server like Websphere or Weblogic or JBoss, which acts as the Transaction Manager, and your various resources (Oracle, IBM MQ JMS, whatever) acting as transaction resources. Your code can then update/delete/publish/whatever across the many resources. When you say "commit", the results are committed across all of the resources. When you say "rollback", everything is rolled back across all resources.
The Transaction Manager coordinates all of this using a protocol called Two Phase Commit (2PC); however, remember that this protocol also has to be supported by the individual resources.
For more details - see the JTA pages on java.sun.com.
Labels:
Java,
Transactions,
Weblogic
Tuesday, 11 January 2011
Transactions and Coding MDBs
Recently I posted a small blog on how to use
It seems to me that although many of the EJB technical books tell you how to write a simple MDB implementation using the MessageListener interface they usually don’t mention transactions in any detail or assume Container Managed Transactions from the start.
setRollbackOnly()
to inform your JEE container that your MDB has encountered an error, and that doing this was the preferred method of error handling when using Container Managed Transactions. It seems to me that although many of the EJB technical books tell you how to write a simple MDB implementation using the MessageListener interface they usually don’t mention transactions in any detail or assume Container Managed Transactions from the start.
Labels:
BMT,
CMT,
Java,
MDB,
Transactions
Monday, 10 January 2011
Shell scripts don’t run in Solaris when stored in DOS mode
Writing a shell script in Windows and FTPing to UNIX may seem like a good idea, after all many projects are written under Windows and go live in UNIX. If you do this you MUST run
Which isn’t very helpful.
dos2unix
on your shell scripts. Otherwise you’ll get a:: bad interpreter: No such file or directory error
Which isn’t very helpful.
Labels:
dos2unix,
shell script,
Solaris,
Unix
Setting Up Solaris Environment Variables
In Solaris, to setup an environment variable you need to both declare it and then export it:
The best place to add these is to the .profile file.
You can’t put dots in an environment variable descriptor:
MYNAME=fred
export MYNAME
The best place to add these is to the .profile file.
You can’t put dots in an environment variable descriptor:
MY.NAME=fred # This won’t work.
Labels:
.profile,
environment,
Solaris,
Unix
Tip: Use NXServer to access your UNIX box remotely.
www.nomachine.com
are the company that produce NXServer, which is a really good way of accessing your home Unix machine (everyone has one) remotely. To install NXServer you need to:- Download and install the NXClient
- Download and install the NXNode
- Download and install the NXServer
If you don't do this, the NXServer installation will fail because it can't find the nxnode program.
The Default Solaris Run Level
The default Solaris run level is 3; that's everything including graphics console and NFS.
To determine the current run level use
To determine the current run level use
who -r
Adding a script to your Solaris boot configuration
This is something that you don’t really need to do that often – only when setting up your home Solaris Sun machine: I guess that everyone has one, so this bog describes how to add a script to the Solaris boot sequence.
All you need to do is:
All scripts that are prefixed with an 'S' are run with a 'start' parameter, eg:
If the service that you're installing has a close down script, then add another link:
This will close the service down and is equivalent to:
Obviously, the close down script is optional and depends upon the service your script deals with.
For some reason, numbers greater than 100 don't seem to work?!? E.G.
Remember that scripts are run in numerical order:
All you need to do is:
- Log in as the super user.
- Write your shell script.
- Copy the file to
//etc//init.d
- Make the script executable.
- Link the file to the run level directory, either
//etc//rc2.d
or//etc//rc3.d
or both. Note that the default run level is '3' so use rc3.d
fred
.
su - root
:
:
cp fred //etc//init.d
cd //etc//init.d
chmod 755 //etc//init.d/fred
ln -s ..//init.d//fred //etc//rc3.d/fred S90fred
All scripts that are prefixed with an 'S' are run with a 'start' parameter, eg:
./etc//init.d/fred start
If the service that you're installing has a close down script, then add another link:
ln -s ..//init.d//fred //etc//rc3.d/fred K90fred
This will close the service down and is equivalent to:
./etc/init.d/fred stop
Obviously, the close down script is optional and depends upon the service your script deals with.
For some reason, numbers greater than 100 don't seem to work?!? E.G.
S110fred
and I don't know why - I guess that it's a bug...Remember that scripts are run in numerical order:
S90bill
runs before S95bill
and K90bill
runs before K95fred
.
Spring 2.x MVC Controller Classes - What do they do?
The Spring framework provides a whole class hierarchy of MVC controllers, but the big question is, where and when do you use each one?
Broadly speaking, there are two main types of controller: normal controllers and form controllers. A normal controller links to it’s next page using an <a> link or http GET, whilst a form controller page contains an HTML form (plus a button) and uses a HTTP POST. So the first decision is simple: is you page a form or a normal page?
March 2011 -> don't forget that these MVC classes have now been deprecated in Spring 3.x.
Broadly speaking, there are two main types of controller: normal controllers and form controllers. A normal controller links to it’s next page using an <a> link or http GET, whilst a form controller page contains an HTML form (plus a button) and uses a HTTP POST. So the first decision is simple: is you page a form or a normal page?
ParameterizableViewController | A controller that uses a parameter to return a static view (one without data from the DB) |
MultiActionController | A controller that can delegate to 0 or more (1 or more) 'delegate' objects in order to determine the next view. (Strategy Pattern) |
AbstractFormController | A basic form controller that automatically populates the form bean with incoming data |
SimpleFormController | A form controller that handles a form that uses one screen. |
AbstractWizardFormController | A form controller that chains multiple forms together. |
March 2011 -> don't forget that these MVC classes have now been deprecated in Spring 3.x.
MDB Durable Subscribers
A durable subscriber is an MDB that will receive its messages even if it goes down. To make a MDB into a durable subscriber, you need to add a couple of lines to the ejb-jar.xml and weblogic-ejb-jar.xml.
The Ejb-Jar
<?xml version="1.0" encoding="UTF-8"?>
<ejb-jar id="ejb-jar_ID" version="2.1" xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/ejb-jar_2_1.xsd">
<display-name>Event Logging Component</display-name>
<enterprise-beans>
<message-driven>
<ejb-name>EventLoggingMDB</ejb-name>
<ejb-class>uk.gov.hmrc.candi.service.ejb.EventLoggingMDB</ejb-class>
<transaction-type>Container</transaction-type>
<message-destination-type>javax.jms.Topic</message-destination-type>
<activation-config>
<activation-config-property>
<activation-config-property-name>subscriptionDurability</activation-config-property-name>
<activation-config-property-value>Durable</activation-config-property-value>
</activation-config-property>
</activation-config>
</message-driven>
</enterprise-beans>
<assembly-descriptor>
<container-transaction>
<method>
<ejb-name>EventLoggingMDB</ejb-name>
<method-name>*</method-name>
</method>
<trans-attribute>Required</trans-attribute>
</container-transaction>
</assembly-descriptor>
</ejb-jar>
The Weblogic-Ejb-Jar
<?xml version="1.0" encoding="UTF-8" ?>
<weblogic-ejb-jar xmlns="http://www.bea.com/ns/weblogic/10.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.bea.com/ns/weblogic/10.0 http://www.bea.com/ns/weblogic/10.0/weblogic-ejb-jar.xsd">
<weblogic-enterprise-bean>
<ejb-name>EventLoggingMDB</ejb-name>
<message-driven-descriptor>
<pool>
<max-beans-in-free-pool>1</max-beans-in-free-pool>
<initial-beans-in-free-pool>1</initial-beans-in-free-pool>
</pool>
<destination-jndi-name>EventTopic</destination-jndi-name>
<connection-factory-jndi-name>weblogic.jms.XAConnectionFactory</connection-factory-jndi-name>
<jms-client-id>EventLoggingClient</jms-client-id>
<max-messages-in-transaction>1</max-messages-in-transaction>
</message-driven-descriptor>
</weblogic-enterprise-bean>
</weblogic-ejb-jar>
Labels:
Durable Subscriber,
Java,
MDB,
Weblogic
EJB/MDB class loading problems with Spring 2.x
This little blogette covers a problem that arises when you try to deploy an EAR file on Weblogic’s web-server where the JEE components such as MDBs and EJB use the wrong Spring Application Context in the wrong place and at the wrong time.
When this error occurs you’ll get a NoClassDefFoundError exception that refers to a class that somewhere deep inside the call stack. This exception happens even though the EAR is correctly configured with all JARs present and classpaths correct.
This is caused by the use of Spring’s ClassPathXmlApplicationContext which loads an entire context for every EJB / MDB.
The fix is to use ContextSingletonBeanFactoryLocator and a beanrefContext.xml (though the xml file name is configurable), which loads the Application context once, sharing it between all EJB or MDB instances.
When this error occurs you’ll get a NoClassDefFoundError exception that refers to a class that somewhere deep inside the call stack. This exception happens even though the EAR is correctly configured with all JARs present and classpaths correct.
This is caused by the use of Spring’s ClassPathXmlApplicationContext which loads an entire context for every EJB / MDB.
The fix is to use ContextSingletonBeanFactoryLocator and a beanrefContext.xml (though the xml file name is configurable), which loads the Application context once, sharing it between all EJB or MDB instances.
Labels:
ContextSingletonBeanFactoryLocator,
EJB,
Java,
MDB,
NoClassDefFoundError,
Weblogic
Maven Scopes
Dependency scope is used to limit the transitivity of a depedency, and also to affect the classpath used for various build tasks.
There are 6 scopes available:
section. It indicates that the specified POM should be replaced with the dependencies in that POM's section. Since they are replaced, dependencies with a scope of import do not actually participate in limiting the transitivity of a dependency.
Each of the scopes (except for import) affects transitive dependencies in different ways, as is demonstrated in the table below. If a dependency is set to the scope in the left column, transitive dependencies of that dependency with the scope across the top row will result in a dependency in the main project with the scope listed at the intersection. If no scope is listed, it means the dependency will be omitted.
(*) Note: it is intended that this should be runtime scope instead, so that all compile dependencies must be explicitly listed - however, there is the case where the library you depend on extends a class from another library, forcing you to have available at compile time. For this reason, compile time dependencies remain as compile scope even when they are transitive.
There are 6 scopes available:
compile
This is the default scope, used if none is specified. Compile dependencies are available in all classpaths of a project. Furthermore, those dependencies are propagated to dependent projects.provided
This is much like compile, but indicates you expect the JDK or a container to provide the dependency at runtime. For example, when building a web application for the Java Enterprise Edition, you would set the dependency on the Servlet API and related Java EE APIs to scope provided because the web container provides those classes. This scope is only available on the compilation and test classpath, and is not transitive.runtime
This scope indicates that the dependency is not required for compilation, but is for execution. It is in the runtime and test classpaths, but not the compile classpath.test
This scope indicates that the dependency is not required for normal use of the application, and is only available for the test compilation and execution phases.system
This scope is similar to provided except that you have to provide the JAR which contains it explicitly. The artifact is always available and is not looked up in a repository.import (only available in Maven 2.0.9 or later)
This scope is only used on a dependency of type pom in theEach of the scopes (except for import) affects transitive dependencies in different ways, as is demonstrated in the table below. If a dependency is set to the scope in the left column, transitive dependencies of that dependency with the scope across the top row will result in a dependency in the main project with the scope listed at the intersection. If no scope is listed, it means the dependency will be omitted.
compile provided runtime test
compile compile(*) runtime
provided provided provided
runtime runtime runtime
test test test
(*) Note: it is intended that this should be runtime scope instead, so that all compile dependencies must be explicitly listed - however, there is the case where the library you depend on extends a class from another library, forcing you to have available at compile time. For this reason, compile time dependencies remain as compile scope even when they are transitive.
Maven Default Properties
Note: In Maven 3.0, all
pom.*
properties are deprecated. Use project.*
instead!Built in properties
${basedir
} represents the directory containing pom.xml ${version
} equivalent to ${project.version
} or ${pom.version
}
Labels:
Java,
Maven,
Properties
Maven Compile Fix
It sometimes happens that an ancestor POM file references a JAR file that’s an older version than the one you want to use in your project. The symptoms of this are compile errors that seem unbelievable as you know your POM references the correct version of the JAR.
For example your POM has a log4j dependency listed as:
whilst the ancestor/super POM has the following:
When building the 1.2.6 version will be picked up first and used.
To fix this problem, use the <compile> element:
… and your problem goes away…
For example your POM has a log4j dependency listed as:
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.8</version>
</dependency>
whilst the ancestor/super POM has the following:
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.6</version>
</dependency>
When building the 1.2.6 version will be picked up first and used.
To fix this problem, use the <compile> element:
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.8</version>
<scope>compile</scope>
</dependency>
… and your problem goes away…
Default Weblogic Connection Factories
Weblogic has two default connection factories:
... one being distributed the other not distributed.
- weblogic.jms.ConnectionFactory
- weblogic.jms.XAConnectionFactory
... one being distributed the other not distributed.
Labels:
ConnectionFactory,
Java,
Weblogic
Closing InitialContexts in Weblogic
In Weblogic (at least), when you create an initial context, it gets attached to a thread presumably using a ThreadLocal stack. This means that you can only have one current InitialContext at any one time and that if you do something like:
then your last call to reuse your first initial context will use your second initial context.
At least that’s the theory, but it gets even more confusing when one Context uses security and the other doesn’t.
SO, the big idea here is to ALWAYS close your initial context after use:
Context ctx = new InitialContext(props)
:
:
:
ctx.close();
For more information take a look at the Weblogic documentation on this
- Create a InitialContext and use it
- Create another InitialContext and use that...
- Reuse your first InitialContext
then your last call to reuse your first initial context will use your second initial context.
At least that’s the theory, but it gets even more confusing when one Context uses security and the other doesn’t.
SO, the big idea here is to ALWAYS close your initial context after use:
Context ctx = new InitialContext(props)
:
:
:
ctx.close();
For more information take a look at the Weblogic documentation on this
Labels:
initialcontext,
Java,
Weblogic
Sunday, 9 January 2011
How to do MDB error handling
If an MDB is consuming a message when an unexpected error occurs most programmers think that the obvious thing to do is to throw an exception back to the MDB's container. The container can then decide how to handle the error: drop the message, delay for a while and then resend depending on how JMS queue or topic is configured.
If your MDB is transactional, then to inform the container of your error all you need to do is to use the bean context to call setRollbackOnly().
To inform the container of a problem for any MDB—transactional or non-transactional—you can throw an exception derived from the RuntimeException or Error thrown by the MDB. This causes the MDB instance to be destroyed and re-created, which incurs a performance penalty.
For more information, take a look at the Weblogic / Oracle website
Applies to Weblogic webserver.
To inform the container of a problem for any MDB—transactional or non-transactional—you can throw an exception derived from the RuntimeException or Error thrown by the MDB. This causes the MDB instance to be destroyed and re-created, which incurs a performance penalty.
For more information, take a look at the Weblogic / Oracle website
Applies to Weblogic webserver.
Subscribe to:
Posts (Atom)