Monday, April 02, 2012

JNDI with grails and TcServer

Just something to be aware of.

In order to reference JNDI resources from a grails (and probably java spring) app on TC Server there are 2 steps to perform.

1/ Add the jndi name to the tcserver conf/server.xml file. This will declare the jndi name and the resource that it represents. In your head you may assume that this is the only step you need (I know I did)...

This is a configuration object in the conf dir of your tcServer directory
e.g. (Note also have variables e.g. my.url defined in catalina.properties here)

<Resource accessToUnderlyingConnectionAllowed="false"
defaultAutoCommit="true" defaultReadOnly="false"
driverClassName="com.sybase.jdbc3.jdbc.SybDriver"
factory="org.apache.tomcat.dbcp.dbcp.BasicDataSourceFactory"
initialSize="0" logAbandoned="false" maxActive="8"
maxIdle="8" maxOpenPreparedStatements="0" maxWait="-1"
minEvictableIdleTimeMillis="1800000" minIdle="0"
name="jdbc/myOtherDS" numTestsPerEvictionRun="3"
password="${my.password}" poolPreparedStatements="false"
removeAbandoned="false" removeAbandonedTimeout="300"
testOnBorrow="true" testOnReturn="false"
testWhileIdle="false" timeBetweenEvictionRunsMillis="-1"
type="javax.sql.DataSource" url="${myOther.url}"
username="${myOther.username}" validationQuery="select @@servername" />
<Resource accessToUnderlyingConnectionAllowed="false"
defaultAutoCommit="true" defaultReadOnly="false"
driverClassName="com.ibm.db2.jcc.DB2Driver"
factory="org.apache.tomcat.dbcp.dbcp.BasicDataSourceFactory"
initialSize="0" logAbandoned="false" maxActive="8" maxIdle="8"
maxOpenPreparedStatements="0" maxWait="-1"
minEvictableIdleTimeMillis="1800000" minIdle="0"
name="jdbc/myDS" numTestsPerEvictionRun="3"
password="${my.password}" poolPreparedStatements="false"
removeAbandoned="false" removeAbandonedTimeout="300"
testOnBorrow="true" testOnReturn="false" testWhileIdle="false"
timeBetweenEvictionRunsMillis="-1"
type="javax.sql.DataSource" url="${my.url}"
username="${my.username}" validationQuery="SELECT 1 from sysibm.sysdummy1" />


2/ You also need to add the jndi name to META_INF/context.xml
This simply creates a mapping from the jndi name to a Java object (Normally a dataSource).

the context.xml is normally part of the source code for the application so will be checked into your source control repository.. You will need a new build if you add or change the data in here. This isn't a big deal really since you will need to add code to deal with the new or updated jndi object at any rate.

Sample

<Context path="myAppUrl" debug="1" reloadable="true" docBase="myAppDocBase" antiResourceLocking="true">
<ResourceLink global="jdbc/myDS" name="jdbc/myDS" type="javax.sql.Datasource"/>
<ResourceLink global="jdbc/myOtherDS" name="jdbc/myOtherDS" type="javax.sql.Datasource"/>
</Context>

Wednesday, March 21, 2012

Grails dynamic methods

One of the great features of Grails is the dynamic methods that allow you to create complex lookup methods dynamically.

Here's a couple of points though


Account.findByLabelInList(labels)


The InList appender allows you to search by items in a list

Likewise for Criteria.


CreateCriteria
e.g.
static findMyAccount(def name, def country, def accountType, def labels) {
(DcmAccount)DcmAccount.createCriteria().get {
eq("name", name
eq("country", country)
eq("accountType", accountType)
'in'("labels", labels)
}
}

This is a method on the domain class that I created to lookup accounts based on 4 criteria. Notice the in criteria. It has to be enclosed in quotes since it is a Grails reserved word. It allows you to search for items contained in a list.

Monday, March 12, 2012

FoxClocks

Fox Clocks is a handy little addon for firefox. It can display multiple clocks around the world so you can see the local time in any chosen city.

I thought there was a problem with the daylights saving time bevahiour of FoxClocks.

I'm using version 2.9.35. It was reporting my local time correctly, but 2 days ago the US had their daylights savings time adjustment, while in Europe we are not having ours for 2 more weeks.

My time was been reported corectly, but my US based FoxClocks were not. They were still showing the old pre-Daylight Savings time.

The problem is because that FoxClocks uses an internal database of when daylights saving events occur. I simply had to update that database using Tools/ Options/ Time Zone Data/ Check Now.
When this is done it displayed the correct US times.

Monday, March 05, 2012

Grails Class.forName (loading classes dynamically)

This is a quickie for now.. I will have to come back and expand this entry when I understand more of why it happens.

simple problem. Wanted to load classes dynamically based on a domain instance name.

Simple (in theory)

String name="Domain"
String className = "com.package.test."+name+"Service"
Object o =Class.forName(className).newInstance()

But it fails with a ClassNotFoundException. (and of course the class does exist).

After a lot of tested I came to the following answer
Object o = Thread.currentThread().contextClassLoader.loadClass(className).newInstance()
or
Object o = SomeOtherService.getClassLoader().loadClass(className).newInstance()

Why I don't know. One tends to work in unit tests and not in application code, and the opposite for the other, so often I include both

Here's some links that may help explain.
http://groovy.dzone.com/news/class-loading-fun-groovy

Based on this I wrote a simple test to check the different class loaders

def testB(){
    parseCL(this.getClass().getClassLoader()) //This ClassLoader does NOT work
        
    parseCL(AnotherService.getClassLoader()) // This class Loader does work
}
    
def parseCL(ClassLoader cl){
    println "********************"
    println cl
    println "********************"
    println "Parent ="+cl.getParent()
    cl = cl.getParent()
    def indent = "--"
    while(cl){
        println indent+cl
        cl = cl.getParent()
        println indent+"Parent ="+cl
        indent = indent +"--"
    }
}


Note the top level classloader is different

********************
java.net.URLClassLoader@247510e7 // DOES NOT LOAD CLASS DYNAMICALLY
********************
Parent =java.net.URLClassLoader@77479ef9
--java.net.URLClassLoader@77479ef9
--Parent =org.codehaus.groovy.grails.cli.support.GrailsRootLoader@15ded0fd
----org.codehaus.groovy.grails.cli.support.GrailsRootLoader@15ded0fd
----Parent =sun.misc.Launcher$AppClassLoader@35a16869
------sun.misc.Launcher$AppClassLoader@35a16869
------Parent =sun.misc.Launcher$ExtClassLoader@77cde100
--------sun.misc.Launcher$ExtClassLoader@77cde100
--------Parent =null
********************
java.net.URLClassLoader@77479ef9 // LOADS CLASS DYNAMICALLY
********************
Parent =org.codehaus.groovy.grails.cli.support.GrailsRootLoader@15ded0fd
--org.codehaus.groovy.grails.cli.support.GrailsRootLoader@15ded0fd
--Parent =sun.misc.Launcher$AppClassLoader@35a16869
----sun.misc.Launcher$AppClassLoader@35a16869
----Parent =sun.misc.Launcher$ExtClassLoader@77cde100
------sun.misc.Launcher$ExtClassLoader@77cde100
--------Parent =null

Friday, February 24, 2012

Windows batch files

Some notes on windows batch files e.g. runnign them in background etc. (start /b cmd ..

for example I use this alot in Grails to start a hsql db instance in the background and the asociated db manager

start /B cmd /c "%JAVA_HOME%\bin\java -cp hsqldb-1.8.0.10.jar org.hsqldb.Server -port 9010 -database.0 myDB -dbname.0 myDB"

%JAVA_HOME%\bin\java -classpath hsqldb-1.8.0.10.jar org.hsqldb.util.DatabaseManager --url jdbc:hsqldb:hsql://localhost:9010/myDB


All listed here (antak's answer) http://stackoverflow.com/questions/649634/how-do-i-run-a-bat-file-in-the-background-from-another-bat-file

(note Call is only needed if you are calling another batch file.. If you have an inline command remove the call)

Built in variables
There are a few build in variables that are useful when writing .bat files

(do a
cmd /?
to get some help on the matter)

%~dp0 lists the current path (d represents the directory, p represents the path)
this is useful if you call a batch file from a different directory.

e.g. cd %~dp0

This however can prove problematic in batch files if you want to append information after the path (e.g. I was trying to append a jar filename e.g.
%~dp0/filename 
does not work. (However you can assign it to a variable

set DIR=%~dp0
set FILE=%DIR%/filename


In those cases %CD% is usefule

e.g.

groovyconsole -cp %CD%\jarfile.jar


This will start the groovy console with jarfile in the path. Useful for tinkering with a new api

Monday, January 16, 2012

Java regex's

Just a quick note on java.util.Pattern. e.g. extract numbers from a known pattern

We know that our data format will be various letters, the number we want to extract. One or more letters. How do we extract the numbers?

Easy, using a regex Pattern, and the Matcher class.

e.g. (in groovy)
import java.util.regex.*
def testString ="abc4567!TheEnd"
def pattern = Pattern.compile("\\D*(\\d*).*") // N.B. Double quotes to escape \ pattern == \D*(\d*).*.. i.e. not a number/ number/ anything
Matcher m = pattern.matcher(testString)
if(m.matches()){
def i=0
while(i<=m.groupCount()) println m.group(i++) }else println "Doesn't match"


Returns our number... 4567

Note groups are returned based 1/ the whole matching string followed by a group for each cycle of parentheses (1 in this case).

e.g. if the above regex is changed to
"\\D*(\\d(\\d(\\d*))).*"

Then the results would be as follows. Note how as the group index increases, we traverse deeper into the parentheses of the regex
group(0) == abc4567!TheEnd
group(1) == 4567
group(2) == 567
group(3) == 67

Wednesday, November 16, 2011

Ec2 Getting started

My notes on getting an Ec2 instance up and running.

I created the (free) Amazon Linux AMI.

This is a base linux distro, so you will need to install any extra software you need (e.g. in my case tomcat, jdk)

Install tomcat6
> sudo yum install tomcat6

Get JDK
wget http://www.java.net/download/jdk6/6u30/promoted/b10/binaries/jdk-6u30-ea-bin-b10-linux-amd64-25_oct_2011-rpm.bin

Install
chmod a+x ./jdk-6u30-ea-bin-b10-linux-amd64-25_oct_2011-rpm.bin
sudo ./jdk-6u30-ea-bin-b10-linux-amd64-25_oct_2011-rpm.bin

Start Tomcat
tbc

Friday, October 21, 2011

Grails dynamic finders not working in Unit Tests

I ran into a problem with my unit test in Grails.

One of the dynamic finders was not working. What was strange was that it worked fine when I ran the app normally. It only failed in the unitTests.


groovy.lang.MissingMethodException: No signature of method: static com.domain.myDomain.findByCode() is applicable for argument types: (java.lang.String) values: [myCode]
at groovy.lang.MetaClassImpl.invokeStaticMissingMethod(MetaClassImpl.java:1357)
at groovy.lang.MetaClassImpl.invokeStaticMethod(MetaClassImpl.java:1343)
at groovy.lang.ExpandoMetaClass.invokeStaticMethod(ExpandoMetaClass.java:1082)
at

Solution.

When unit testing, grails mocks out all backend access. In order to do this it must dynamically update the domain classes (e.g. save method), so that they dont try to talk to the DB.

Therefore when using any unit testing on domain object you must first mock it out. This is easily done in the unitTest class in the setUp() method

e.g.
mockDomain myDomain


It can save you a lot of hassle

Tuesday, October 18, 2011

Stack trace cleanup

Groovy has a handy class for sanitize stack traces. (i.e. it removes any java, groovy classes from the classpath, so that just so called 'Business' classes remain.

Of course if you are using thirdparty libraries then this might not cleanse the stack trace enough. Therefore it might be useful to append extra ignorable packages into the ignore list.

e.g.

// Add any extra package names here
String[] GROOVY_PACKAGES =
System.getProperty("groovy.sanitized.stacktraces",
"groovy.," +
"org.codehaus.groovy.," +
"java.," +
"javax.," +
"sun.," +
"gjdk.groovy.,"
).split("(\\s|,)+");


public static Throwable sanitize(Throwable t) {
// Note that this getBoolean access may well be synced...
if (!Boolean.getBoolean("groovy.full.stacktrace")) {
StackTraceElement[] trace = t.getStackTrace();
List newTrace = new ArrayList();
for (StackTraceElement stackTraceElement : trace) {
if (isApplicationClass(stackTraceElement.getClassName())) {
newTrace.add(stackTraceElement);
}
}
// We don't want to lose anything, so log it
STACK_LOG.log(Level.WARNING, "Sanitizing stacktrace:", t);


StackTraceElement[] clean = new StackTraceElement[newTrace.size()];
newTrace.toArray(clean);
t.setStackTrace(clean);
}
return t;
}

Thursday, October 13, 2011

Grails local plugin repository

If you are creating your own grails plugins, then you need to
1/ Store them on a central server
2/ Inform grails to check this server to find your plugins before going online to download them

There are 2 ways to do this (see http://grails.org/doc/1.3.x/guide/12.%20Plug-ins.html)

1/ Grails Compatible Repositories
This is easily achieved by creating (or updating if it already exists) the $HOME/.grails/settings.groovy file

e.g. to add myPluginRepository

The discovery, and distribution locations are svn repositories
grails.plugin.repos.resolveOrder=['myPluginRepository', 'default', 'core']
grails.plugin.repos.discovery.myPluginRepository="http://myServer/svn//my-plugin-distributions"
grails.plugin.repos.distribution.myPluginRepository="http://myServer/svn//my-plugin-distributions"
To publish
grails release-plugin -repository = myPluginRepository

2/ Maven Compatible Repositories (Recommended)
maven-install
The maven-install command will install the Grails project or plugin artifact into your local Maven cache:
grails maven-install

In the case of plugins, the plugin zip file will be installed, whilst for application the application WAR file will be installed.

maven-deploy
The maven-deploy command will deploy a Grails project or plugin into a remote Maven repository:
grails maven-deploy

It is assumed that you have specified the necessary configuration within a pom.xml or that you specify the id of the remote repository to deploy to:
grails maven-deploy --repository=myPluginRepository

The repository argument specifies the 'id' for the repository. You need to configure the details of the repository specified by this 'id' within your grails-app/conf/BuildConfig.groovy file or in your USER_HOMER/.grails/settings.groovy file:
grails.project.dependency.distribution = {
localRepository = "/path/to/my/local"
remoteRepository(id:"myPluginRepository", url:"http://myserver/path/to/repo")
}

The syntax for configuring remote repositories matches the syntax from the remoteRepository element in the Ant Maven tasks. For example the following XML:
<remoteRepository id="myPluginRepository" url="scp://localhost/www/repository">
<authentication username="..." privateKey="${user.home}/.ssh/id_dsa"/>
</remoteRepository>

Can be expressed as:
remoteRepository(id:"myPluginRepository", url:"scp://localhost/www/repository") {
authentication username:"...", privateKey:"${userHome}/.ssh/id_dsa"
}

By default the plugin will try to detect the protocol to use from the URL of the repository (ie "http" from "http://.." etc.), however if you need to explicitly specify a different protocol you can do:
grails maven-deploy --repository=myPluginRepository --protocol=webdav

The available protocols are:

* http
* scp
* scpexe
* ftp
* webdav

Tuesday, October 11, 2011

Arrays Maps List syntax for groovy/ java/ javascript

Slight syntax differences

Note groovy maps are different to json maps, and proposed Java map literals. Grrovy maps use similar syntax to arrays

1/ Groovy syntax

Map
def map= ['id':'FX-11', 'name':'Radish', 'no':1234, 99:'Y']
assert map == ['name':'Radish', 'id':'FX-11', 99:'Y', 'no':1234] //order of keys irrelevant
def map4= [:]
assert map == java.util.LinkedHashMap

def map2= [id:'FX-11', two:"two"] as Hashtable
assert map2 == java.util.Hashtable
assert map2.two == "two"
assert map2['two'] == "two"

Note: key may be string or not.

Array
a= [ 11, 12, 13, 14 ] as Object[]


List (by default create ArrayList)
def list = [5, 6, 7, 8]
assert list.get(2) == 7
assert list[2] == 7
assert list instanceof java.util.List
assert list instanceof java.util.ArrayList

def emptyList = []
assert emptyList.size() == 0
assert emptyList instanceof java.util.ArrayList

// To force to type other than ArrayList use
numbers3 = new LinkedList(['One', 'Two', 'Three', 'Four', 'Five'])
numbers4 = ['One', 'Two', 'Three', 'Four', 'Five'] as Stack // Groovy 1.6+

Note Groovy also has Range type. This is inherits from java.util.List, but is a pure groovy class (e.g. groovy.lang.IntRange)

2/ Java (8) syntax (Note these produce immutable items)
http://sellmic.com/blog/2011/07/08/7-new-cool-features-in-java-7/
http://blog.joda.org/2007/02/java-7-list-and-map-literals_6278.html
http://code.joejag.com/2009/new-language-features-in-java-7/

Map
Map map = {"key" : 1};
int value = map["key"];

Set set = {"item"};

Array
String[] array = {"item1", "item2",}

List
List list = ["Abba", "Beatles", "Corrs"];
List emptyList = [];

3/ Javascript/ Json Syntax

Array
var emptyList = [];
var homogenousList = [1, 2, 3];
var heterogenousList = ["one", 2, 3.0];
Var list = new Array();
list[0] = "item";
list[1] = "item1";

List
Use Array

Map
var emptyMap = {};
var homogenousMap = {"one": 1, "two": 2, "three": 3};
var heterogenousMap = {"one": 1,
"two": "two",
"three": 3.0};

map = {'key':'value'}
map.key == 'value'
map['key'] == 'value'

Monday, October 10, 2011

Grails (hibernate) "Could not find a setter for property in class"

When working on a Domain class (in grails) I wanted to add a convenience method to return some information.

e.g. I had a property endDate, and I wanted to have a method isActive to return true if the endDate does not exist or is in the future.

boolean isActive(){
if(endDate==null) return true;
return endDate
}


However when I try to run the app I get

Solution is

def isActive(){
if(endDate==null) return true;
return endDate
}


If defined as boolean (or int string etc), then Hibernate interprets it as a getter, and will look for corresponding setter, and throw an exception when not finding it.
Defined as with a def, means this won't happen.
Alternative is to set it in the transients static.

e.g.
static transients = [ "active" ]
http://grails.1312388.n4.nabble.com/Transient-properties-td1345135.html

Saturday, October 08, 2011

No Sql

This video is useful

At a high level there are 4 cetegories of noSql Db's


Key Value based e.g. Amazon Riak, Voldemort
Column based e.g. HBase, Bigtable. each row can have its own schema (semi structured)
Document Databases (e.g. couchDb, mongoDb).. Key Value based
Graph based:

Sunday, September 25, 2011

Configuring 2-way SSL with Oracle Service Bus

Configuring 2-way SSL with Oracle Service Bus

Must set up Identity and trust.

Identity represents the server itself. This corresponds to the Servers private key. (Its public key is embedded in its certificate)

Trust is for when weblogic is communicating with clients over 2-way SSL. It must store a list of certificates it trusts. The client must then supply one of these as part of the handshaking protocol.

Server Side configuration (ie. For terminating 2 way SSL requests)

Enable X509 as an Identity Asserter type

Error if not present:

X.509 token identity assertion is not enabled in the security realm

Goto Security/ myrealm/ Providers/ Authentication/ DefaultIdentityAsserter

Add X509 to DefaultIdentityAsserter. (Note also that wsse.PasswordDigest is also present here for WS-Security UsernameToken. (Digest Replay Detection Enabled can be also be set here). Also to enable this you also must set “Enable Password Digests” in the DefaultAuthenticator.)

Restart Server

Next Step

Error

The X.509 username-mapper sub-plugin of the default identity asserter in not configured

HTTPS inbound endpoint inboundEndpoint specifies CLIENT-CERT authentication, therefore the username mapper properties of the default identity asserter must be configured (this is required to support 2-way SSL)

Action

Configure the username-mapper fields of the Default Identity Assertion provider in the security realm pages of the WebLogic Server console

Client

Configuring 2-way SSL with SoapUI (client)

A lot of these settings are configured in the Global Preferences table, so cannot be saved per project.

Firstly load the KeyStore (where the client certificate is stored) in the SSL tab of the Prferences.

Note: Requires Client Authentication box is part of the Mock definitions, and is not required for a client configuration.

You may also need to configure a proxy (I did) if your client is on the external web, and you use a proxy to access that.

Keytool commands

Command

Description

keytool -genkey -keystore keystorename -storepass keystorepassword

Generates a new private key entry and self-signed digital certificate in a keystore. If the keystore does not exist, it is created.

keytool -import -alias aliasforprivatekey
-file privatekeyfilename.pem
-keypass privatekeypassword
-keystore keystorename -storepass keystorepassword

Updates the self-signed digital certificate with one signed by a trusted CA.

keytool -import -alias aliasfortrustedca -trustcacerts -file trustedcafilename.pem -keystore keystorename -storepass keystorepassword

Loads a trusted CA certificate into a keystore. If the keystore does not exist, it is created.

keytool -certreq -alias alias
-sigalg
sigalg
-file
certreq_file
-keypass
privatekeypassword
-storetype
keystoretype
-keystore
keystorename
-storepass
keystorepassword

Generates a Certificate Signing Request (CSR), using the PKCS#10 format, and a self-signed certificate with a private key.

Stores the CSR in the specifiedcertreq_file, and the certificate/private key pair as a key entry in the specified keystore under the specified alias.

keytool -list -keystore keystorename

Displays what is in the keystore.

keytool -delete -keystore keystorename -storepass keystorepassword -alias privatekeyalias

Deletes the entry identified by the specified alias from the keystore.

keytool -help

Provides online help for keytool.

Initial Setup steps

In order to enable outbound two way SSL (i.e. MW making a two way SSL call out to a client) we need to create a Service Key Provider

Create a Service Key Provider

To use a service key provider, you must configure a PKI credential mapping provider.

To use the PKI Credential Mapping provider, you need to:

  1. Configure keystores with appropriate keys and distribute the keystores on all machines in a WebLogic Server cluster. Setting up keystores is not a WebLogic Server function. For information about setting up keystores, see the help for the Java keytool utility at http://java.sun.com/j2se/1.4.2/docs/tooldocs/solaris/keytool.html. See alsoConfiguring Identity and Trust, for information about keystores and keys in WebLogic Server.
  2. Configure a PKI Credential Mapping provider. A PKI Credential Mapping provider is not already configured in the default security realm (myrealm). See PKI Credential Mapper Attributes and Configure Credential Mapping providers in the Administration Console online help.
  3. Create credential mappings. See Create PKI Credential Mappings in the Administration Console online help.

Create Java Keystore in Domain

Create a Keystore. Import certificate (user identification certificate) into keystore.

See http://download.oracle.com/docs/cd/E13159_01/osb/docs10gr3/security/model.html#wp1089312

(see step 6)

Configure each WebLogic Server instance to have access to its own copy of each keystore. All entries referred to by the PKI credential mapper must exist in all keystores (same entry with the same alias).

May have to convert certificate to format understood by keytool

keytool -importkeystore -srckeystore pki\GTMSWebUser.pfx -srcstoretype pkcs12 -destkeystore ./pkiKeystore

So I was able to directly import the pfx file containing the private key and certificate.

From OSB this was then accessible in the ServiceKey Provider. Not when selecting the Key, you must supply the private key password to access it (not the keystore password)

Create a PKI credential mapping Provider

Got security/ myrealm/ providers/ CredentialMapping

Select New.

Select PKICredentialMapper

Supply a name (e.g. PkiCredentialMapper)

Create Credential Mapping

Got security/ myrealm/ providers/ CredentialMapping

Select New.

Protocol= https

remoteHost= web3.bgegtms.ie

PrincipleName = GTMS

CredentialType = Cert

Create ServiceBus ServiceKeyProvider

Configure a PKI Credential Mapping provider

Goto Providers./ CredentialMapping. Select New/ PKICredentialMapper

Note a restart is required after this.

Create Credential Mappings

Configure a PKI Credential Mapping provider

Not sure if this is needed?

Restart server

PKI credential mapper provider

Create a new PKI Credential mapper in the console

Click on new and create KeyStore

There is no PKI credential mapper provider configured in your security realm. Service key provider management will be disabled. Configure a PKI credential mapper provider if you need service provider support. This is typically the case if you have Oracle Service Bus proxy services with web service security enabled or outbound 2-way SSL connections.

Friday, August 19, 2011

Ordered Map vs Sorted Map

This is obvious once you know it (isnt’ everything).

A little bit of a rant at declining standards first.. (its ok, I’m not lamenting the youth of today, or society; its my own declining standards I’m ranting about)..

I feel that a lot of times I rely on google to give me a quick solution to a problem. There’s nothing inherently wrong with this. I imagine 95% of developers do it and certainly it leads to quicker solutions. One negative consequence of this is that I don’t get any depth of knowledge, just a quick link to a possible solution which I often can paste in to fulfil my needs. Little effort, quick result, but little return and learnt. In some ways this blog is an attempt to expand some of these topics just a little bit more, in order to get a better understanding of them, but it too has a bit of the copy and paste solution about it.

Of course this only works if you 1/ Ask the correct question, and 2/ form your question correctly.... So today (possibly as a result of years of quick solution hunting, and no learning) I forgot some of the basics, and didn’t ask the correct question.

I had a Map instance where I wanted to control the sequencing of the keys. I knew this class existed in the java.util Collections classes (or failing that the commons collections), so I was frantically searching the web for a Sorted Map.

I found java.util.SortedMap. Perfect ...
I read the javadoc description and thought.. this isn’t what I want... It sorts on natural Order, or based on applying a custome comparator. After much head scratching about how I would create a custom comparator to order my Map in the order which it was created, I finally had my Eureka moment... I didn’t want a Sorted Map at all

Of course what I really wanted was java.util.LinikedHashMap. This stores the Keys within an internal LinkedList structure that maintains the order of the elements as they are added. Quite different to a sorted List which dynamically sorts the keys based on a algorithm (either natural or custom).

So todays lesson is simple. Learn the basic terminology before consulting the almighty google. And LinkedHashMap is quite different to SortedMap

Sunday, August 14, 2011

Gson inheritance

This article helped fix a problem I had with inheritance, and Gson (JSON api)

http://www.velvetcache.org/2011/01/24/gson-inheritance-issues


Basically, key is to ensure that you specify the field values as private fields, and assign their values in the constructor (not by creating a new private field with an updated value)

Monday, August 01, 2011

jconsole for high level profiling

I’ve mentioned it obliquely before but its time I highlighted the free profiling tool jconsole.

Always good to infrequently check your application especially if you are getting OutOfMemory errors.

It also doubles up as an MBean browser

Saturday, July 23, 2011

Wget (or curl) can be a magic command at the right times.

Heres some options I’ve used to retrieve a directory from svn

I wanted to download the everything below
https://remotehost/svn/Base/Streams/1.3/Projects/ProjectName/trunk/osb/Interface/Resources

wget -r --no-parent -nH --cut-dirs=10 --no-check-certificate --http-user=user --http-password=password https://remotehost/svn/Base/Streams/1.3/Projects/ProjectName/trunk/osb/Interface/Resources
or



-r = recursive
--no-parent stops it looping back to parent directory should any references point there
-nH. Ignore the host when saving any resources (removes remotehost directory)
--cut-dirs=10. Removes 10 directories when saving resources. This removes /svn/Base/Streams/1.3/Projects/ProjectName/trunk/osb/Interface/Resources, and will only save any subsequent directories and filenames.

--no-check-certificate, ignores any https cert problems. Handy for local sites with untrusted certs.

-m = mirror. Handy replacement for, -N -r -l inf --no-remove-listing

-Rindex.html : do not download index.html pages

--http-user, --http-password specify some HTTP basic auth if required

Proxy
--proxy-user=, --proxy-password= specify some proxy auth if required. The actual proxy itself

To specify the proxy. Yo must set environment variables
e.g. export http_proxy=http://192.168.10.250:80


variables are
http_proxy
https_proxy
If set, the http_proxy and https_proxy variables should contain the urls of the proxies for http and https connections respectively.

ftp_proxy
This variable should contain the url of the proxy for ftp connections. It is quite common that http_proxy and ftp_proxy are set to the same url.

no_proxy

This variable should contain a comma-separated list of domain extensions proxy should not be used for. For instance, if the value of no_proxy is ‘.mysite.com’, proxy will not be used to retrieve documents from mysite.

Monday, July 18, 2011

JSTL Gotcha

Why doesn’t this work?


<%@ taglib uri="http://stripes.sourceforge.net/stripes.tld" prefix="stripes" %>
<%@ taglib uri="http://www.stripes-stuff.org/security.tld" prefix="security" %>
<%@ taglib uri="http://stripes.bge.ie/StripesExtension.tld" prefix="stripes-extension" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/functions" prefix="fn" %>


<c:set var="a" value="A"></c:set>
<c:set var="b" value="B"></c:set>
<c:set var="c" value="C"></c:set>

<c:if test="${a=='A' }">
a= A,
<c:if test="${b=='B' } ">
b=B
<c:if test="${c=='C' }">
c=C
</c:if>
</c:if>
</c:if>

The answer is the space in the test B jstl tag.

Another few hours of my life wasted...
Also another time waster... Beware of <div id=”myDiv” class=”myDiv” />

Firefox didn’t like the autoclose tag. I needed to explicitly add a </div>

SoapUi Scripting

Heres a simple project with some scripting in it.

Key points are.

1/ Any output from script gets redirected to the script log. This is visible as a tab at the bottom of the main pane.

Note. This tab only appears after a script generates a log message.

2/ Examples are online at. This includes writing request to file, and dynamically generating responses

http://www.soapui.org/Service-Mocking/creating-dynamic-mockservices.html



Sample project
salaryTest-soapui-project.xml