Showing posts with label java. Show all posts
Showing posts with label java. Show all posts

Wednesday, October 15, 2014

How to find which method called the current method at runtime


I’m using the following helper class to find which method called the current method (at runtime.)

import java.lang.reflect.Method;
import java.security.AccessController;
import java.security.PrivilegedAction;

public class TraceHelper {
    private volatile static Method m;
    private static Throwable t;

    public TraceHelper() {
        try {
            m = Throwable.class.getDeclaredMethod("getStackTraceElement", int.class);
            AccessController.doPrivileged(
                    new PrivilegedAction() {
                        public Object run() {
                            m.setAccessible(true);
                            return null;
                        }
                    }
            );
            t = new Throwable();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public String getMethodName(final int depth, boolean useNew) {
        return getMethod(depth, t != null && !useNew ? t : new Throwable());
    }

    public String getMethod(final int depth, Throwable t) {
        try {
            StackTraceElement element = (StackTraceElement) m.invoke(t, depth + 1);
            return element.getClassName() + "$" + element.getMethodName();
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

}
Then I use the following code inside my aspect to get the name of the method which called my current (executing) method.
String previousMethodName = new TraceHelper().getMethodName(2, false);

Include/exclude sources when using aspect-maven-plugin


AspectJ mavn plugin will add all .java and .aj files in the project source directories by default. By using <include/> and <exclude/> tags, you can add filtering on top of that. 


            <plugin>
                <groupId>org.codehaus.mojo</groupId>
                <artifactId>aspectj-maven-plugin</artifactId>
                <version>1.5</version>
                <configuration>
                    <complianceLevel>1.7</complianceLevel>
                    <source>1.7</source>
                    <target>1.7</target>

                    <sources>
                        <source>
                            <!--<basedir>src/main/java</basedir>-->
                            <!--<includes>-->
                                <!--<include>**/TransationAspect.java</include>-->
                            <!--</includes>-->
                            <excludes>
                                <exclude>**/DcXferHandler.java</exclude>
                                <!--<exclude>**/ChunkingSqlSerActor.java</exclude>-->
                            </excludes>
                        </source>
                    </sources>
                </configuration>
                <executions>
                    <execution>
                        <!--<phase>process-sources</phase>-->
                        <goals>
                            <goal>compile</goal>
                            <goal>test-compile</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>

Tuesday, October 14, 2014

Stackmap frame errors when building the aspectj project with Java 1.7


I had a project which used aspectj and it was building fine with Java 1.6. When I updated it to Java 1.7 I saw the following error.

[INFO] Molva the Destroyer Aspects ....................... FAILURE [2.324s]
[INFO] Molva The Destroyer Client ........................ SKIPPED
[INFO] Molva The Destroyer Parent ........................ SKIPPED
[INFO] Molva The Destroyer Distribution .................. SKIPPED
[INFO] ------------------------------------------------------------------------
[INFO] BUILD FAILURE
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 2.424s
[INFO] Finished at: Tue Oct 14 11:16:19 PDT 2014
[INFO] Final Memory: 12M/310M
[INFO] ------------------------------------------------------------------------
[ERROR] Failed to execute goal org.codehaus.mojo:exec-maven-plugin:1.1:java (default) on project molva-the-destroyer-aspects: An exception occured while executing the Java class. Expecting a stackmap frame at branch target 30
[ERROR] Exception Details:
[ERROR] Location:
[ERROR] com/concur/puma/molva/aspects/TestTarget.main([Ljava/lang/String;)V @12: invokestatic
[ERROR] Reason:
[ERROR] Expected stackmap frame at this location.
[ERROR] Bytecode:
[ERROR] 0000000: 2a4d b200 5e01 012c b800 644e b800 c62d
[ERROR] 0000010: b600 ca2c 2db8 00bb 2db8 00bf 57b1 3a04
[ERROR] 0000020: b800 c62d 1904 b600 ce19 04bf
[ERROR] Exception Handler Table:
[ERROR] bci [12, 30] => handler: 30
[ERROR] -> [Help 1]
[ERROR]
[ERROR] To see the full stack trace of the errors, re-run Maven with the -e switch.
[ERROR] Re-run Maven using the -X switch to enable full debug logging.
[ERROR]
[ERROR] For more information about the errors and possible solutions, please read the following articles:
[ERROR] [Help 1] http://cwiki.apache.org/confluence/display/MAVEN/MojoExecutionException

My maven configuration looked like below.
    <dependencies>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>3.8.1</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjrt</artifactId>
            <version>1.6.5</version>
        </dependency>
        <dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
            <version>1.2.17</version>
        </dependency>
        <dependency>
            <groupId>org.perf4j</groupId>
            <artifactId>perf4j</artifactId>
            <version>0.9.16</version>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.codehaus.mojo</groupId>
                <artifactId>aspectj-maven-plugin</artifactId>
                <version>1.2</version>
                <configuration>
                    <source>1.7</source>
                    <target>1.7</target>
                </configuration>
                <executions>
                    <execution>
                        <goals>
                            <goal>compile</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
            <plugin>
                <groupId>org.codehaus.mojo</groupId>
                <artifactId>exec-maven-plugin</artifactId>
                <version>1.1</version>
                <executions>
                    <execution>
                        <phase>package</phase>
                        <goals>
                            <goal>java</goal>
                        </goals>
                    </execution>
                </executions>
                <configuration>
                    <mainClass>com.concur.puma.molva.aspects.TestTarget</mainClass>
                </configuration>
            </plugin>
        </plugins>
    </build>

Fix 

The default compliance level for aspectj-maven-plugin is 1.4 according to http://mojo.codehaus.org/aspectj-maven-plugin/compile-mojo.html#complianceLevel. Since I did not have that tag specified, the build was using the default value. Once I inserted the tag into the configuration, the build was successful.

Compile aspectj project containing Java 1.7 Source


Following maven configuration let’s you compile a project with Java 1.7 source.
<dependencies>
        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjrt</artifactId>
            <!--<version>1.6.5</version>-->
            <version>1.8.2</version>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.codehaus.mojo</groupId>
                <artifactId>aspectj-maven-plugin</artifactId>
                <version>1.7</version>
                <configuration>
                    <complianceLevel>1.7</complianceLevel>
                    <source>1.7</source>
                    <target>1.7</target>
                </configuration>
                <executions>
                    <execution>
                        <!--<phase>process-sources</phase>-->
                        <goals>
                            <goal>compile</goal>
                            <goal>test-compile</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>

Tuesday, March 25, 2014

Custom Log Formatter

Following is the source for a custom log formatter.

import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.logging.Formatter;
import java.util.logging.Handler;
import java.util.logging.LogRecord;

public class CustomFormatter extends Formatter {

    private static final DateFormat df = new SimpleDateFormat("dd/MM/yyyy hh:mm:ss.SSS");

    public String format(LogRecord record) {
        StringBuilder builder = new StringBuilder(1000);
        builder.append(df.format(new Date(record.getMillis()))).append(" - ");
        builder.append("[").append(record.getSourceClassName()).append(".");
        builder.append(record.getSourceMethodName()).append("] - ");
        builder.append("").append(record.getLevel()).append(" - ");
        builder.append(formatMessage(record));
        builder.append("\n");
        return builder.toString();
    }

    public String getHead(Handler h) {
        return super.getHead(h);
    }

    public String getTail(Handler h) {
        return super.getTail(h);
    }
}

Following is the way how the log messages will turn up in your log file.

25/03/2014 08:46:17.770 - [com.company.util.memcache.EntityThreadTask.setDataToMemcache] - INFO - thread05 compositekey set time : 5 ms
25/03/2014 08:46:17.781 - [com.company.util.memcache.EntityThreadTask.setDataToMemcache] - INFO - thread03 compositekey set time : 11 ms
25/03/2014 08:46:17.783 - [com.company.util.memcache.EntityThreadTask.setDataToMemcache] - INFO - thread05 compositekey set time : 12 ms
25/03/2014 08:46:17.785 - [com.company.util.memcache.EntityThreadTask.setDataToMemcache] - INFO - thread03 compositekey set time : 4 ms
25/03/2014 08:46:17.787 - [com.company.util.memcache.EntityThreadTask.setDataToMemcache] - INFO - thread05 compositekey set time : 4 ms

Thursday, January 30, 2014

Aspect oriented programming with Java

I started working with AspectJ and Perf4J recently. I did not have any prior AOP experience. I was looking for an example which did not use Spring AOP but I did not find a good sample which I could use to get my work done. Therefore, once I completed my project, thought of writing this sample up. There are a lot of tutorials out there which describes what AOP is. Therefore, I’m not going to introduce it here. You can do a Google search and find it out.

What I wanted was to measure the method runtimes without doing any modifications to the existing source. AspectJ helped me to achieve that.

Following are my sample source code. Following is my test class which I'm using to measure method runtimes.
import org.apache.log4j.Logger;

public class TestTarget {

    static Logger logger = Logger.getLogger(TestTarget.class);

    public static void main(String[] args) throws Exception {
        // Test case 01
        testCountFast(1000);

        // Test case 02
        testCountSlow(1000);

    }

    public static void testCountSlow(int value) {
        count(value,5);
    }

    public static void testCountFast(int value) {
        count(value,0);
    }

    private static void count(int value, int delay) {
        for (int i=0;i<value;i++) {
            try {
                Thread.sleep(delay);
            } catch (Exception e) {
                logger.error("Error occurred while sleeping", e);
            }
        }
    }

}
Following is my Aspect class which uses AspectJ and Perf4J.
import org.apache.log4j.Logger;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.perf4j.StopWatch;
import org.perf4j.log4j.Log4JStopWatch;

@Aspect
public class Perf4JAspect {
    static Logger logger = Logger.getLogger(Perf4JAspect.class);

    @Around("execution (* com.company.molva.aspectj.TestTarget.test*(..))")
    public Object measureExecutionTime(ProceedingJoinPoint joinPoint) throws Throwable {
        logger.info(MolvaLoggingUtil.getCurrentDateTime()
                + " MainAspect.measureExecutionTime() called on " + joinPoint.getSignature());

        long startNanoTime = System.nanoTime();
        StopWatch stopWatch = new Log4JStopWatch();
        Object proceed = joinPoint.proceed();
        stopWatch.stop(joinPoint.getSignature().toLongString());

        long endNanoTime = System.nanoTime();
        long executionNanoTime = endNanoTime - startNanoTime;
        logger.info(MolvaLoggingUtil.getCurrentDateTime() + " "
                + joinPoint.getSignature()+" took "+ executionNanoTime/1000000.0 +"ms");
        return proceed;
    }
}
My aop.xml configuration is as follows.
<aspectj>
    <aspects>
        <aspect name="com.company.molva.aspectj.MainAspect"/>
        <aspect name="com.company.molva.aspectj.Perf4JAspect"/>
    </aspects>

    <weaver options="-verbose">
        <include within="com.aspectj.*"/>
    </weaver>
</aspectj>
My log4j.xml looks as follows.
 
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">

<log4j:configuration debug="false" xmlns:log4j="http://jakarta.apache.org/log4j/">

    <appender name="aspectjFileAppender" class="org.apache.log4j.FileAppender">
        <param name="File" value="aspectj_stats.log"/>
        <layout class="org.apache.log4j.PatternLayout">
            <param name="ConversionPattern" value="%m%n"/>
        </layout>
    </appender>
 
    <appender name="CoalescingStatistics"
              class="org.perf4j.log4j.AsyncCoalescingStatisticsAppender">
        <param name="TimeSlice" value="10000"/>
        <appender-ref ref="fileAppender"/>
    </appender>

    <appender name="fileAppender" class="org.apache.log4j.FileAppender">
        <param name="File" value="perf_stats.log"/>
        <layout class="org.apache.log4j.PatternLayout">
            <param name="ConversionPattern" value="%m%n"/>
        </layout>
    </appender>

     <logger name="org.perf4j.TimingLogger" additivity="false">
        <level value="INFO"/>
        <appender-ref ref="CoalescingStatistics"/>
    </logger>

    <root>
        <level value="INFO"/>
        <appender-ref ref="aspectjFileAppender"/>
    </root>
    
</log4j:configuration>
Once the sample completes running, I get the following logs at my log files.
aspectj_stats.log:
2014-01-30 13:19:25 MainAspect.measureExecutionTime() called on void com.company.molva.aspectj.TestTarget.testCountFast(int)
2014-01-30 13:19:25 void com.company.molva.aspectj.TestTarget.testCountFast(int) took 0.904ms
2014-01-30 13:19:25 MainAspect.measureExecutionTime() called on void com.company.molva.aspectj.TestTarget.testCountSlow(int)
2014-01-30 13:19:31 void com.company.molva.aspectj.TestTarget.testCountSlow(int) took 5608.996ms
perf_stats.log:
Performance Statistics   2014-01-30 13:19:20 - 2014-01-30 13:19:30
Tag                                                                        Avg(ms)         Min         Max     Std Dev       Count
public static void com.company.molva.aspectj.TestTarget.testCountFast(int)     0.0           0           0         0.0           1
public static void com.company.molva.aspectj.TestTarget.testCountSlow(int)  5608.0        5608        5608         0.0           1
As you can see, we can use AspectJ and Perf4J to generate some nice statistics.

Java library to convert XML to JSON

Recently I wanted to convert some XMLs to JSON messages. I came across this library called JSON-Java and found it very useful.
import org.json.JSONException;
import org.json.JSONObject;
import org.json.XML;

public class Main {

    public static int PRETTY_PRINT_INDENT_FACTOR = 4;
    public static String TEST_XML_STRING =
            "\n" +
                    "\n" +
                    "Belgian Waffles\n" +
                    "$5.95\n" +
                    "\n" +
                    "Two of our famous Belgian Waffles with plenty of real maple syrup\n" +
                    "\n" +
                    "650\n" +
                    "\n" +
                    "\n" +
                    "Strawberry Belgian Waffles\n" +
                    "$7.95\n" +
                    "\n" +
                    "Light Belgian waffles covered with strawberries and whipped cream\n" +
                    "\n" +
                    "900\n" +
                    "\n" +
                    "";

    public static void main(String[] args) {
        try {
            JSONObject xmlJSONObj = XML.toJSONObject(TEST_XML_STRING);
            String jsonPrettyPrintString = xmlJSONObj.toString(PRETTY_PRINT_INDENT_FACTOR);
            System.out.println(jsonPrettyPrintString);
        } catch (JSONException je) {
            System.out.println(je.toString());
        }
    }
}
The XML:
<breakfast_menu>
<food>
<name>Belgian Waffles</name>
<price>$5.95</price>
<description>
Two of our famous Belgian Waffles with plenty of real maple syrup
</description>
<calories>650</calories>
</food>
<food>
<name>Strawberry Belgian Waffles</name>
<price>$7.95</price>
<description>
Light Belgian waffles covered with strawberries and whipped cream
</description>
<calories>900</calories>
</food>
</breakfast_menu>
JSON:
{"breakfast_menu": {"food": [
    {
        "price": "$5.95",
        "description": "Two of our famous Belgian Waffles with plenty of real maple syrup",
        "name": "Belgian Waffles",
        "calories": 650
    },
    {
        "price": "$7.95",
        "description": "Light Belgian waffles covered with strawberries and whipped cream",
        "name": "Strawberry Belgian Waffles",
        "calories": 900
    }
]}}

Friday, April 2, 2010

Using Event Broker in WSO2 Carbon to generate Events

Following code/configuration show what are required to make use of the event broker in carbon to generate events. In the following example we are looking at how to generate an email notification.

1). Declarative Service Component to obtain the service URL.

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.axis2.context.ConfigurationContext;
import org.apache.axis2.engine.AxisConfiguration;
import org.apache.axis2.engine.ListenerManager;
import org.apache.axis2.addressing.EndpointReference;
import org.apache.axis2.AxisFault;
import org.apache.log4j.*;
import org.osgi.service.component.ComponentContext;
import org.osgi.framework.BundleContext;
import org.wso2.carbon.utils.ConfigurationContextService;
import org.wso2.carbon.utils.NetworkUtils;
import org.wso2.carbon.eventing.broker.services.EventBrokerService;

import java.net.SocketException;

/**
* @scr.component name="org.wso2.carbon.health.service" immediate="true"
* @scr.reference name="configuration.context.service"
* interface="org.wso2.carbon.utils.ConfigurationContextService" cardinality="1..1"
* policy="dynamic" bind="setConfigurationContextService" unbind="unsetConfigurationContextService"
* @scr.reference name="listener.manager.service"
* interface="org.apache.axis2.engine.ListenerManager" cardinality="0..1" policy="dynamic"
* bind="setListenerManager" unbind="unsetListenerManager"
* @scr.reference name="eventbroker.service"
* interface="org.wso2.carbon.eventing.broker.services.EventBrokerService"
* cardinality="1..1" policy="dynamic" target="(name=HealthMonitorEventBroker)"
* bind="setHealthMonitorEventBrokerService" unbind="unsetHealthMonitorEventBrokerService"
*/
public class HealthMonitorEventingServiceComponent {
private static Log log = LogFactory.getLog(HealthMonitorEventingServiceComponent.class);

private boolean configurationDone = false;

private ConfigurationContextService configurationContextService = null;

private ListenerManager listenerManager = null;

private boolean initialized = false;

private static EventBrokerService healthMonitorEventBrokerService = null;

private String endpoint = null;

private static BundleContext bundleContext = null;

static Logger logger = Logger.getLogger(HealthMonitorEventingServiceComponent.class);

Logger rootLogger = LogManager.getRootLogger();

protected void activate(ComponentContext context) {
bundleContext = context.getBundleContext();
}

public static BundleContext getBundleContext() {
return bundleContext;
}

private void initializeAppender() {
if (listenerManager == null || healthMonitorEventBrokerService == null) {
return;
}
System.out.println("Carbon Health Monitor started!");

rootLogger.addAppender(new JiraAppender());
log.info("Jira appender added to the root logger");
// Setting level of root logger
//rootLogger.setLevel(Level.DEBUG);

addAppenders();
rootLogger.error("This log message is used to trigger the JiraAppender");
}

public void addAppenders() {
SimpleLayout layout = new SimpleLayout();
FileAppender appender = null;
try {
appender = new FileAppender(layout, "/tmp/output1.txt", false);
} catch (Exception e) {
logger.error(e);
}

rootLogger.addAppender(appender);
logger.debug("DEBUG message 2");
logger.debug("DEBUG message 3");
log.info("Appender added to the logger");
}

protected void deactivate(ComponentContext context) {
}

protected void setConfigurationContextService(ConfigurationContextService configurationContextService) {
this.configurationContextService = configurationContextService;
}

protected void unsetConfigurationContextService(ConfigurationContextService configurationContextService) {
}

protected void setHealthMonitorEventBrokerService(EventBrokerService healthMonitorEventBrokerService) {
this.healthMonitorEventBrokerService = healthMonitorEventBrokerService;
initializeAppender();
}

protected void unsetHealthMonitorEventBrokerService(EventBrokerService healthMonitorEventBrokerService) {
this.healthMonitorEventBrokerService = null;
}

protected void setListenerManager(ListenerManager listenerManager) {
this.listenerManager = listenerManager;
initialize();
initializeAppender();
}

protected void unsetListenerManager(ListenerManager listenerManager) {
this.listenerManager = null;
}

private void initialize() {
ConfigurationContext serverConfigurationContext = configurationContextService.getServerConfigContext();
if (!configurationDone && listenerManager != null) {
String host = null;
try {
host = NetworkUtils.getLocalHostname();
} catch (SocketException e) { }
if (serverConfigurationContext != null) {
AxisConfiguration config = serverConfigurationContext.getAxisConfiguration();
if (config != null && config.getTransportIn("http") != null &&
config.getTransportIn("http").getReceiver() != null) {
try {
EndpointReference[] eprArray = config.getTransportIn("http")
.getReceiver().getEPRsForService("HealthMonitorEventingService",
host);
if (eprArray != null && eprArray[0] != null) {
endpoint = eprArray[0].getAddress();
}
} catch (AxisFault e) { }
}
}
configurationDone = true;
}
}

public static EventBrokerService getHealthMonitorEventBrokerService() {
return healthMonitorEventBrokerService;
}
}


2). Generating Events.

OMFactory fac = OMAbstractFactory.getOMFactory();
Event<OMElement> event = new Event<OMElement>(zipElement);
event.setTopic("/mail-sending/mail");
OMElement topic = EventBrokerUtils.buildTopic(fac,event);
EventBrokerUtils.generateEvent(event.getMessage(), topic, HealthMonitorEventingServiceComponent.getHealthMonitorEventBrokerService());


3). The services.xml for the service.

<serviceGroup>
<service name="HealthMonitorEventingService" targetNamespace="http://eventing.registry.carbon.wso2.org">
<transports>
<transport>http</transport>
</transports>
<description>
Health Monitor Eventing Service
</description>
<messageReceivers>
<messageReceiver mep="http://www.w3.org/2004/08/wsdl/in-only"
class="org.wso2.carbon.eventing.broker.receivers.CarbonEventingMessageReceiver"/>
<messageReceiver mep="http://www.w3.org/2004/08/wsdl/in-out"
class="org.wso2.carbon.eventing.broker.receivers.CarbonEventingMessageReceiver"/>
</messageReceivers>
<parameter name="enableSubscribe" locked="true">true</parameter>
<operation name="Subscribe" mep="http://www.w3.org/ns/wsdl/in-out">
<actionMapping>http://schemas.xmlsoap.org/ws/2004/08/eventing/Subscribe</actionMapping>
</operation>
<parameter name="enableRenew" locked="true">false</parameter>
<!--operation name="Renew" mep="http://www.w3.org/ns/wsdl/in-out">
<actionMapping>http://schemas.xmlsoap.org/ws/2004/08/eventing/Renew</actionMapping>
</operation-->
<parameter name="enableUnsubscribe" locked="true">false</parameter>
<!--operation name="Unsubscribe" mep="http://www.w3.org/ns/wsdl/in-out">
<actionMapping>http://schemas.xmlsoap.org/ws/2004/08/eventing/Unsubscribe</actionMapping>
</operation-->
<parameter name="enableGetStatus" locked="true">false</parameter>
<!--operation name="GetStatus" mep="http://www.w3.org/ns/wsdl/in-out">
<actionMapping>http://schemas.xmlsoap.org/ws/2004/08/eventing/GetStatus</actionMapping>
</operation-->
<operation name="Publish" mep="http://www.w3.org/ns/wsdl/in-out">
<actionMapping>http://ws.apache.org/ws/2007/05/eventing-extended/Publish</actionMapping>
</operation>

<parameter name="eventBrokerInstance" locked="true">HealthMonitorEventBroker</parameter>
</service>
<parameter name="hiddenService" locked="true">true</parameter>
</serviceGroup>


4). Event Broker configuration

<eventBroker xmlns="http://wso2.org/ns/2009/09/eventing">
<eventStream name="HealthMonitorEventBroker">
<subscriptionManager class="org.wso2.carbon.eventing.impl.EmbeddedRegistryBasedSubscriptionManager">
<parameter name="topicHeaderName">topic</parameter>
<parameter name="topicHeaderNS">http://wso2.org/ns/2009/09/eventing/notify</parameter>
<parameter name="subscriptionStoragePath">/carbon/eventing/registry</parameter>
</subscriptionManager>
<!-- Uncomment to to RemoteRegistryBasedSubscriptionManager -->
<!--subscriptionManager class="org.wso2.carbon.eventing.impl.RemoteRegistryBasedSubscriptionManager">
<parameter name="topicHeaderName">topic</parameter>
<parameter name="topicHeaderNS">http://wso2.org/ns/2009/09/eventing/notify</parameter>
<parameter name="subscriptionStoragePath">/carbon/eventing/registry</parameter>
<parameter name="registryURL">http://remote-ip:port/registry/</parameter>
<parameter name="username">username</parameter>
<parameter name="password">password</parameter>
</subscriptionManager-->
<!--<eventDispatcher>org.wso2.carbon.registry.eventing.RegistryEventDispatcher</eventDispatcher>-->
<eventDispatcher>org.wso2.carbon.eventing.broker.CarbonEventDispatcher</eventDispatcher>
<notificationManager class="org.wso2.carbon.eventing.broker.CarbonNotificationManager">
<parameter name="minSpareThreads">25</parameter>
<parameter name="maxThreads">150</parameter>
<parameter name="maxQueuedRequests">100</parameter>
<!-- Keep Alive time in nano seconds -->
<parameter name="keepAliveTime">1000</parameter>
<!-- Specify path of security policy file to enable security. -->
<!--parameter name="securityPolicy">policypath</parameter-->

<!-- Parameters specific to the Registry Event Broker configuration -->
<!-- Set this as false to disable displaying of registry URL in notification e-mails -->
<parameter name="showRegistryURL" locked="true">true</parameter>
</notificationManager>
</eventStream>
</eventBroker>


I have used the above method to generate email notifications within the Carbon Health Monitor component which I developed. More info on Health Monitor component will be discussed later.

Programmetically add Log4J Appenders

Following code snippet shows how to programmetically add log4j Appenders to your java code.

import org.apache.log4j.ConsoleAppender;
import org.apache.log4j.FileAppender;
import org.apache.log4j.Level;
import org.apache.log4j.Logger;
import org.apache.log4j.PatternLayout;
import org.apache.log4j.SimpleLayout;

public class SampleLoggingAppender {
static Logger logger = Logger.getLogger(SampleLoggingAppender.class);

public static void main(String args[]) {
SimpleLayout layout = new SimpleLayout();
FileAppender fileAppender = null;
try {
fileAppender = new FileAppender(layout, "log.txt", false);
} catch (Exception ignored) {
}

ConsoleAppender consoleAppender = new ConsoleAppender(new PatternLayout());

logger.addAppender(fileAppender);
logger.addAppender(consoleAppender);
logger.setLevel(Level.DEBUG);

logger.debug("DEBUG");
logger.info("INFO");
logger.warn("WARN");
logger.error("ERROR");
logger.fatal("FATAL");
}
}

Saturday, March 27, 2010

Restore a Registry Resource stored in a file to WSO2 Registry

Following code snippet shows, how to programmetically restore a Registry Resourece written in to a file, back to WSO2 Registry using RemoteRegistry. This is a follow-up to an earlier blogpost.

import org.wso2.carbon.registry.app.RemoteRegistry;
import org.wso2.carbon.registry.core.exceptions.RegistryException;

import java.net.URL;
import java.net.MalformedURLException;
import java.io.FileWriter;
import java.io.FileReader;
import java.io.IOException;

public class RemoteRegistrySampleTest {
public static void main(String[] args) {
System.setProperty("javax.net.ssl.trustStore", "CARBON_HOME/resources/security/client-truststore.jks");
System.setProperty("javax.net.ssl.trustStorePassword", "wso2carbon");
System.setProperty("javax.net.ssl.trustStoreType", "JKS");

RemoteRegistry esb2xRemoteRegistry = null;
try {
esb2xRemoteRegistry = new RemoteRegistry(new URL("https://localhost:9443/registry"),
"admin", "admin");
esb2xRemoteRegistry.restore("/esb-resources", new FileReader("/home/heshan/Dev/wso2_heshan/temp/registry.xml"));
} catch (RegistryException e) {
e.printStackTrace();
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}

}
}

Backup WSO2 Registry Resource to a file

Following code snippet shows, how to programmetically backup WSO2 Registry Resource to a file using RemoteRegistry.

import org.wso2.carbon.registry.app.RemoteRegistry;
import org.wso2.carbon.registry.core.exceptions.RegistryException;

import java.net.URL;
import java.net.MalformedURLException;
import java.io.FileWriter;
import java.io.FileReader;
import java.io.IOException;

public class RemoteRegistrySampleTest {
public static void main(String[] args) {
System.setProperty("javax.net.ssl.trustStore", "CARBON_HOME/resources/security/client-truststore.jks");
System.setProperty("javax.net.ssl.trustStorePassword", "wso2carbon");
System.setProperty("javax.net.ssl.trustStoreType", "JKS");

RemoteRegistry esb2xRemoteRegistry = null;
try {
esb2xRemoteRegistry = new RemoteRegistry(new URL("https://localhost:9443/registry"),
"admin", "admin");
esb2xRemoteRegistry.dump("/esb-resources", new FileWriter("/home/heshan/Dev/wso2_heshan/temp/registry.xml"));
} catch (RegistryException e) {
e.printStackTrace();
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}

}
}

Tuesday, March 2, 2010

Remove Line Breaks From a Java String

Following code snippet shows how to remove line termination characters from a String.


import java.util.regex.*;

public class ClassA {
public static void main(String args []) {
String inputText = "sdfsdfsf\nsdfsdfsd";
String inputText2 = "var trpListenerGr\naphDivId = #trpLi\nstenerGraph2\n";
RemoveLineTerminationCharacterss(inputText);
System.out.println("-------------------------------");
RemoveLineTerminationCharacterss(inputText2);

}

public static String RemoveLineTerminationCharacterss(String inputText){
Pattern p;
Matcher m;
System.out.println(" Input Text : " + inputText);
p = Pattern.compile("\n");
m = p.matcher(inputText);
String str = m.replaceAll("");
System.out.println(" OUtput Text: " + str);
return str;
}
}

Wednesday, January 20, 2010

Access JMX MBean information through RMI

This is a follow up to my earlier post.
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import javax.management.remote.JMXServiceURL;
import javax.management.remote.JMXConnector;
import javax.management.remote.JMXConnectorFactory;
import javax.management.*;
import javax.management.openmbean.CompositeData;
import java.lang.management.ManagementFactory;
import java.net.MalformedURLException;
import java.io.IOException;
import java.util.Set;

public class JmxReport {
private static final Log log = LogFactory.getLog(JmxReport.class);

public static void logJmxInfo() {
// Operating System MXBean
log.info("Operating system architecture : " + ManagementFactory.getOperatingSystemMXBean().getArch());
log.info("Available processors : " + ManagementFactory.getOperatingSystemMXBean().getAvailableProcessors());
log.info("Operating system name : " + ManagementFactory.getOperatingSystemMXBean().getName());
log.info("System load average : " + ManagementFactory.getOperatingSystemMXBean().getSystemLoadAverage());
log.info("Operating system version : " + ManagementFactory.getOperatingSystemMXBean().getVersion());

// Memory MXBean
log.info("Heap memory usage : " + ManagementFactory.getMemoryMXBean().getHeapMemoryUsage().toString());
log.info("Non-heap memory usage : " + ManagementFactory.getMemoryMXBean().getNonHeapMemoryUsage().toString());

// Class loading MXBean
log.info("Loaded class count : " + ManagementFactory.getClassLoadingMXBean().getLoadedClassCount());
log.info("Total loaded class count : " + ManagementFactory.getClassLoadingMXBean().getTotalLoadedClassCount());
log.info("Unloaded class count : " + ManagementFactory.getClassLoadingMXBean().getUnloadedClassCount());
}

public static void getJmxStatisticsViaRmi() {
try {
String jmxAgentName = "org.apache.synapse";
MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();

JMXConnector c = JMXConnectorFactory.newJMXConnector(createConnectionURL("heshan-laptop", 1099), null/*map*/);
c.connect();
Object o = c.getMBeanServerConnection().getAttribute(new ObjectName("java.lang:type=Memory"), "HeapMemoryUsage");
CompositeData cd = (CompositeData) o;
System.out.println(cd.get("committed"));

Object object2 = c.getMBeanServerConnection().getObjectInstance(new ObjectName("org.apache.synapse:Type=Transport,ConnectorName=nio-http-listener"));
Object lastResetTime = c.getMBeanServerConnection().getAttribute(new ObjectName("org.apache.synapse:Type=Transport,ConnectorName=nio-http-listener"), "LastResetTime");
System.out.println("lastResetTime : " + lastResetTime.toString());

ObjectName objName = new ObjectName("org.apache.synapse:Type=Transport,ConnectorName=nio-http-listener");
Set set2 = mbs.queryNames(objName, null);
for (Object o2 : set2) {
log.info(" :: " + o2.toString());
}
} catch (MalformedObjectNameException e) {
e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
} catch (InstanceNotFoundException e) {
e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
} catch (MalformedURLException e) {
e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
} catch (IOException e) {
e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
} catch (ReflectionException e) {
e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
} catch (AttributeNotFoundException e) {
e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
} catch (MBeanException e) {
e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
}
}

private static JMXServiceURL createConnectionURL(String host, int port) throws MalformedURLException {
JMXServiceURL serviceURL = new JMXServiceURL("rmi", "", 0, "/jndi/rmi://" + host + ":" + port + "/synapse");
/* To monitor JMX info of Carbon Platform need to enable jmx port @ carbon.xml
The link is service:jmx:rmi:///jndi/rmi://10.100.1.143:9999/server
*/
return serviceURL;
}

public static void main(String args[]) {
getJmxStatisticsViaRmi();
}
}

Programmetically access JMX MBean information


import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import java.lang.management.ManagementFactory;

public class JmxReport {
private static final Log log = LogFactory.getLog(JmxReport.class);

public static void logJmxInfo() {
// Operating System MXBean
log.info("Operating system architecture : " + ManagementFactory.getOperatingSystemMXBean().getArch() );
log.info("Available processors : " + ManagementFactory.getOperatingSystemMXBean().getAvailableProcessors() );
log.info("Operating system name : " + ManagementFactory.getOperatingSystemMXBean().getName() );
log.info("System load average : " + ManagementFactory.getOperatingSystemMXBean().getSystemLoadAverage() );
log.info("Operating system version : " + ManagementFactory.getOperatingSystemMXBean().getVersion() );

// Memory MXBean
log.info("Heap memory usage : " + ManagementFactory.getMemoryMXBean().getHeapMemoryUsage().toString() );
log.info("Non-heap memory usage : " + ManagementFactory.getMemoryMXBean().getNonHeapMemoryUsage().toString() );

// Class loading MXBean
log.info("Loaded class count : " + ManagementFactory.getClassLoadingMXBean().getLoadedClassCount() );
log.info("Total loaded class count : " + ManagementFactory.getClassLoadingMXBean().getTotalLoadedClassCount() );
log.info("Unloaded class count : " + ManagementFactory.getClassLoadingMXBean().getUnloadedClassCount() );


}

public static void main(String args[]) {
logJmxInfo();
}
}

Thursday, September 10, 2009

Create ZIP archieve from multiple files

Following code snippet shows how to create a zip archieve from multiple files.

import java.util.zip.*;
import java.util.Iterator;
import java.util.List;
import java.util.ArrayList;
import java.io.*;

public class ZipDemo {
static int BUFFER_SIZE = 1024;
static String zipArchieveName = "allfiles.zip";

public static void main(String args[]) {
try {
// Reference to the file we will be adding to the zipfile
BufferedInputStream origin = null;

// Reference to zip file
FileOutputStream dest = new FileOutputStream(zipArchieveName);

// Wrap our destination zipfile with a ZipOutputStream
ZipOutputStream out = new ZipOutputStream(new BufferedOutputStream(dest));

// Create a byte[] buffer that we will read data from the source
// files into and then transfer it to the zip file
byte[] data = new byte[BUFFER_SIZE];

List files = new ArrayList();
files.add("/tmp/systemInfo.txt");
files.add("/tmp/osgiInfo.txt");
files.add("/tmp/errorInfo.txt");

// Iterate over all of the files in list
for (Iterator i = files.iterator(); i.hasNext();) {
// Get a BufferedInputStream that we can use to read the source file
String filename = (String) i.next();
System.out.println("Adding: " + filename);
FileInputStream fi = new FileInputStream(filename);
origin = new BufferedInputStream(fi, BUFFER_SIZE);

// Setup the entry in the zip file
ZipEntry entry = new ZipEntry(filename);
out.putNextEntry(entry);

// Read data from the source file and write it out to the zip file
int count;
while ((count = origin.read(data, 0, BUFFER_SIZE)) != -1) {
out.write(data, 0, count);
}

// Close the source file
origin.close();
}

// Close the zip file
out.close();
}
catch (Exception e) {
e.printStackTrace();
}
}
}

Thursday, July 10, 2008

"SUN Setting" their eyes on Python



SUN is planning to support Jython and Python languages. This will be done in their future Netbeans IDE releases. It will support Syntax highlighting with version support, Code Completion, Python/Jython support, PyUnit support, Debugger support, Python library manager, Bundled Jython Package and Execution of python scripts. Earlier this year SUN hired Frank Wierzbicki (who is leading the Jython project). I think he might be one of the forces behind this decision. So it is a good news that SUN opted to support Jython and Python.

What is Jython?



JPython was the first implementation of Python programming language in java. Then the project was moved to SourceForge and renamed Jython. Jython is a programming hybrid. It exhibits the strengths of both its parents, namely Java and Python. Since Jython is written in 100% pure java , scripts written using jython will run on top of any compliant Java Virtual Machine (JVM). Jython interpreter will support existing java libraries as if they were your own python modules.
I have been playing around with Jython for about 6 months now. I have an idea to start a mini-tutorial series out of the knowledge I gathered upto now. So stay tuned in to my blog ;)