Friday, November 26, 2010

Web services : cURL

If you need to do some web service client testing, there are a number of tools like SOAPUI but they all involve installing programs etc.

Then I came across this neat tool cURL

To quote from the docs:

"curl is a command line tool for transferring data with URL syntax, supporting DICT, FILE, FTP, FTPS, GOPHER, HTTP, HTTPS, IMAP, IMAPS, LDAP, LDAPS, POP3, POP3S, RTMP, RTSP, SCP, SFTP, SMTP, SMTPS, TELNET and TFTP. curl supports SSL certificates, HTTP POST, HTTP PUT, FTP uploading, HTTP form based upload, proxies, cookies, user+password authentication (Basic, Digest, NTLM, Negotiate, kerberos...), file transfer resume, proxy tunneling and a busload of other useful tricks."

It runs on a wide variety of platforms.

So how do you use it to test a web service?

You need to mock-up what the actual SOAP packet looks like e.g.

to test a web service called TestWS, the information might look like:






123456
Joe
Bloggs





Save this in a file called TestWS.xml.

The command line for cURL would then be:

curl --data @TestWS.xml --header "Content-Type: text/xml" --header "Accept-Encoding: gzip,deflate" --verbose http://host:port/TestWSService


This then sends the HTTP POST which itself contains a SOAP message which invokes the web service.

The verbose option prints out both the request and the response.

Enjoy!

Tuesday, November 23, 2010

Netbeans : Providing command line arguments inside Netbeans

I write a lot of command line Netbeans (6.9) Java programs. A lot of them take command line arguments e.g.


java Program Option1 Option2


and you access them from "String[] args".

When you are running inside Netbeans, you need to provide the arguments by:

Right click the project / Properties / Run / Arguments

If you right click the Java file you are testing (the Main class) and select "Run File" the program runs but ignores the configured arguments.

To get around this, you have to right click the project and select "Run".

Enjoy!

Java : Checking if environment variables are valid

Has a few problems with environment variables and I couldn't find a utility that would check them for me e.g. checking if all the entries in my PATH environment variable were valid.

So I rolled my own:


public class CheckEnv {

/**
* @param args the command line arguments
*/
static String envVar = "";
static String envValue = "";
static String envValueStrings[];
static String envValueString = "";
static boolean valid = false;

public static void main(String[] args) {
// TODO code application logic here

if (args.length < 1) {
System.out.println("\nUsage is 'java -jar CheckEnv.jar '");
System.out.println();
System.out.println(" e.g. 'java -jar CheckEnv.jar PATH'");
System.out.println(" 'java -jar CheckEnv.jar CLASSPATH'");
System.out.println(" 'java -jar CheckEnv.jar INCLUDE'");
System.out.println(" 'java -jar CheckEnv.jar LIB'");
System.exit(1);
}

envVar = args[0];

envValue = System.getenv(envVar);

System.out.println ("\nChecking for environment variable " + envVar + "\n");

if (envValue == null)
{
System.out.println ("Environment variable " + envVar + " doesn't exist");
System.exit(1);
}

envValueStrings = envValue.split(";");

for (int i = 0; i < envValueStrings.length; i++) {
envValueString = envValueStrings[i];

System.out.print("Checking " + envValueString + " ");

File file = new File(envValueString);
valid = file.exists();

if (valid) {
System.out.println("- variable exists");
} else {
System.out.println("- variable does not exist : WARNING");
}

}
}
}



Usage is 'java -jar CheckEnv.jar '

e.g. 'java -jar CheckEnv.jar PATH'
'java -jar CheckEnv.jar CLASSPATH'
'java -jar CheckEnv.jar INCLUDE'
'java -jar CheckEnv.jar LIB'


The output looks like e.g.


Checking C:\Program Files\Java\jdk1.6.0_22\jre\bin - variable exists
Checking C:\Program Files\Reflection - variable exists
Checking C:\Perl\bin\ - variable exists


Enjoy!

Monday, November 22, 2010

JMeter : IOException: Exceeded maximum number of redirects: 5

Using the JMeter proxy server to record and playback some logins to a site and got this error.

Mr. Google to the rescue and the trick is to modify the jmeter.properties file in the JMeter bin directory.


# Maximum redirects to follow in a single sequence (default 5)
httpsampler.max_redirects=20


Modify the above line in that file to increase the maximum from the default of 5. In my case, I found 20 to be adequate.

You need some kind of upper limit because otherwise the trace could just get stuck in a loop.

Note that you have to restart JMeter after making this change.

Enjoy!

Friday, November 19, 2010

Netbeans : SOAPUI plugin

Using Netbeans 6.9.

I wanted to download the SOAPUI plugin from soapUI NetBeans Plugin.

Although the description says "com-eviware-soapui-netbeans-module.nbm", when you actually download the file, you'll find it's a zip file.

Netbeans doesn't like loading zip files. A little research at Mr. Google shows that a .nbm file is essentially just a zip file with a different extension.

So I simply simply renamed

com-eviware-soapui-netbeans-module.zip to com-eviware-soapui-netbeans-module.nbm

and the plugin installed no problems at all.

It does warn you that the plugin is not signed but just ignore that and continue.

Enjoy!

Thursday, November 18, 2010

CXF : Deploying the java_first_jaxws sample direct to Tomcat

Decided I wanted to learn a bit about CXF so downloaded the development kit and has a look at the java_first_jaxws project in the \samples directory.

Before you try and do anything, ensure you have the environment set up correctly.

I created a bat file (as per README) which looks like:


set CXF_HOME=x:\apache-cxf-2.3.0
set JAVA_HOME=x:\Program Files\Java\jdk1.6.0_22
set ANT_HOME=C:\apache-ant-1.8.1

set PATH=%JAVA_HOME%\bin;%ANT_HOME%\bin;%CXF_HOME%\bin;%PATH%
set CLASSPATH=.;%CXF_HOME%\lib\cxf-manifest.jar;.\build\classes

set CATALINA_HOME=x:\Program Files\Apache Software Foundation\Apache Tomcat 6.0.26


which also serves as a useful list of the file versions I have.

One level up from the project you will find a useful file i.e.

common_build.xml

which is worth looking through.

In the actual project directory you will find a build.xml which calls the above.

ant -p


shows:


Main targets:

build build demo client and server
client run demo client
client-servlet run demo client hitting servlet
deploy deploy the application into the container
server run demo server
undeploy undeploy the application from the container
Default target: build


so we first do:

ant build

which builds both the client and the server.

Then we run:

ant server


and

ant client


Note that the client and server run in two separate command prompts.

The client then sends some canned messages to the server:


client:
[java] Hello World
[java] Hello World
[java] Hello Galaxy
[java] Hello Universe
[java]
[java] Users:
[java] 1: World
[java] 2: Galaxy
[java] 3: Universe


and the server receives:


server:
[java] Starting Server
[java] Server ready...
[java] sayHi called
[java] sayHiToUser called
[java] sayHiToUser called
[java] sayHiToUser called
[java] getUsers called


Note that this is running is a "built-in" Jetty server and the URL the client calls is:

http://localhost:9000/helloWorld

OK, that sets the scene for the main thrust of this article which is how to deploy this client to a real instance of Tomcat.

So start up the Tomcat server as usual by running "startup.bat" in the \bin directory.

My installation of Tomcat runs on port 8080 so we need to change Client.java as follows:


//String endpointAddress = "http://localhost:9000/helloWorld";
String endpointAddress = "http://localhost:8080/helloworld/services/hello_world";


Now we run the normal "ant build" and then we run "ant deploy".

This builds the war file and then deploys it to Tomcat (which is where the CATALINA_HOME environment variable comes in.)

Then we run the normal "ant client" and this time, the server output messages will appear in the Tomcat window.

Note that the WSDL can be found at:

http://localhost:8080/helloworld/services/hello_world?wsdl

Where on earth does this URL come from?

As per Creating a WSDL-first web service with Apache CXF or GlassFish Metro, scroll down to Point 2 in the "Additional notes".

Adapting for our project, we get:

http://localhost:8080/helloworld/services/hello_world?wsdl

"localhost:8080" is the host and port of the servlet container.
"helloworld" is the name of the war file.
"services" comes from the url-pattern element in the web.xml file.
"hello_world" comes from the address attribute in the cxf-servlet.xml file (for CXF).

If we look into the web.xml file (you'll need to look at the war file in the ...\samples\java_first_jaxws\build\war directory), we find:

servlet-name = cxf
url-pattern = /services/*

If we look into the cxf-servlet.xml file (in the wsdl directory), we find:


jaxws:server id="jaxwsService" serviceClass="demo.hw.server.HelloWorld" address="/hello_world"


Enjoy!

Tuesday, November 16, 2010

Metro : Jax WS incompatibilities with Netbeans

Using Netbeans 6.9 and Tomcat 6 with JAX WS via Metro and Java JDK 6 on Windows.

The Tomcat installation is the one that is loaded as part of Netbeans.

When you try and invoke the web service, you get a string of errors e.g.

java.lang.NoSuchMethodError: javax.xml.ws.WebFault.messageName()Ljava/lang/String


The basic problem seems to be that the versions of JAX WS bundled with Netbeans / Java / Tomcat are incompatible.

(Metro provides JAX-WS 2.2 while Java SE includes JAX-WS 2.1. If you want to run Metro applications outside Tomcat, you will need to use the endorsed standards override mechanism. For more details see:

http://java.sun.com/javase/6/docs/technotes/guides/standards/index.html)

There are literally hundreds of articles etc. all over the web about how to fix this problem with tips about installing file x into the endorsed directory, the common/endorsed directory, updating Tomcat, updating Java etc. etc.

I tried a heap of them and none of the ones I tried fixed the problem. This is Google search at it's worst - tons of articles, all different, none of which appeared to work and utter frustration.

To complicate the issue, it you don't back out the failed change, you run the risk that the next change won't work because you didn't start from a known point.

To complicate things further, some of these changes partly work which means that next time you simply get a different error message and you have to start the process all over again.

Eventually, I went back to the source i.e. Metro and JAX WS.

I came across this article:

Creating a WSDL-first web service with Apache CXF or GlassFish Metro

which pointed me to:

Using JAX-WS 2.x / Metro 1.x/2.0 with Java SE 6

So, download Metro 2 - refer Metro 2.0

Ensure Netbeans and Tomcat are shut down.

Sort the zip file by path.

You do not need to extract all the files. You only need:

metro-on-tomcat.xml and all the jar files under /metro/lib and /metro/osgi.

Extract these to a directory.

Ensure you have ant installed.

Open a command prompt and navigate to the directory that you have just extracted the files to.

Type:

...\metro>set CATALINA_HOME=x:\Program Files\Apache Software Foundation\Apache Tomcat 6.0.26

i.e. the path where Tomcat 6 is installed

where ... is the directory that the files were extracted to.

Then run:

ant -f metro-on-tomcat.xml install


which produces:


Buildfile: metro-on-tomcat.xml

catalinahome-test:

init:

uninstall:

update-catalina-props:

test-api:

check-api:

install-api-tomcat5:

install-api-tomcat6:
[mkdir] Created dir: x:\Program Files\Apache Software Foundation\Apache Tomc
at 6.0.26\endorsed
[copy] Copying 2 files to x:\Program Files\Apache Software Foundation\Apach
e Tomcat 6.0.26\endorsed

install-api-tomcat:

install:
[echo] Installing Metro 2.0 FCS for x:\Program Files\Apache Software Founda
tion\Apache Tomcat 6.0.26 ...
[mkdir] Created dir: x:\Program Files\Apache Software Foundation\Apache Tomc
at 6.0.26\shared\lib
[copy] Copying 4 files to x:\Program Files\Apache Software Foundation\Apach
e Tomcat 6.0.26\shared\lib
[echo] ... installation complete.

BUILD SUCCESSFUL


The two files copied to the \endorsed directory are :

jsr173_api.jar and webservices-api.jar


The four files copied to the \shared\lib directory are:

webservices-extra.jar, webservices-extra-api.jar, webservices-rt.jar and webservices-tools.jar


In addition, the script updates catalina.properties in the \conf directory. It changes:

shared.loader=


to

shared.loader=${catalina.home}/shared/lib/*.jar


And that, believe it or not, is that!

Problem solved!

If you want to back the change out, run:

ant -f metro-on-tomcat.xml uninstall


For completeness, if you want to enable JAX-WS 2.2 for all applications running under Java SE 6, you may run the command:

ant install-api


That command will copy the file webservices-api.jar to ${java.home}/lib/endorsed.

(The command needs to be run by a user that has the permissions to copy files into ${java.home}/lib/endorsed.)

Note that I didn't need to do this.

Enjoy!

Thursday, November 11, 2010

Netbeans : Can't login to Tomcat as Admin or Manager

Using Netbeans 6.9 and Tomcat 6 - integrated with Netbeans.

When I go to the Tomcat server home page i.e. http://localhost:8084/

and then click on the Manager link, I am asked to login. But my login is not accepted! WTF?

The usual course of action is to go to the Tomcat installation which is usually something like:

...\Program Files\Apache Software Foundation\Apache Tomcat 6.0.26\conf

and edit the tomcat-users.xml file adding the lines:






but this login is not accepted.

Looked through the logs and noticed:

Using CATALINA_BASE: "...\Tmp\.netbeans\6.9\apache-tomcat-6.0.26_base"
Using CATALINA_HOME: "...\Program Files\Apache Software Foundation\Apache Tomcat 6.0.26"


where the Tmp directory is my Netbeans work directory.

You have to edit the xml file in that directory NOT the one in the "Program Files" tree.

Then found an easier way.

Click on the Server tab in Netbeans, then right click Tomcat and click Properties.

Click the Connection tab.

The credentials in that tab are what you have to use. It's normally ide and some random password which you can change.

Note that the CATALINA_BASE and CATALINA_HOME settings appear in this tab as well.





Enjoy!

Friday, November 05, 2010

Glassfish : Moving a project from Glassfish 2 to 3

Migrated a web application project inside Netbeans from Glassfish 2 to Glassfish 3 and built it on another PC.

Obviously the paths had changed so I did a Search / Replace across all the Netbeans project files.

Then got an error:

... \nbproject\wsit-deploy.xml:12: Must set Sun app server root.


Clicking on that line showed:

unless="sjsas.root" Must set Sun app server root


For once, Mr. Google failed to come to the rescue.

Eventually, I brute force searched the actual Glassfish installation under:

\Program Files\glassfish-3.0.1

and found:

...\Program Files\glassfish-3.0.1\glassfish\domains\domain1\config\domain.xml

system-property name="sjsas.root" value="...\Program Files\glassfish-3.0.1"


Damn - wrong path.

Moral of the story. When you migrate projects across machines, you may need to update the Glassfish configuration files as well as the Netbeans project files.

Note: The ... above represents the actual directory which is different in each environment.

Aside: Because this was a Glassfish issue rather than a project issue, I got the same error when I tried using Tomcat instead of Glassfish. Maybe that should have been a hint!

Enjoy!