Saturday, December 6, 2008

What to do if Remote JMS Client can not get factory and throw classcastexception?

What to do if Remote JMS Client can not get factory and throw classcastexception?

First: Add the following property to initialcontext like:

props.put("java.naming.factory.initial", "org.jnp.interfaces.NamingContextFactory");
props.put("java.naming.provider.url", "jnp://localhost:1099");
props.put("java.naming.factory.url.pkgs", "org.jboss.naming:org.jnp.interfaces");

ctx = new InitialContext(props);

Second: Check the version of jar file: jboss-messaging-client. It has to have the same version with jms in jboss.

That's all

Thursday, September 25, 2008

JMS on JBoss using EJB3 MDB

Introduction

This simple JMS application has you submit a form which sends a message to a JBoss queue. A Message-Driven Bean (MDB) will be listening on that queue destination and receives the mssage and processes it. What makes this lesson different than this one is that this MDB example runs in an EJB3 container and the MDB is exposed using a simple annotation. To appreciate this simple example, it will really help to view the 'old way' of having to do things in the link above. With the EJB3 approach there is a lot less configuration. We don not need to configure the jboss-web.xml, destinations-service.xml, ejb-jar.xml, or the jboss.xml.
The Setup
Download the source Download the source above and unzip it into your project directory of choice. For eclipse users the source comes with an eclipse project so you can just import that project file and be good to go. To build using ant, type 'ant all' or if you want to build and deploy to jboss type 'ant deploy' to build and deploy the ear to JBoss.

Java5 The Java5 JDK needs to be set as your environment. JAVA_HOME env variable needs to be defined pointing to yth the JDK home directory.

JBoss 4.2+ - Download JBoss 4.2 here http://labs.jboss.com/portal/jbossas/download. (This should also run on 4.0.5 if it's patched to support EJB3 using the JEMS installer.)

Running the example If you've built the project usingg ant (ant deploy), the ear will be deployed to jboss and you simply go to your jboss home dir/bin and start jboss with run.sh (Nix flavors) or run.bat (Windows). If you want to just see the app run you can download the ear above and put the ear into your jboss/default/deploy directory. Once jboss is started, go the following url: http://localhost:8080/rr-jms

LongProcessMessageBean
This is our Message Driven Bean. Notice the EJB3 annotations. The annotation tells the container to deploy this as an Message Driven Bean and it also creates the queue based off our annotation. We are also using Resource injection with the @Resource annotation which injects our MessageDrivenContext message which we use if their was some business logic problem and we need to do a rollback in the catch block ( context.setRollbackOnly() .) All this MDB does is mimic calling some business process (doLongProcess). You'll see in your jboss console the println statements when this gets called. (Of course in real life you'd be using Logging and not stupid println statements.)

import javax.annotation.Resource;
import javax.ejb.ActivationConfigProperty;
import javax.ejb.MessageDriven;
import javax.ejb.MessageDrivenContext;
import javax.jms.Message;
import javax.jms.MessageListener;
import javax.jms.ObjectMessage;

import net.learntechnology.dto.ProcessDTO;
import net.learntechnology.util.LongProcessService;
import net.learntechnology.util.ProcessResult;

@MessageDriven(name="LongProcessMessageBean", activationConfig = {
@ActivationConfigProperty(propertyName="destinationType", propertyValue="javax.jms.Queue"),
@ActivationConfigProperty(propertyName="destination", propertyValue="queue/examples/OurSampleQueue")

})
public class LongProcessMessageBean implements MessageListener {

@Resource
private MessageDrivenContext context;

public void onMessage(Message message) {
String name = null;
try {
if (message instanceof ObjectMessage) {
ObjectMessage objMessage = (ObjectMessage) message;
Object obj = objMessage.getObject();
if (obj instanceof ProcessDTO) {
name = ((ProcessDTO)obj).getName();
System.out.println("****************************************************");
System.out.println("LongProcessMessageBean.onMessage(): Received message. NAME: "+name);
System.out.println("****************************************************");
System.out.println("Now calling LongProcessService.doLongProcess");

ProcessResult result = LongProcessService.doLongProcess((ProcessDTO)obj);
} else {
System.err.println("Expecting ProcessDTO in Message");
}
} else {
System.err.println("Expecting Object Message");
}
System.out.println("*******************************************");
System.out.println("Leaving LongProcessMessageBean.onMessage(). NAME: "+name );
System.out.println("*******************************************");
} catch (Throwable t) {
t.printStackTrace();
context.setRollbackOnly();
}
}
}
index.jsp form
A simple JSP page. All it does is submit some text to our Servlet (AppServlet).

Your name: lt;input type="text" name="name" size="40">






AppServlet
Our AppServlet takes the request of text submitted from index.jsp and passes it to our JmsProducer. Our JmsProducer will need to know the jndi names of the connection factory and the queue name, so we are defining them here as well and passing them to our JmsProducer class.

public class AppServlet extends HttpServlet {
private static final String QUEUE_CONNECTION_FACTORY = "ConnectionFactory";
private static final String LONG_PROCESS_QUEUE = "queue/examples/OurSampleQueue";

public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doPost(request, response);
}

public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("in doPost of AppServlet..");
String name = request.getParameter("name");
System.out.println("name: "+name );
ProcessDTO processDTO = new ProcessDTO();
processDTO.setName(name);
JmsProducer.sendMessage(processDTO, QUEUE_CONNECTION_FACTORY, LONG_PROCESS_QUEUE);
request.setAttribute("started",true);
RequestDispatcher dispatcher = getServletContext().getRequestDispatcher("/index.jsp");
dispatcher.forward(request, response);
}
}
JmsProducer
This is our JMS client code that sends the message to the queue. We pushed the Connection lookup and the Destination lookup into another class called 'ServiceLocator' which is shown next.

public class JmsProducer {
private JmsProducer() {}
public static void sendMessage(Serializable payload, String connectionFactoryJndiName,
String destinationJndiName) throws JmsProducerException {
try {
ConnectionFactory connectionFactory = null;
Connection connection = null;
Session session = null;
Destination destination = null;
MessageProducer messageProducer = null;
ObjectMessage message = null;
System.out.println("In sendMessage of JmsProducter,
getting ConnectionFactory for jndi name: "+connectionFactoryJndiName );
connectionFactory = ServiceLocator.getJmsConnectionFactory(
connectionFactoryJndiName);

connection = connectionFactory.createConnection();
session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
destination = ServiceLocator.getJmsDestination(destinationJndiName);
messageProducer = session.createProducer(destination);
message = session.createObjectMessage(payload);
messageProducer.send(message);
System.out.println("Message sent to messageProducer");
messageProducer.close();
session.close();
connection.close();
} catch (JMSException je) {
throw new JmsProducerException(je);
} catch (ServiceLocatorException sle) {
throw new JmsProducerException(sle);
}
}
}
ServiceLocator
This is a simple utility class used to look up our Connection and Destination via a JNDI lookup. In real life we might use a cache as well to store these lookups.

public class ServiceLocator {
private ServiceLocator() {}
public static ConnectionFactory getJmsConnectionFactory(String jmsConnectionFactoryJndiName)
throws ServiceLocatorException {
ConnectionFactory jmsConnectionFactory = null;
try {
Context ctx = new InitialContext();
jmsConnectionFactory = (ConnectionFactory) ctx.lookup(jmsConnectionFactoryJndiName);
} catch (ClassCastException cce) {
throw new ServiceLocatorException(cce);
} catch (NamingException ne) {
throw new ServiceLocatorException(ne);
}
return jmsConnectionFactory;
}
public static Destination getJmsDestination(String jmsDestinationJndiName)
throws ServiceLocatorException {
Destination jmsDestination = null;
try {
Context ctx = new InitialContext();
jmsDestination = (Destination) ctx.lookup(jmsDestinationJndiName);
} catch (ClassCastException cce) {
throw new ServiceLocatorException(cce);
} catch (NamingException ne) {
throw new ServiceLocatorException(ne);
}
return jmsDestination;
}
}
You might be wondering how to set the IntialContext with the proper host name to do its lookups. The best place to do that is in a jndi.properties file (which this app uses). Our jndi.properties file looks like this:

#jndi.properties
java.naming.factory.initial=org.jnp.interfaces.NamingContextFactory
java.naming.factory.url.pkgs=org.jboss.naming:org.jnp.interfaces
java.naming.provider.url=localhost:1099
application.xml
Necessary for our ear deployment to jboss.


xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee
http://java.sun.com/xml/ns/j2ee/application_1_4.xsd"
version="1.4">
rr-jms-ejb3 Example EAR



rr-jms-webapp.war
rr-jms



conf.jar


common.jar



rr-jms-ejb.jar


Sunday, August 3, 2008

PHP - How to parse RSS?

It is very easy to parse RSS and print out all information of RSS as following
All we need is calling function simplexml_load_string


$rss = '';
$url = "http://www.dantri.com.vn/Sukien.rss";
$rss_file = file_get_contents($url);
if(!$feed = simplexml_load_string($rss_file)){
die("Cannot load RSS Feed. This application supports RSS 1.0 and 2.0");
}

// print out the title of the feed
echo '

';
echo $feed->channel->title;
echo '

';
// check for RSS Version
$items = ($feed['version'] != '') ? $feed->channel->item : $feed->item;
// PRINT OUT ITEMS
/*---------------------------------------------------------------------------------------*/
foreach($items as $item)
{
echo $item->description.'

';
}
/*---------------------------------------------------------------------------------------*/

Thursday, May 22, 2008

How to log sql statement stored in PreparedStatement



Take the following program.

import java.net.URL;
import java.sql.*;

class JDBCapp {
static MyConnection theConn;

public static void main (String args[]) {
new JDBCapp().doit();
}

public void doit() {
theConn = new MyConnection();
theConn.connect("EAS Demo DB V3", "dba", "sql");

PreparedStatement prepstmt;
try {
prepstmt = theConn.dbConn.prepareStatement
("SELECT emp_id FROM employee" );
prepstmt.execute();
prepstmt.close();
}
catch (Exception e) { e.printStackTrace(); }
theConn.disconnect();
}
}


class MyConnection {
Connection dbConn = null;
void connect(String db, String user, String passw) {
try {
Driver d =
(Driver)Class.forName("sun.jdbc.odbc.JdbcOdbcDriver").newInstance();
String URL = "jdbc:odbc:" + db;
dbConn = DriverManager.getConnection(URL, user, passw);
java.io.PrintWriter w =
new java.io.PrintWriter
(new java.io.OutputStreamWriter(System.out));
DriverManager.setLogWriter(w);

}
catch (Exception e) {
e.printStackTrace();
}
}

void disconnect() {
try {
dbConn.close();
}
catch (Exception e) {
e.printStackTrace();
}
}
}


If we use BasicDataSource to getConnection instead of DriverManager,
use BasicDataSource .setLogWriter.

In addition, to log these sql strings to log4j, we will redirect these messages from printwriter to log4j. Use the following code to do this.

http://www.cenqua.com/clover/eg/jboss/report/org/jboss/logging/util/LoggerWriter.html

Wednesday, May 21, 2008

Show lock on table in oracle and unlock them

Show lock
=========
select O.object_name,
O.object_type,
S.sid,
S.serial#,
L.oracle_username,
L.os_user_name,
L.locked_mode
from dba_objects O,
v$locked_object L,
v$session S
where O.object_id = L.object_id
and S.sid = L.session_id
=============

Unlock
ALTER SYSTEM KILL SESSION 'sid, serialid';

Monday, May 5, 2008

Angry with entrecard

I am very angry with entrecard system. They considers my site was spam blog.
They said that because entrecard is their system and they want to do what they want.
It is not acceptable. I will make my own system which can be better than entrecard. If we have more competition, i think they will know where they are in internet.
They delete my site but all their ads is still in my site. What do you think about them? They are all bullshit.

Saturday, April 12, 2008

How to use org.apache.commons.httpclient and excute method via proxy

I try to find out how to use httpclient with proxy and do not want to change java system property. But it seems that we can not find much document about it.
Finally, i have find out the solution:

First: Create httpclient
HttpClient client = new HttpClient();

set proxy
client.getHostConfiguration().setProxy(proxyhost, proxyPort);

//create authenticate
AuthScope auth = new AuthScope(proxyhost,proxyPort, AuthScope.ANY_REALM);
Credentials cred = new UsernamePasswordCredentials("","");
client.getState().setProxyCredentials(auth, cred);
=> now we can connect to internet through proxy.

If you want more information, please post comment. I will answer.

Saturday, March 8, 2008

Privacy Policy

Privacy Policy

The privacy of our visitors to http://thegioitinhoccuatoi.blogspot.com is important to us.

At http://thegioitinhoccuatoi.blogspot.com, we recognize that privacy of your personal information is important. Here is information on what types of personal information we receive and collect when you use visit http://thegioitinhoccuatoi.blogspot.com, and how we safeguard your information. We never sell your personal information to third parties.

Log Files

As with most other websites, we collect and use the data contained in log files. The information in the log files include your IP (internet protocal) address, your ISP (internet service provider, such as AOL or Shaw Cable), the browser you used to visit our site (such as Internet Explorer or Firefox), the time you visited our site and which pages you visited throughout our site.

Cookies and Web Beacons

We do use cookies to store information, such as your personal preferences when you visit our site. This could include only showing you a popup once in your visit, or the ability to login to some of our features, such as forums.

We also use third party advertisements on http://thegioitinhoccuatoi.blogspot.com to support our site. Some of these advertisers may use technology such as cookies and web beacons when they advertise on our site, which will also send these advertisers (such as Google through the Google AdSense program) information including your IP address, your ISP , the browser you used to visit our site, and in some cases, whether you have Flash installed. This is generally used for geotargeting purposes (showing New York real estate ads to someone in New York, for example) or showing certain ads based on specific sites visited (such as showing cooking ads to someone who frequents cooking sites).

You can chose to disable or selectively turn off our cookies or third-party cookies in your browser settings, or by managing preferences in programs such as Norton Internet Security. However, this can affect how you are able to interact with our site as well as other websites. This could include the inability to login to services or programs, such as logging into forums or accounts.
Contact Information

If users have any questions or suggestions regarding our privacy policy, please contact me through my contact form or send me an email to: testoldfriend(at) yahoo (dot) com.

Friday, March 7, 2008

Hibernate, JBoss and auto-increment field

The element

This is the optional element under element. The element is used to specify the class name to be used to generate the primary key for new record while saving a new record. The element is used to pass the parameter (s) to the class. Here is the example of generator element from our first application:

In this case element do not generate the primary key and it is required to set the primary key value before calling save() method.

Here are the list of some commonly used generators in hibernate:

Generator Description
increment It generates identifiers of type long, short or int that are unique only when no other process is inserting data into the same table. It should not the used in the clustered environment.
identity It supports identity columns in DB2, MySql, MS SQL Server, Sybase and HypersonicSQL. The returned identifier is of type long, short or int.
sequence The sequence generator uses a sequence in DB2, PostgreSQL, Oracle, SAP DB, McKoi or a generator in Interbase. The returned identifier is of type long, short or int
hilo The hilo generator uses a hi/lo algorithm to efficiently generate identifiers of type long, short or int, given a table and column (by default hibernate_unique_key and next_hi respectively) as a source of hi values. The hi/lo algorithm generates identifiers that are unique only for a particular database. Do not use this generator with connections enlisted with JTA or with a user-supplied connection.
seqhilo The seqhilo generator uses a hi/lo algorithm to efficiently generate identifiers of type long, short or int, given a named database sequence.
uuid The uuid generator uses a 128-bit UUID algorithm to generate identifiers of type string, unique within a network (the IP address is used). The UUID is encoded as a string of hexadecimal digits of length 32.
guid It uses a database-generated GUID string on MS SQL Server and MySQL.
native It picks identity, sequence or hilo depending upon the capabilities of the underlying database.
assigned lets the application to assign an identifier to the object before save() is called. This is the default strategy if no element is specified.
select retrieves a primary key assigned by a database trigger by selecting the row by some unique key and retrieving the primary key value.
foreign uses the identifier of another associated object. Usually used in conjunction with a primary key association.

Therefore,
If your application is EJB, WS which create multiple threads, you should not use class=increment. Instead, you should use class=sequence or native. Or you will
encounter the problem: unique constrain violation.

Friday, February 15, 2008

Java: how to find the absolute path with white space to the resource ?

For example: our program contains the resource A and class MyClass


src
main
java
MyClass
resource
A


When we package our program, A will be at root.
To get the absolute path to resource(for example when we want to do unit test
and load those resource for test), we will call
String path = MyClass.getClass.GetResource("/A").toURI().getPath();
And now we have the absolute path to resource.

JMock and how to mock static function and final class?

Unit test is one of the "must" task when we develop software. One of the most technology we usually used is mock. As i already said in one of my previous post,
mock is the powerful technology but they have some limitation. This limitation is depend on which type of mock object( JMock, AMock, NMock ...) or the environment.
For example, if you want to test some DAO class which directly access to DBMS, you can not create mock for all JDBC class to do unit test. And in this case, we also can not do unit test because the test depend on the environment(we have to set up an DBMS just for do unit test). Therefore, we have to chose the most suitable way to test: System test, module test, review code ...
JMock like others mock object, has it own limitation. It can not mock final class, static method. It is because of its implementation. For final class, JMock can not inherit the class to create new mock class ==> can not mock this class.
With static method, because static method can not be overriden, so JMock has no way to create mock object.

So in this case, we have to think about design and test first before code
1. Case: our method use final class.

We will use pattern template method to separate code which contain instances of final class.


class OurClass {
function myFunc() {
my code
......
URL url = new URL(href); //Can not mock URL because of final class
url.openstream(...)
....
my code


}
}
Our mission is test this function.


In this case, we create new class calls MockHelperTest and a factory MockHelperFactory



IHelperFactory = interface{
IHelperTest getMockHelper;
}

MockHelperTest = class implements IHelperTest{

void funcHelper() {
///Prepare data , result and code for mock
}
}

and we change our class to:


class OurClass {
public IHelperFactory factory = null; //factory can be set by unit test

//If we test this function, we will
//pass mock factory to this class and
//function will call mock function
//instead of real code.
//If we want to to do real code,
//just pass null factory, and it will
//create real factory and then myFunc
//will call funcMockHelper which call
//real code:
//URL url = new URL(href); //Can not mock URL because of final class
//url.openstream(...)

OurClass(IHelperFactory mockFactory) {
if mockFactory == null ) {
factory = new RealFactory();
} else {
factory = mockFactory;
}
}

function myFunc() {

my code
......
IHelperTest helper = factory.funcHelper().getMockHelper();
helper.funcMockHelper();
....
my code
}
}



And now, we can easily replace the code which can not mock which the mock code.
The same pattern for static function.

Conclusion: Think about test + design first and then code.

Sunday, February 3, 2008

NUnit === How to and FAQ

NUnit goal:

+ NUnit is a unit-testing framework for all .Net languages. Initially ported from JUnit, the current production release, version 2.4, is the fifth major release of this xUnit based unit testing tool for Microsoft .NET. It is written entirely in C# and has been completely redesigned to take advantage of many .NET language features, for example custom attributes and other reflection related capabilities. NUnit brings xUnit to all .NET languages
Homepage: http://www.nunit.org/index.php

+ Why do we use NUnit?
Because it makes us do unit test very easy and very efficiently

+ How to use NUnit:

1.We have to import library:
using System;
using NUnit.Framework;
2. Declare[TestFixture] attribute to class
3. Declare [SetUp] attribute for setup function. This function will be called before any call to tested function
4. Run NUnit test GUI to test assemblies

+ Some functions need for test:
Assert.AreEqual: raise exception if two object are not the same
Assert.IsTrue: raise exception if condition is false
Assert.IsFalse: raise exception if condition is true
Assert.Fail: Raise exception to notify test case fail.
....

+ How do I implement a test case for a thrown exception?
Catch the exception and if it isn't thrown call the Fail method. Fail signals the failure of a test case. Here is an example:


public void TestArgumentOutOfRangeException() {
ArrayList l = new ArrayList(10)
try {
Object o= l[l.Count];
Fail("Should raise an ArgumentOutOfRangeException");
} catch (ArgumentOutOfRangeException) {
}
}

or use the ExceptionTestCase as follows.
1) make your TestCase class a subclass of ExceptionTestCase.
2) write the test ignoring exceptions

public void TestArgumentOutOfRangeException() {
ArrayList l= new ArrayList(10);
l[l.Count];
}

3) create the TestCase:

Test t= new ExceptionTestCase("TestArgumentOutOfRangeException", typeof(ArgumentOutOfRangeException))


Looking at this again, the first way is simpler. Sigh...

Another way:
Declare:


[Test]
[[ExpectedException( typeof( AException ) )]
void testFunction() {
...............
};



+ How do I organize my Test Cases?
Here is one way:

1. create a test namespace for each of your application namespaces. For example, for a namespace MyApp.Util define MyApp.UtilTest. Put all the fixtures for the Util namespace into this namespace.
2. in MyApp.UtilTest define a class which creates a suite with all the tests in this namespace. To do so define a class AllTests which includes a single static Suite property. Here is an example:

public static ITest Suite {
get {
TestSuite suite= new TestSuite();
suite.AddTest(Fixture1.Suite);
suite.AddTest(Fixture2.Suite);
return suite;
}
}


3. define similar AllTests classes that create higher level suites containing the suites from other test packages.

When the fixtures are in a separate test assembly the test cases don't have access to the methods and fields with internal visibility. A variation of the above convention is to put all fixtures into the application assembly itself. This gives the fixtures access to all the assembly visible methods and fields. To separate the fixture classes from the production classes put them into a separate directory that you then add to the project. This makes it easy to ship the production classes independent of the fixtures.

How do I run setup code once for all my TestCases?
Wrap the top level suite in a subclass of TestSetup. Here is a sample AllTests.Suite method:


protected class WrappedTestSetup: TestSetup {
public WrappedTestSetup(ITest test) : base(test) {}
protected override void SetUp() {
OneTimeSetUp();
}
};

public static ITest Suite {
get {
TestSuite suite= new TestSuite();
...add your tests and suites here...
TestSetup wrapper= new WrappedTestSetup(suite);
return wrapper;
}
}


+ I want to debug when a test fails
Start the test runner under the debugger and configure the debugger so that it catches the NUnit.Framework.AssertionFailedError. How you do this depends on the used IDE. Most debuggers support to stop the program when a specific exception is fired. Notice, that this will only break into the debugger when an "anticipated" assertion failed error occurs.

Steps:
1. Start C# IDE ( Visual .net ide)
2. Build project + test in debug mode.
3. Configure NUnit GUI to support VS.NET project
3. Add debug assembly to NUnit GUI.
4. Put breakpoint to where you want to debug
Finished.


Sample:


namespace NUnit.Samples.Money
{
using System;
using NUnit.Framework;
///
///
///

///
[TestFixture]
public class MoneyTest
{
private Money f12CHF;
private Money f14CHF;
private Money f7USD;
private Money f21USD;

private MoneyBag fMB1;
private MoneyBag fMB2;

///
///
///

///
[SetUp]
protected void SetUp()
{
f12CHF= new Money(12, "CHF");
f14CHF= new Money(14, "CHF");
f7USD= new Money( 7, "USD");
f21USD= new Money(21, "USD");

fMB1= new MoneyBag(f12CHF, f7USD);
fMB2= new MoneyBag(f14CHF, f21USD);
}

///
///
///

///
[Test]
public void BagMultiply()
{
// {[12 CHF][7 USD]} *2 == {[24 CHF][14 USD]}
Money[] bag = { new Money(24, "CHF"), new Money(14, "USD") };
MoneyBag expected= new MoneyBag(bag);
Assert.AreEqual(expected, fMB1.Multiply(2));
Assert.AreEqual(fMB1, fMB1.Multiply(1));
Assert.IsTrue(fMB1.Multiply(0).IsZero);
}

///
///
///

///
[Test]
public void BagNegate()
{
// {[12 CHF][7 USD]} negate == {[-12 CHF][-7 USD]}
Money[] bag= { new Money(-12, "CHF"), new Money(-7, "USD") };
MoneyBag expected= new MoneyBag(bag);
Assert.AreEqual(expected, fMB1.Negate());
}

///
///
///

///
[Test]
public void BagSimpleAdd()
{
// {[12 CHF][7 USD]} + [14 CHF] == {[26 CHF][7 USD]}
Money[] bag= { new Money(26, "CHF"), new Money(7, "USD") };
MoneyBag expected= new MoneyBag(bag);
Assert.AreEqual(expected, fMB1.Add(f14CHF));
}

///
///
///

///
[Test]
public void BagSubtract()
{
// {[12 CHF][7 USD]} - {[14 CHF][21 USD] == {[-2 CHF][-14 USD]}
Money[] bag= { new Money(-2, "CHF"), new Money(-14, "USD") };
MoneyBag expected= new MoneyBag(bag);
Assert.AreEqual(expected, fMB1.Subtract(fMB2));
}

///
///
///

///
[Test]
public void BagSumAdd()
{
// {[12 CHF][7 USD]} + {[14 CHF][21 USD]} == {[26 CHF][28 USD]}
Money[] bag= { new Money(26, "CHF"), new Money(28, "USD") };
MoneyBag expected= new MoneyBag(bag);
Assert.AreEqual(expected, fMB1.Add(fMB2));
}

///
///
///

///
[Test]
public void IsZero()
{
Assert.IsTrue(fMB1.Subtract(fMB1).IsZero);

Money[] bag = { new Money(0, "CHF"), new Money(0, "USD") };
Assert.IsTrue(new MoneyBag(bag).IsZero);
}

///
///
///

///
[Test]
public void MixedSimpleAdd()
{
// [12 CHF] + [7 USD] == {[12 CHF][7 USD]}
Money[] bag= { f12CHF, f7USD };
MoneyBag expected= new MoneyBag(bag);
Assert.AreEqual(expected, f12CHF.Add(f7USD));
}

///
///
///

///
[Test]
public void MoneyBagEquals()
{
//NOTE: Normally we use Assert.AreEqual to test whether two
// objects are equal. But here we are testing the MoneyBag.Equals()
// method itself, so using AreEqual would not serve the purpose.
Assert.IsFalse(fMB1.Equals(null));

Assert.IsTrue(fMB1.Equals( fMB1 ));
MoneyBag equal= new MoneyBag(new Money(12, "CHF"), new Money(7, "USD"));
Assert.IsTrue(fMB1.Equals(equal));
Assert.IsTrue(!fMB1.Equals(f12CHF));
Assert.IsTrue(!f12CHF.Equals(fMB1));
Assert.IsTrue(!fMB1.Equals(fMB2));
}

///
///
///

///
[Test]
public void MoneyBagHash()
{
MoneyBag equal= new MoneyBag(new Money(12, "CHF"), new Money(7, "USD"));
Assert.AreEqual(fMB1.GetHashCode(), equal.GetHashCode());
}

///
///
///

///
[Test]
public void MoneyEquals()
{
//NOTE: Normally we use Assert.AreEqual to test whether two
// objects are equal. But here we are testing the MoneyBag.Equals()
// method itself, so using AreEqual would not serve the purpose.
Assert.IsFalse(f12CHF.Equals(null));
Money equalMoney= new Money(12, "CHF");
Assert.IsTrue(f12CHF.Equals( f12CHF ));
Assert.IsTrue(f12CHF.Equals( equalMoney ));
Assert.IsFalse(f12CHF.Equals(f14CHF));
}

///
///
///

///
[Test]
public void MoneyHash()
{
Assert.IsFalse(f12CHF.Equals(null));
Money equal= new Money(12, "CHF");
Assert.AreEqual(f12CHF.GetHashCode(), equal.GetHashCode());
}

///
///
///

///
[Test]
public void Normalize()
{
Money[] bag= { new Money(26, "CHF"), new Money(28, "CHF"), new Money(6, "CHF") };
MoneyBag moneyBag= new MoneyBag(bag);
Money[] expected = { new Money(60, "CHF") };
// note: expected is still a MoneyBag
MoneyBag expectedBag= new MoneyBag(expected);
Assert.AreEqual(expectedBag, moneyBag);
}

///
///
///

///
[Test]
public void Normalize2()
{
// {[12 CHF][7 USD]} - [12 CHF] == [7 USD]
Money expected= new Money(7, "USD");
Assert.AreEqual(expected, fMB1.Subtract(f12CHF));
}

///
///
///

///
[Test]
public void Normalize3()
{
// {[12 CHF][7 USD]} - {[12 CHF][3 USD]} == [4 USD]
Money[] s1 = { new Money(12, "CHF"), new Money(3, "USD") };
MoneyBag ms1= new MoneyBag(s1);
Money expected= new Money(4, "USD");
Assert.AreEqual(expected, fMB1.Subtract(ms1));
}

///
///
///

///
[Test]
public void Normalize4()
{
// [12 CHF] - {[12 CHF][3 USD]} == [-3 USD]
Money[] s1 = { new Money(12, "CHF"), new Money(3, "USD") };
MoneyBag ms1= new MoneyBag(s1);
Money expected= new Money(-3, "USD");
Assert.AreEqual(expected, f12CHF.Subtract(ms1));
}

///
///
///

///
[Test]
public void Print()
{
Assert.AreEqual("[12 CHF]", f12CHF.ToString());
}

///
///
///

///
[Test]
public void SimpleAdd()
{
// [12 CHF] + [14 CHF] == [26 CHF]
Money expected= new Money(26, "CHF");
Assert.AreEqual(expected, f12CHF.Add(f14CHF));
}

///
///
///

///
[Test]
public void SimpleBagAdd()
{
// [14 CHF] + {[12 CHF][7 USD]} == {[26 CHF][7 USD]}
Money[] bag= { new Money(26, "CHF"), new Money(7, "USD") };
MoneyBag expected= new MoneyBag(bag);
Assert.AreEqual(expected, f14CHF.Add(fMB1));
}

///
///
///

///
[Test]
public void SimpleMultiply()
{
// [14 CHF] *2 == [28 CHF]
Money expected= new Money(28, "CHF");
Assert.AreEqual(expected, f14CHF.Multiply(2));
}

///
///
///

///
[Test]
public void SimpleNegate()
{
// [14 CHF] negate == [-14 CHF]
Money expected= new Money(-14, "CHF");
Assert.AreEqual(expected, f14CHF.Negate());
}

///
///
///

///
[Test]
public void SimpleSubtract()
{
// [14 CHF] - [12 CHF] == [2 CHF]
Money expected= new Money(2, "CHF");
Assert.AreEqual(expected, f14CHF.Subtract(f12CHF));
}
}
}

Monday, January 21, 2008

How to use interface correctly?

A: IparentInterface;
B: IchildInterface;

This code will generate error:

B: = IchildInterface (A); ==> will generate expected error whenever we access to B. At the time we down-cast A, we do not have exception.

The correct code should be:

A.QueryInterface (IchildInterface, B);

So the lesson here: Always use QueryInterface when you want to access other inteface of the same object. Do not cast Interface except you really know what you do.

Delphi Memory Leak

I have a lession learn today when I work with delphi. We should avoid using Tlist to store object which implemented any interfaces.

We should use TinterfaceList instead of Tlist. The reason is: Tlist use pointer to reference to object. When we get an object and from that object we get one of its interfaces. This interface is not referenced by anyone (although Tlist use pointer to point to the object) .Therefor when go out of variable scope, this interface is freed automatically.

Hereunder is the sample explaining the lession.


InterfaceA = Iinterface
Procedure methodA;
End;


ClassA = class(TinterfaceObject, InterfaceA)
Procedure methodA;
End;


Var
A: TOBbject
List: Tlist;
Begin
List := Tlist.Create;
List.Add(A);
methodX;
methodY; ==> Exception occur here.
End.

Procedure methodX;
Var
X: InterfaceA;
Obj: ClassA;
Begin
Obj := Tlist.Items[0];
Obj.QueryInterface(InterfaceA, X); ==> Get interface here. Reference count increased to 1
End; ==> Interface will release reference count. Reference count = 0 ==> Obj is freed.

Procedure methodY;
Begin
Obj := Tlist.Items[0];
Obj.methodA; รง Exception because of object is freed.
End;


Hope this lession lean can help you avoid unexpected exception.

Does java have memory leak?

According to the IBM's artical, JAVA also has problems of memory leak event though they have its own memory garbage collector. The main reason is that: design is not good.

I. How memory garbage collector work?

The job of the garbage collector is to find objects that are no longer needed by an application and to remove them when they can no longer be accessed or referenced. The garbage collector starts at the root nodes, classes that persist throughout the life of a Java application, and sweeps though all of the nodes that are referenced. As it traverses the nodes, it keeps track of which objects are actively being referenced. Any classes that are no longer being referenced are then eligible to be garbage collected. The memory resources used by these objects can be returned to the Java virtual machine (JVM) when the objects are deleted.

II. How it leaks?

"An object is only counted as being unused when it is no longer referenced" ==> The garbage collector can not do its job if an object is referenced by others object for a very long time even though it is no longer needed. It can lead to a terrible problems: out of memory.

Example:

Object A = new Object; //A exists until program terminate.
During program life cycle, an object B is created and referenced by A
Because programmer believe in garbage collector, so they do not free memory manually,
but let garbage collector do it for him ==> B exist until A freed.
If program create many and many B for its life ==> all B will exist too ==> cause out of memory.

It is the obvious example of problem of memory leak. So we do not believe in Garbage Collector 100%. Let free object manually by assigned unused object to nil.


III.Preventing memory leaks

You can prevent memory leaks by watching for some common problems. Collection classes, such as hashtables and vectors, are common places to find the cause of a memory leak. This is particularly true if the class has been declared static and exists for the life of the application.

Another common problem occurs when you register a class as an event listener without bothering to unregister when the class is no longer needed. Also, many times member variables of a class that point to other classes simply need to be set to null at the appropriate time.

Hope i can help you in avoid memory leak in java.

Saturday, January 19, 2008

How to get the path and filename of executable file of current process (or running process)?

How to get the path + file name of the current process or the running process?
There are two way to this:

I will illustrate idea in delphi

1. You can call the API function: GetProcessImageFileName

Declare prototype:

interface
function GetProcessImageFileNameA(hProcess: THandle; lpImageFileName: LPSTR;
nSize: DWORD): DWORD; stdcall;
{$EXTERNALSYM GetProcessImageFileNameA}
function GetProcessImageFileNameW(hProcess: THANDLE; lpImageFileName: LPWSTR;
nSize: DWORD): DWORD; stdcall;
{$EXTERNALSYM GetProcessImageFileNameW}
function GetProcessImageFileName(hProcess: THANDLE; lpImageFileName: LPTSTR;
nSize: DWORD): DWORD; stdcall;
{$EXTERNALSYM GetProcessImageFileName}

implementation

function GetProcessImageFileNameA(hProcess: THandle; lpImageFileName: LPSTR;
nSize: DWORD): DWORD; stdcall; external 'Psapi.dll' name 'GetProcessImageFileNameA';
function GetProcessImageFileNameW(hProcess: THANDLE; lpImageFileName: LPWSTR;
nSize: DWORD): DWORD; stdcall; external 'Psapi.dll' name 'GetProcessImageFileNameW';
function GetProcessImageFileName(hProcess: THANDLE; lpImageFileName: LPTSTR;
nSize: DWORD): DWORD; stdcall; external 'Psapi.dll' name 'GetProcessImageFileNameA';


Calling function:

+ GetWindowThreadProcessId(WindowHandle, @processID); ==> get processid
+ processHandle := OpenProcess(PROCESS_TERMINATE or PROCESS_QUERY_INFORMATION,
False, processID); ==> Get process handler
+ GetProcessImageFileName(processHandle , bufferout, lenghtofbufferout)


2. The second way:

Call function GetModuleFileName with first parameter nil
+ GetModuleFileName(0, Buffer, 1024); <== Buffer contain the current path of current process.

Google