hello world
Thursday, March 18, 2004
 
Moving home
I'm now working for Ellison Brookes

After a pleasant few months here on blogspot I'm moving to JRoller so I won't be publishing any more content here. I'll leave this page in place, hopefully it will still be of some use to some people.
Tuesday, February 24, 2004
 
Aspectwerkz and Jamon
Here is an the same example using Aspectwerkz instead of DynAOP

import com.jamonapi.Monitor;
import com.jamonapi.MonitorFactory;
import org.codehaus.aspectwerkz.advice.AroundAdvice;
import org.codehaus.aspectwerkz.joinpoint.JoinPoint;
import org.codehaus.aspectwerkz.joinpoint.MethodJoinPoint;
public class TraceAdvice extends AroundAdvice {
public TraceAdvice() {
super();
}
public Object execute(final JoinPoint joinPoint) throws Throwable {
MethodJoinPoint jp = (MethodJoinPoint) joinPoint;
StringBuffer buffer = new StringBuffer();
buffer.append(jp.getMethod().getDeclaringClass().getName());
buffer.append(".");
buffer.append(jp.getMethod().getName());
Monitor mon = MonitorFactory.start(buffer.toString());
Object result = joinPoint.proceed();
mon.stop();
System.out.println(mon.toString());
return result;
}
}

And the aspectwerkz.xml

<!DOCTYPE aspectwerkz PUBLIC "-//AspectWerkz//DTD 0.8//EN" "http://aspectwerkz.codehaus.org/dtd/aspectwerkz_0_8.dtd">
<aspectwerkz id="samples">
<advice-def name="trace" class="TraceAdvice" deployment-model="perJVM"/>
<aspect name="jamon">
<pointcut-def name="all" type="method" pattern="* mypackage.MyClass.setName(..)"/>
<bind-advice pointcut="all">
<advice-ref name="trace"/>
</bind-advice>
</aspect>
</aspectwerkz>

Note that this is for XML definitions using Aspectwerkz 0.8, to port to 0.9 then move around advice to the org.codehaus.aspectwerkz.xml.advice package.
Friday, February 13, 2004
 
DynAOP & Jamon
Heres a more interesting example of using AOP to monitor an application. This Interceptor will start monitoring before the method is called and stop straight after and log the results.

import com.jamonapi.Monitor;
import com.jamonapi.MonitorFactory;
import dynaop.Interceptor;
import dynaop.Invocation;
public class TraceInterceptor implements Interceptor {
public Object intercept(Invocation invocation) throws Throwable {
StringBuffer buffer = new StringBuffer();
buffer.append(invocation.getMethod().getDeclaringClass().getName());
buffer.append(".");
buffer.append(invocation.getMethod().getName());
// Start the monitor
Monitor mon = MonitorFactory.start(buffer.toString());
// Invoke the method
Object result = invocation.proceed();
// Stop the monitor
mon.stop();
// Print results to stdout
System.out.println(mon.toString());
return result;
}
}

Now register the Interceptor in the dynaop.bsh file

interceptor(
mypackage.MyClass.class,
signature("setName"),
new TraceInterceptor()
);

You can find out more about Jamon here http://www.javaperformancetuning.com/tools/jamon/index.shtml


 
DynAOP - NKOTB
I've been looking at Bob Lee's excellent new DynAOP framework over the past couple of days and I've got to say, it can't get much simpler than this. Whilst it may not have same power as Aspectwerkz (AW) (AW in online mode is an incredibly useful tool), it makes it so simple to start using AOP in your applications with very little effort.


Another strong aspect of the AW is the list of very simple examples that Jonas and Alex provide which highlight the features that they are describing and nothing else. Bob's examples contain a little bit too much code which distracted me from the meat of framework. I've posted some samples here that people might find a little easier to digest.


Here is the interface we are going to use

package mypackage;
public interface MyClass {
public void setName(String name);
}

and here is the implementation

package mypackage;
public class MyClassImpl implements MyClass {
private String name;
public MyClassImpl() {
}
public String getName() {
return name;
}
public void setName(String string) {
System.out.println("Inside MyClassImpl.setName()");
name = string;
}
}

Here is the dynaop.bsh configuration file (hurrah, no XML :-))

mixin(
mypackage.MyClass.class,
MixinImpl.class
);
interceptor(
mypackage.MyClass.class,
signature("setName"),
new LoggingInterceptor()
);

This is the mixin interface

public interface Mixin {
public String getMessage();
}

and heres the mixin implementation

import dynaop.Proxy;
import dynaop.ProxyAware;
public class MixinImpl implements Mixin, ProxyAware {
public String getMessage() {
return "Hello World";
}
// this is called by dynaop.
public void setProxy(Proxy proxy) {
}
}

heres the LoggingInterceptor class

import dynaop.Interceptor;
import dynaop.Invocation;
public class LoggingInterceptor implements Interceptor {
public Object intercept(Invocation invocation) throws Throwable {
System.out.println("This is from the logging interceptor : before");
Object result = invocation.proceed();
System.out.println("This is from the logging interceptor : after");
return result;
}
}

Now lets create a class that shows the LogginInterceptor in action

import mypackage.MyClass;
import dynaop.ProxyFactory;
public class InterceptorExample {
public static void main(String[] args) {
MyClass myClass = (MyClass) ProxyFactory.getInstance().extend(mypackage.MyClassImpl.class);
// An interceptor has been registered in the dynaop.bsh file for this method
myClass.setName("graham");
}
}

When you run this class you will see the following printed to stdout

This is from the logging interceptor : before
Inside MyClassImpl.setName()
This is from the logging interceptor : after

Now lets look at an example of our mixin in action.

import mypackage.MyClass;
import dynaop.ProxyFactory;
public class MixinExample {
public static void main(String[] args) {
MyClass myClass = (MyClass) ProxyFactory.getInstance().extend(mypackage.MyClassImpl.class);
System.out.println(((Mixin) myClass).getMessage());
}
}

When you run this example you'll see the flollowing printed to stdout

Hello World

Simple. The getMethod() method has been mixed-in to the MyClass interface and called by the executing thread. Heres a link to this project including an ANT build script (just type 'ant' and the application will compile and run) and Eclipse projects files so you can import it and have a look http://www.mycgiserver.com/~grahamoregan/dynaop_example.zip


Hopefully you'll find this little easier to play with so you can start to benefit from DynAOP as soon as possible.

Wednesday, December 10, 2003
 
Beanshell


In the latest version of Beanshell, developers can now use existing Java classes in a dynamic environment. Heres an example of a Java class called TestScript being called by a class called TestBS.



TestScript.java



import java.util.Date;
public class TestScript {
public String getVersion(Date date) {
String ver = "Hello World";
return "BeanShell version: " + ver +" "+ date.getTime();
}
}

TestBS



import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStreamReader;
import java.util.Date;
import bsh.EvalError;
import bsh.Interpreter;

public class TestBS {
public static void main(String[] args) {
Interpreter interpreter = new Interpreter();
try {
interpreter.eval(new InputStreamReader(new FileInputStream("C:/src/bs/src/TestScript.java")));
Date d = new Date();
interpreter.set("date", d);
interpreter.eval("TestScript script = new TestScript()");
System.out.println((String) interpreter.eval("script.getVersion(date)"));
System.exit(0);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (EvalError e) {
e.printStackTrace();
}
}
}


This is a pretty complete example as it shows how to call an existing class, pass parameters to it and accept returned values. Now imagine calling dynamic classes from servlets/struts actions, you wouldn't have to recompile your code and restart your server, just edit the dynamic file and view the page again. Best of all, because the dynamic classes are proper Java files, you still benefit from being able to use your existing development/debugging tools.


Sunday, November 23, 2003
 
Jakarta James FetchPOP
As the battle between Apache's Jakarta group and JBoss heats up, it seems that mail servers are the next target. Whilst JBoss are clearly ahead of Apache in terms of application servers, Apache have offered James, their mail server for several years now. However, the JBoss group seems to be developing a M$-based approach and devouring existing products to bolster their own product line. Eric Daugherty, who developed one of the leading Java mail servers JES (Java Email Server) is currently working with JBoss on their offering, but a full release still seems to be some time away.

In the mean time, I have been looking at James to solve some of the problems that I have being having with Spam. I wanted to set up a mail server that will poll my existing email accounts, remove spam and virii, and consolidate the results into a single POP3 account that I can use. At this stage, the Spam filtering is in place, but I'm investigating how to integrate ClamAV too to complete the solution.

Most aspects of James are quite mature at this stage, but one of the central componets that I required, FetchPOP, still suffers from a lack of clear documentation. Hopefully this blog can serve as a guide to people starting off on a similar quest.

Firstly, you will have a to acquire and unpack a copy of James, and create a user to test with. This aspect of James is well documented so I won't repeat the procedure. To collect all the mail from an existing account, try this

1. Open ${JAMES_HOME}/apps/james/SAR-INF/config.xml for edit and look for the FetchPOP section.
2. By default FetchPOP will be disabled, change <fetchpop enabled="false"> to <fetchpop enabled="true"> to enable it.
3. Create an new "fetch" entry in the FetchPOP section like this

<fetchpop enabled="true">
<fetch name="account_name">
<host>pop3.myisp.com</host>
<user>username</user>
<password>password</password>
<interval>600000</interval>
</fetch>
</fetchpop>

4. Now you have to tell the root processor what to do with messages from this account. Add this to the root processor's config section

<mailet match="FetchedFrom=account_name" class="ToProcessor">
<processor>fetchprocessor</processor>
</mailet>

This tells the root procesor to forward messages from account_name to another processor called "fetchprocessor".
5. Create a new process to deal with this messages


<processor name="fetchprocessor">
<mailet match="RecipientIs=me@isp.com" class="Forward">
<forwardto>me@localhost</forwardto>
</mailet>
</processor>


This processor tries to match the email address of the account that the message has been fetched from and will then forward it to the specified,local account.

Simple as that, you can add as many accounts as you want to the FetchPOP section, and James will try to filter the accounts for Spam. Next on the list? AV.
 
Aspectwerkz
Here is simple example of using Aspectwerkz to apply AOP to your code. I have downloaded and unpacked the Aspectwerkz (AW) code to c:\java\aspectwerkz. Note that this example is very similar to the example code on the AW site and Jonas' blog, I hope this doesn't upset anyone too much.

1. Create a simple bean to test with, here a very simple example POJO


package aspectz;

public class TestBean {

private String name;

public TestBean() {

}

public String getName() {
return name;
}

public void setName(String string) {
name = string;
}

}



2. Next, we need a class with a main() method to create an object of our bean class


package aspectz;

public class Runner {

public static void main(String[] args) {

TestBean bean = new TestBean();

bean.setName("te5t");

System.out.println(bean.getName());
}
}



3. Now we need to create the apectwerkz.xml file that is used to declare our aspects/pointcuts etc.


<!DOCTYPE aspectwerkz PUBLIC "-//AspectWerkz//DTD 0.8//EN" "http://aspectwerkz.codehaus.org/dtd/aspectwerkz_0_8.dtd">

<aspectwerkz id="samples">

<advice-def name="log" class="aspectz.LoggingAdvice" deployment-model="perJVM"/>

<aspect name="test">

<pointcut-def name="all" type="method" pattern="* aspectz..*+.*(..)"/>

<bind-advice pointcut="all">

<advice-ref name="log"/>

</bind-advice>

</aspect>

</aspectwerkz>



4. We now need to create our advice


package aspectz;

import org.codehaus.aspectwerkz.advice.AroundAdvice;
import org.codehaus.aspectwerkz.joinpoint.JoinPoint;
import org.codehaus.aspectwerkz.joinpoint.MethodJoinPoint;


public class LoggingAdvice extends AroundAdvice {


public LoggingAdvice() {
super();
}

public Object execute(final JoinPoint joinPoint) throws Throwable {

MethodJoinPoint jp = (MethodJoinPoint) joinPoint;

System.out.println("execute() called by "+ jp.getMethodName());

return joinPoint.proceed();
}


}


5. Now all we need to do is run the example. AW expects that you have defined JAVA_HOME and ASPECTWERKZ_HOME before running. Now you can run the example by typing c:\java\aspectwerkz-0.8.1\bin\aspectwerkz -Daspectwerkz.definition.file=C:\src\test\aspectwerkz.xml aspectz.Runner (Obviously your path names would/could be different. When you run this you will see the output of the AW wrapper and then the output of the program which will resemble something like this


execute() called by main
execute() called by setName
execute() called by getName
te5t

 
PHP and Tomcat - Perfect bed-fellows?
After installing Perl on Tomcat, I started getting a bit carried away so I had a quick look around to see if PHP had been integrated too. It turns out that a servlet wrapper is part of the core download of PHP, and with after a few minutes tinkering, I had it up and running too. These guildelines are for the windows version, but seeing as the PHP setup is well documented, you shouldn't hvae much trouble getting it set up. The only changes that I had t o make were to reflect the refactoring in Tomcat 4.1.

1. setup Tomcat - look at the docs at http://jakarta.apache.org, I'll refer to location where Tomcat is installed as %TOMCAT_HOME%
2. Download PHP, I'll refer to the location where you install it to as %PHP_HOME%
3. Add %PHP_Home%\ and %PHP_Home%\sapi to your %PATH% environment variable
4. Add the following to the %TOMCAT_HOME%\conf\web.xml


<servlet>
<servlet-name>php</servlet-name>
<servlet-class>net.php.servlet</servlet-class>
</servlet>

<servlet>
<servlet-name>php-formatter</servlet-name>
<servlet-class>net.php.formatter</servlet-class>
</servlet>

<servlet-mapping>
<servlet-name>php</servlet-name>
<url-pattern>*.php</url-pattern>
</servlet-mapping>

<servlet-mapping>
<servlet-name>php-formatter</servlet-name>
<url-pattern>*.phps</url-pattern>
</servlet-mapping>


5. Add phpsrvlt.jar to %TOMCAT_HOME%\common\lib

6. Uncomment the following line in your php.ini (you can copy php.ini-dist and rename to php.ini) ;extension=php_java.dll so it becomes extension=php_java.dll.

7. Change the lines in the [Java] setion of php.ini to reflect your environment

Now create a test php file and add the following to it


<?php phpinfo(); ?>


Now try and view the file in a browser and you should see a page listing all the info of the php environment.
 
Running Perl CGI's on Tomcat
This is essentially a rehash of a Java Pro article, I've just included it here in case the original article disappears. Here is a link to the original

http://www.fawcette.com/javapro/2003_03/online/perl_teden_03_18_03/

In short, Tomcat has a cgi servlet, to enable it rename the ${TOMCAT_HOME}/server/lib/servlets-cgi.renametojar to ${TOMCAT_HOME}/server/lib/servlets-cgi.jar and the same with the SSI jar (not sure if this is really required - didn't test). Then uncomment the mapping for the servlet so cgi-bin is mapped to the cgi servlet. You'll also have to create a WEB-INF/cgi folder in your web application ti hold the perl scripts.

When you have this set up, copy this script into the folder and view it in your browser (http://localhost:8080/${app_name}/cgi-bin/test.cgi for example)


#!C:\cygwin\bin\perl.exe
print "Hello World!";


You'll have to change the value after #! to be the correct location, but then, if you're reading an article on enabling Perl CGI you'll know that already ;-)

Wednesday, November 19, 2003
 
Load balanced workers2.properties
Here is a sample workers2.properties for load balancing between two jboss instances with Apache using mod_jk2. The example on the Apache site doesn't seemed to include load balancing...

[logger.apache2]
level=ERROR


[shm]
file=/opt/apache/logs/shm.file
size=8388608


[lb:jboss]


# Example socket channel, override port and host.
[channel.socket:channel1]
port=8009
host=192.168.0.1

#Example socket channel, override port and host.
[channel.socket:channel2]
port=8009
host=192.168.0.2


# define the worker
[ajp13:channel1]
group=jboss
lbfactor=1
tomcatId=server1:8009

# define the worker
[ajp13:channel2]
group=jboss
lbfactor=1
tomcatId=server2:8009

Powered by Blogger