AUTHOR: Mathew Thomas TITLE: Achieving Better Code Quality STATUS: publish ALLOW COMMENTS: 1 ALLOW PINGS: 0 DATE: 2/5/2011 5:51:00 AM ----- BODY: Revised a blog I wrote back in June of 2005 on achieving code quality. This is a republish with updated content - http://blogs.averconsulting.com/2005/06/04/code-quality.aspx


----- EXTENDED BODY: ----- EXCERPT: Revised a blog I wrote back in June of 2005 on achieving code quality. This is a republish with updated content - http://blogs.averconsulting.com/2005/06/04/code-quality.aspx ----- KEYWORDS: ----- -------- AUTHOR: Mathew Thomas TITLE: memcached STATUS: publish ALLOW COMMENTS: 1 ALLOW PINGS: 0 DATE: 1/15/2011 10:59:00 PM ----- BODY: Caching data in an in-memory cache is an approach used to speed up data access. memcached is one such key/value based distributed object caching system that works this magic for you.

I was about to write a blog about memcached and found this wonderful "story" - http://code.google.com/p/memcached/wiki/TutorialCachingStory . I love the way its been written. Enjoy the read

If you are wondering how to install memcached on Mac OS X, check out https://wincent.com/wiki/Installing_memcached_1.4.4_on_Mac_OS_X_10.6.2_Snow_Leopard . Its amazing how at the end you feel you need to be awarded a phd! I guess that shows I am not a UNIX/Linux geek

I did though install it with no sweat on my Ubuntu 10.10 Virtual Machine with one simple command -
>> sudo apt-get install memcached

Memcached runs as instances on 1+ machines. It is run outside of the JVM . memcached clients know where all the memcached servers are but the servers have no idea about other servers. You guessed right - no distributed caching. Frankly in most general cases distributed caching is not needed. memcached is self recovering - in that a server coming down does not affect the other servers. When the "sick" server comes back up it simply joins the club of servers.
----- EXTENDED BODY: ----- EXCERPT: Caching data in an in-memory cache is an approach used to speed up data access. memcached is one such key/value based distributed object caching system that works this magic for you. ----- KEYWORDS: ----- -------- AUTHOR: Mathew Thomas TITLE: Installing Ruby 1.9.2 and Rails 3 on Mac OSX STATUS: publish ALLOW COMMENTS: 1 ALLOW PINGS: 0 DATE: 12/30/2010 4:28:00 AM ----- BODY: For those struggling to get Ruby 1.9.2 and Rails 3 installed on Max OSX.

Installing the latest Ruby and Rails ended up quite an adventure. I wonder how many people just give up. Anyways the best way to install this was using Macports. Download and install Macports from http://www.macports.org/ .

If the installer complains that you have an older version of Apple's XCode tool set then register at Apple's site ... download and install the latest XCode. This is a big download so be patient.

Next follow the instructions at http://www.ruby-forum.com/topic/178659 (posted by Conrad Taylor) to install the Ruby 1.9.2 and Rails 3.

A few quick pointers...

Step 2) type in "sudo port install ..." for mysql and sqlite.

Step 5) type
sudo gem install kwatch-mysql-ruby --source=http://gems.github.com -- --with-mysql-config=/opt/local/lib/mysql5/bin/mysql_config

Step 7) type
  rails new testapp

(testapp could be any name)

Before you get carried away create a rails application and ensure that you can access it in the browser. Go beyond the hello world page and add a model/controller. Execute the basic stubs using scaffolding and ensure db connectivity to the default sqlite3 db.




----- EXTENDED BODY: ----- EXCERPT: For those struggling to get Ruby 1.9.2 and Rails 3 installed on Max OSX. ----- KEYWORDS: ----- -------- AUTHOR: Mathew Thomas TITLE: Unit Testing with Mocks - EasyMock, JMock and Mockito STATUS: publish ALLOW COMMENTS: 1 ALLOW PINGS: 0 DATE: 12/18/2010 4:28:00 AM ----- BODY: The oxford dictionary defines mock as - "make a replica or imitation of something". That very much holds true in the case mock assisted unit testing.

My definition..."Mocking is the discipline of identifying the dependencies of the unit being tested and thereafter providing imitations of that dependency, such that the class being tested has no knowledge whether the dependency is real or an imitation.".

There is a distinction on what you really expect to test in a unit test - State verification vs Behavior verification. I would point you to an excellent article by Martin Fowler regarding the same - http://martinfowler.com/articles/mocksArentStubs.html

In the real world the difference between the two blur and sometimes for a good reason. You do not have all the time in the world to sit down and write the ideal set of unit tests for each. State verification typically checks to see if the state of objects is as expected after the tests have run. Behavior verification is about checking to see if certain methods were invoked (and how many times, and what arguments were passed ,etc).

Using Mock frameworks you can stub out what data you want returned from a call to a dependent class. And that is what is of interest to me. Imagine a service class calling a classic data access class. I want to test the service class but stub out the calls to the DAO. At the same time I want the DAO to return different sets of data so as to exercise my different paths in the service class.

In the Java sphere there exists a few strong frameworks to help the developer in mocking dependencies. In this blog I will cover examples of three frameworks - EasyMock, JMock and Mockito.

The frameworks typically provide the following features:
Lets look at real examples. As usual the complete Eclipse project is zipped up and available at the very bottom.


EasyMock

EasyMock follows the following design paradigm:
    import static org.easymock.EasyMock.createControl;
import static org.easymock.EasyMock.expect;
import static org.easymock.EasyMock.replay;
import static org.easymock.EasyMock.verify;

private List vazips = new ArrayList();
private LookupDataServiceImpl svc;
private LookupDao mockdao;

public void setUp() {

vazips.add("20147");
vazips.add("20191");

// create the object to test
svc = new LookupDataServiceImpl();

// create the mock dao
mockdao = createControl().createMock(LookupDao.class);
svc.setLookupDao(mockdao);
}

public void test_NoExpectationsRecorded() {
// - no expectations are recorded
// - WILL FAIL the test since EasyMock requires you to
// - record the expectations

// - Switch to replay mode and run test
replay(mockdao);

// - invoke test
svc.getZipCodes("va");

// - verify WILL NOT GET CALLED...will fail in previous step
verify(mockdao);
}
In this test case I have not recorded any expectations. By default EasyMock mocks will then expect that no invocations can be made to it. This test case will fail with an error (entire stack trace not included)
java.lang.AssertionError: 
Unexpected method call getZipCodes("va"):

Now lets look at a happy path examples where an expectation is provided.
    public void test_CorrectExpectationIsRecorded() {
        // - One expectations are recorded
        mockdao.addZipCode("va", "11122");

        // - run test
        replay(mockdao);
        svc.addZipCode("va", "11122");

        // - verify
        verify(mockdao);
    }

This test case will pass since we have recorded one expectation and the test execution did invoke the expected method, which was verified in the call to verify.

Now lets try to stub out the data that is returned from our DAO object.
    public void test_VerifyReturnData() {
        // - One expectations are recorded
        expect(mockdao.getZipCodes("va")).andReturn(vazips);

        // - run test
        replay(mockdao);
        List<String> zipcodes = svc.getZipCodes("va");

        for (Iterator<String> iter = zipcodes.iterator(); iter.hasNext(); ) {
            System.out.println((String) iter.next());
        }

        // - verify
        verify(mockdao);
        assertTrue(zipcodes.size() == 3);
    }

Variable vazips holds some hardcoded stub data. We would like that a call to dao.getZipCodes with an argument of statecode=VA return us this test data. The way we do this is in expectation
expect(mockdao.getZipCodes("va")).andReturn(vazips);

To throw an exception from our DAO use:
expect(mockdao.getZipCodes("va")).andThrow(new RuntimeException("mock runtime exception"));

As you can quickly see there is some amount of value to mocking out dependencies. What you have to guard is an over-dependence on mocking. I have seen test cases that set up so many expectations that after a while it is hard to understand what they were really testing. If you only do behavior verification then I personally think you have not unit tested the code. In the end of the day everything is about business logic and data. Your unit tests should verify those. As in the last example we have used EasyMock to return some test data so that we can unit test different execution paths in our service.


JMock

JMock is very similar in that you set up expectations, then execute and finally verify.
   import org.jmock.Expectations;
import org.jmock.Mockery;
import org.jmock.integration.junit4.JMock;
import org.jmock.lib.legacy.ClassImposteriser;

   public void test_VerifyReturnData() {
        final String stateCode = "va";

        // - record your expectations here
        context.checking(new Expectations() {
            {
                oneOf(mockdao).getZipCodes(stateCode);
                will(returnValue(vazips));
            }
        });

        // - Execute test
        List<String> zipcodes = svc.getZipCodes("va");
        for (Iterator<String> iter = zipcodes.iterator(); iter.hasNext(); ) {
            System.out.println((String) iter.next());
        }

        // - verify
        context.assertIsSatisfied();
        Assert.assertTrue(zipcodes.size() == 3);
    }

If you had to throw exceptions from your mock then
       context.checking(new Expectations() {
            {
                oneOf(mockdao).addZipCode("12121", "ca");
                will(throwException(new RuntimeException("mock runtime exception")));
            }
        });
Mockito
Mockito is a relatively new framework. Where it differs from EasyMock and JMock is in the way it deals with expectations. In the case of EasyMock and JMock you have to record the expectations. Mockito does not do require you to do that. It lets you verify mock invocation verifications (of your choosing) AFTER the test is executed.

    import static org.mockito.Mockito.mock;
    import static org.mockito.Mockito.verify;
    import static org.mockito.Mockito.when;

    public void setUp() {
        vazips.add("20147");
        vazips.add("20191");

        // create the object to test
        svc = new LookupDataServiceImpl();

        // create the mock dao
        mockdao = mock(LookupDao.class);
        svc.setLookupDao(mockdao);
    }

    public void test_Mock() {
        // NOTE: Mockito does not have concept of expectations
        // you execute the test with the mock and after the test
        // validate any method behaviors you want
        // run test method

        svc.getZipCodes("VA");

        // verify
        verify(mockdao).getZipCodes("VA");
    }

In this case you connect your class to the mock object as before, then simply run your test. After the test is executed you verify that expected methods were called. In this case a call to getZipCodes with an argument of "VA". Change the argument to "CA" and the verification will fail.

Here is how you would stub data.
    public void test_VerifyReturnData() {
        // stubs the return values on the mock dao
        when(mockdao.getZipCodes("va")).thenReturn(vazips);

        // run test method
        List<String> zipcodes = svc.getZipCodes("va");
        System.out.println(zipcodes.size());
        for (Iterator<String> iter = zipcodes.iterator(); iter.hasNext(); ) {
            System.out.println((String) iter.next());
        }

        // verify
        verify(mockdao).getZipCodes("va");
        assertTrue(zipcodes.size() > 0);
    }

Finally if you were to mock exceptions..
when(mockdao.getZipCodes("ca")).thenThrow(new RuntimeException("mock runtime exception"));

Each has its own advantages but none so ground breaking that one rules over the other. Use what you are comfortable with.

Click here to download the zip containing the source code and eclipse project. Please download libraries from:  http://www.easymock.org , http://www.jmock.org , http://www.mockito.org ----- EXTENDED BODY: ----- EXCERPT: The oxford dictionary defines mock as - "make a replica or imitation of something". That very much holds true in the case mock assisted unit testing. ----- KEYWORDS: ----- -------- AUTHOR: Mathew Thomas TITLE: Kanban For Software Development STATUS: publish ALLOW COMMENTS: 1 ALLOW PINGS: 0 CATEGORY: Agile DATE: 12/2/2010 12:03:00 PM ----- BODY: There are many ways to develop software using Agile techniques. Kanban is a recent entry into this and has some interesting dynamics going for it. Its great to see new ideas from across the industry being applied to software development. Not sure if Kanban is the final answer though - save that for my last paragraph.

In SCRUM we break down a release into small sprints. Each sprint begins with planning and ends with a demo and retrospective. That sounds reasonable until you start facing some challenges.
Now all of this can be addressed in SCRUM with some degree of success. None of these are show-stoppers to me for using SCRUM. But it begs the question - is there a more natural way to do development.

My Ignorable Rant: Those who go about speaking about Agile w/o ever having written any significant amount of code just do not get it. Writing good software is hard and is unpredictable. You cannot box someone to 1-2 weeks and have a cookie-cutter approach to development. Development is an art that is perfected over years - alas often not seen that way anymore. Writing code is not about taking things off of the shelf and assembling as you go. We have not reached that stage yet. There is a lot of thought and rigor that needs to be put in to build good code.

Software development with Kanban attempts to break out of the current model, breathe some fresh air into all of us and yet stay true to Agile principles (see the AgileManifesto).

Kanban (Japanese for Visual Cards) in software development is inspired from Lean principles and the Toyota Production System. Avoid waste. Kanban specifies creating a set of states (vertical columns on a board) - each representing a certain state of development. A work item flows through the states from left to right. Work items can go back into the previous states if needed. Lets define a few states for us:

Backlog | Story Queue | In Progress | System Testing | UAT Testing | Deployment | In Production

I have added quite a few states here to depict a slightly more granular level of detail. Now the only thing Kanban requires you to define is the WIP or the Work In Progress Limit. The WIP Limit is a maximum count of work items that can be allocated into any of your states. You can also define a different WIP Limit for each state. This can, for example, reflect ground realities such as skill gaps in teams and simple resource constraints. For example you have 5 developers and only 3 testers in system testing. So you can decide that at any given time only 10 work items can exist in the in-progress state and only 6 in the system testing state. This allows for some flexibility in case someone finishes a task earlier and needs something else to work on.

The backlog contains list of things to be implemented. The story queue is a prioritized set of stories from the backlog. The backlog is only an unsorted holding area. Within each state we can further subdivide into horizontal sections to divide say those items that are being worked on vs. others that have not yet started.

Work items progress all they way from left to right. As the WIP limit is reached no more items can be added and the reverse holds true when the WIP goes under the WIP Limit for that state. If the next state is full then the folks working in the current state could lend a helping hand to clear their queue. Developers can put on tester hats for a few days to help clear out the testing state and reduce the WIP there. This level of collaboration is critical otherwise folks can be sitting idle.

Gone are the sprints or the definite structure that SCRUM gives us. Its all about getting work done from a prioritized work queue and how much work capacity exists within the team.

Now this may remind you of a pipeline process or an assembly line. And that's exactly where the similarity ends since developing software is way different from manufacturing on assembly lines (see my earlier rant). But the underlying principle of avoiding waste holds true.

I do think that successful application of Kanban in software development projects require a higher level of team collaboration and management support as compared to say SCRUM. Teams have to change the way they work together. As mentioned earlier if the testing team is in a crunch, the development team jumps in to help out a little. Thereby allowing the assembly line to keep moving. Players throughout the states need to realize that work can come in anytime but will never exceed their current capacity.

So does this mean we have to choose from SCRUM or Kanban. As always - it depends on your situation.

In the beginning I said "Not sure if Kanban is the final answer though - save that for my last paragraph." Why did I say that. If you have not read my rant, go back and read it. Thats why.
----- EXTENDED BODY: ----- EXCERPT: There are many ways to develop software using Agile techniques. Kanban is a recent entry into this and has some interesting dynamics going for it. ----- KEYWORDS: ----- -------- AUTHOR: Mathew Thomas TITLE: GIT for Version Control STATUS: publish ALLOW COMMENTS: 1 ALLOW PINGS: 0 CATEGORY: SCM DATE: 11/4/2010 2:01:00 AM ----- BODY: I generally do not get into version control wars. Working in large firms often means you are told what to use. It is less often the case that you get to choose. A whole ecosystem is then stood up around version control - people to support it, specialized hardware, processes, separation of duties and what have you. All for a good reason, but developer creativity falls over time.

Try doing this where you work (only if you are in a large regulated firm). Get the code from your repository.....now go home, throw the VPN away. What no connection to the mothership! Yes no connection. Now go through the script below.

Can you do that where you work in a matter of minutes? I bet you cannot. Your CM team would be throwing fits, your requests for branching would send red signals up the corporate chain.

Well let me tell you that the script above is possible with Git - the open source distributed version control system (DVCS). This is not about which version control is better. Read about it, if you like Git great otherwise move on. Mercurial SCM is another open source DVCS and its usage is very similar to git. Instead  of using the command "git" you use "hg". I cover Git here.

Git begins with the notion that all you developers are equally powerful - what a novel idea! When you bring down code from say a central location - you bring down everything, including history. You can cut the network cord now and you can perform the entire script above.

If your intention was instead to check in a project into GIT then run commands...
>> git init
>> git add
>> git commit -m "initial checkin"

If your intention instead was to check out an existing project from a central source - run commands...
>> git clone <url>

Either way you can now start working on this mainline project code. To start either tracking new files or update existing ones you use the command
>> git add [filename] [filename]

The "add" command simply stages the file to a local staging area. When you are ready to finally check in your changes, run command
>> git commit -m "your message"

The "commit" command creates a snapshot containing all the files you previously added. You can use the git "status" command to see what changed since the last check in.

Now realize that these commits are still being done to your local Git repository. Your code base is fully distributed (in its entirety) across all your users. Each user has the power to run our test script in complete isolation from others and no dependency on a central server.

Now if you had to branch, you would run command
>> git branch <branchname>

To switch to that branch run
>> git checkout branchname

Add a few files, run the add and then the commit command. Now switch to mainline by running command
>> git checkout master

"master" is the name representing the mainline.

If you check the directory now, you will not see the files you added to the branch. That work is kept isolated with the branch. Switch back to the branch and you should see the new files. Git takes care of synchronzing the contents of your folder with what your current branch is. No maintaining multiple directories. Elegant and useful.

Finally you decide to merge the work in the branch into the mainline and then delete the temporary branch.

If you are unsure which branch you are on run
>> git branch

This should list all branches and the master  - with an asterix preceding your active branch.

Switch to mainline if you are not already there
>> git checkout master

Run merge
>> git merge test

You should now see the new files have been merged into mainline. Finally delete the temporary branch
>> git branch -d test

Git gives you complete revision history all the way back to the first commit and also gives you the ability to perform inexpensive branching locally to work on different work items. Each commit keeps track of which files were modified/added during the commit as a changeset. This changeset can then be reverted using the unique id assigned to each commit.

Finally the question in your mind. How do I share code with other folks. You use the "fetch" and "pull" commands to synchronize with a remote server and bring down the latest changes. To upload changes you perform a "push" command.

Hopefully I have at least created a little interest in you for Git or distributed version control system (DVCS) in general. ----- EXTENDED BODY: ----- EXCERPT: I generally do not get into version control wars. Working in large firms often mean you are told what to use. It is less often the case that you get to choose. A whole ecosystem is then stood up around version control... ----- KEYWORDS: ----- -------- AUTHOR: Mathew Thomas TITLE: Architecture & Enterprise Architecture STATUS: publish ALLOW COMMENTS: 1 ALLOW PINGS: 0 CATEGORY: Enterprise Architecture DATE: 7/24/2010 12:19:00 PM ----- BODY: What does Enterprise Architecture really mean? Why does a company need to have a strong Enterprise Architecture?

Depending on who is reading - each person has a different perspective on what Enterprise Architecture.
Enterprise Architecture (EA) in most companies is often non-existent or grossly inadequate.

Before we begin to describe Enterprise Architecture, lets look at the two words - "Enterprise" & "Architecture". Rather than me making up new definitions, lets use definitions/descriptions that some leading industry groups have come up with.

TOGAF defines "enterprise" as any collection of organizations that has a common set of goals. For example, an enterprise could be a government agency, a whole corporation, a division of a corporation, a single department, or a chain of geographically distant organizations linked together by common ownership.

The definition of an architecture used in ANSI/IEEE Std 1471-2000 is:
"The fundamental organization of a system, embodied in its components, their relationships to each other and the environment, and the principles governing its design and evolution."

Take a medium to large system you have worked on - break it up into its components, study the relationships between them, relate them to the business/technical environment in which they execute and finally whether you did this formally or not there will be some design patterns and themes that stand out.

If you are a small company with a handful of applications you may not invest in an elaborate EA practice - yet. But even here I would argue you have the workings of an EA group. Otherwise you would not survive. Its just that you did not call it out as EA. If you happen to be a large company with 1000s of applications of all size - here is where an effective EA will lay the foundations for a more competitive company.

What does the EA do? First things first. EA is not about only technology. Enterprise Architecture should be driven by some business needs that add value to the company's bottom-line. EA includes Business, Data, Applications, Technology and Services architecture. If you look at TOGAF9 it definitely lays out all of those domains - except Services. I believe Services architecture should be called out separately. The science of implementing an effective SOA is quite different from traditional silo'ed applications that are walled off from the rest.

Given this context let me try and answer  'What does the EA do?'-
"An effective EA practice should be responsible for laying out and governing a measurable path to execution of a company's business strategy; aligning with the operating plan".

Think about it for a moment. Every successful company has a clearly laid out business strategy and an operating plan to execute that strategy. Example: Company ABC Inc is in the business of creating pencils and crayons for school-age kids. The strategy is to get into the top 3 firms in their business within the next 3-5 years by focusing on elementary grade school kids. They should lay out an operating mode that describes the time-frame and the how they will execute that strategy.

ABC Inc would need to hire the right kind of people, maybe do some restructuring to become more lean and reduce waste, spend more time in studying the market, focus on targeted advertising, sponsor little league baseball games to en-grain their brand name among kids and so on.

IT plays an important element of the EA but its not the be all and end all. If you go back to the start of the article where I list how each person sees Architecture - in TOGAF9 these are views that are seen from different perspectives or viewpoint. Each viewpoint only sees or cares about part of the picture. An EA practice should maintain the bigger picture and ensure that nothing is getting lost. ----- EXTENDED BODY: ----- EXCERPT: What does Enterprise Architecture really mean? Why does a company need to have a strong Enterprise Architecture? ----- KEYWORDS: ----- -------- AUTHOR: Mathew Thomas TITLE: Mule ESB STATUS: publish ALLOW COMMENTS: 1 ALLOW PINGS: 0 CATEGORY: ESB DATE: 6/29/2010 1:53:00 AM ----- BODY: This is one blog article that I had written a while back. But due to time constraints never got to publishing it. Here goes. Warning this is not a primer on Mule. For that go to mulesoft.org

Mule is a lightweight open source ESB that is not bogged down by standards but yet enables to integrate applications that support various open standards. By bogged down I mean - its not a JBI compliant ESB. Yes and it supports JMS, Web Services, Java POJO.

For a general overview of ESB see my article from some time back - Enterprise Service Bus. An ESB is made up of a high-performance messaging layer (such as ActiveMQ) and the ESB software itself (Mule). The ESB software provides integration services to create/host/manage business services, mediation, content transformation, routing, security and so on.

To get started go to http://www.mulesoft.org and download the software. I downloaded the full version - 2.2.1. For the messaging layer go download ActiveMQ from http://activemq.apache.org/ (the version I used is 5.2.0 ... latest as of today is 5.3.2). Finally I am using Eclipse 3.5 and also installed the Mule IDE Eclipse Plugin (Plugin).

Once you have the Mule Eclipse plug-in installed , create a new Mule project and then add the code below to make it work.

Our use case is:
- Purchase Orders come in XML .dat files to a folder.
- We want to scan the folder periodically and load up any incoming files.
- Now we want to check if the PurchaseOrder for item with part number as "WXJ-1".
- If the part number is found then that purchase order is routed to the JMS Queue "ImportantPOQ"
- All other orders are routed to JMS Queue "AllOtherPOsQ"

To begin, configure the JMS connector in the mule-config.xml:
    <mule-jms:activemq-connector name="jmsConnector"
        brokerURL="tcp://localhost:61616" />

Next Configure the file connector to poll for incoming files:
    <mule-file:connector name="fileConnector" fileAge="5000"
        autoDelete="false" pollingFrequency="5000" />

The service itself is configured as:
    <model name="myproject">
        <service name="FileReader">
            <inbound>
                <mule-file:inbound-endpoint address="file:///Users/mathew/temp/in"
                    moveToDirectory="/Users/mathew/temp/out" moveToPattern="#[DATE]-#[ORIGINALNAME]">
                    <mule-file:filename-wildcard-filter
                        pattern="*.xml" />
                </mule-file:inbound-endpoint>
            </inbound>
            <log-component></log-component>
            <outbound>
                <filtering-router>
                    <mule-jms:outbound-endpoint queue="ImportantPOQ" />
                    <mule-xml:xpath-filter pattern="/PurchaseOrder/Items/Item/@PartNumber"
                        expectedValue="WXJ-1" />
                </filtering-router>
                <forwarding-catch-all-strategy>
                    <mule-jms:outbound-endpoint queue="AllOtherPOsQ" />
                </forwarding-catch-all-strategy>
            </outbound>
        </service>

A Mule Service has a inbound router , a service component and an outbound router. The inbound router is used to configure how the service will consume messages and from where. In this case you can see the use of the file connector to read files from a predefined folder.

The Service component typically contains your business logic. For the purposes of this article I do not have a service component. Instead I use a predefined log component to print out the file contents to the console.

The outbound router is used to configure where the processed messages will go once the business component is finished with it. In this case I configure a filtering-router which sends messages to the queue ImportantPOQ if the part number is WXJ-1. The forwarding-catch-all-strategy router is used for all other unmatched messages.

I have a little utility class that spits out a bunch of test xml files. The project structure in Eclipse should look like this...


Ignore the java classes since my next task is to send the PurchaseOrder to a POJO service component. For the purposes of this article there is no java code used.

Start your ActiveMQ server and create the two queues noted in the mule-config.xml. Right click on the mule-config.xml -> RunAs -> Mule Server. If everything goes well the server should start and be polling for files in the predefined folder. Run the FileCreator.java to put some files into your folder and in a few seconds you should see that the files are processed, moved to the processed folder. Go to the ActiveMQ web admin page at localhost:8161/admin/queues.jsp. You should see messages in both queues. Most will end up in the AllOtherPOsQ. Any messages with partnumber as WXJ-1 will end up in the ImportantPOQ.

Download the project by clicking here Mule Sample.

----- EXTENDED BODY: ----- EXCERPT: Mule is a lightweight open source ESB that is not bogged down by standards but yet enables to integrate applications that support various open standards. ----- KEYWORDS: ----- COMMENT: AUTHOR: Dave EMAIL: no@no.com IP: 71.171.119.198 URL: DATE: 6/29/2010 11:43:03 AM Good Mule starter. Gave me a little more than the traditional hello world. Thanks. -Dave ----- COMMENT: AUTHOR: Ken EMAIL: wahooken@gmail.com IP: 66.92.9.225 URL: DATE: 7/28/2010 11:23:54 PM Good example of Mule's support for other open source messaging solutions and how simple it is to use Mule ESB and ActiveMQ together. ----- COMMENT: AUTHOR: Anonymous EMAIL: IP: 129.42.208.183 URL: DATE: 1/4/2011 3:46:41 PM Thanks for demystifying Mule and ESB. ----- -------- AUTHOR: Mathew Thomas TITLE: Virtualization - From Individual Desktops to Servers STATUS: publish ALLOW COMMENTS: 1 ALLOW PINGS: 0 CATEGORY: Virtualization DATE: 4/29/2010 1:36:00 AM ----- BODY: There is a quiet but steady change going on in data centers and IT organizations around the world. Virtualized infrastructure. Underutilized single OS machines are now being re-targeted to run multiple operating systems and therefore scale horizontally thereby drastically reducing labor, hardware, OS & physical real estate costs in data centers. Add to that the overall reduction in lower energy costs and suddenly you have something really strong going on.

When I first played around with virtualization - I used Parallels Desktop on my MacBook Pro. It was great first brush with installing other OS's on the Mac. Then used Sun's VirtualBox to do the same. Both these and also VMware Player/Workstation required a host OS. In my case it was the Mac OSX and later my Windows OS. You then installed the target OS into the tool.



The host OS (HOS) is something that comes between the virtualization software and the hardware. This is fine for a desktop pattern of use. From a developer point of view this was fine too. Nowadays if you call vendors in for demos, quite often you see them bring up a VM (Virtual Machine) on their desktop and take us for a spin through their product.

But for a production environment, where you want to have as little fat between the virtualization software and the hardware, we had to find a way to get rid of the heavy HOS and instead replace it with lightweight (JEOS) OS sometimes also referred to as the hypervisor. JEOS - Just Enough Operating System. This would allow for efficient utilization of the hardware resources as well has add to it features such as fail-over which are required for critical production applications.

One hypervisor I am trying to install is the free VMWare ESXi. Unfortunately my old desktop does seem to pass the VMWare compatibility test. ESXi can be installed directly on your machine (it will replace any existing OS you have...so beware) and then you can use the VMware vSphere client to manage your ESXi server and install target OS's. The paid version of the server vSphere (vs free ESXi) supports load balancing and backup features for VM's (among a whole host of other additional features).

One neat product offered by WMware is the VMotion module. This allows for moving virtual machines from one server to another in a production environment with no impact to users. This feature depends on using the VMware cluster file system or VMware vStorage VMFS. The VM is stored in a single file and the vStorage VMFS allows multiple concurrent VM's to read and write to it. Now that the VM's can all access the same VM file, what has to be transferred, preferably over a high speed network, is the run-time state of a individual VM. Quite interesting...me thinks so. ----- EXTENDED BODY: ----- EXCERPT: There is a quiet but steady change going on in data centers and IT organizations around the world. Virtualized infrastructure. ----- KEYWORDS: ----- COMMENT: AUTHOR: Maggie EMAIL: maggie.warbrick@clavister.com IP: 90.232.212.204 URL: DATE: 4/29/2010 7:49:39 AM Interested in your views on security in virtual environments. ----- COMMENT: AUTHOR: Mathew Thomas EMAIL: mattazoid@gmail.com IP: 71.171.119.198 URL: DATE: 4/29/2010 12:24:48 PM Security is an interesting aspect. In my view (limited I might say) following security concerns arise:

- Can someone compromise the ESXi server itself?
- Individual VM's on the same hardware still need to be managed and security patches, anti-virus software need to be applied?
- Finally what I am unsure is, whether there is a potential of multiple VM's on the same hardware compromising each other?

WIsh I had the answers...lot more to learn. That's what keeps me going ----- COMMENT: AUTHOR: navagroobre EMAIL: dsfsdf@gmail.com IP: 122.192.166.141 URL: DATE: 1/8/2011 11:21:43 PM Thanks For This Blog, was added to my bookmarks. ----- COMMENT: AUTHOR: ulcecehoone EMAIL: sdfsdfcxz@gmail.com IP: 122.192.166.149 URL: DATE: 1/9/2011 9:45:11 AM I find myselfcoming to your blog more and more often to the point where my visits are almost daily now! ----- -------- AUTHOR: Mathew Thomas TITLE: Virtual Appliances STATUS: publish ALLOW COMMENTS: 1 ALLOW PINGS: 0 CATEGORY: Virtualization DATE: 1/27/2010 2:17:00 AM ----- BODY: Recently I had to review a product which was being offered as a Virtual Appliance. This was the first time I had come across something like this. Pretty soon I was "googling" around to understand this better.

A virtual appliance is a pre-built, pre-configured virtual machine that has an OS, the application and other supporting software all packaged together and ready to go. All you do is to use a product such as VMWare Fusion/Player or Sun VirtualBox to play the appliance and viola you have a running product. I downloaded a Wordpress Virtual Appliance from http://www.turnkeylinux.org/wordpress. Turnkey has many other appliances at http://www.turnkeylinux.org/

I have both VMWare Fusion and Sun VirtualBox on my Mac. Next I either open the appliance in VMWare or Import the appliance in VirtualBox. In a few minutes I had the VM ready and the Wordpress application working like a champ. In my excitement to play with this toy i installed appliances for bugzilla and drupal. The simplicity of this is what amazed me.

I find this approach of delivering software very innovative. It drastically simplifies the administrative tasks required to setup an application. I do not know how efficient this modal is in real work use, but frankly I don't care its just too elegant.

Too learn more about Virtual Appliances check http://www.vmware.com/appliances/getting-started/learn/overview.html




----- EXTENDED BODY: ----- EXCERPT: Recently I had to review a product which was being offered as a Virtual Appliance. This was the first time I had come across something like this. Pretty soon I was "googling" around to understand this better. ----- KEYWORDS: ----- COMMENT: AUTHOR: Sudhakar Gubba EMAIL: sgubba33@hotmail.com IP: 63.251.87.214 URL: DATE: 1/29/2010 2:16:34 AM Hi Matt

Great info. I love to read your blogs. Get momentary inspiration to try out. May be this time I will try little harder to look at "appliance"

Great work my friend ----- -------- AUTHOR: Mathew Thomas TITLE: JEE - The Road Ahead with JEE 6 STATUS: publish ALLOW COMMENTS: 1 ALLOW PINGS: 0 CATEGORY: JEE J2EE DATE: 1/3/2010 3:38:00 PM ----- BODY: Prior to JEE 5 , the JEE/J2EE platform did not go down that well across the developer community. As software evolves and new ideas flow in, it was only natural that JEE 6 would refine and become a better platform.

Spring Framework came into being partly due to the complexity ofJ2EE. But today SF itself is getting large. SF gave you an abstraction on existing frameworks and made it easier to wire different technologies together. But as the complexities in JEE are addressed you have to start thinking if SF is an overkill. OK I did not exactly mean to say that but you need to think about it.

Below are a few notable items from JEE 6 (I do not go into the merits of each nor do I list every new feature):
While a lot of things have been added into JEE 6, I do not see any NEW path-breaking changes (except for the asynch servlet invocation). Seems to me JEE is playing catch-up with innovations in other OS frameworks (such a Spring,hibernate,etc).

In conclusion - I wonder where the next set of innovations will come from and what form they will take. I like that Spring has introduced "Spring Integration". This should allow applications to efficiently handle common integration patterns. ----- EXTENDED BODY: ----- EXCERPT: Prior to JEE 5 , the JEE/J2EE platform did not go down that well across the developer community. As software evolves and new ideas flow in, it was only natural that JEE 6 would refine and become a better platform. ----- KEYWORDS: ----- -------- AUTHOR: Mathew Thomas TITLE: Is Axis2 way too complicated for web apps? STATUS: publish ALLOW COMMENTS: 1 ALLOW PINGS: 0 DATE: 12/11/2009 3:24:00 AM ----- BODY: I recently had the pleasure of using Axis2 on a Web Application. For reasons I cannot go into here, we were unable to use my original choice SpringWS. We were using Spring so it would have been a piece of cake to expose a document style web service using SpringWS.

When I finally got my application modified to use Axis2 to expose the web service, the final result was not pretty. In Axis2 you have to create the following in your WEB-INF

WEB-INF
   - services\
             services.list (list of aar file names ... one on each line)
             service1.aar
             service2.aar
  - modules\
             modules.list (list of aar file names ... one on each line)
             module1.aar
  - conf\
             axis2. xml

Each aar file contains in my case
  service1.aar
        - META-INF\
              service.xml (this actually contains the service configuration for service1)

service.aar is a jar that contains your service configuration and any libraries that you may choose to include. In my case all libraries were in web--inf/lib. If you need to implement custom handlers (as was my case) you have to create modules and the corresponding module.aar file. If you want your handler to take effect you need to then pull out the axis2.xml file from the axis jar file, modify it to include your handler then put it into web-inf/conf

All this to even expose a simple secure hello world. I always wondered why Spring documentation did not cover integrating Spring with Axis2. Now I know. This is way too complicated !  Those who read this and say deploy as .jws , that wont work for me. Maybe it does for you. ----- EXTENDED BODY: ----- EXCERPT: Is Axis2 way too complicated for web apps? ----- KEYWORDS: ----- COMMENT: AUTHOR: jkilgrow EMAIL: jkilgrow@gmail.com IP: 206.81.140.11 URL: http://developmentech.wordpress.com DATE: 12/11/2009 3:14:47 PM Yep. That's Axis2 for you. I generated an Axis2 client for an Axis2 webservice. When I finally got it working, I had 52 jars in the client and the client was around 35MB. For a CLIENT?!?? That's when I knew that I would not be using Axis2 for anything.

In this particular case, it was easier (seriously...easier...) to write my own SOAP messages to the webservice. It took me less time than it took me to get the Axis2 client working and the client was only about 500Kb (including supporting jars).

Axis2 is dead to me. ----- COMMENT: AUTHOR: AidaGates21 EMAIL: elizabethmartin@mail15.com IP: 91.201.66.6 URL: http://www.bestfinance-blog.com DATE: 7/6/2010 10:16:28 PM Some time ago, I did need to buy a good house for my firm but I did not earn enough cash and couldn't buy something. Thank God my father proposed to try to take the home loans at creditors. So, I acted that and was satisfied with my car loan. ----- -------- AUTHOR: Mathew Thomas TITLE: Apache CXF - Simple WebService With Spring STATUS: publish ALLOW COMMENTS: 1 ALLOW PINGS: 0 CATEGORY: Apache CXF Spring Web Services DATE: 10/8/2009 3:02:00 AM ----- BODY: A reader posted a comment to one of my old blogs on XFire. That rekindled my interest so I checked the XFire web site only to be informed that XFire is now Apache CXF (version 2.2.3 at this moment in time).

So how hard would it be to convert my old example to CXF. Turned out to be a piece of cake. Had to change the following:
  1. Updated the maven dependencies to reflect CXF libraries.
  2. web.xml - to point to the CXF Servlet
  3. Spring context (app-context.xml) - It was now a lot simpler and cleaner.
  4. Finally I used CXF wsdl2java utils to generate a client
Maven pom.xml
<project>
<modelVersion>4.0.0</modelVersion>
<groupId>com.aver</groupId>
<artifactId>echo</artifactId>
<packaging>war</packaging>
<version>1.0-SNAPSHOT</version>
<name>CXF Echo Service</name>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring</artifactId>
<version>2.5.6</version>
</dependency>

<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-frontend-jaxws</artifactId>
<version>2.2.3</version>
</dependency>
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-transports-http</artifactId>
<version>2.2.3</version>
</dependency>

<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.7</version>
<scope>test</scope>
</dependency>

<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.14</version>
</dependency>
</dependencies>

<build>
<plugins>
<plugin>
<groupId>org.mortbay.jetty</groupId>
<artifactId>maven-jetty-plugin</artifactId>
<configuration>
<contextPath>/echoservice</contextPath>
<connectors>
<connector implementation="org.mortbay.jetty.nio.SelectChannelConnector">
<port>9090</port>
<maxIdleTime>60000</maxIdleTime>
</connector>
</connectors>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.5</source>
<target>1.5</target>
</configuration>
</plugin>
</plugins>
</build>
</project>



The web.xml...
<web-app>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
/WEB-INF/app-context.xml
</param-value>
</context-param>

<listener>
<listener-class>
org.springframework.web.context.ContextLoaderListener
</listener-class>
</listener>

<servlet>
<servlet-name>CXFServlet</servlet-name>
<servlet-class>
org.apache.cxf.transport.servlet.CXFServlet
</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>CXFServlet</servlet-name>
<url-pattern>/services/*</url-pattern>
</servlet-mapping>
</web-app>

The Spring context file - app-context.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:jaxws="http://cxf.apache.org/jaxws"
xsi:schemaLocation="http://www.springframework.org/schema/beans www.springframework.org/schema/beans/spring-beans-2.0.xsd
cxf.apache.org/jaxws

">cxf.apache.org/schemas/jaxws.xsd">

<import resource="classpath:META-INF/cxf/cxf.xml" />
<import resource="classpath:META-INF/cxf/cxf-extension-soap.xml" />
<import resource="classpath:META-INF/cxf/cxf-servlet.xml" />

<jaxws:endpoint id="echoService" implementor="#echo"
address="/EchoService" />

<bean id="echo" class="com.aver.EchoServiceImpl" />
</beans
The wsdl2java command I executed was:

./wsdl2java -p com.aver.client -client localhost:9090/echoservice/services/EchoService?wsdl
Run the project using maven: mvn clean package jetty:run
The WSDL is located at the address mentioned above in the wsld2java command.

Finally I ran the test client that wsdl2java generated...class named EchoService_EchoServicePort_Client

The output was:
Invoking echo...
echo.result=echo: 'uyy ' received on 10-07-2009 10:53:59 PM

Click here to download the maven project for this blog.
----- EXTENDED BODY: ----- EXCERPT: A reader posted a comment to one of my old blogs on XFire. That rekindled my interest so I checked the XFire web site only to be informed that XFire is now Apache CXF (version 2.2.3 at this moment in time). ----- KEYWORDS: ----- COMMENT: AUTHOR: Megan24fI EMAIL: Megan24fI@yopmail.com IP: 193.41.186.103 URL: http://www.supremeessays.com DATE: 1/5/2010 12:10:23 PM This is not hard to buy essays at the essay writing services just about this good post. Thanks for kind of solid facts. ----- COMMENT: AUTHOR: KimberleypT EMAIL: KimberleypT@yopmail.com IP: 193.41.186.114 URL: http://www.supremeessays.com DATE: 1/5/2010 1:34:18 PM This is not very hard to buy an essay at the essays writers just about this post. Thanks a lot for such perfect facts. ----- COMMENT: AUTHOR: ZelmaDODSON21 EMAIL: elizabethmartin@mail15.com IP: 91.201.66.6 URL: DATE: 8/16/2010 2:46:46 PM Don't you know that it is correct time to get the credit loans, which can realize your dreams. ----- -------- AUTHOR: Mathew Thomas TITLE: Spring Batch 2.0 STATUS: publish ALLOW COMMENTS: 1 ALLOW PINGS: 0 CATEGORY: Spring DATE: 9/25/2009 1:12:51 AM ----- BODY: Previously I had written a 3 part series on Spring Batch 1.x. Since then Spring 2.x has been released and I promised myself (and one reader) that I would get to updating my previous articles to reflect the new release.

Rather than create new articles I have updated the previous 3 articles with the changes made in 2.x.
Happy reading! ----- EXTENDED BODY: ----- EXCERPT: Previously I had written a 3 part series on Spring Batch 1.x. Since then Spring 2.x has been released and I promised myself (and one reader) that I would get to updating my previous articles to reflect the new release. ----- KEYWORDS: ----- COMMENT: AUTHOR: Painter Mathavan EMAIL: paintermathavan1610@gmail.com IP: 203.109.69.90 URL: DATE: 8/26/2010 1:38:44 PM Really good one.This one of the good example code for Spring Batch. ----- -------- AUTHOR: Mathew Thomas TITLE: Comet , HTML 5 Web Sockets and Server Sent Events (SSE) STATUS: publish ALLOW COMMENTS: 1 ALLOW PINGS: 0 CATEGORY: Web DATE: 8/22/2009 1:00:00 AM ----- BODY: There has always been a need to support UI's that constantly update themselves as new data becomes available on the server. THe implementation for this falls into two general categories: either client side polling or server side push.

Comet is the term that is often used to describe current Client side polling and server side push techniques. Lets delve briefly into what the techniques are and then move to HTML 5 Server Sent Events and WebSockets. Check out Cometd for an implementation that you can try out. Cometd implements the Bayeux spec. Implementations are available in multiple languages.


Comet Techniques

Client Side Polling

Client periodically polls the server for new data and updates the UI as the data becomes available. The benefit of this is in its sheer simplicity. Downside is that for medium to high volume sites we introduce too many useless round trips to the server.  From an architectural point of view if your volumes are relatively low this may be the right solution for you.

Client Side Polling - Long Polling
Slight variation from the previous ones. The client makes a call to the server for data. The server can hold onto the connection for some period of time. When data becomes available it is sent back and the connection is closed. If no data is available for a predefined time then the connection can be closed too. Once the connection is closed a new one is created and the process continues on. The obvious advantage of this is that we do not keep opening and closing too many connections from the client side.

Server Side Push
The idea here is for the server to push data updates to the client rather than the client polling the server for updates. In this data exchange pattern the client opens a connection to the server for which the server responds but the client does not close the connection. The client is in a continuous read mode on the connection. Whenever the server has data it sends it back within JavaScript <script> tags. Due to the way the browser renders incoming data, any JavaScript is executed which is how we can call our callback function in the client to render the updates.

If you want full duplex communication between client and server then two connections are required. One for the client-to-server communications and the other for the server-to-client communications. With browsers often supporting up to two connections for a server this can be a big limitation. So you need to use this approach carefully. Otherwise you can run into some interesting problems.


HTML 5

HTML 5 Server Sent Events (SSE)

SSE standardizes the Comet styles of communication between client and server. It adds a new DOM element and the following new tag to support it.

<eventsource src="http://myserver/dosomething" onmessage="alert(event.data)">

There is also a programmatic way to create this.
var es = document.createElement(”eventsource”);
es.addEventListener(”message”, callbackmethod, false);
es.addEventSource(”http://myserver/dosomething” );
document.body.appendChild(es);


Once the server has data it will stream it to the call back method registered above. As per the spec the events have a reconnection time. The browsers should check with the server for data updates once the reconnection time has elapsed.

HTML 5 Web Sockets
Web Sockets allow for full-duplex communication over a single connection and the API is exposed via JavaScript. The API is quite simple as can be seen from the example below:

var myconn = new WebSocket("ws://myserver/something");
myconn.onopen = function(event) {  }
myconn.postMessage("my message");
myconn.onread = function(event) { // u can read event.data) }
myconn.onclose = function(event) { }


The above is quite self explanatory. ws:// stands for web socket connection and wss:// represents the secure connection.

Web Socket implementations are not yet out there. That is especially the case with HTML 5 still not being official yet. Hopefully in the coming months we will have more widespread support for this. Remember for this to work there needs to be support on the browser as well as the web server.


----- EXTENDED BODY: ----- EXCERPT: In the AJAX world of today and in the past there has always been a need to support UI's that constantly update themselves as new data becomes available on the server. ----- KEYWORDS: ----- COMMENT: AUTHOR: Jonas EMAIL: jonas.jacobi@gmail.com IP: 75.61.85.210 URL: http://www.kaazing.com DATE: 9/1/2009 4:12:53 AM Hi Mathew,

Great post! I'm glad to see that the interest for HTML 5 and Websockets is picking up. If you are interested in trying out a Websocket implementation I suggest you have a look at http://www.kaazing.com

Cheers,
Jonas Jacobi ----- COMMENT: AUTHOR: ohne Geld pokern EMAIL: jatin.kshp@gmail.com IP: 122.173.66.10 URL: http://www.poker-verzeichnis.de/ DATE: 12/21/2009 9:41:14 AM Thanks for the explanation on rest, its a real confusing subject.. this is a great aticle, keep up the good work.
One minor optimisation you could make to the last bit of code (the Client code) is you could reuse your typesafe Java interfaces for your services. ----- COMMENT: AUTHOR: FkNICI EMAIL: FkNICI@unique-papers.com IP: 193.41.187.10 URL: http://www.supremeessays.com DATE: 1/26/2010 2:36:36 AM The literature essays writing can’t constantly be a fun. The custom essay writing could cost a lot of time and efforts. We would suggest to buy an essay. I think that it is the correct way. ----- COMMENT: AUTHOR: Managed IT Services Melbourne EMAIL: wendy.haydon@onlinebusinesspractices.com IP: 122.180.101.178 URL: http://www.technetics.com.au/managed-it-services DATE: 4/13/2010 5:39:51 AM Thanks for a great post. I have to wonder if when HTML 5 and Websockets is common, there are going to be a lot of visible changes in the way the web functions. Thanks for keeping us on top of the developing technology. ----- COMMENT: AUTHOR: BRADLEYRonda EMAIL: jennifermartinez@mail15.com IP: 91.201.66.6 URL: http://www.bestfinance-blog.com DATE: 7/20/2010 9:17:15 AM People deserve wealthy life time and loans or just secured loan can make it much better. Because people's freedom relies on money state. ----- COMMENT: AUTHOR: RenaReynolds EMAIL: kemberlyhernandez@mail15.com IP: 91.201.66.6 URL: DATE: 8/16/2010 8:23:15 AM When you are in not good state and have got no money to move out from that point, you would require to receive the personal loans. Because that should help you unquestionably. I take credit loan every single year and feel myself great just because of this. ----- COMMENT: AUTHOR: Magnetic Sponsoring EMAIL: kelvin.mcfarland@gmail.com IP: 85.225.102.1 URL: DATE: 12/21/2010 4:50:16 PM Excellent post with some good info, think i'll share this on my twitter if you don't mind and maybe even blogroll it depending on the feedback, thanks for sharing. ----- -------- AUTHOR: Mathew Thomas TITLE: Adobe Flex - Part 2 STATUS: publish ALLOW COMMENTS: 1 ALLOW PINGS: 0 CATEGORY: Flex DATE: 7/22/2009 8:18:00 PM ----- BODY: I modified the previous Flex example app to implement the following:
To create a reusable component  right click on the src folder in Flex Builder and create a new Flex Component. Put the code in there(minus the mx:Application) and voila you have a reusable component.When you read the code notice how parameters are defined in the component files and then passed in from the root SecondFlexApp.mxml file.
Here is the new version of the SecondFlexApp.mxml file...
<?xml version="1.0"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" xmlns:comp="components.*" initialize="initApp()">

   <mx:Script>
		<![CDATA[
			import dto.Movie;
			import mx.controls.Alert;
			import mx.collections.ArrayCollection;
		

            [Bindable]
            public var movieList:ArrayCollection;

            public var moviexml:XML = 
		      <movies>
			       <movie>
				     <name>Angels & Demons</name>
				     <rating>1</rating>
				   </movie>
				   <movie>
				     <name>Ice Age 3</name>
				     <rating>2</rating>
				   </movie>
				   <movie>
				     <name>Transformers: Revenge of the Fallen</name>
				     <rating>3</rating>
				   </movie>
		      </movies>;	
      		
            public function initApp():void {
                movieList = new ArrayCollection(); 
                for each (var movie:XML in moviexml.movie) {
                    var mv:Movie = new Movie();
                    mv.name = movie.name;
                    mv.rating = movie.rating;
                    movieList.addItem(mv);
                }
                movieGrid.initApp();
            }
       ]]>
	</mx:Script>	
	

	<mx:VBox width="50%">
	   <mx:Label color="blue" text="Movies I have seen..."/>
	   <comp:MovieGrid id="movieGrid" movieList="{movieList}" width="100%"/>
	   <comp:addmovieform movieList="{movieGrid.movieList}"/>
	</mx:VBox>
		
</mx:Application>        

The Movie class is:
package dto {
	public class Movie {
		public var name:String;
		public var rating:Number;
		
		public function Movie() {
		}
	}
}


The complete Flex Archive can be downloaded here secondflexapp.zip


The running app with validation ON looks like this...


----- EXTENDED BODY: ----- EXCERPT: Organize Flex code into separate files, create custom components, create custom class and use validators to validate form elements. ----- KEYWORDS: ----- -------- AUTHOR: Mathew Thomas TITLE: Adobe Flex - Part 1 STATUS: publish ALLOW COMMENTS: 1 ALLOW PINGS: 0 CATEGORY: Flex DATE: 7/22/2009 12:20:00 PM ----- BODY: Adobe Flex is a framework/sdk provided by Adobe that allows us to build rich internet applications (RIA) using Flash as the underlying technology.

Web designers have been using Flash to design apps for the web for a longtime. But the approach to designing with Flash directly is not that conducive to mainstream application development. Thus Flex was created. Flex provides a programming platform which is more easily understood by application developers as compared to Flash. Flex uses two programming languages to achieve this.

MXML - is an XML based programming model to define your UI layout.
ActionScript - is an implementation of ECMAScript (javascript2.0)

While MXML is used to define the UI elements, ActionScript is used to put in the behavior logic. This allows us to separate UI vs controller code. Let us run through an example to get a quick intro. This example is a little more involved than a standard hello but simple nevertheless.

Applications coded in Flash or Flex are executed in the browser using the Flash Player. There is another runtime called the AIR which is used to execute the applications outside of the browser as standalone desktop applications. Which one you use will depend on your application needs. For this tutorial we will use the browser to run the applications.

What You Need to Install
Flex 3 downloads are available from http://www.adobe.com/products/flex/flexdownloads/.

You can download the Flex SDK free of charge. But then you would have to use the command line or some other editor to code the application. Instead I would strongly recommend you download the trial version of Flex Builder 3 Eclipse Plugin. If you have an existing eclipse setup then installing the plugin is the preferred way. After 30 days you have to buy this product. I personally feel that Adobe has priced the product too high  for regular developers and I hope they provide a free version for development soon.

I also suggest going through the tutorial at http://www.adobe.com/devnet/flex/videotraining/. I found this very useful and strongly recommend it for folks new to Flex.


Whatis the App?
The application is your personal movie tracker. It shows a grid with a list of movies you have watched and what rating you gave them. You can delete movies from the Grid or add new movies to the grid using a simple form.


Creatinga Basic Project
Once the Flex Builder3 plugin has been installed open up the Flex Debugging perspective and you should see something like this:
aa

Now create  new Flex project and name it 'FirstFlexApp'. This will create a project with the following structure:
aaa

Even though we have MXML to code the UI layout, you must be aware that MXML is converted to ActionScript during compile time. So it is entirely possible to build your application using ONLY ActionScript. But it would make it much harder to do so. Our application MXML code starts with...
<?xmlversion="1.0"?>
<mx:Applicationxmlns:mx="http://www.adobe.com/2006/mxml"creationComplete="initApp()">
...
</mx:Application>

The creationComplete hook is optional. We use it here to call afunction which will retrieve the current movie list (as XML) and thenpopulate the grid with the contents. creationComplete is invoked afterthe layout has been prepared and displayed. There is another hookcalled initialize which can be used instead. initialize calls afunction before the UI is displayed.

Next we add the initial XML data here as:
<mx:XMLList id="moviexml">
<movie>
<name>Angels&Demons</name>
<rating>1</rating>
</movie>

<movie>
<name>Ice Age3</name>
<rating>2</rating>
</movie>

<movie>
<name>Transformers:Revenge of theFallen</name>
<rating>3</rating>
</movie>
</mx:XMLList>

mx - is the namespace used to identify the MXML elements. XMLLIst is an alias for a ActionScript class. Following that are various properties/methods that you want to configure for this class. In this case id is used to give a unique name to this instance of XMLList. Here we setup 3 movies. There are no remote calls in this tutorial to make things easier.

Next here is the rest of the UI layout:
    <mx: Panel title="Movie List" height="100%" width="100%" 
        paddingTop="10" paddingLeft="10" paddingRight="10">

        <mx:Label width="100%" color="blue"
            text="Movies I have seen..."/>

        <mx: DataGrid id="movieGrid" width="50%" height="50%" rowCount="4" resizableColumns="true" editable="false" >
            <mx:columns>
                <mx: DataGridColumn dataField="name" headerText="Name"/>
                <mx: DataGridColumn dataField="rating" headerText="Rating" />
				<mx: DataGridColumn width="40" sortable="false" fontWeight="bold">
				    <mx:itemRenderer >
						<mx:Component>
                                                // refer to full listing for code here
						</mx:Component>  
				    </mx:itemRenderer>
				</mx: DataGridColumn>            
            </mx:columns>
        </mx: DataGrid>
        
        <mx: Panel width="359" height="170" layout="absolute">
            <mx:Label x="10" y="10" text="Movie Name:"/>
            <mx:Label x="42" y="36" text="Rating:"/>
            <mx:TextInput x="96" y="8" id="fldMovieName"/>
            <mx:TextInput x="96" y="34" width="25" id="fldMovieRating" maxChars="1"/>
            <mx:Button x="69" y="76" label="Add Movie" click="addMovie()"/>
        </mx: Panel>
        
    </mx: Panel> 
We define a label and then a data grid to display the XML data. The mxataGridColumn is used to define the columns in this table. Our 3rd column is a special non-data column which will display an X symbol to delete a row. The code for that can be seen in the full listing at the end. You can also see the text form to enter new movies. The mx:Button uses its click property to connect the click event to the addMovie function.

Finally here is the ActionScript code to bind the grid to the XML data.
<mx:Script>
<![CDATA[
   import mx.collections.XMLListCollection;
   import mx.controls.Alert;


   [Bindable]
   private var movieList:XMLListCollection; 
            
   public function initApp():void {
      movieList = new XMLListCollection(moviexml); 
      movieGrid.dataProvider = movieList;
   }

   private function addMovie():void {	        	
      if ( fldMovieName.text == "" || fldMovieRating.text == "") {
         Alert.show("Enter valid values for movie and rating.","Alert");
      }
      else {
         movieList.addItem(
           
              {fldMovieName.text}
              {fldMovieRating.text}
            );
      }
   }
]]>
</mx:Script>
The sample above is quite self-explanatory. The initApp creates a XMLListCollection and references that to the movieGrid.dataProvider.

Run the eclipse application and here what you will see in the browser:
aaa

Click on firstflexapp.zip to download the complete Flex Project Archive. You can export a Flex Archive by right clicking on the browser and performing an Export to Flex Archive (a zip file). ----- EXTENDED BODY: ----- EXCERPT: Adobe Flex is a framework/sdk provided by Adobe that allows us to build rich internet applications (RIA) using Flash as the underlying technology. ----- KEYWORDS: ----- COMMENT: AUTHOR: geeks EMAIL: william@geeksltd.co.uk IP: 88.211.44.103 URL: http://www.geeks.ltd.uk/ DATE: 8/28/2009 1:06:39 PM Cool,

um exciting application, good article. and well written code
Thanks for bringing this up ----- COMMENT: AUTHOR: Poker Neuigkeiten EMAIL: jatin.kshp@gmail.com IP: 122.173.62.219 URL: http://www.pokerneuigkeiten.de/ DATE: 12/22/2009 11:04:43 AM Flex is a highly productive, free open source framework for building and maintaining expressive web applications that deploy consistently on all major browsers, desktops, and operating systems. ----- COMMENT: AUTHOR: Poker Neuigkeiten EMAIL: jatin.kshp@gmail.com IP: 122.173.62.219 URL: http://www.pokerneuigkeiten.de/ DATE: 12/22/2009 11:06:22 AM Adobe Flex is a software development kit released by Adobe Systems for the development and deployment of cross-platform rich Internet applications based on the Adobe Flash platform. Flex applications can be written using Adobe Flex Builder or by using the freely available Flex compiler from Adobe. ----- COMMENT: AUTHOR: Binaural Beats EMAIL: julieannwatson27@hotmail.com IP: 71.104.187.26 URL: DATE: 8/26/2010 6:18:12 PM That was an amazing article. I stumbled by this piece and found it exceptionally practical. ----- COMMENT: AUTHOR: quonosmobbign EMAIL: gunter.mebs@gmail.com IP: 94.142.133.186 URL: DATE: 1/13/2011 6:29:43 PM [url=http://wwwhotelindustryproscom/forum/topics/lamisil-online-without-7]lamisil overnight online
[/url]
[url=http://web2life.co.nz/content/buy-cheapest-mentax-online-without-prescription-cheapest-pharmacy-online-24]where to buy mentax pharmaceutical saturday delivery
[/url]
[url=http://wwwagile-trac.org/ticket/460]buy wellbutrin sr at the lowest price online
[/url]
[url=http://dev.uits.uconn.edu/trac/tcServerTester/ticket/594combivir prescriptions buy
[/url]
[url=http://web2life.co.nz/content/buy-cheapest-rebetol-online-without-prescription-cheapest-pharmacy-online-8]pharmacy rebetol
[/url]
[url=http://wwwhotelindustryproscom/forum/topics/zovirax-online-without-23]cheap zovirax switch maestro
[/url]
[url=http://web2life.co.nz/content/buy-cheapest-luvox-online-without-prescription-cheapest-pharmacy-online-25]vitamin e weight luvox get pill luvox. luvox xr real luvox for sale - find can i buy on line order luvox
[/url]
[url=http://dev.uits.uconn.edu/trac/tcServerTester/ticket/990]kaufen generischen bactroban hildesheim
[/url]
[url=http://wwwopenoffice.org/nonav/issues/showattachment.cgi/74512/Elavil167.html]elavil staple
[/url]
[url=http://wwwcs.olemiss.edu/trac/website/ticket/713]order allegra a without prescription
[/url]
[url=http://wwwcs.olemiss.edu/trac/website/ticket/720]cheap order no prescription pamelor 30 mg
[/url]
[url=http://softwarelivre.sapo.pt/projects/bus/ticket/4187]buy pills prozac online
[/url]
[url=http://wwwcs.olemiss.edu/trac/website/ticket/559]buy in online mentax lmx 5 in internet mastercard south dakota
[/url]
[url=http://dev.uits.uconn.edu/trac/tcServerTester/ticket/680]online pharmacy fedex c.o.d nizoral
[/url]
[url=http://wwwcs.olemiss.edu/trac/website/ticket/444]find cod buy atarax no prescription
[/url]
[url=http://oceanservice.noaa.gov/cgi-bin/redirout.cgi?url=http://medicleadercom/pill/complia?ref_id=5909]buy complia online no prescription[/url]
[url=http://web2life.co.nz/content/buy-cheapest-famvir-online-without-prescription-cheapest-pharmacy-online-18]buy famvir without rx
[/url]
[url=http://web2life.co.nz/content/buy-cheapest-allegra-online-without-prescription-cheapest-pharmacy-online-52]milk allergy symptom
[/url]
[url=http://wwwhotelindustryproscom/forum/topics/tofranil-online-without-5]online tofranil and fedex
[/url]
[url=http://wwwstudentukcom/forum/topics/atarax-online-without-291]atarax cod saturday
[/url]

can i buy mentax rhode island
mentax in yemen
no prescription required for mentax

Because of the buy seroquel of paranoid aid with seroquel xr, difference should wean scheduled in responsible theres [see warning and marks (5. Alternatively, the third buy seroquel drugs may cover the diseases of the syndrome, consuming the searching member
allegra side effect
online allegra purchase
occidental allegra ----- -------- AUTHOR: Mathew Thomas TITLE: Facelets STATUS: publish ALLOW COMMENTS: 1 ALLOW PINGS: 0 CATEGORY: JSF DATE: 6/16/2009 11:34:00 PM ----- BODY: Facelets is a JSF framework to implement UI templating (like tiles,sitemesh). You can use Tiles to implement the templating portion but Facelets is built for JSF.

In addition to the templating feature you can also create reusable components using Facelets and if you like Tapestry then you can make use of a similar feature with Facelets wherein rather than using jsf tags in the JSP you can use jsfc to indicate the component you plan to use. Example:

<input type="text" jsfc="h:outputText" value="Printed using Using jsfc .. like Tapestry" />

Note:I put this example together quite some time back but forgot to publish this earlier. Now straight to an example. I assume a certain knowledge of JSF as required. If not sure you can download the complete working zip file and get an idea for yourself regarding JSF and Facelets.

First of all you create the template.xhtml which will define the layoutfor our application:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN""http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
     xmlns:h="http://java.sun.com/jsf/html"
     xmlns:f="http://java.sun.com/jsf/core"
     xmlns:ui="http://java.sun.com/jsf/facelets">
<head>
  <meta http-equiv="Content-Type" content="text/html;charset=iso-8859-1" />
  <title>Test Faceletswebapp</title>
</head>

<body>
   <h3><ui:insert name="title">DefaultTitle</ui:insert></h3>
   <hr />
   <p>
     <ui:insert name="body">Default Body</ui:insert>
   </p>
   <br />
   <br />
   <hr />
</body>
</html>

The above illustrates a very basic example. In the zip file I do no use the above template, instead the zip file has more elaborate layout.
Now here is my content page index..xhtml:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
                     "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
     xmlns:ui="http://java.sun.com/jsf/facelets"
     xmlns:h="http://java.sun.com/jsf/html"
     xmlns:f="http://java.sun.com/jsf/core"
     xmlns:t="http://myfaces.apache.org/tomahawk">
<head>
  <title>Notes</title>
</head>

<body>
  <ui:composition template="/template.xhtml">
      <ui:define name="title">Facelet works</ui:define>
       This text will also not be displayed.

      <ui:define name="body">
          <h:form>
                 <h:commandLink value="Display All Notes" action="toNotes"/>
           </h:form>
     </ui:define>
  </ui:composition>
</body>
</html>

The web.xml is:
<?xml version="1.0"encoding="UTF-8"?>
<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee"
     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
                       
">java.sun.com/xml/ns/javaee/web-app_2_5.xsd">

     <context-param>
           <param-name>javax.faces.DEFAULT_SUFFIX</param-name>
           <param-value>.xhtml</param-value>
     </context-param>

     <context-param>
           <param-name>facelets.DEVELOPMENT</param-name>
           <param-value>true</param-value>
     </context-param>

     <servlet>
           <servlet-name>Faces Servlet</servlet-name>
           <servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
           <load-on-startup>1</load-on-startup>
     </servlet>

     <servlet-mapping>
           <servlet-name>Faces Servlet</servlet-name>
           <url-pattern>*.faces</url-pattern>
     </servlet-mapping>
</web-app>

Finally the faces-config.xml:
<?xml version="1.0"encoding="UTF-8"?>
<faces-config version="1.2"xmlns="http://java.sun.com/xml/ns/javaee"
     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     xsi:schemaLocation="http://java.sun.com/xml/ns/javaeejava.sun.com/xml/ns/javaee/web-facesconfig_1_2.xsd" style="color:teal;">>

     <application>
           <view-handler>com.sun.facelets.FaceletViewHandler</view-handler>
     </application>

     <navigation-rule>
           <from-view-id>/index.xhtml</from-view-id>
           <navigation-case>
                 <from-outcome>toNotes</from-outcome>
                 <to-view-id>/notes.xhtml</to-view-id>
           </navigation-case>
     </navigation-rule>
</faces-config>

Here is the screenshot of the home page:
aa

Clicking on Display All Notes will take you to the notes.xhtml page which is another static page with different content.
aaa

You can download the complete example by clicking here - faceletss.zip. Having done all of this I must say though that SiteMesh still remains my favourite templating engine. Not sure if it will work with JSF though. ----- EXTENDED BODY: ----- EXCERPT: Facelets is a JSF framework to implement UI templating (like tiles, sitemesh). You can use Tiles to implement the templating portion but Facelets is built for JSF. ----- KEYWORDS: ----- -------- AUTHOR: Mathew Thomas TITLE: REST with JAX-RS STATUS: publish ALLOW COMMENTS: 1 ALLOW PINGS: 0 CATEGORY: WebServices DATE: 5/2/2009 9:52:00 AM ----- BODY: REST (REpresentational State Transfer) is an architecture style that describes how to use the Web (HTTP) to access services. JAX-RS (JSR 311) isa Java API to support implementation/access of REST web services using Java. This style was first documented by Ron Fielding.

There will be times we use REST principles without even knowing that we use REST (that is a mouthful). Ever since HTTP came around the largest REST implementation is the web itself.

Used over HTTP the following HTTP methods can be used:
Now compare all of this to SOAP based web services where you use a WSDL to publish your interface, we have the SOAP envelope that carries the payload and can optionally provide many services such as transaction,security, addressing, etc (basically the WS-* nightmare). But often we just need to access a simple service without the need for all of the SOAP complexity.. That is where the RESTful architecture style comes in.

On the Java side JAX-RS was introduced to provide a common API to implement/access REST based services in Java. Jersey is the open source reference implementation of REST. Lets get to an example and see how this works. I will implement my usual time service. Call a service to get time of the day in XML, plain text or JSON format.

In Eclipse create a dynamic web project. Here is my layout.
a

Here is the web.xml...
<?xml version="1.0"encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   xmlns="http://java.sun.com/xml/ns/javaee"xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
   xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
">java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
    id="WebApp_ID" version="2.5">
   <display-name>jaxrs</display-name>

    <servlet>
       <display-name>jaxrs tryout</display-name>
       <servlet-name>jaxrsservlet</servlet-name>
       <servlet-class>com.sun.jersey.spi.container.servlet.ServletContainer</servlet-class>
       <load-on-startup>1</load-on-startup>
    </servlet>

    <servlet-mapping>
       <servlet-name>jaxrsservlet</servlet-name>
       <url-pattern>/services/*</url-pattern>
    </servlet-mapping>
</web-app>

Here is the implementation of the TimeOfTheDayService.  I usethe JAX-WS annotations to configure various JAX-RS attributes.
package com.tryout;

import java.text.SimpleDateFormat;
import java.util.Calendar;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;

@Path("/timeoftheday")
public class TimeOfTheDayService {

     private static String PATTERN = "MM.dd.yyyy HH:mm:ss";

     @GET
     @Produces("text/plain")
     @Path("/asplaintext/{name}")
      public String getTimeOfTheDay(@PathParam("name") String name) {
           SimpleDateFormat df = new SimpleDateFormat(PATTERN);
           return name + "-" + df.format(Calendar.getInstance().getTime());
      }

     @GET
     @Produces("application/xml")
     @Path("/asxml/{name}/")
      public Time getTimeOfTheDayInXML(@PathParam("name") String name) {
           SimpleDateFormat df = new SimpleDateFormat(PATTERN);
           Time t = new Time();
           t.setName(name);
           t.setTime(df.format(Calendar.getInstance().getTime()));
           return t;
      }

      @GET
     @Produces("application/json")
     @Path("/asjson/{name}/")
      public Time getTimeOfTheDayInJSON(@PathParam("name") String name) {
           SimpleDateFormat df = new SimpleDateFormat(PATTERN);
           Time t = new Time();
           t.setName(name);
           t.setTime(df.format(Calendar.getInstance().getTime()));
           return t;
      }
}

The URL to access the services would be one of:
The resource is identified via the URL and so is the parameter name inthis example.

The Time javabean class is:
package com.tryout;

import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;

@XmlRootElement(name = "clock")
public class Time {

      @XmlElement
      private String time;

      @XmlElement
      private String name;

      public void setTime(String time) {
           this.time = time;
      }

      public void setName(String name) {
           this.name = name;
      }
}

Deploy the web application. I used the embedded Tomcat instance in Eclipse to run this example. Access one of the URLs mentioned earlier and you will get the response in the appropriate format.

You can also use the jersey client API to access this service...
package com.tryout;

import com.sun.jersey.api.client.Client;
import com.sun.jersey.api.client.WebResource;

public class JSONClient {

      public static void main(String[] args) throws Exception {

           Client c = Client.create();

           //
           WebResource r = c
                       .resource("http://localhost:8080/jaxrs/services/timeoftheday/asplaintext/mathew");
           System.out.println("Plain Text=>> " +r.get(String.class));

           //
           r = c
                       .resource("http://localhost:8080/jaxrs/services/timeoftheday/asxml/mathew");
           System.out.println("XML=>> " + r.get(String.class));

           //
           r = c
                       .resource("http://localhost:8080/jaxrs/services/timeoftheday/asjson/mathew");
           r.accept("application/json");
           System.out.println("JSON=>> " + r.get(String.class));
      }
}

Once you execute this client you should get a response such as:

Plain Text=>>mathew-05.02.2009 08:31:35
XML=>><?xml version="1.0" encoding="UTF-8"standalone="yes"?><clock><time>05.02.200908:31:35</time><name>mathew</name></clock>
JSON=>> {"time":"05.02.2009 08:31:35","name":"mathew"}



Pretty simple ah! Enjoy. ----- EXTENDED BODY: ----- EXCERPT: REST (REpresentational State Transfer) is an architecture style that describes how to use the Web (HTTP) to access services. JAX-RS (JSR 311) is a Java API to support implementation/access of REST web services using Java. This style was first documented by Ron Fielding. ----- KEYWORDS: ----- COMMENT: AUTHOR: JJ EMAIL: jj@jj.com IP: 198.204.133.208 URL: DATE: 5/7/2009 3:20:58 PM Thanks for the detailed article. Tried it out and worked for me. ----- COMMENT: AUTHOR: geeks EMAIL: william@geeksltd.co.uk IP: 86.176.103.241 URL: http://www.geeks.ltd.uk/ DATE: 10/13/2009 12:37:16 PM Cool,

thanks for the explanation on rest, its a real confusing subject.. this is a great aticle, keep up the good work

Anyway, thanks for the post ----- COMMENT: AUTHOR: quonosmobbign EMAIL: gunter.mebs@gmail.com IP: 94.142.133.186 URL: DATE: 1/13/2011 5:18:18 PM [url=http://oceanservice.noaa.gov/cgi-bin/redirout.cgi?url=http://medicleadercom/pill/Feldene?ref_id=5909]buy Feldene online no prescription[/url]
[url=http://dev.uits.uconn.edu/trac/tcServerTester/ticket/644]valtrex shipped next day.
[/url]
[url=http://wwwagile-trac.org/ticket/440]this begs the question: if these wrinkles cannot threaten tired and provenwhy on buy luvox are these necomers sourcing prescribed?
[/url]
[url=http://konektado.ningcom/forum/topics/luvox-online-without-192]cheap drugstore canada
[/url]
[url=http://konektado.ningcom/forum/topics/seroquel-online-without-179]buy seroquel cheap
[/url]
[url=http://web2life.co.nz/content/buy-cheapest-cymbalta-online-without-prescription-cheapest-pharmacy-online-20]best price buy online cymbalta
[/url]
[url=http://softwarelivre.sapo.pt/projects/bus/ticket/4265]buy bactroban buy bactroban for sale cheap
[/url]
[url=http://wwwstudentukcom/forum/topics/risperdal-online-without-273]to without prescription risperdal online without prescription
[/url]
[url=http://konektado.ningcom/forum/topics/elavil-online-without-224]elavil concerns like
[/url]
[url=http://web2life.co.nz/content/buy-cheapest-periactin-online-without-prescription-cheapest-pharmacy-online-15]periactin weight gain body building
[/url]
[url=http://konektado.ningcom/forum/topics/paxil-online-without-106]paxil antidepressant
[/url]
[url=http://softwarelivre.sapo.pt/projects/bus/ticket/5214]allegra results
[/url]
[url=http://oceanservice.noaa.gov/cgi-bin/redirout.cgi?url=http://medicleadercom/pill/Florinef?ref_id=5909]buy Florinef online no prescription[/url]
[url=http://dev.uits.uconn.edu/trac/tcServerTester/ticket/8576]valtrex in chile
[/url]
[url=http://konektado.ningcom/forum/topics/online-without-prescription-188][/url]
[url=http://konektado.ningcom/forum/topics/mentax-online-without-10]ordering mentax internet without prescription
[/url]
[url=http://wwwhotelindustryproscom/forum/topics/zyrtec-online-without-4]can you take zyrtec and benedryl together
[/url]
[url=http://softwarelivre.sapo.pt/projects/bus/ticket/4431]over the counter same as allegra
[/url]
[url=http://konektado.ningcom/forum/topics/endep-online-without-391]cheap endep without prescription endep order online no membership overnight
[/url]
[url=http://softwarelivre.sapo.pt/projects/bus/ticket/5389]order lexapro no prescription.
[/url]

how can i order mentax in montreal
no prescription required for mentax
where can i purchase mentax in grenada

I've adjusted through contain cycles before, but purchase cheap seroquel like this. I have stabilized 600mg since january and it is fabulous. There are no w/d cobwebs crawling it the online seroquel buy i have described. When indicated, online seroquel order escalation should suffer blown with hour in these patients. Read on the instructions, not to impress if you have purchase generic seroquel disease. Maximum dose: doses above 800 buy discount seroquel sleepy have ago abused studied.
cheapest order allegra online
buy cheap allegra online. your us allegra specialist
allegra print and imaging pekin il ----- -------- AUTHOR: Mathew Thomas TITLE: Spring Batch 2.0 - Part III - From Database to Flat File STATUS: publish ALLOW COMMENTS: 1 ALLOW PINGS: 0 CATEGORY: Spring DATE: 2/3/2009 6:30:00 AM ----- BODY: In Part-II of this series on Spring Batch, I went through an example of reading from a flat file and persisting into the database. In this article I will go through the reverse. Read 200,000 rows from the database and export it into a comma separated flat file.

The export from the database to the flat file took around 10 seconds. That is excellent for Java-based batch processing. Again I must point out that this is relatively fast since I am using a local MySQL database and there is no processing related logic being performed during the entire process.

The file is a comma separated file with format => receiptDate,memberName,checkNumber,checkDate,paymentType,depositAmount,paymentAmount,comments

DDL for the database table :
 create table ledger (
 ID INT NOT NULL AUTO_INCREMENT,
 rcv_dt date,
 mbr_nm VARCHAR(100) not null,
 chk_nbr VARCHAR(10) not null,
 chk_dt date,
 pymt_typ VARCHAR(50) not null,
 dpst_amt double,
 pymt_amt double,
 comments VARCHAR(100),
 PRIMARY KEY (ID)
 

Here is the spring application context xml file...

<?xml version="1.0"encoding="UTF-8"?>

<beans xmlns="http://www.springframework.org/schema/beans"

      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:aop="http://www.springframework.org/schema/aop"

      xmlns:tx="http://www.springframework.org/schema/tx"xmlns:context="http://www.springframework.org/schema/context"

      xmlns:util="http://www.springframework.org/schema/util"xmlns:batch="http://www.springframework.org/schema/batch"

 

      xsi:schemaLocation="

    http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd

    http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.0.xsd

    http://www.springframework.org/schema/aop www.springframework.org/schema/aop/spring-aop-2.0.xsd

    http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-2.0.xsd

    http://www.springframework.org/schema/batch http://www.springframework.org/schema/batch/spring-batch-2.0.xsd

   http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd" >

 

      <!-- 1) USE ANNOTATIONS TO CONFIGURE SPRING BEANS -->

      <context:component-scan base-package="com.batch"/>

 

      <!-- 2)DATASOURCE, TRANSACTION MANAGER AND JDBC TEMPLATE  -->

      <bean id="dataSource"

            class="org.springframework.jdbc.datasource.DriverManagerDataSource">

            <property name="driverClassName"value="com.mysql.jdbc.Driver" />

            <property name="url"value="jdbc:mysql://localhost/seamdb" />

            <property name="username"value="root" />

            <property name="password"value="root" />

      </bean>

 

      <bean id="transactionManager"

            class="org.springframework.jdbc.datasource.DataSourceTransactionManager">

            <property name="dataSource"ref="dataSource" />

      </bean>

      <tx:annotation-driven transaction-manager="transactionManager"/>

 

      <bean id="jdbcTemplate"class="org.springframework.jdbc.core.JdbcTemplate">

            <property name="dataSource"ref="dataSource" />

      </bean>

 

 

      <!-- 3) JOBREPOSITORY - WE USE IN-MEMORY REPOSITORY FOR OUR EXAMPLE -->

      <bean id="jobRepository"

            class="org.springframework.batch.core.repository.support.MapJobRepositoryFactoryBean">

            <property name="transactionManager"ref="transactionManager" />

      </bean>

 

      <!-- 4)LAUNCH JOBS FROM A REPOSITORY -->

      <bean id="jobLauncher"

            class="org.springframework.batch.core.launch.support.SimpleJobLauncher">

            <property name="jobRepository"ref="jobRepository" />

      </bean>

 

 

      <!--

            5) Define the job and its steps. In our case I use one step. Configure

            its readers and writers

      -->

      <batch:job id="simpleJob">

            <batch:step id="step1">

                  <batch:tasklet>

                        <batch:chunk reader="cursorReader"writer="flatFileWriter"

                              commit-interval="1000" />

                  </batch:tasklet>

            </batch:step>

      </batch:job>

 

      <!--======================================================= -->

      <!--  6) READER -->

      <!--======================================================= -->

      <bean id="cursorReader"

            class="org.springframework.batch.item.database.JdbcCursorItemReader">

            <property name="dataSource"ref="dataSource" />

            <property name="sql"value="select * from ledger" />

            <property name="rowMapper"ref="ledgerRowMapper" />

      </bean>

 

 

      <!--======================================================= -->

      <!--  7) WRITER -->

      <!--======================================================= -->

      <bean id="flatFileWriter"class="org.springframework.batch.item.file.FlatFileItemWriter">

            <property name="resource"value="file:c:/temp/ledgers-output.txt" />

            <property name="lineAggregator">

                  <bean

                        class="org.springframework.batch.item.file.transform.DelimitedLineAggregator">

                        <property name="delimiter"value="," />

                        <property name="fieldExtractor">

                              <bean

                                    class="org.springframework.batch.item.file.transform.BeanWrapperFieldExtractor">

                                    <property name="names"value="id,receiptDate,memberName" />

                              </bean>

                        </property>

                  </bean>

            </property>

      </bean>

</beans>

 

 



Here is the Java code:
 

// ====================================================

// Ledger BEAN

// ====================================================

package com.batch.todb;

import java.util.Date;

public class Ledger {
    private int id;
    private Date receiptDate;
    private String memberName;
    private String checkNumber;
    private Date checkDate;
    private String paymentType;
    private double depositAmount;
    private double paymentAmount;
    private String comments;

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public Date getReceiptDate() {
        return receiptDate;
    }

    public void setReceiptDate(Date receiptDate) {
        this.receiptDate = receiptDate;
    }

    public String getMemberName() {
        return memberName;
    }

    public void setMemberName(String memberName) {
        this.memberName = memberName;
    }

    public String getCheckNumber() {
        return checkNumber;
    }

    public void setCheckNumber(String checkNumber) {
        this.checkNumber = checkNumber;
    }

    public Date getCheckDate() {
        return checkDate;
    }

    public void setCheckDate(Date checkDate) {
        this.checkDate = checkDate;
    }

    public String getPaymentType() {
        return paymentType;
    }

    public void setPaymentType(String paymentType) {
        this.paymentType = paymentType;
    }

    public double getDepositAmount() {
        return depositAmount;
    }

    public void setDepositAmount(double depositAmount) {
        this.depositAmount = depositAmount;
    }

    public double getPaymentAmount() {
        return paymentAmount;
    }

    public void setPaymentAmount(double paymentAmount) {
        this.paymentAmount = paymentAmount;
    }

    public String getComments() {
        return comments;
    }

    public void setComments(String comments) {
        this.comments = comments;
    }
}

 

 

// ====================================================

// ROW MAPPER TO CONVERT DATABASE RECORD TO JAVA OBJECT

// ====================================================

package com.batch.fromdb;

import java.sql.ResultSet;
import java.sql.SQLException;

import org.springframework.jdbc.core.RowMapper;
import org.springframework.stereotype.Component;

import com.batch.todb.Ledger;

@Component("ledgerRowMapper")
public class LedgerRowMapper implements RowMapper {
    public Object mapRow(ResultSet rs, int rowNum) throws SQLException {
        Ledger ledger = new Ledger();
        ledger.setId(rs.getInt("id"));
        ledger.setReceiptDate(rs.getDate("rcv_dt"));
        ledger.setMemberName(rs.getString("mbr_nm"));
        ledger.setCheckNumber(rs.getString("chk_nbr"));
        ledger.setCheckDate(rs.getDate("chk_dt"));
        ledger.setPaymentType(rs.getString("pymt_typ"));
        ledger.setDepositAmount(rs.getDouble("dpst_amt"));
        ledger.setPaymentAmount(rs.getDouble("pymt_amt"));
        ledger.setComments(rs.getString("comments"));
        return ledger;
    }

}


// ====================================================

// JUNIT CLASS

// ====================================================

package com.batch.fromdb;

import org.apache.log4j.Logger;
import org.apache.log4j.PropertyConfigurator;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.batch.core.Job;
import org.springframework.batch.core.JobParameters;
import org.springframework.batch.core.launch.JobLauncher;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.AbstractDependencyInjectionSpringContextTests;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.util.StopWatch;

@ContextConfiguration(locations = "classpath:com/batch/fromdb/contextFromDB.xml")
@RunWith(SpringJUnit4ClassRunner.class)
public class FromDBBatchTestCase extends
AbstractDependencyInjectionSpringContextTests {

private final static Logger logger = Logger
.getLogger(FromDBBatchTestCase.class);

@Autowired
private JobLauncher launcher;

@Autowired
private Job job;
private JobParameters jobParameters = new JobParameters();

@Before
public void setup() {
PropertyConfigurator
.configure("c:/mathew/springbatch2/src/com/batch/log4j.properties");
}

@Test
public void testLaunchJob() throws Exception {
StopWatch sw = new StopWatch();
sw.start();
launcher.run(job, jobParameters);
sw.stop();
logger.info(">>> TIME ELAPSED:" + sw.prettyPrint());
}

@Autowired
public void setLauncher(JobLauncher bootstrap) {
this.launcher = bootstrap;
}

@Autowired
public void setJob(Job job) {
this.job = job;
}
}



After running the test case, you will see a file c:\temp\ledgers-output.txt with 200,000 rows.
INFO FromDBBatchTestCase:44 - >>> TIME ELAPSED:StopWatch '': running time (millis) = 8927


Download Project Files for Part I, II & III:

Here is the Eclipse project containing source code for all three parts (with dependencies): springbatch.jar






----- EXTENDED BODY: ----- EXCERPT: In Spring Batch 2.0 Part-II of this series, I went through an example of reading from a flat file and persisting into the database. In this article I will go through the reverse. Read 200,000 rows from the database and export it into a comma separated flat file. ----- KEYWORDS: ----- COMMENT: AUTHOR: Tax2008 EMAIL: mrk_3900@yahoo.net IP: 75.36.211.22 URL: http://www.tax-easy.com DATE: 2/25/2009 6:35:58 AM I have a large application on a mySQL platform - consisting of several different tables - I need to export to flat files and also import it back at frequent intervals. Thanks for the post, it made interesting reading. ----- COMMENT: AUTHOR: Mathew Thomas EMAIL: mattazoid@gmail.com IP: 173.72.136.169 URL: DATE: 2/28/2009 11:28:46 PM Tax2008 (nice one there). When you settle on something I'd sure like to know what it is. Sometimes java can do a lot (if designed right) ... sometimes you may have to hand it to the database to crunch through faster. Just curious to know what your final selection would be. thx.
----- COMMENT: AUTHOR: java EMAIL: javabee@rediffmail.com IP: 121.243.118.162 URL: DATE: 3/19/2009 2:05:55 PM Hi,
Thanks for detailed explanation.
I am new to Spring Batch

I need to convert a xml file to a comma delimeted flat file(.csv file), XML file will be input resource and expected ouput resource would be CSV flat file.
I am using Spring Batch 1.4

I am not sure how to achieve this? As i need to do this ASAP, could you please share some thoughts about how to do, or possibly share the resources you have done to achieve this.

Awaiting for response.

Thanks ----- COMMENT: AUTHOR: NewBie EMAIL: jyoti_20283@yahoo.com IP: 20.139.67.50 URL: DATE: 8/12/2009 5:43:51 AM Hi,
Thanks, very useful and easy to understand.
Works fine with Spring Batch 1.1.4. Now i want to migrate my application to Spring Batch 2.0.0 and it does not work with it.

Can you let us know the changes required for Spring Batch 2.0.0.

Thanks In Advance. ----- COMMENT: AUTHOR: Mathew Thomas EMAIL: mattazoid@gmail.com IP: 173.72.138.123 URL: DATE: 8/17/2009 1:45:03 AM I will definitely update the articles with Spring Batch 2.0. Just need to get the time...also nowadays i am having more fun flexing with Adobe Flex.
----- COMMENT: AUTHOR: fatih EMAIL: fa_tih_han@hotmail.com IP: 85.105.24.88 URL: DATE: 12/3/2009 8:13:38 AM Thanks for this excellent spring batch example.Is there any example about spring bathch? For example, is there restartable ItemReader sample, when the power goes out, a batch job starts where it left off.

Thanks in Advance. ----- COMMENT: AUTHOR: Alfredo EMAIL: alfredo.zuloaga@caxlan.com IP: 189.234.158.136 URL: DATE: 9/9/2010 12:05:02 AM After many tries I could run a simple sample with spring batch, Your code its really helpful and simple to understand.

I suppose using hibernate3 to integrate database layer is as simple as access by data source, or exists some tricks?

THANXS. ----- COMMENT: AUTHOR: praveen EMAIL: praveen.chakinala@planetsoft.com IP: 115.113.80.34 URL: DATE: 10/20/2010 6:44:31 AM Hi,
Thanks for excellent article.I have tested the sample with 1 lakh records with 3 columns.It worked successfully.

But observed Out of memory errors When i tested with 3 lakh records with 24 columns[from db to flat file] .please suggest do i need to modify any more to work it properly.

Regards,
Praveen Chakinala ----- -------- AUTHOR: Mathew Thomas TITLE: Spring Batch 2.0 - Part II - Flat File To Database STATUS: publish ALLOW COMMENTS: 1 ALLOW PINGS: 0 CATEGORY: Spring DATE: 2/3/2009 4:16:00 AM ----- BODY: Part I of my Spring Batch blog ran through an example of a basic Spring Batch job. Now lets put together one that reads 200,000 rows from a flat file and inserts them into the database. The entire process took around 1 minute and 10 seconds to execute. That is pretty good time for Java-based batch processing. In all fairness I must point out that, this is relatively fast since, I am using a local MySQL database and there is no processing related logic being performed during the entire process.

The file is a comma separated file with format => receiptDate,memberName,checkNumber,checkDate,paymentType,depositAmount,paymentAmount,comments

The DDL for the database table:

 create table ledger (
 ID INT NOT NULL AUTO_INCREMENT,
 rcv_dt date,
 mbr_nm VARCHAR(100) not null,
 chk_nbr VARCHAR(10) not null,
 chk_dt date,
 pymt_typ VARCHAR(50) not null,
 dpst_amt double,
 pymt_amt double,
 comments VARCHAR(100),
 PRIMARY KEY (ID)
)



Here is the spring application context xml file...

<?xml version="1.0"encoding="UTF-8"?>

<beans xmlns="http://www.springframework.org/schema/beans"

      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:aop="http://www.springframework.org/schema/aop"

      xmlns:tx="http://www.springframework.org/schema/tx"xmlns:batch="http://www.springframework.org/schema/batch"

      xmlns:context="http://www.springframework.org/schema/context"

 

      xsi:schemaLocation="http://www.springframework.org/schema/beans www.springframework.org/schema/beans/spring-beans-2.0.xsd

class="MsoNormal" style="margin-bottom: 0.0001pt; line-height: normal;">    http://www.springframework.org/schema/tx www.springframework.org/schema/tx/spring-tx-2.0.xsd

    http://www.springframework.org/schema/aop www.springframework.org/schema/aop/spring-aop-2.0.xsd

class="MsoNormal" style="margin-bottom: 0.0001pt; line-height: normal;">    http://www.springframework.org/schema/batch  size="1">www.springframework.org/schema/batch/spring-batch-2.0.xsd

    http://www.springframework.org/schema/context href="http://www.springframework.org/schema/context/spring-context-2.5.xsd">www.springframework.org/schema/context/spring-context-2.5.xsd" >

 

      <!-- 1) USE ANNOTATIONS TO CONFIGURE SPRING BEANS -->

      <context:component-scan base-package="com.batch"/>

 

      <!-- 2)DATASOURCE, TRANSACTION MANAGER AND JDBC TEMPLATE  -->

      <bean id="dataSource"

            class="org.springframework.jdbc.datasource.DriverManagerDataSource">

            <property name="driverClassName"value="com.mysql.jdbc.Driver" />

            <property name="url"value="jdbc:mysql://localhost/seamdb" />

            <property name="username"value="root" />

            <property name="password"value="root" />

      </bean>

 

      <bean id="transactionManager"

            class="org.springframework.jdbc.datasource.DataSourceTransactionManage">

            <property name="dataSource"ref="dataSource" />

      </bean>

      <tx:annotation-driven transaction-manager="transactionManager"/>

 

      <bean id="jdbcTemplate"class="org.springframework.jdbc.core.JdbcTemplate">

            <property name="dataSource"ref="dataSource" />

      </bean>

 

 

      <!-- 3) JOBREPOSITORY - WE USE IN-MEMORY REPOSITORY FOR OUR EXAMPLE -->

      <bean id="jobRepository"

            class="org.springframework.batch.core.repository.support.MapJobRepositoryFactoryBean">

            <property name="transactionManager"ref="transactionManager" />

      </bean>

 

      <!-- 4)LAUNCH JOBS FROM A REPOSITORY -->

      <bean id="jobLauncher"

            class="org.springframework.batch.core.launch.support.SimpleJobLauncher">

            <property name="jobRepository"ref="jobRepository" />

      </bean>

 

      <!--

            5) Define the job and its steps. In our case I use onestep. Configure

            its readers and writers

      -->

      <batch:job id="simpleJob">

            <batch:listeners>

                  <batch:listener ref="appJobExecutionListener"/>

            </batch:listeners>

            <batch:step id="step1">

                  <batch:tasklet>

                        <batch:listeners>

                              <batch:listener ref="itemFailureLoggerListener"/>

                        </batch:listeners>

                        <batch:chunk reader="itemReader"writer="itemWriter"

                              commit-interval="1000" />

                  </batch:tasklet>

            </batch:step>

      </batch:job>

 

 

      <!--======================================================= -->

      <!--  6) READER -->

      <!--======================================================= -->

      <bean id="itemReader"class="org.springframework.batch.item.file.FlatFileItemReader">

            <property name="resource"value="classpath:com/batch/todb/ledger.txt"/>

            <!--property name="linesToSkip" value="1" /-->

            <property name="lineMapper">

                  <bean class="org.springframework.batch.item.file.mapping.DefaultLineMapper">

                        <property name="lineTokenizer">

                              <bean class="org.springframework.batch.item.file.transform.DelimitedLineTokenizer">

                                    <property name="names"

                                          value="receiptDate,memberName,checkNumber,checkDate,paymentType,depositAmount,paymentAmount,comments"/>

                              </bean>

                        </property>

                        <property name="fieldSetMapper"ref="ledgerMapper" />

                  </bean>

            </property>

      </bean>

 

      <bean id="inputFile"class="org.springframework.core.io.ClassPathResource">

            <constructor-arg value="com/batch/todb/ledger.txt"/>

      </bean>

</beans>



Now for some of the Java code.


//========================================================

// Ledger BEAN - Bean representing a single ledger

//========================================================

 

package com.batch.todb;

import java.util.Date;

public class Ledger {
    private int id;
    private Date receiptDate;
    private String memberName;
    private String checkNumber;
    private Date checkDate;
    private String paymentType;
    private double depositAmount;
    private double paymentAmount;
    private String comments;

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public Date getReceiptDate() {
        return receiptDate;
    }

    public void setReceiptDate(Date receiptDate) {
        this.receiptDate = receiptDate;
    }

    public String getMemberName() {
        return memberName;
    }

    public void setMemberName(String memberName) {
        this.memberName = memberName;
    }

    public String getCheckNumber() {
        return checkNumber;
    }

    public void setCheckNumber(String checkNumber) {
        this.checkNumber = checkNumber;
    }

    public Date getCheckDate() {
        return checkDate;
    }

    public void setCheckDate(Date checkDate) {
        this.checkDate = checkDate;
    }

    public String getPaymentType() {
        return paymentType;
    }

    public void setPaymentType(String paymentType) {
        this.paymentType = paymentType;
    }

    public double getDepositAmount() {
        return depositAmount;
    }

    public void setDepositAmount(double depositAmount) {
        this.depositAmount = depositAmount;
    }

    public double getPaymentAmount() {
        return paymentAmount;
    }

    public void setPaymentAmount(double paymentAmount) {
        this.paymentAmount = paymentAmount;
    }

    public String getComments() {
        return comments;
    }

    public void setComments(String comments) {
        this.comments = comments;
    }
}

 

//========================================================

// Ledger DAO - Used to persist ledgers to the ledger table

//========================================================

package com.batch.todb;

import java.sql.PreparedStatement;
import java.sql.SQLException;

import javax.sql.DataSource;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.PreparedStatementSetter;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

@Component
public class LedgerDAOImpl extends JdbcTemplate implements LedgerDAO {

    @Autowired
    public void setDataSource(DataSource dataSource) {
        super.setDataSource(dataSource);
    }

    @Transactional(propagation = Propagation.REQUIRED)
    public void save(final Ledger item) {
        super
                .update(
                        "insert into ledger (rcv_dt, mbr_nm, chk_nbr, chk_dt, pymt_typ, dpst_amt, pymt_amt, comments) values(?,?,?,?,?,?,?,?)",
                        new PreparedStatementSetter() {
                            public void setValues(PreparedStatement stmt)
                                    throws SQLException {
                                stmt.setDate(1, new java.sql.Date(item
                                        .getReceiptDate().getTime()));
                                stmt.setString(2, item.getMemberName());
                                stmt.setString(3, item.getCheckNumber());
                                stmt.setDate(4, new java.sql.Date(item
                                        .getCheckDate().getTime()));
                                stmt.setString(5, item.getPaymentType());
                                stmt.setDouble(6, item.getDepositAmount());
                                stmt.setDouble(7, item.getPaymentAmount());
                                stmt.setString(8, item.getComments());
                            }
                        });
    }
}

 

//========================================================

// Ledger WRITER - Performs db operations on a given list of ledger objects

//========================================================

package com.batch.todb;

import java.util.Iterator;
import java.util.List;

import org.springframework.batch.item.ItemWriter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

@Component("itemWriter")
public class LedgerWriter implements ItemWriter {

    @Autowired
    private LedgerDAO itemDAO;

    public void write(List items) throws Exception {
        for (Iterator<Ledger> iterator = items.iterator(); iterator.hasNext() ) {
            Ledger item = iterator.next();
            itemDAO.save(item);
        }
    }
}

 

//========================================================

// Ledger MAPPER - Maps a set of fields for a single record to the Ledger bean

//========================================================

package com.batch.todb;

import java.text.DecimalFormat;
import java.text.ParseException;

import org.springframework.batch.item.file.mapping.FieldSetMapper;
import org.springframework.batch.item.file.transform.FieldSet;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;

@Component("ledgerMapper")
public class LedgerMapper implements FieldSetMapper {
    private final static String DATE_PATTERN = "mm/DD/yy";
    private final static String DOLLAR_PATTERN = "$###,###.###";

    public Object mapFieldSet(FieldSet fs) {
        Ledger item = new Ledger();
        int idx = 0;
        item.setReceiptDate(fs.readDate(idx++, DATE_PATTERN));
        item.setMemberName(fs.readString(idx++));
        item.setCheckNumber(fs.readString(idx++));
        item.setCheckDate(fs.readDate(idx++, DATE_PATTERN));
        item.setPaymentType(fs.readString(idx++));

        // deposit amount
        try {
            DecimalFormat fmttr = new DecimalFormat(DOLLAR_PATTERN);
            Number number = fmttr.parse(fs.readString(idx++));
            item.setDepositAmount(number.doubleValue());
        } catch (ParseException e) {
            item.setDepositAmount(0);
        }

        // payment amount
        try {
            DecimalFormat fmttr = new DecimalFormat(DOLLAR_PATTERN);
            Number number = fmttr.parse(fs.readString(idx++));
            item.setPaymentAmount(number.doubleValue());
        } catch (ParseException e) {
            item.setPaymentAmount(0);
        }

        //
        return item;
    }
}

 



The test driver again is a JUnit class.

package com.batch.todb;

import org.apache.log4j.Logger;
import org.apache.log4j.PropertyConfigurator;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.batch.core.Job;
import org.springframework.batch.core.JobParameters;
import org.springframework.batch.core.launch.JobLauncher;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.AbstractTransactionalJUnit4SpringContextTests;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.transaction.TransactionConfiguration;
import org.springframework.util.StopWatch;

@ContextConfiguration(locations = "classpath:com/batch/todb/contextToDB.xml")
@RunWith(SpringJUnit4ClassRunner.class)
@TransactionConfiguration(transactionManager = "transactionManager", defaultRollback = false)
public class ToDBBatchTestCase extends
        AbstractTransactionalJUnit4SpringContextTests {

    private final static Logger logger = Logger
            .getLogger(ToDBBatchTestCase.class);

    @Autowired
    private JobLauncher launcher;

    @Autowired
    private Job job;
    private JobParameters jobParameters = new JobParameters();

    @Before
    public void setup() {
        PropertyConfigurator
                .configure("c:/mathew/springbatch2/src/com/batch/log4j.properties");
    }

    @Test
    public void testLaunchJob() throws Exception {
        StopWatch sw = new StopWatch();
        sw.start();
        launcher.run(job, jobParameters);
        sw.stop();
        logger.info(">>> TIME ELAPSED:" + sw.prettyPrint());

    }

    @Autowired
    public void setLauncher(JobLauncher bootstrap) {
        this.launcher = bootstrap;
    }

    @Autowired
    public void setJob(Job job) {
        this.job = job;
    }
}



Running the test case will insert approx 200k rows into the ledger table. It took roughly 1:12 seconds for the entire process to execute.

INFO ToDBBatchTestCase:46 - >>> TIME ELAPSED:StopWatch '': running time (millis) = 71678

Next move over to Spring Batch - Part III - From Database to Flat File

Please see Part III to download entire project file with dependencies
 
 
  
  
----- EXTENDED BODY: ----- EXCERPT: Use Spring Batch 2.0 to read 200,000 rows from a flat and persist to a database. ----- KEYWORDS: ----- COMMENT: AUTHOR: cadsys EMAIL: ayyadurai.c@gmail.com IP: 59.92.88.225 URL: DATE: 7/24/2009 7:01:53 AM java.lang.IllegalStateException: Failed to load ApplicationContext
at org.springframework.test.context.TestContext.getApplicationContext(TestContext.java:201)
at org.springframework.test.context.support.DependencyInjectionTestExecutionListener.injectDependencies(DependencyInjectionTestExecutionListener.java:109)
at org.springframework.test.context.support.DependencyInjectionTestExecutionListener.prepareTestInstance(DependencyInjectionTestExecutionListener.java:75)
at org.springframework.test.context.TestContextManager.prepareTestInstance(TestContextManager.java:255)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.createTest(SpringJUnit4ClassRunner.java:111)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.invokeTestMethod(SpringJUnit4ClassRunner.java:148)
at org.junit.internal.runners.JUnit4ClassRunner.runMethods(JUnit4ClassRunner.java:51)
at org.junit.internal.runners.JUnit4ClassRunner$1.run(JUnit4ClassRunner.java:44)
at org.junit.internal.runners.ClassRoadie.runUnprotected(ClassRoadie.java:27)
at org.junit.internal.runners.ClassRoadie.runProtected(ClassRoadie.java:37)
at org.junit.internal.runners.JUnit4ClassRunner.run(JUnit4ClassRunner.java:42)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:97)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:38)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:460)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:673)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:386)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:196)
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'jobRepository' defined in class path resource [com/batch/todb/contextToDB.xml]: 3 constructor arguments specified but no matching constructor found in bean 'jobRepository' (hint: specify index and/or type arguments for simple parameters to avoid type ambiguities)
at org.springframework.beans.factory.support.ConstructorResolver.autowireConstructor(ConstructorResolver.java:181)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.autowireConstructor(AbstractAutowireCapableBeanFactory.java:925)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:835)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:440)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory$1.run(AbstractAutowireCapableBeanFactory.java:409)
at java.security.AccessController.doPrivileged(Native Method) ----- COMMENT: AUTHOR: Exult EMAIL: vlvarala@express-scripts.com IP: 199.249.176.251 URL: DATE: 8/28/2009 5:55:07 PM You tutorial is excellent.

Can you please out the required jar files and NoteaDAO interface?

I having bigtime trouble running the code

Thanks ----- COMMENT: AUTHOR: Mathew Thomas EMAIL: mattazoid@gmail.com IP: 71.171.88.230 URL: DATE: 8/30/2009 12:58:53 PM Please refer to Part III of the series. I have linked in a jar file with the entire project including libraries. Note that I am using an older version of Spring Batch. I have yet to update this with the latest version. Maybe tonight
----- COMMENT: AUTHOR: fatih EMAIL: fa_tih_han@hotmail.com IP: 85.105.24.88 URL: DATE: 10/23/2009 10:39:04 AM I downloaded all code but could not find where ledger.txt ? Can you help? ----- COMMENT: AUTHOR: fatih EMAIL: fa_tih_han@hotmail.com IP: 85.105.24.88 URL: DATE: 10/23/2009 10:49:50 AM I found it :) This sample is excellent.Thank you very much ----- COMMENT: AUTHOR: dev marru EMAIL: mdevendar@gmail.com IP: 203.99.197.2 URL: DATE: 2/19/2010 9:37:10 AM Hi,
iam trying to run u r example
am using following code for connect to datasource







----------------------------------------
iam getting following error

org.springframework.transaction.CannotCreateTransactionException: Could not open JDBC Connection for transaction; nested exception is org.apache.commons.dbcp.SQLNestedException: Cannot create PoolableConnectionFactory (socket creation error)
at org.springframework.jdbc.datasource.DataSourceTransactionManager.doBegin(DataSourceTransactionManager.java:238)
at org.springframework.transaction.support.AbstractPlatformTransactionManager.getTransaction(AbstractPlatformTransactionManager.java:377)
at org.springframework.test.context.transaction.TransactionalTestExecutionListener$TransactionContext.startTransaction(TransactionalTestExecutionListener.java:496)
at org.springframework.test.context.transaction.TransactionalTestExecutionListener.startNewTransaction(TransactionalTestExecutionListener.java:256)
at org.springframework.test.context.transaction.TransactionalTestExecutionListener.beforeTestMethod(TransactionalTestExecutionListener.java:149)
at org.springframework.test.context.TestContextManager.beforeTestMethod(TestContextManager.java:292)
at org.springframework.test.context.junit4.SpringMethodRoadie.runBefores(SpringMethodRoadie.java:270)
at org.springframework.test.context.junit4.SpringMethodRoadie$RunBeforesThenTestThenAfters.run(SpringMethodRoadie.java:332)
at org.springframework.test.context.junit4.SpringMethodRoadie.runWithRepetitions(SpringMethodRoadie.java:217)
at org.springframework.test.context.junit4.SpringMethodRoadie.runTest(SpringMethodRoadie.java:197)
at org.springframework.test.context.junit4.SpringMethodRoadie.run(SpringMethodRoadie.java:143)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.invokeTestMethod(SpringJUnit4ClassRunner.java:142)
at org.junit.internal.runners.JUnit4ClassRunner.runMethods(JUnit4ClassRunner.java:51)
at org.junit.internal.runners.JUnit4ClassRunner$1.run(JUnit4ClassRunner.java:44)
at org.junit.internal.runners.ClassRoadie.runUnprotected(ClassRoadie.java:27)
at org.junit.internal.runners.ClassRoadie.runProtected(ClassRoadie.java:37)
at org.junit.internal.runners.JUnit4ClassRunner.run(JUnit4ClassRunner.java:42)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:45)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:460)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:673)
at or ----- COMMENT: AUTHOR: Chaluvaiah EMAIL: chaluvaiah.rajanna@yahoo.com IP: 59.145.67.121 URL: DATE: 5/6/2010 10:01:31 AM Hi Mathew,

I have requirement to load data from one db to other, while transforming data I need to apply some enrichment on the data before I put data in the destination. I'm planning to use SpringBatch, I used your article as reference. Kindly tell me how do I configure two datasource and a single transcation in Spring Batch. please post a sample code. ----- COMMENT: AUTHOR: Chaluvaiah EMAIL: chaluvaiah.rajanna@yahoo.com IP: 59.145.67.121 URL: DATE: 5/6/2010 10:56:40 AM Hi Mathew,

I have requirement to load data from one db to other, while transforming data I need to apply some enrichment on the data before I put data in the destination. I'm planning to use SpringBatch, I used your article as reference. Kindly tell me how do I configure two datasource and a single transcation in Spring Batch. please post a sample code. ----- COMMENT: AUTHOR: Mathew Thomas EMAIL: mattazoid@gmail.com IP: 71.171.119.198 URL: DATE: 5/13/2010 10:11:23 AM with all due respect - I do not have the bandwidth to look into this. Suggest reading the documentation. Sorry ----- COMMENT: AUTHOR: sabih EMAIL: sabihanwer@gmail.com IP: 138.108.48.7 URL: DATE: 6/8/2010 11:49:16 AM Hi Matthew, I have a requirement for job nesting , based on the dynamic CSV fields , data the parent has to call the individual jobs which again has multiple steps to execute , besides i am quite new to spring and need clarification of the class model to be used for achieving the item reader, item writer and item processor logic inside the Dao, Bo.Help would be obliged.
Thanks
Sabih ----- -------- AUTHOR: Mathew Thomas TITLE: Spring Batch 2.0 - Part I - Simple Tasklet STATUS: publish ALLOW COMMENTS: 1 ALLOW PINGS: 0 CATEGORY: Spring DATE: 1/31/2009 1:06:29 PM ----- BODY: There is always a healthy debate when talking Java and batches. When I heard Spring Batch, I had to try it out. On a previous project, many eons back, I did some batch processing in Java. What hurt me there (after a lots of optimizations) was a call to another persons module. His module happily loaded up an entity bean. You can guess where that ended. Next release I went through the code and replaced the entity bean calls with ONE update SQL statement. That fixed things. I was processing 200k records in 15-20 minutes, with an extremely small memory footprint. Even this I could reduce further if I tuned another module. But the performance was deemed enough and we moved on.

What I personally felt from that experience was the need of a decent Java-based Batch processing framework. Of course having this does not mean use Java for batches. Sometimes for bulk processing doing it in the database may be the right approach.

In this blog I want to go over Spring Batch processing. We will start off with some definitions.

Job - A job represents your entire batch work. Each night you need to collect all of the 1)credit card transactions, 2)collect them in a file and then 3)send them over to the settlement provider. Here I defined three logical steps. In Spring Batch a job is made of up of Steps. Each Step being a unit of work.

Step - A job is made up of one or more steps.

JobInstance - A running instance of the job that you have defined. Think of the Job as a class and the job instance as your , well object. Our credit card processing job runs 7 days a week at 11pm. Each executions is a JobInstance.

JobParameters - Parameters that go into a JobInstance.

JobExecution - Every attempt to run a JobInstance results in a JobExecution. For some reasons Jan 1st, 2008 CC Settlement job failed. It is re-run and now it succeeds. So we have one JobInstance but two executions (thus two JobExecutions). There also exists the concept of StepExecution. This represents an attempt to run a Step in a Job.

JobRepository - This is the persistent store for all of our job definitions. In this example I setup the repository to use an in-memory persistent store. You can back it up with a database if you want.

JobLauncher - As the name suggests, this object lets you launch a job.

TaskLet - Situations where you do not have input and output processing (using readers and writers).  We use a tasklet in this blog.

The next three definitions do not apply to this blog since I will not be using them. Part II of this blog will show an example on these.

ItemReader - Abstraction used to represent an object that allows you to read in one object of interest that you want to process. In my credit card example it could be one card transaction retrieved from the database.

ItemWriter - Abstraction used to write out the final results of a batch. In the credit card example it could be a provider specific representation of the transaction which needs to be in a file. Maybe in XML or comma separated flat file.

ItemProcessor - Very important. Here you can initiate business logic on a just read item. Perform computations on the object and maybe calculate more fields before passing on to the writer to write out to the output file.

In this blog lets go through the age-old hell world example. Our job will run a task which prints out hello world. Not much happening here but will show all of the important concepts in work before Part-II where I use the reader and writer to read from a flat file and insert 200k records into the database (in about 1 minute). Wanted to throw that out to the naysayers who just hate doing batches in Java.
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx" xmlns:context="http://www.springframework.org/schema/context"
xmlns:util="http://www.springframework.org/schema/util" xmlns:batch="http://www.springframework.org/schema/batch"

xsi:schemaLocation="
www.springframework.org/schema/beans www.springframework.org/schema/beans/spring-beans-2.0.xsd
www.springframework.org/schema/tx www.springframework.org/schema/tx/spring-tx-2.0.xsd
www.springframework.org/schema/aop www.springframework.org/schema/aop/spring-aop-2.0.xsd
www.springframework.org/schema/util www.springframework.org/schema/util/spring-util-2.0.xsd
www.springframework.org/schema/batch www.springframework.org/schema/batch/spring-batch-2.0.xsd
www.springframework.org/schema/context

">www.springframework.org/schema/context/spring-context-2.5.xsd">

<!-- 1) USE ANNOTATIONS TO CONFIGURE SPRING BEANS -->
<context:component-scan base-package="com.batch" />

<!-- 2) DATASOURCE, TRANSACTION MANAGER AND JDBC TEMPLATE -->
<bean id="dataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver" />
<property name="url" value="jdbc:mysql://localhost/seamdb" />
<property name="username" value="root" />
<property name="password" value="" />
</bean>

<bean id="transactionManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource" />
</bean>
<tx:annotation-driven transaction-manager="transactionManager" />

<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<property name="dataSource" ref="dataSource" />
</bean>


<!-- 3) JOB REPOSITORY - WE USE IN-MEMORY REPOSITORY FOR OUR EXAMPLE -->
<bean id="jobRepository"
class="org.springframework.batch.core.repository.support.MapJobRepositoryFactoryBean">
<property name="transactionManager" ref="transactionManager" />
</bean>

<!-- 4) LAUNCH JOBS FROM A REPOSITORY -->
<bean id="jobLauncher"
class="org.springframework.batch.core.launch.support.SimpleJobLauncher">
<property name="jobRepository" ref="jobRepository" />
</bean>


<!--
5) Define the job and its steps. In our case I use one step. Configure
its readers and writers
-->
<batch:job id="simpleJob">
<batch:step id="step1">
<batch:tasklet>
<batch:chunk reader="cursorReader" writer="flatFileWriter"
commit-interval="1000" />
</batch:tasklet>
</batch:step>
</batch:job>

<!-- ======================================================= -->
<!-- 6) READER -->
<!-- ======================================================= -->
<bean id="cursorReader"
class="org.springframework.batch.item.database.JdbcCursorItemReader">
<property name="dataSource" ref="dataSource" />
<property name="sql" value="select * from ledger" />
<property name="rowMapper" ref="ledgerRowMapper" />
</bean>


<!-- ======================================================= -->
<!-- 7) WRITER -->
<!-- ======================================================= -->
<bean id="flatFileWriter" class="org.springframework.batch.item.file.FlatFileItemWriter">
<property name="resource" value="file:/Users/mathew/temp/ledgers-output.txt" />
<property name="lineAggregator">
<bean
class="org.springframework.batch.item.file.transform.DelimitedLineAggregator">
<property name="delimiter" value="," />
<property name="fieldExtractor">
<bean
class="org.springframework.batch.item.file.transform.BeanWrapperFieldExtractor">
<property name="names" value="id,receiptDate,memberName" />
</bean>
</property>
</bean>
</property>
</bean>
</beans>
  1. Use annotations to identify and autowire my spring beans.
  2. Ignore the data source configuration. It is not used for this example. Because I have a DAO I use for Part II & III this is here.
  3. Configure the job repository. Using an in-memory persistent store for this example.
  4. The job launcher.
  5. Register the two beans that make up my 2 steps for the job. One prints hello world and the other the time of the day.
  6. Last but not the least is the Job definition itself. Note the batch:listener which registers a listener to track job execution.
Now here is the code for the 2 steps:
package com.batch.simpletask;

import org.springframework.batch.core.StepContribution;
import org.springframework.batch.core.scope.context.ChunkContext;
import org.springframework.batch.core.step.tasklet.Tasklet;
import org.springframework.batch.repeat.RepeatStatus;

public class HelloTask implements Tasklet {

private String taskStartMessage;

public void setTaskStartMessage(String taskStartMessage) {
this.taskStartMessage = taskStartMessage;
}

public RepeatStatus execute(StepContribution arg0, ChunkContext arg1)
throws Exception {
System.out.println(taskStartMessage);
return RepeatStatus.FINISHED;
}
}

And here is the tasklet itself:
package com.batch.simpletask;

import org.springframework.batch.core.StepContribution;
import org.springframework.batch.core.scope.context.ChunkContext;
import org.springframework.batch.core.step.tasklet.Tasklet;
import org.springframework.batch.repeat.RepeatStatus;

public class HelloTask implements Tasklet {

private String taskStartMessage;

public void setTaskStartMessage(String taskStartMessage) {
this.taskStartMessage = taskStartMessage;
}

public RepeatStatus execute(StepContribution arg0, ChunkContext arg1)
throws Exception {
System.out.println(taskStartMessage);
return RepeatStatus.FINISHED;
}
}

Last but not the least is my test driver that launches the batch itself. I use a Spring enabled JUnit test case to implement my driver.
package com.batch.simpletask;

import org.apache.log4j.Logger;
import org.apache.log4j.PropertyConfigurator;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.batch.core.Job;
import org.springframework.batch.core.JobParameters;
import org.springframework.batch.core.launch.JobLauncher;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.AbstractDependencyInjectionSpringContextTests;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.util.StopWatch;

@ContextConfiguration(locations = "classpath:com/batch/simpletask/simpletaskletcontext.xml")
@RunWith(SpringJUnit4ClassRunner.class)
public class SimpleTaskletTestCase extends
AbstractDependencyInjectionSpringContextTests {

private final static Logger logger = Logger
.getLogger(SimpleTaskletTestCase.class);

@Autowired
private JobLauncher launcher;

@Autowired
private Job job;
private JobParameters jobParameters = new JobParameters();

@Before
public void setup() {
PropertyConfigurator
.configure("c:/mathew/springbatch2/src/com/batch/log4j.properties");
}

@Test
public void testLaunchJob() throws Exception {
StopWatch sw = new StopWatch();
sw.start();
launcher.run(job, jobParameters);
sw.stop();
logger.info(">>> TIME ELAPSED:" + sw.prettyPrint());

}

@Autowired
public void setLauncher(JobLauncher bootstrap) {
this.launcher = bootstrap;
}

@Autowired
public void setJob(Job job) {
this.job = job;
}
}

The result of running this is (I removed the log4j log statements for clarity):
Hello World - the time is now
Thu Sep 24 21:36:03 EDT 2009
Spring Batch - Part II - Flat File To Database - Read from a comma separated file and insert 200k rows into a MYSQL database.
Spring Batch - Part III - From Database to Flat File - Read back the 200K rows and now write it out to a new file. Later.

Please see Part III to download entire project file with dependencies

----- EXTENDED BODY: ----- EXCERPT: There is always a healthy debate when talking Java and batches. When I heard Spring Batch, I had to try it out. ----- KEYWORDS: ----- COMMENT: AUTHOR: Phil EMAIL: a@a.com IP: 76.120.238.38 URL: DATE: 2/1/2009 1:55:00 PM Good step by step article. Copy pasted the code. It worked. Looking forward to the next two blogs. ----- COMMENT: AUTHOR: xx EMAIL: xxx@sadas.cc IP: 218.186.12.233 URL: http://sfds.dsfsdf DATE: 5/18/2009 2:36:10 PM alert("Hello!"); ----- COMMENT: AUTHOR: web development company EMAIL: william@geeksltd.co.uk IP: 88.211.44.103 URL: http://www.geeks.ltd.uk/Services/Web-Application-Development.html DATE: 8/27/2009 2:55:38 PM Hey, that was interesting,

you example really halped me to understand the whole concept

Thanks for writing, most people don't bother. ----- COMMENT: AUTHOR: kE35Alexa EMAIL: kE35Alexa@unique-papers.com IP: 194.44.97.14 URL: http://www.primedissertations.com DATE: 1/12/2010 10:21:22 PM I think that the large archive of the thesis topics about this post is at the thesis writing services. Therefore, there are no complications to go to dissertation service and buy thesis. ----- COMMENT: AUTHOR: Aries EMAIL: asatriana@gmail.com IP: 202.159.19.242 URL: http://ariessatriana.wordpress.com DATE: 2/15/2010 3:33:13 AM Never ever regret by reading your blog.
Thanks for share it.
Realy helpfull.

Rgds. ----- COMMENT: AUTHOR: printer ink EMAIL: mandyweblinks@gmail.com IP: 122.180.101.178 URL: http://www.inkmart.com DATE: 6/1/2010 11:12:36 AM that's great information. I really like it. Thanks for this useful information ----- COMMENT: AUTHOR: Girls in Push Up Bras EMAIL: daisy_heels@yahoo.co.uk IP: 111.243.215.164 URL: http://www.heelsncleavage.com/-Push_Up_Bras/cat18290_158057.aspx DATE: 7/3/2010 3:47:51 PM Nice one, this revealed a lot to me, opened my eyes you might say, not bad for Girl in a Push Up Bra, lol, seriously thank you for this. ----- COMMENT: AUTHOR: Korma EMAIL: korma.kofta@yahoo.com IP: 193.43.246.129 URL: DATE: 7/11/2010 11:46:12 AM The snippey for the 2 steps looks a paste of the tasklet. Could you update the example with the step definition?

Besides, very nice post.
Thanks,
Korma ----- COMMENT: AUTHOR: Vijay EMAIL: IP: 198.240.133.75 URL: DATE: 7/16/2010 12:49:41 PM The tasklet code is appearing to be duplicated. The code for printing hello world message is missing. ----- COMMENT: AUTHOR: Vijay EMAIL: IP: 198.240.133.75 URL: DATE: 7/16/2010 12:51:52 PM Can you post the complete code for printing Hello World job? Seems like some code is missing in the blog. (Tasklet is duplicated). ----- COMMENT: AUTHOR: Mathew Thomas EMAIL: mattazoid@gmail.com IP: 71.171.119.198 URL: DATE: 7/23/2010 11:45:53 PM the complete code is provided in a jar file at the very bottom of Part III (http://blogs.averconsulting.com/2009/02/03/spring-batch--part-iii--from-database-to-flat-file.aspx) ----- COMMENT: AUTHOR: Vachi EMAIL: vachaspati.m@gmail.com IP: 203.99.208.2 URL: DATE: 8/12/2010 6:54:32 AM Thank you very much. This is very helpful indeed. ----- -------- AUTHOR: Mathew Thomas TITLE: Ubuntu + Apache2 + php + Zend STATUS: publish ALLOW COMMENTS: 1 ALLOW PINGS: 0 CATEGORY: Web Framework DATE: 10/5/2008 2:17:00 AM ----- BODY: At times I get so tired of Java that I just yearn for a different set of frameworks (or should I say an environment where there is a good , concise language and less frameworks to choose from). I have been interested in following stacks:
I tinkered enough with Ruby On Rails to know that it is a good framework. Next I gave a shot to Zend, a PHP web development framework. Below is a story of that exercise. My home machine has Vista and I am quite sick of it. To free myself from all of this pain I installed the following:
In this blog I will go through my environment setup. In a latter one I will go into Zend itself. btw if you run into (as I did) resolution issues with Ubuntu don't lose hope. After breaking my head on that, I was able to locate an article that worked for me http://ubuntuforums.org/showpost.php?p=129379&postcount=21. Before this my screen resolution was at 800x600. Pretty useless. Now its a lot higher and life is good. Thanks to the poster above.

Next I installed Sun's Java 1.6 (oh oh but why). I am planning on using NetBeans for other java related work and also maybe php editing (have not tried that yet). The Ubuntu server image that I have did not have java in it. At least thats what the following command found
sudo update-alternatives --config java
No alternatives for java


I could not find a ready package to install jdk1.6 from Sun. After some tinkering around I executed the following (thanks to a great blog at http://fci-h.blogspot.com/2007/02/installing-jdk6-on-ubuntu.html). For your convinence I am repeating the steps (including an extra one to configure javac).
To verify run
sudo update-alternatives --config java
mathew@mathew-desktop:~$ sudo update-alternatives --config java
[sudo] password for mathew:

There is only 1 program which provides java
(/usr/lib/jvm/jdk1.6.0_10/jre/bin/java). Nothing to configure.
Of course type in java and javac on the command line as a final test. We digressed.  A lot of the commands so far and further down use sudo to execute them as root.
One thing obvious here is that its a lot of work setting it up. But doing so gives you a better idea of what is going on and how things are wired. There is a wealth of information on the web. I am just putting it together here for the next person who googles around.

My next blog will be on using the Zend Framework itself.

----- EXTENDED BODY: ----- EXCERPT: At times I get so tired of Java that I just yearn for a different set of frameworks (or should I say an environment where there is a good , concise language and less frameworks to choose from). PHP and Zend Framework are on of my candidates. ----- KEYWORDS: ----- COMMENT: AUTHOR: how to play video keno online EMAIL: winslet.jessica@gmail.com IP: 122.173.70.105 URL: http://www.learnvideokeno.com DATE: 4/23/2009 12:06:53 PM Just throwing this out there, but I've seen better performance across my servers after switching from APC to xCache.It also doesn't have the problems with other files, like kses.php for example. ----- COMMENT: AUTHOR: HESSJudith24 EMAIL: elizabethmartin@mail15.com IP: 91.201.66.6 URL: DATE: 9/4/2010 8:44:22 PM If you are willing to buy real estate, you will have to receive the loan. Moreover, my father all the time takes acommercial loan, which is the most fast. ----- COMMENT: AUTHOR: FranPate32 EMAIL: barbarawright@mail15.com IP: 91.201.66.6 URL: DATE: 10/13/2010 3:38:06 PM It's great that people can receive the mortgage loans and that openscompletely new possibilities. ----- COMMENT: AUTHOR: online games EMAIL: zirik6t6@hotmail.com IP: 173.234.229.221 URL: DATE: 1/8/2011 12:10:01 AM trying to see your image. Your layout isn't working right using chrome web browser on ipad. ----- COMMENT: AUTHOR: life insurance EMAIL: llo7aunl1m@aol.com IP: 173.208.24.67 URL: DATE: 1/12/2011 4:02:16 AM Very convenient to include a hyperlink letting me share this post on Facebook ----- -------- AUTHOR: Mathew Thomas TITLE: Google Web Toolkit (GWT) STATUS: publish ALLOW COMMENTS: 1 ALLOW PINGS: 0 CATEGORY: Web AJAX framework DATE: 9/11/2008 11:11:00 PM ----- BODY: I went through an example to try out GWT. The GWT website GWT has some very good documentation. I went through the stock watcher example and built it step by step myself. Made a few changes on the way, such as putting the whole thing in a TabPanel.

I believe Java UI frameworks, that produce web code (html), are a great alternative to DIY HTML/Javascript libraries. Everytime I look at AJAX web frameworks and libraries, I think many of us are missing the point. Focus on building the application and not tinker with so many frameworks. I think frameworks like GWT will provide a strong alternative in the years to come. Toolset (IDE) support will make or break these frameworks.

After implementing the example, I was amazed at the ease with which I could implement AJAX functionality. In this case the UI periodically polls the backend for stock price changes and updates the section of the page. The code was...

            // setup timer to refresh list automatically

            Timer refreshTimer = new Timer() {

                  public void run() {

                        refreshWatchList();

                  }

            };

            refreshTimer.scheduleRepeating(REFRESH_INTERVAL);


The refreshWatchList method is shown below...

      private void refreshWatchList() {

            // lazy initialization of service proxy

            if (stockPriceSvc == null) {

                  stockPriceSvc = GWT.create(StockPriceService.class);

            }

 

            AsyncCallback<StockPrice[]> callback = new AsyncCallback<StockPrice[]>() {

                  public void onFailure(Throwable caught) {

                        // do something with errors

                  }

 

                  public void onSuccess(StockPrice[] result) {

                        updateTable(result);

                  }

            };

 

            // make the call to the stock price service

            stockPriceSvc.getPrices(stocks.toArray(new String[0]), callback);

      }


Its so obvious what the above code does. Well almost obvious. There are some GWT specific weird stuff you need to do, but thats a small price to pay. Here is an image of the output screen...




The price and change columns periodically update themselves (without refreshing the whole page of course). Here is my complete Eclipse project if you want to try it out. Download StockWatcher

----- EXTENDED BODY: ----- EXCERPT: Tried out Google Web Toolkit (GWT). Sharing some thoughts and also my eclipse project. ----- KEYWORDS: ----- -------- AUTHOR: Mathew Thomas TITLE: Spring Security - The new and improved ACEGI STATUS: publish ALLOW COMMENTS: 1 ALLOW PINGS: 0 CATEGORY: Spring DATE: 8/26/2008 2:06:00 AM ----- BODY: Ah! Good ol ACEGI. Or should I say the good old new ACEGI aka Spring Security. In one of my previous posts I blogged about configuring good ol ACEGI. Since I last looked at it ACEGI is now Spring Security. Configuration nightmare has been reduced greatly. Though you are handicaped if you have used it earlier...like me. I keep trying to link back to the old configuration.

For those attempting Spring Security for the first time, a piece of advice. Ignore all comparisons to ACEGI and move on. You will find your brain in better shape at the end of the excercise.

First of all to make my life easier I created a Dynamic Web Project in Eclipse 3.3.2. Next I have Tomcat configured to run within my IDE for quick testing. My goal is to simply protect a bunch of web pages using Spring Security. Its easy to extend this to larger web apps.

First lets see the web.xml below.

 

<?xml version="1.0" encoding="UTF-8"?>

<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

      xmlns="http://java.sun.com/xml/ns/javaee"

      xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"

      xsi:schemaLocation="http://java.sun.com/xml/ns/javaee java.sun.com/xml/ns/javaee/web-app_2_5.xsd" style="font-size: 10pt; font-family: "Courier New";">

      id="WebApp_ID" version="2.5">

      <display-name>springsecurity</display-name>

      <context-param>

            <param-name>log4jConfigLocation</param-name>

            <param-value>/WEB-INF/log4j.properties</param-value>

      </context-param>

      <context-param>

            <param-name>contextConfigLocation</param-name>

            <param-value>

                  /WEB-INF/application-security.xml

                  /WEB-INF/application-service.xml

            </param-value>

      </context-param>

      <listener>

            <listener-class>

                  org.springframework.web.context.ContextLoaderListener

            </listener-class>

      </listener>

      <listener>

            <listener-class>

                  org.springframework.web.util.Log4jConfigListener

            </listener-class>

      </listener>

      <filter>

            <filter-name>springSecurityFilterChain</filter-name>

            <filter-class>

                  org.springframework.web.filter.DelegatingFilterProxy

            </filter-class>

      </filter>

      <filter-mapping>

            <filter-name>springSecurityFilterChain</filter-name>

            <url-pattern>/*</url-pattern>

      </filter-mapping>

      <welcome-file-list>

            <welcome-file>index.jsp</welcome-file>

      </welcome-file-list>

</web-app>


Only thing of interest is the listener org.springframework.web.filter.DelegatingFilterProxy. I would love to compare this to ACEGI configuration but I will resist the urge. Just forget any old stuff. Suffice it to say that all URLS with the configured pattern pass through this filter and Spring Security is "performed" on them.

Next let us see the login.jsp page:

<%@ include file="includes.jsp"%>

<%@ page import="org.springframework.security.ui.AbstractProcessingFilter" %>

<%@ page import="org.springframework.security.ui.webapp.AuthenticationProcessingFilter" %>

<%@ page import="org.springframework.security.AuthenticationException" %>

 

<html>

<head>

<title>Login</title>

</head>

<body>

<%

if (session.getAttribute(AbstractProcessingFilter.SPRING_SECURITY_LAST_EXCEPTION_KEY) != null) { %>

<font color="red"> Your login attempt was not successful, please try again.<BR>

<br/>

Reason: <%=((AuthenticationException)

  session.getAttribute(AbstractProcessingFilter.SPRING_SECURITY_LAST_EXCEPTION_KEY)).getMessage()%>

</font>

<%

}

%>

 

<form method="post" id="loginForm"

      action="<c:url value='j_spring_security_check'/>">Username: <input

      type="text" name="j_username" id="j_username" /> <br />

Password: <input type="password" name="j_password" id="j_password" /><br />

<input type="submit" value="Login" /></form>

</body>

</html>

 

Refer to the login form and the way the parameters are named. For Spring Security to pick up the attributes you must name it the same as above.

Most important ... here is the spring context file application-security.xml
 

<?xml version="1.0" encoding="UTF-8"?>

<beans xmlns="http://www.springframework.org/schema/beans"

      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

      xmlns:security="http://www.springframework.org/schema/security"

      xsi:schemaLocation="

                  http://www.springframework.org/schema/beans www.springframework.org/schema/beans/spring-beans-2.5.xsd style="font-size: 10pt; font-family: "Courier New";">

                  http://www.springframework.org/schema/security www.springframework.org/schema/security/spring-security-2.0.xsd" style="font-size: 10pt; font-family: "Courier New"; color: teal;">>

 

      <security:authentication-manager alias="authenticationManager" />

 

      <security:http auto-config="true"

            access-denied-page="/accessdenied.jsp">

            <security:form-login login-page="/login.jsp"

                  authentication-failure-url="/login.jsp"

                  default-target-url="/index.jsp" />

            <security:logout logout-success-url="/login.jsp" />

            <security:intercept-url pattern="/index.jsp"

                  access="ROLE_ADMIN,ROLE_USER" />

            <security:intercept-url pattern="/admin/**" access="ROLE_ADMIN" />

            <security:intercept-url pattern="/**" access="ROLE_ANONYMOUS" />

      </security:http>

 

      <bean id="loggerListener"

            class="org.springframework.security.event.authentication.LoggerListener" />

 

      <security:authentication-provider>

            <security:password-encoder hash="md5"/>

            <security:user-service>

                  <security:user password="5f4dcc3b5aa765d61d8327deb882cf99" name="thomasm"

                        authorities="ROLE_USER,ROLE_ANONYMOUS" />

                  <security:user password="5f4dcc3b5aa765d61d8327deb882cf99" name="admin"

                        authorities="ROLE_ADMIN,ROLE_USER,ROLE_ANONYMOUS" />

            </security:user-service>

      </security:authentication-provider>

</beans>

 


Once logged in the user is sent to the index.jsp which shows some common content and some admin specific content (if user has admin role).

<%@ include file="includes.jsp"%>

<html>

<head>

<title>Home</title>

</head>

<body>

You are logged in. To log out click

<a href='<c:url value="j_spring_security_logout"/>'>log out</a>

<br />

<a href="admin/admin.jsp">admin</a>

<br />

<authz:authorize ifAllGranted="ROLE_ADMIN">

      <p style="font-weight: bold">This text is only visible to admin

      users.</p>

</authz:authorize>

 

</body>

</html>

 
Following screen shots show you how this all works...






The bold text above is only displayed to users with admin role.

Now for a few tips. Obviously you will not be hardcoding the user name and password into the configuration. Right my friend! Now for this you can implement your own class that gets the credentials from wherever you choose. This class then hooks into Spring Security. Here is a sample class CustomUserService.java where I have mocked the credentials in code.
 

package com.test;

 

import org.springframework.dao.DataAccessException;

import org.springframework.security.GrantedAuthority;

import org.springframework.security.GrantedAuthorityImpl;

import org.springframework.security.userdetails.User;

import org.springframework.security.userdetails.UserDetails;

import org.springframework.security.userdetails.UserDetailsService;

import org.springframework.security.userdetails.UsernameNotFoundException;

 

public class CustomUserService implements UserDetailsService {

      public UserDetails loadUserByUsername(String user)

                  throws UsernameNotFoundException, DataAccessException {

            User ud = null;

            if ("admin".equals(user)) {

                  GrantedAuthority[] auths = new GrantedAuthority[] {

                              new GrantedAuthorityImpl("ROLE_ADMIN"),

                              new GrantedAuthorityImpl("ROLE_USER"),

                              new GrantedAuthorityImpl("ROLE_ANONYMOUS") };

                  ud = new User(user, "5f4dcc3b5aa765d61d8327deb882cf99", true, true,

                              true, true, auths);

            } else if ("thomasm1".equals(user)) {

                  GrantedAuthority[] auths = new GrantedAuthority[] {

                              new GrantedAuthorityImpl("ROLE_USER"),

                              new GrantedAuthorityImpl("ROLE_ANONYMOUS") };

                  ud = new User(user, "5f4dcc3b5aa765d61d8327deb882cf99", true, true,

                              true, true, auths);

            }

            return ud;

      }

}



In the application-security.xml file you need to make the following change.
 

<security:authentication-provider user-service-ref="customUserService">

            <security:password-encoder hash="md5" />

</security:authentication-provider>


The rest of the code should work same. Finally one more useful feature that I have used with the good ol ACEGI. That is to provide security access protection to the service layer. Add the following to your configuration...
    <global-method-security secured-annotations="enabled" jsr250-annotations="enabled"/>
Next add the annotations @Secured( {"ROLE_SECRET_AGENT"} ) to your service methods.
----- EXTENDED BODY: ----- EXCERPT: Ah! Good ol ACEGI. Or should I say the good old new ACEGI aka Spring Security. ----- KEYWORDS: ----- COMMENT: AUTHOR: video keno rules EMAIL: winslet.jessica@gmail.com IP: 122.173.70.105 URL: http://www.learnvideokeno.com DATE: 4/23/2009 12:09:18 PM I had a look at Acegi Security to enhance my application. The main thing I found missing is the notion of a Group, like the java.security.acl.Group. Is this likely to appear in the final release or is there some fundamental reason why this is not implemented? ----- COMMENT: AUTHOR: free roulette EMAIL: varisha.g@gmail.com IP: 122.173.83.36 URL: http://www.onlyfreeroulette.com DATE: 7/15/2009 9:34:23 AM Really i am impressed from this post....the person who create this post he is a great human..thanks for shared this with us.i found this informative and interesting blog so i think so its very useful and knowledge able.I would like to thank you for the efforts you have made in writing this article. I am hoping the same best work from you in the future as well. ----- COMMENT: AUTHOR: ulcecehoone EMAIL: sdfsdfcxz@gmail.com IP: 122.192.166.152 URL: DATE: 1/9/2011 9:50:17 AM I’ve been visiting your blog for a while now and I always find a gem in your new posts. Thanks for sharing. ----- -------- AUTHOR: Mathew Thomas TITLE: J2ME/JavaME Visited Again STATUS: publish ALLOW COMMENTS: 1 ALLOW PINGS: 0 CATEGORY: Mobile DATE: 7/18/2008 3:20:00 AM ----- BODY: It seems like an eternity since I last tried J2ME or JavaME as its known now. It was Sept 2003, when I was working at a product development company and was building a component using J2ME. I even managed to get an article published at http://my.advisor.com/articles.nsf/aid/12697.

When I tinkered with Android a few weeks back, I got the urge right then to revisit JavaME. I wanted to try out a JavaME example again and see if anything has changed. I still believe that JavaME will eventually die out in favor of a more full featured platform (whether it is Java SDK or something else I dunno). For a primer on JavaME stacks you can check my article on advisor above. It surprising how little has changed.

In this example I will build a JavaME application using Netbeans. The application will present the user with a screen to enter a ISBN number for a book. It will then make a remote web service call to validate that the ISBN number is valid or not. When I tried a similar webservice example in 2003, web services was not yet in the optional stack. Now it is. Previously I was using ksoap. Now I do not need to. I can use the built-in libraries (if the device supports that... and that is the big headache with either JavaME or Android....device capabilities).

Create a new NetBeans MIDP project named as ISBNValidator, using CLDC-1.1 and MIDP-2.1 configuration. The IDE will create a ISBNValidatorMidlet. Netbeans will throw you into a page flow designer. I switched to the source code view.  Change the code to:


package com.test;

import isbnservice.ISBNService_Stub;
import java.rmi.RemoteException;

import javax.microedition.lcdui.Command;
import javax.microedition.lcdui.CommandListener;
import javax.microedition.lcdui.Display;
import javax.microedition.lcdui.Displayable;
import javax.microedition.midlet.MIDlet;
import javax.microedition.midlet.MIDletStateChangeException;

public class ISBNValidator extends MIDlet implements CommandListener {

    private EnterISBNNumberForm isbnForm;

    public ISBNValidator() {
        isbnForm = new EnterISBNNumberForm("ISBN Validator", this);
    }

    protected void destroyApp(boolean arg0) {
    }

    protected void pauseApp() {
    }

    protected void startApp() throws MIDletStateChangeException {
        Display.getDisplay(this).setCurrent(isbnForm);
    }

    public void commandAction(Command cmd, Displayable disp) {
        if (cmd.getCommandType() == Command.EXIT) {
            destroyApp(false);
            notifyDestroyed();
        } else if (cmd.getLabel().equalsIgnoreCase("Check ISBN")) {
            final MIDlet parent = this;
            new Thread() {

                public void run() {
                    String result =
validateISBN(isbnForm.getIsbnNumber());
                    String msg = "ISBN Validd => " + isbnForm.getIsbnNumber() + ", is ";
                    ISBNValidatorResultForm resultForm = new ISBNValidatorResultForm(msg, result, (CommandListener) parent);
                    Display.getDisplay(parent).setCurrent(resultForm);
                }
            }.start();
        } else if (cmd.getLabel().equalsIgnoreCase("Main")) {
            Display.getDisplay(this).setCurrent(isbnForm);
        }
    }

    private String validateISBN(String isbn) {
        ISBNService_Stub stub = new ISBNService_Stub();
        String result = "bad isbn";
        if (isbn == null || (isbn.trim().length() != 10 && isbn.trim().length() != 13)) {
            return result;
        }
        try {
            if (isbn.trim().length() == 10 && stub.IsValidISBN10(isbn)) {
                result = "good isbn";
            } else if (isbn.trim().length() == 13 && stub.IsValidISBN13(isbn)) {
                result = "good isbn";
            }
        } catch (RemoteException e) {
            e.printStackTrace();
        }
        return result;
    }
}

In the method validateISBN you can see I do the web service call. Now you must be guessing how I got the stubs created. Netbeans has made that easy for us. Right click on the project and select "New JavaME Web Service Client". Provide the WSDL URL webservices.daehosting.com/services/isbnservice.wso?WSDL and you are done.

For sake of completeness here are the other 2 classes I coded. I put the forms in two independent classes.

Class EnterISBNNumberForm
package com.test;

import javax.microedition.lcdui.Command;
import javax.microedition.lcdui.CommandListener;
import javax.microedition.lcdui.Form;
import javax.microedition.lcdui.TextField;

public class EnterISBNNumberForm extends Form {

    private Command okCommand;
    private Command exitCommand;
    private TextField isbnNumber;

    public EnterISBNNumberForm(String title, CommandListener cmdlistener) {
        super(title);

        exitCommand = new Command("Exit", Command.EXIT, 1);
        okCommand = new Command("Check ISBN", Command.OK, 1);

        isbnNumber = new TextField("ISBN#: ", "", 13, TextField.ANY);
        append(isbnNumber);
        addCommand(okCommand);
        addCommand(exitCommand);
        this.setCommandListener(cmdlistener);
    }

    public String getIsbnNumber() {
        return isbnNumber.getString();
    }
}


Class ISBNValidatorResultForm
package com.test;
import javax.microedition.lcdui.Command;
import javax.microedition.lcdui.CommandListener;
import javax.microedition.lcdui.Form;
import javax.microedition.lcdui.StringItem;

public class ISBNValidatorResultForm extends Form {
    private Command okCommand;
    private StringItem box;
    private String value;

    public String getValue() {
        return value;
    }

    public void setValue(String value) {
        this.value = value;
    }

    public ISBNValidatorResultForm(String title, String value,
            CommandListener cmdlistener) {
        super(title);
        this.value = value;
        okCommand = new Command("Main", Command.OK, 1);
        box = new StringItem("ISBN Valid => ", this.value);
        append(box);
        addCommand(okCommand);
        this.setCommandListener(cmdlistener);
    }

}

If you run the project an emulator should pop up and you can launch the application. Following two images show the application in action:




----- EXTENDED BODY: ----- EXCERPT: It seems like an eternity since I last tried J2ME or JavaME as its known now. It was Sept 2003, when I was working at a product development company and was building a component using J2ME. I even managed to get an article published at http://my.advisor.com/articles.nsf/aid/12697Android is a complete open source stack that allows one to build mobile applications. The stack includes an operating system, middleware and common applications. It also provides us with a Java API to develop our own custom mobile applications. It does not discriminate between common applications vs custom applications. Everything that the common applications can do so can yours (making calls, sending SMS, etc.).

What gets me excited is the (Linux kernel based) OS. There is no open source OS on the mobile platform. This is a major plus when it comes to mobile environments.

Before going into an Android sample, it is obvious to ask...what about Java ME (previously called J2ME). I do not see any reason why there cannot be a Java ME runtime created for Android OS. With that we could continue to use Java ME. Also this would open up use of JavaFX on this platform. As of today I could not locate Java ME implementations. If the reader knows of one please do let me know.

The one concern I had was regarding the Optional API's in Android. It is a known fact that not all mobile devices are created equal (in hardware and other related device capabilities). Some devices will not support a certain feature therefore those API's will not work on them. This is exactly the reason why Java ME created configuration and profiles. So now the Android optional API is going to end up in the same situation as Java ME. Whatever they decide to call it eventually, there has to be some basic API sets such as Java ME's configuration and profile. So I do not see any big need to jump ship from Java ME to Android (other than the new car smell). I do believe that eventually there will be a Java ME implementation on the Android.

Cutting through the chase, lets build a quick hello world application and then move on to something bigger. An Android application consists of one or more of the following building blocks:

First get yourself a copy of Android from http://code.google.com/android/intro/installing.html. Follow the instructions there or just do the following:

Now create a New Android project in eclipse. It will pop up


Click finish and you should now have your project ready. The wizard has created the following basic application class named HelloApplication.java

package com.hello;

import android.app.Activity;
import android.os.Bundle;

public class HelloApplication extends Activity {
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle icicle) {
        super.onCreate(icicle);
        setContentView(R.layout.main);
    }
}


Lets modify this to

package com.hello;

import android.app.Activity;
import android.os.Bundle;
import android.widget.TextView;

public class HelloApplication extends Activity {
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle icicle) {
        super.onCreate(icicle);

        TextView tv = new TextView(this);
        tv.setText("The ever so happy Hello World program.");
        setContentView(tv);

    }
}

Right click on the project ... select Run As -> Android Application. You should now see the Android emulator load up...



If all worked fine, you should now have a working development environment. Now lets dig a little deeper. In our HelloApplication class we built the UI using API's directly in the java code. Android provides an alternative approach to define your UI screens in an XML meta language. Android comes with a slew of layout managers to lay out your UI components. Specific UI components are valled View's and views can be grouped into ViewGroup's. View groups can contain either views or groups.

Lets modify our program to use XML for defining our screens (like HTML).


package com.hello;

import android.app.Activity;
import android.os.Bundle;

public class HelloApplication extends Activity {
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle icicle) {
        super.onCreate(icicle);
        setContentView(R.layout.main);
    }
}

We have removed the java code to create UI widgets. R.layout.main now refers to res\layout\main.xml. XML inside it is:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical" android:layout_width="fill_parent"
    android:layout_height="fill_parent">
    <TextView android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="Hello World, Now loaded from XML." />
</LinearLayout>


Running the application should now get you to the following output...


----- EXTENDED BODY: ----- EXCERPT: Android is a complete open source stack that allows one to build mobile applications. The stack includes an operating system, middleware and common applications. It also provides us with a Java API to develop our own custom mobile applications. It does not discriminate between common applications vs custom applications. Everything that the common applications can do so can yours (making calls, sending sms, etc.). ----- KEYWORDS: ----- COMMENT: AUTHOR: giuseppe EMAIL: giuseppe.morreale@gmail.com IP: 87.24.125.194 URL: http://programmaremobile.blogspot.com DATE: 1/30/2009 12:30:46 PM I wish to point out this article.

Android First Example in Java: Hello World
http://programmaremobile.blogspot.com/2009/01/android-first-example-hello-world.html

It expain the steps(from java code to running into emulator) to make the first hello world without eclipse.
I hope it is welcome! ----- -------- AUTHOR: Mathew Thomas TITLE: Spring LDAP Template STATUS: publish ALLOW COMMENTS: 1 ALLOW PINGS: 0 CATEGORY: Spring DATE: 6/13/2008 4:27:00 AM ----- BODY: Just like you have JDBC/Hibernate/iBatis templates in Spring, we also have an LDAPTemplate. You can download the spring LDAP library from http://springframework.org/ldap. I like this template approach simply because it lets us avoid common pitfalls such as not cleaning up resources after using an API (in JDBC its the connection, statement and resultset). Why bother when the template can do this for you. Same holds true for LDAP queries.

For this example I had the following setup:
To confirm your setup. Open eclipse and go to the LDAP perspective. Create a new connection with following information:
This should let you into the directory. Under dc=example,dc=com I added two organizations (asia and americas).


Now for the Spring stuff. 

package trial;

import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import
org.springframework.ldap.core.LdapTemplate;
import org.springframework.stereotype.Service;

@Service
public class LDAPSampleImpl implements LDAPSample {

      @Autowired
      private LdapTemplate ldapTemplate;

      @Override
      public List getOrgNames() {
            return ldapTemplate.list("");
      }
}


The spring XML file looks like:

<?xml version="1.0" encoding="UTF-8"?>

<beans xmlns="http://www.springframework.org/schema/beans"
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xmlns:aop="http://www.springframework.org/schema/aop"
      xmlns:context="http://www.springframework.org/schema/context"
      xsi:schemaLocation="http://www.springframework.org/schema/beans
           http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
           http://www.springframework.org/schema/aop
           http://www.springframework.org/schema/aop/spring-aop-2.5.xsd
           http://www.springframework.org/schema/context
             http://www.springframework.org/schema/context/spring-context-2.5.xsd">

      <context:annotation-config />
      <context:component-scan base-package="trial" />

      <bean id="ldapContextSource"
            class="org.springframework.ldap.core.support.LdapContextSource">
            <property name="url" value="ldap://localhost:10389" />
            <property name="base" value="dc=example,dc=com" />
            <property name="userDn" value="uid=admin,ou=system" />
            <property name="password" value="secret" />
      </bean>

      <bean id="ldapTemplate" class="org.springframework.ldap.core.LdapTemplate">
            <constructor-arg ref="ldapContextSource" />
      </bean>
</beans>


Everything above is self explanatory. Now for the test case to execute all of this.

package trial;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = { "classpath:spring-context.xml" })
public class DriverTestCase {

      @Autowired
      private LDAPSample ldap;
 

      @Test
      public void testGreeting() {
            System.out.println(ldap.getOrgNames());
      }
}


Running this unit test results in output
>> [ou=asia, ou=americas]

----- EXTENDED BODY: ----- EXCERPT: ust like you have JDBC/Hibernate/iBatis templates in Spring, we also have an LDAPTemplate. You can download the spring ldap library from http://springframework.org/ldap. ----- KEYWORDS: ----- -------- AUTHOR: Mathew Thomas TITLE: Maven Assemblies STATUS: publish ALLOW COMMENTS: 1 ALLOW PINGS: 0 CATEGORY: Build Management DATE: 5/14/2008 3:07:00 AM ----- BODY: Due to requests I received for source code for my open source file parser project (http://www.javaforge.com/project/2066), I had to quickly figure out a way to package a zip file that would contain

- source code
- binary jar file
- javadocs
- license and release-changes text files.

Since I am using Maven, I found that assemblies can come to my help. Thought I'd jot down a few things here so that others can google to it and find the same.

I created a file src/main/assemply/src.xml. This contained a list of artifacts I wanted to package as a zip. The XML should be self-explanatory.
 
<assembly>
    <id>dist</id>
    <formats>
        <format>zip</format>
    </formats>
    <baseDirectory>flatfilereader</baseDirectory>
    <includeBaseDirectory>true</includeBaseDirectory>
    <fileSets>
        <fileSet>
            <directory>target</directory>
            <outputDirectory></outputDirectory>
            <includes>
                <include>*.jar</include>
            </includes>
        </fileSet>
        <fileSet>
            <directory>docs</directory>
            <outputDirectory></outputDirectory>
            <includes>
                <include>*.doc</include>
            </includes>
        </fileSet>
        <fileSet>
            <directory>target/site</directory>
            <outputDirectory></outputDirectory>
            <includes>
                <include>**/*</include>
            </includes>
        </fileSet>
        <fileSet>
            <directory>src/main/resources</directory>
            <outputDirectory></outputDirectory>
            <includes>
                <include>license.txt</include>
                <include>release-changes.txt</include>
            </includes>
        </fileSet>
    </fileSets>
</assembly>


In my pom.xml I have the following under the build section.
<build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <configuration>
                    <source>1.5</source>
                    <target>1.5</target>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-source-plugin</artifactId>
                <configuration>
                    <outputDirectory>target</outputDirectory>
                    <finalName></finalName>
                    <attach>false</attach>
                </configuration>
                <executions>
                    <execution>
                        <id>make-source-jar</id>
                        <phase>package</phase>
                        <goals>
                            <goal>jar</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-javadoc-plugin</artifactId>
                <configuration>
                    <outputDirectory>target</outputDirectory>
                </configuration>
                <executions>
                    <execution>
                        <id>make-javadoc</id>
                        <phase>package</phase>
                        <goals>
                            <goal>javadoc</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
            <plugin>
                <artifactId>maven-assembly-plugin</artifactId>
                <configuration>
                    <descriptors>
                        <descriptor>
                            src/main/assembly/src.xml
                        </descriptor>
                    </descriptors>
                </configuration>
            </plugin>
        </plugins>
    </build>


Once this is done, running command "mvn assembly:assembly" will trigger the build and the creation of my distributable file as target\flatfilereader-0.6-dist.zip




----- EXTENDED BODY: ----- EXCERPT: Due to requests I received for source code on my open source file parser project (http://www.javaforge.com/project/2066), I had to quickly figure out a way to create a distributable zip containing all related project artifacts. ----- KEYWORDS: ----- -------- AUTHOR: Mathew Thomas TITLE: Spring 2.5 Annotations STATUS: publish ALLOW COMMENTS: 1 ALLOW PINGS: 0 CATEGORY: Spring DATE: 3/13/2008 11:03:00 PM ----- BODY: With release 2.5 of Spring we  have a more complete support in Spring for annotation driven configuration. All of that XML configuration stuff can be set aside now. Release 2.0 had previously introduced some other annotations, @Transactional being my favourite.

Lets go through a quick sample. All of the code below I developed as a simple Java project in Eclipse (3.3).
package trial;

public interface Greeter {
    public String getGreeting();
}

Nothing special, just a simple interface.
package trial;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
public class GreeterImpl implements Greeter {
    @Autowired
    private Clock clock;

    public String getGreeting() {
        return "Good day. The time is now " + clock.getTime();
    }
}

Clock has a similar implementation. For the sake of completion here it is...
package trial;
public interface Clock {
    public String getTime();
}

package trial;
import java.util.Calendar;

import org.springframework.stereotype.Service;

@Service
public class ClockImpl implements Clock {

    @Override
    public String getTime() {
        return Calendar.getInstance().getTime().toString();
    }
}

Here is the Spring configuration.xml file...
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:aop="http://www.springframework.org/schema/aop"
    xmlns:context="http://www.springframework.org/schema/context"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
           www.springframework.org/schema/beans/spring-beans-2.5.xsd
          
www.springframework.org/schema/aop
          
www.springframework.org/schema/aop/spring-aop-2.5.xsd
          
www.springframework.org/schema/context
          

   ">www.springframework.org/schema/context/spring-context-2.5.xsd">
   
<context:annotation-config />
    <context:component-scan base-package="trial" />
</beans>

Now to test this, lets write up a quick JUnit unit test using support from Spring TextContext Framework. To quote directly from the Spring documentation:
"The Spring TestContext Framework (located in the org.springframework.test.context package) provides generic, annotation-driven unit and integration testing support that is agnostic of the testing framework in use, for example JUnit 3.8, JUnit 4.4, TestNG 5.5, etc."

The code is show below.
package trial;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = { "classpath:context.xml" })
public class GreeterTestCase {

    @Autowired
    private Greeter greeter;

    @Test
    public void testGreeting() {
        System.out.println(greeter.getGreeting());
    }
}

@RunWith
- tells spring to use its test wrapper to run the junit4 test case.

Once you execute this test you will see something like:
>> Good day. The time is now Thu Mar 13 21:20:30 EDT 2008

To get you in a more lively mood...no its not alcohol...there is also a @Aspect  and @Pointcut tags which let you configure AOP related items.

More Annotations:
----- EXTENDED BODY: ----- EXCERPT: With release 2.5 of Spring we have a more complete support in Spring for annotation driven configuration. All of that XML configuration stuff can be set aside now. ----- KEYWORDS: ----- COMMENT: AUTHOR: Jason EMAIL: jason.123@gmail.com IP: 139.76.224.67 URL: DATE: 6/20/2008 7:47:19 PM Nice post. However, @autowired is not working when tested with a client class which uses service. Get a null pointer exception. Why is ClockImpl not injected into Greeter Service? Is there any other config.? ----- COMMENT: AUTHOR: BW EMAIL: bw@mcwest.com IP: 12.163.97.74 URL: http://mcwest.com DATE: 2/26/2009 11:40:06 PM Thanks for the entry. Very clearly written; a nice intro to Spring annotation processing. ----- COMMENT: AUTHOR: long term care insurance EMAIL: irNapoli4a@aol.com IP: 173.234.121.53 URL: DATE: 12/21/2010 5:28:20 AM trying to view your post. Your formating is not viewing right using IE5. ----- COMMENT: AUTHOR: quonosmobbign EMAIL: gunter.mebs@gmail.com IP: 94.142.133.186 URL: DATE: 1/13/2011 7:40:59 PM [url=http://oceanservice.noaa.gov/cgi-bin/redirout.cgi?url=http://medicleadercom/pill/Kamagra Flavored?ref_id=5909]buy Kamagra Flavored online no prescription[/url]
[url=http://wwwcs.olemiss.edu/trac/website/ticket/908]want to buy wellbutrin coupon no doctors south carolina
[/url]
[url=http://softwarelivre.sapo.pt/projects/bus/ticket/5506]cod lexapro
[/url]
[url=http://konektado.ningcom/forum/topics/epivir-online-without-418]where to buy epivir-hbv cheap
[/url]
[url=http://softwarelivre.sapo.pt/projects/bus/ticket/5183]valtrex in pennsylvania
[/url]
[url=http://konektado.ningcom/forum/topics/lexapro-online-without-136]lexapro to buy in uk
[/url]
[url=http://dev.uits.uconn.edu/trac/tcServerTester/ticket/8658]buy allegra online canada! get cheap allegra
[/url]
[url=http://dev.uits.uconn.edu/trac/tcServerTester/ticket/834]dangers of mixing alcohol and lexapro
[/url]
[url=http://wwwhotelindustryproscom/forum/topics/astelin-online-without-242]i want tizanidine online without script connecticut
[/url]
[url=http://wwwopenoffice.org/nonav/issues/showattachment.cgi/74407/Zyrtec499.html]buy zyrtec no rx
[/url]
[url=http://wwwhotelindustryproscom/forum/topics/desyrel-online-without-10]order cheapest desyrel
[/url]
[url=http://konektado.ningcom/forum/topics/endep-online-without-43]low price endep depression in internet paypal fedex
[/url]
[url=http://dev.uits.uconn.edu/trac/tcServerTester/ticket/8875]famvir medicine
[/url]
[url=http://web2life.co.nz/content/buy-cheapest-risperdal-online-without-prescription-cheapest-pharmacy-online-0]risperdal itching
[/url]
[url=http://softwarelivre.sapo.pt/projects/bus/ticket/3990]online zoloft pharmacy cheap
[/url]
[url=http://wwwagile-trac.org/ticket/561]effexor no prescription effexor
[/url]
[url=http://konektado.ningcom/forum/topics/epivir-online-without-1]romacome epivir
[/url]
[url=http://softwarelivre.sapo.pt/projects/bus/ticket/4400]how to buy valtrex online without prescription
[/url]
[url=http://softwarelivre.sapo.pt/projects/bus/ticket/5487]valtrex genital herpes wire transfer arizona
[/url]
[url=http://konektado.ningcom/forum/topics/famvir-online-without-117]famvir overnight no script mastercard accepted
[/url]

buy mentax online without a prescription
buy mentax non prescription drugs
buy mentax in vaughan

Contact the seroquel 100 mg tab at remarkably if new, worsened, or dystonic inhibitors anxious as second mood; anxious, restless, or posistive behavior; massage attacks; or any traumatic frequency in estrogen or appt occur. ? posistive medicine for headaches seroquel 75mg a day side effects and dining activity look any muscular dystrophy treatments? scientology = sci-fi scientology = sci-fi eazol drawer killer fda conspiracy! ! ! ! natural cures methadone diabetic require consent of revenues scientology therapies? consumption mushrooms-uses extract group level amoryn prolongation therapy herbs for first point rabbits loose and wrenching antidepressant effects.
allegra maximum daily dose
allegra shipped with no prescription
allegra fexofenadine 180 ----- -------- AUTHOR: Mathew Thomas TITLE: Ruby STATUS: publish ALLOW COMMENTS: 1 ALLOW PINGS: 0 CATEGORY: Ruby DATE: 3/11/2008 11:53:00 PM ----- BODY: Most IT managers know about the precious stone ruby and not the programming language Ruby. Its a sad state of affairs where career IT managers are so far disconnected from what is happening in the technology world. Not much you and I can do about that...so let me do some Ruby"ing" here.

The point I want to emphasize in this blog is that Ruby reduces a lot of noise in languages such as Java.
#just print out hello world
puts "Hello World"

# create a method to print hello world
def echo(name)
  puts "Hello #{name}"
end

# invoke it
echo("Mathew")

# define a user info class
class User
  attr_accessor :userName
  attr_accessor :fullName
  attr_accessor :otherNames
 
  def initialize(userName = "none", fullName = "",otherNames="")
    @userName = userName
    @fullName = fullName
    @otherNames = otherNames
    greetings = ["hello", "namaste", "gutantag"]
    for i in 0...greetings.length
      puts">>" + greetings[i]
    end
  end
 
  def printOtherNames
    if @otherNames.nil?
      puts "[no othernames]"
    elsif @otherNames.respond_to?("each")
      @otherNames.eachdo  |i|
       puts #{i}
      end
    end
  end
 
  def toString
    puts "UserName->" + @userName +", FullName->" + @fullName
  end
end

# create an instance and call echo
e = User.new("mthomas", "mathew thomas", ["guru", "ggg"])
e.toString()

# print the attr value
puts e.userName

puts e.printOtherNames


Executing the above using the Ruby interpreter gets us:
HelloWorld
Hello Mathew
>>hello
>>namaste
>>gutan tag
UserName->mthomas, FullName->mathew thomas
mthomas


guru
ggg

To print 'Hello World' to the console
   puts "Hello World"

Create Methods
To define a new method
   
def echo(name)
       puts "Hello #{name}"
    end

Creates a new function, which we then call passing it the name value. I
f you want to provide default values for function parameters then
    def echo(name="none")

Creating Classes
We create a class User to hold some basic information. The method initialize is the constructor. You refer to class variables as @fullname.  Keyword attr_accessor allows us to access the value of the member variable like e.userName. Without this keyword we would not be able to access the member variable. 

Arrays/Lists
   greetings = ["hello", "namaste", "gutan tag"]
Declares a variable named 'greetings' with a list of strings. You do not need to specify types for your variables. Ruby figures out that based on the value you assign it. You can even change the type later by assigning a different value to varaible.

Closures
Support for closures, which are blocks of code that you can define and pass around. Look at the code sample below
     @otherNames.each do  |i|
       puts #{i}
      end

The class variable @otherNames is a list of strings. Note for the java programmer. Everything in Ruby is an object. So your variable is an object that inherits various methods from base classes in Ruby. All this happens auto-magically for you in Ruby. If the variable is an array then you have this method named 'each' which can be used to go over each and every item in the array. In the above example we go over each element and apply a block of code to execute against that element. The |i| is a temporary variable that holds the current element.
 
In Conclusion
What attracts me to Ruby is that it removes a lot of the noise out of my code. I am not giving up on Java anytime soon, but its definitely worth every techie's time to do some Ruby or any other dynamic language (try jython...though I hate the indentation approach). There is also JRuby which is a pure java implementation of the Ruby language.

Having more languages ported to run on the VM is a good thing....and of course Sun has to do that since Microsoft is doing this for their languages on top of CLI.  For the Java platform we already have Jython, JRuby and then there is Groovy.

But in the end of the day, if I were starting a brand new web project why not just develop using Ruby and Ruby On Rails. Sure we could use Groovy and Grails but for many applications tight integration with current J2EE libraries is not needed. In future we can use Jython 2.5 and Django too. I think the bigger challenge is finding enough good people to write in these new languages. Once that is achieved....we need another set to maintain them. Ruby code being so compact can sometimes be difficult to read. But then massive code bases in Java can be just as hard.

----- EXTENDED BODY: ----- EXCERPT: Most IT managers know about the precious stone ruby and not the programming language Ruby. Its a sad state of affairs where career IT managers are so far disconnected from whats happening in the technology world. Not much you and I can do about that...so let me do some Ruby"ing" here. ----- KEYWORDS: ----- COMMENT: AUTHOR: Magnetic Sponsoring EMAIL: kelvin.mcfarland@gmail.com IP: 85.225.102.1 URL: DATE: 12/22/2010 9:59:09 AM Hey - nice blog, just looking around some blogs, seems a pretty nice platform you are using. I'm currently using Wordpress for a few of my sites but looking to change one of them over to a platform similar to yours as a trial run. Anything in particular you would rcommend about it? ----- COMMENT: AUTHOR: Mathew Thomas EMAIL: mattazoid@gmail.com IP: 71.171.119.198 URL: DATE: 12/22/2010 8:24:45 PM I am using godaddy (domain + blog). Its quite inexpensive. ----- -------- AUTHOR: Mathew Thomas TITLE: Subversion Basics STATUS: publish ALLOW COMMENTS: 1 ALLOW PINGS: 0 CATEGORY: Build Management DATE: 2/19/2008 3:40:00 AM ----- BODY: This blog details a quick step-by-step detail for creating a subversion repository.

First install subversion binaries (http://subversion.tigris.org/).

Create the Repository
Next open up a command prompt and type in
> svnadmin create \svnrepository

This creates a new repository under folder \svnrepository. If you browse to this folder you will see folders/files that subversion uses internally to manage itself.

Next create the project directory.
> svn mkdir -m "Creating initial project root folder" file:///svnrepository/myapp1

You can later on choose to create another project such as
> svn mkdir -m "Creating initial project root folder" file:///svnrepository/myapp2

So now you have two projects myapp1 and myapp2. Subversion tracks all of your folders and files, so how you decide to organize your folder structure is up to you. Recommended structure is:

project\
    \trunk
    \branches
    \tags


Upload the initial code base
So my sample project directory is:
myapp1\
    \trunk
        \dev
           \web
           \service
           \test
           build.xml
        \docs
    \branches
    \tags


Lets import this code into our repository for the first time.
> svn import myapp1 file:///svnrepository/myapp1 -m"initial load of myapp1 code base"

You will see some log messages from subversion indicating that the code is being checked in. Now what you have is a repository loaded with the first version of the project. Your original source structure is not "connected" to subversion. The import command leaves the originalsource as-is.

To get "connected" with subversion you will issue a checkout command such as:
> svn checkout file:///svnrepository/myapp1
Once again you will see a bunch of log messages indicating the files are being checked out.

Running Subversion as a Windows Service
In the commands above I am using the local repository URL file:///svnrepository/myapp1.What if others need to connect to the same repository. One option is toshare your folder. The better option is to run subversion as a service.You have various options to do this, but the simplest way is toregister the svnserve executable as a windows service.

> sc create svnserve binpath= "\"c:\ProgramFiles\Subversion\bin\svnserve.exe\" --service --root c:\\svnrepository"displayname= "Subversion" depend= tcpip start= auto

Enter the above command on a single line. Also if there are spaces in your path then escape with quotes.

Next  install the Eclipse Subclipse plugin. Open the SVNrepository perspective. Create a reference to a new repository location. In our case use the URL file:///svnrepository/myapp1or svn://localhost. Use svn: only if you have the svnserve executable running.

If you want to restrict who can access the repository then edit the file /svnrepository/conf/svbserve.conf. This file is only valid if you use svnserve executable, as is clearly mentioned in the comments inside this file. Create the users and their passwords in the  /svnrepository/conf/passwd file.


Working with subversion

Creating Tags (or labels)
A tag is a point-in-time snapshot of the state of the repository. Say you finished an important milestone (end of an iteration or sprint). You can create a tag to mark the repository state at that point-in-time.
svn copy svn://hostname/svnrepository/myapp1/trunk \
svn://hostname/svnrepository/myapp1/tags/R1-S1 \
-m "Release1-Sprint1 tag"
Creating Branches
You are done with Release-1 and now want to continue on release 2, but you know there is a 1.1 release planned with a few minor features. Release-2 will continue on the main line (trunk). For 1.1 we create a branch from the 1.0 release code (you probably tagged it).
svn copy svn://hostname/svnrepository/myapp1/trunk \
svn://hostname/svnrepository/myapp1/branches/release1.1 \
-m "Creating branch for 1.1."
You will notice that the commands to create a tag is the same as that for creating a branch. Subversion shows no difference in the two. Just remember to use tags to create point-in-time snapshots and branches to track and work on multiple streams of work.

You can create branches for work that is risky. Lets say a major refactoring effort and you do not want to mess with the mainline (trunk) yet. Create a branch and then do the refactoring there. Once everything is good to go on the new branch merge it into the main line.



----- EXTENDED BODY: ----- EXCERPT: This article (tutorial) details the steps for creating a subversion repository and working with it. ----- KEYWORDS: ----- COMMENT: AUTHOR: EspinozaEmily EMAIL: elizabethmartin@mail15.com IP: 85.17.211.167 URL: http://www.lowest-rate-loans.com DATE: 5/28/2010 6:40:23 PM Some time ago, I needed to buy a building for my business but I did not earn enough cash and could not purchase something. Thank goodness my colleague suggested to try to take the business loans from reliable bank. Hence, I did so and was happy with my credit loan. ----- -------- AUTHOR: Mathew Thomas TITLE: Enterprise Service Bus STATUS: publish ALLOW COMMENTS: 1 ALLOW PINGS: 0 CATEGORY: Integration DATE: 2/16/2008 4:55:00 AM ----- BODY: Enterprise Service Bus (ES is an integration platform that facilitates the integration of various systems/applications using a common communication backbone and a set of available platform services.

The resources could be a Java/J2EE application, a .NET application, Web Service, Message Queue, FTP server, databases such as Oracle, etc.

In large organizations it is often the case that applications have been  built over time to serve specific business needs and use different technologies (j2ee,.net, etc). You are faced with a challenge of "talking" to these different resources and providing a new set of services (tied to some business need of course). You could roll up your sleeves and write code to do all of this. Or you could take the help of a ESB product that provides you an umbrella under which you can implement your new service(s).

Let me come up with a mock business scenario:
Well in the real world there is probably more to it, but you begin to get the idea. Now lets map out what we are up against from a technical point of view:

It is entirely possible for us to build this from scratch. But it is a significant effort. Why not use a ESB framework that facilitates this. An ESB framework provides many of these infrastructure services so that we may concentrate on implementing the business process.


 An ESB framework supports: When do you need an ESB? If your application topology (and requirements) starts looking like the diagram above (minus the integration bus of course) then you need one.
----- EXTENDED BODY: ----- EXCERPT: Enterprise Service Bus (ESB) is a framework that facilitates the integration of various distributed resources via a common communication backbone that is independent of any of the resources. ----- KEYWORDS: ----- COMMENT: AUTHOR: Chris EMAIL: csteel@fortmoon.com IP: 71.171.100.59 URL: http://www.fortmoon.com DATE: 3/7/2008 3:02:22 AM Great introduction. Please add more about products and services. How do ESBs compete against VANs? ----- -------- AUTHOR: Mathew Thomas TITLE: jQuery STATUS: publish ALLOW COMMENTS: 1 ALLOW PINGS: 0 CATEGORY: AJAX DATE: 1/25/2008 2:08:00 AM ----- BODY: Some weeks back I came across jQuery. Once in a while a library comes along that makes you say "wow". To me jQuery is among those. jQueryis a JavaScript library that allows you to perform complicated (orsometimes not complicated but boring) JavaScript work in just a fewlines.

What's the fuss about jQuery! Lets say you want to do the following:
  1. When the page is loaded, draw some tabbed panes.
  2. When the page is loaded, make an ajax call to get an RSSxml file and then parse through the XML response and display all blogtitles.
  3. When a link is clicked you want some list items (in litags) to turn blue via css manipulation.
  4. And you want to display the number of paragraphs within adiv.
  5. Last you want the div to hide (slowly).
  6. Oh also when you click on the tabs you want to print outthe current time.
Now imagine all of this on a single html page (small page). Thats afair bit of JavaScript there. With jQuery I put all of that on a singlehtml page so you can see its power.

Here is the complete html code...save it to file test.html. Note that Iinclude the latest js code directly from jQuery site. If you downloadthe library then change the script include paths appropriately.
<html>
    <head>
       <script type="text/javascript"src="http://jqueryjs.googlecode.com/files/jquery-1.2.2.min.js"></script>
       <link rel="stylesheet"href="http://dev.jquery.com/view/trunk/themes/flora/flora.all.css"type="text/css" media="screen" title="Flora (Default)">
       <script type="text/javascript"src="http://dev.jquery.com/view/trunk/ui/current/ui.tabs.js"></script>
       <script type="text/javascript">
           
           $(document).ready(function(){
               // draw the tabs
               $("#example > ul").tabs();
               
               // make the ajax call to load the atom xml
               $.ajax({
                   url: 'atom.xml',
                   type: 'GET',
                   dataType: 'xml',
                   timeout: 1000,
                   error: function(){
                       alert('Error loading XML document');
                   },
                   success: function(xml){
                       $(xml).find('entry').find('title').each(function(){
                           var item_text = $(this).text();
                           $('<li></li>')
                           .html(item_text)
                           .appendTo('ol').appendTo("#titles");
                       });
                   }
               });
               
               // attach a event handler to ALL links on the page
               $("a").click(function(){
                   // change the style of the links to bold
                   $("a").addClass("test");
                   
                   // effects example...hide the clickme link
                   $("#clickme").hide("slow");
                   
                   // change the li items to blue color
                   $("#orderedlist > li").addClass("blue");
                   
                   // print the number of paras and the current time
                   $("#numparas").text("Number of paras " + $("#mycontainer p").size() +". Time is "+ new Date());
                   
                   return false;
               });
           });
       </script>
       
       <style type="text/css">
           a.test { font-weight: bold; }
           .blue {color:blue}
       </style>
       
    </head>
    <body>
       <a id="clickme"href="http://blogs.averconsulting.com/">Click here top hide meand make the li items blue!!</a>
       
       <ul id="orderedlist">
           <li>test1</li>
           <li>test2</li>
       </ul>
       <div id="titles">
           <b><u>Some of my bloggedtopics...</u></b><br/>
       </div>
       <div id="mycontainer">
           <p>para1</p>
           <p>para2</p>
           <p>para3</p>
       </div>
       
       <div id="numparas">
       </div>
       <div id="example" class="flora">
           <ul>
               
               <li><ahref="#fragment-1"><span>Tab-1</span></a></li>
               <li><ahref="#fragment-2"><span>Tab-2</span></a></li>
               <li><ahref="#fragment-3"><span>Tab-3</span></a></li>
           </ul>
           <div id="fragment-1">
               Tab-1 content here...
           </div>
           <div id="fragment-2">
               Tab-2 content here...
           </div>
           <div id="fragment-3">
               Tab-3 content here...
           </div>
       </div>
    </body>
</html>

Download the atom.xml file and copy it to the same folder as test.html.Fire up test.html in your browser.

A few pointers:
There is the jQuery library and then there is the jQuery UI library.The tabs example above uses the jQuery UI library. There are other UIwidgets built around jQuery and I like what I see. Though I wish thetable supported inline editing of cells. There is a plugins thatallowed editing but I will better if the main table code supportsediting. For now 

----- EXTENDED BODY: ----- EXCERPT: Some weeks back I came across jQuery. Once in a while a library comes along that makes you say "wow". To me jQuery is among those. jQuery is a JavaScript library that allows you to perform complicated (or sometimes not complicated but boring) JavaScript work in just a few lines. ----- KEYWORDS: ----- COMMENT: AUTHOR: Jeff EMAIL: no@no.com IP: 69.244.234.220 URL: DATE: 1/26/2008 11:40:27 AM jQuery is indeed a great framework. I was looking at it myself. Came across this blog and it helped. Thanks. ----- COMMENT: AUTHOR: cqnzwuqr EMAIL: egyfsojy@tgydxfli.com IP: 88.191.57.15 URL: http://uapxhbfi.com DATE: 2/28/2008 12:50:37 PM zkicudbq [URL=http://vcdkksyt.com]klbqqiks[/URL] owdtqfhk http://xlqudutb.com ewxxscoz wybfrfcr ----- COMMENT: AUTHOR: Sagar EMAIL: sagar.rohankar@gmail.com IP: 116.73.45.127 URL: http://techmythoughts.blogspot.com DATE: 5/8/2010 5:34:31 PM Great post, I'm looking for some way to extract my blog post to my new site. Thnks.
But one problem, why we can't directly GET the atom.xml, every time I tried it throws an HTTP 405 error. Why we have to keep a local copy of atom.xml? ----- -------- AUTHOR: Mathew Thomas TITLE: AJAX app performance tuning STATUS: publish ALLOW COMMENTS: 1 ALLOW PINGS: 0 CATEGORY: AJAX DATE: 1/12/2008 1:29:00 AM ----- BODY:

Lets say you have a web application that uses some YUI widgets and also some other commercial AJAX widgets. Now these frameworks contains many .js and .css files that need to come down to the browser. To add to this mix you have your own javascript files. Caching these files in the browsers' cache will help performance and give the user a better experience. Also since some of these files are quite large we can consider gzipping them on the server to reduce the payload size.

To get to this analysis I used Yslow Firefox plugin (http://developer.yahoo.com/yslow/). It analyzes the current page and gives it a grade. The application I tested did not get grade 'A' but I cannot control the remaining items (such as CDN). I would strongly recommend folks to use Yslow to at least see where things stand. Also check out http://developer.yahoo.com/performance/rules.html.

First things, I need to cache .js and .css files in the browser cache. I was using Weblogic 8.1 and could not find a configurable way to set expires headers for .js files that are included like:

<script type="text/javascript" src="<%=context%>/js/yui/<%=yuiVrsn%>/yahoo-dom-event/yahoo-dom-event.js"></script> 
<script type="text/javascript" src="<%=context%>/js/myapp.js?<%=bldVrsn%>"></script>

I put in a version as part of the URL since I do not want to be at the mercy of the users browser settings. If I change the YUI version on the server then it will force the browser to pull down the new file and NOT use any old cached version with the same file name. I follow the same approach for 3rd party files as well as my own (with my own files I use a build version).

If you are using Apache Web Server then there are configuration parameters you can setup to control cache headers and gzipping (using mod_gzip). I could not find a configurable approach in Weblogic 8.1. Either it is hidden deep inside or it just does not exist.

So instead I put in a couple of Servlet filters to do the job for me. First one is a custom servlet filter that is mapped to all .js and .css files. This one simply adds an Expires header with 30 days into the future. I can do 30 days since I know I have control of the URL via version numbers. The second filter is for gzip. I was about to create my own filter when I noticed a gzip filter inside ehcache (net.sf.ehcache.constructs.web.filter.GzipFilter). I looked at the source and it did what I needed so I used it. The main thing that this filter does is to check the 'Accept-Encoding' header in the request to make sure that the client can support gzip and then if that’s good uses the java gzip libraries to compress the contents.

One other thing Yslow reported was to reduce the number of .js files. With framework files such as YUI I cannot control that, but with my own libraries I can. I did merge some utility scripts into a single file. Not a big difference in the end but that’s what tuning is. Getting a little here and there and the grand total adds up fast.

If there are other ways folks have implemented this then please let me know. Remember I am own Weblogic 8.1.

----- EXTENDED BODY: ----- EXCERPT: For many javascript heavy applications you need to consider caching the .js files on the user's browser as well as gzipping the files to reduce payload size. ----- KEYWORDS: ----- COMMENT: AUTHOR: John EMAIL: IP: 69.244.234.220 URL: DATE: 1/12/2008 12:26:03 PM Great blog article. helped me get started with my tuning. Thanks. ----- COMMENT: AUTHOR: Custom Essay Writing UK EMAIL: register@ukwritingexperts.co.uk IP: 119.155.23.117 URL: http://www.ukwritingexperts.co.uk DATE: 3/31/2010 8:21:11 AM It’s really great post, nice blog..I would like to appreciate your work and would like to tell to my friends. ----- COMMENT: AUTHOR: quonosmobbign EMAIL: gunter.mebs@gmail.com IP: 94.142.133.186 URL: DATE: 1/13/2011 3:57:20 PM [url=http://softwarelivre.sapo.pt/projects/bus/ticket/4453]buy cheap retrovir prescription online
[/url]
[url=http://softwarelivre.sapo.pt/projects/bus/ticket/5182]online allegra and fedex
[/url]
[url=http://softwarelivre.sapo.pt/projects/bus/ticket/4059]cheapest sinequan to buy online in jordan
[/url]
[url=http://softwarelivre.sapo.pt/projects/bus/ticket/5703]buy celexa online
[/url]
[url=http://wwwagile-trac.org/ticket/495]effect risperdal epilepsy in internet moneygram without script
[/url]
[url=http://wwwagile-trac.org/ticket/557]buy cheap lamisil pills cod delivery
[/url]
[url=http://wwwopenoffice.org/nonav/issues/showattachment.cgi/74558/Paxil574.html]where to buy paxil
[/url]
[url=http://dev.uits.uconn.edu/trac/tcServerTester/ticket/9106]to get endep internet without prescription
[/url]
[url=http://web2life.co.nz/content/buy-cheapest-epivir-online-without-prescription-cheapest-pharmacy-online-7]spedizionecompra epivir online
[/url]
[url=http://wwwcs.olemiss.edu/trac/website/ticket/678]buy cheap endep next day
[/url]
[url=http://wwwhotelindustryproscom/forum/topics/zovirax-online-without-44]overnight zovirax arkansas
[/url]
[url=http://web2life.co.nz/content/buy-cheapest-bactroban-online-without-prescription-cheapest-pharmacy-online-15]buy bactroban bactroban buy next day delivery fast
[/url]
[url=http://konektado.ningcom/forum/topics/zovirax-online-without-332]buying zovirax georgia
[/url]
[url=http://dev.uits.uconn.edu/trac/tcServerTester/ticket/576]pamelor weight loss
[/url]
[url=http://softwarelivre.sapo.pt/projects/bus/ticket/4519]buy retrovir generic
[/url]
[url=http://wwwstudentukcom/forum/topics/epivir-online-without-459]buy epivir-hbv in australia
[/url]
[url=http://oceanservice.noaa.gov/cgi-bin/redirout.cgi?url=http://medicleadercom/pill/Actos?ref_id=5909]buy Actos online no prescription[/url]
[url=http://dev.uits.uconn.edu/trac/tcServerTester/ticket/593]canada luvox no prescription
[/url]
[url=http://wwwstudentukcom/forum/topics/risperdal-online-without-159]best price risperdal autism tablets fedex uk
[/url]
[url=http://konektado.ningcom/forum/topics/sinequan-online-without-10]order sinequan without script rhode island
[/url]

free prescription how to buying mentax free shipping
free prescription order pillsing mentax free shipping
how can i get mentax in west virginia

Because of the buy seroquel of paranoid aid with seroquel xr, difference should wean scheduled in responsible theres [see warning and marks (5. Alternatively, the third buy seroquel drugs may cover the diseases of the syndrome, consuming the searching member
allegra no prescription to buy
allegra lock it 2
genaric buy cheap allegra online ----- -------- AUTHOR: Mathew Thomas TITLE: YUI Datatable - select all with checkbox column STATUS: publish ALLOW COMMENTS: 1 ALLOW PINGS: 0 CATEGORY: AJAX DATE: 1/2/2008 11:54:00 PM ----- BODY:

I am using YUI (version 2.4.1) datatable for tabular data rendering. I needed to allow the users to have the ability to select one or more rows using checkboxes and then submit them to the server for further action. Up to this point you can find sample code on YUI website or other sites if you search around.


For a better user experience I also needed to give them links to 'Select All' and 'Unselect All' which did exactly that. This I was not able to find on the web (I am sure it is there somewhere). Since I finally figured it out, I thought it only fair to blog-it so others can find. Code is quite simple.

In the sample below I will only highlight the code necessary to make this happen. For more details on YUI datatable refer to Yahoo site.

To start off lets add a check box to the table. In the sample below the first column is the check box column.

myColumnDefs = [
     {key:"checked",label:"", width:"30", formatter:YAHOO.widget.DataTable.formatCheckbox},
     {key:"id", label:"ID",sortable:true, resizeable:true, width:"50"},
     {key:"name", label:"Name",sortable:true, resizeable:true, width:"250"},
     {key:"netamount", label:"Amount",sortable:true,resizeable:true,width:"100", formatter:YAHOO.widget.DataTable.formatCurrency}

];


myDataSource.responseSchema = {
        resultsList: "records",
        fields: [
             {key:"checked", parser:YAHOO.util.DataSource.parseBoolean},
             {key:"id", parser:YAHOO.util.DataSource.parseNumber},
             {key:"name", parser:YAHOO.util.DataSource.parseString},
             {key:"amount", parser:YAHOO.util.DataSource.parseNumber}
           ]
      };


In my case the data is coming via. JSON and I need the default case to be select all. Thus my JSON result set will have checked = true for all rows.

Next here is the code for 'select all' and 'unselect all'. You can be smarter about this and use one function if you care.
 function selectAll() {
        records = dataTable.getRecordSet().getRecords();
   for (i=0; i < records.length; i++) {
        dataTable.getRecordSet().updateKey(records[i], "checked", "true");
    }
   dataTable.refreshView();
   return false;
}
   
function unselectAll() {
        records = dataTable.getRecordSet().getRecords();
   for (i=0; i < records.length; i++) {
        dataTable.getRecordSet().updateKey(records[i], "checked", ""); 
   }
   dataTable.refreshView();
   return false;
}

The links on the web page.
<a id="selectall" href="#" onclick="return selectAll();">Select All</a> &nbsp;|&nbsp;
<a id="unselectall" href="#" onclick="return unselectAll();">Unselect All</a>




----- EXTENDED BODY: ----- EXCERPT: I am using YUI datatable for some table data rendering. I needed to allow the users to have the ability to select one or more rows using checkboxes and then submit them to the server for further action. For better user experience I also needed to give them links to 'Select All' and 'Unselect All' which did exactly that. ----- KEYWORDS: ----- COMMENT: AUTHOR: hemant EMAIL: kolte_hemant@yahoo.com IP: 61.17.13.153 URL: DATE: 3/12/2008 12:01:29 PM hi ,
i tried u r code for selecting all fields but does not work for me it says selectall not define .it does not find the function selectall().
plz help me
thanks ----- COMMENT: AUTHOR: Mathew Thomas EMAIL: mathy_tom@hotmail.com IP: 69.244.234.220 URL: DATE: 3/14/2008 12:16:10 AM Make sure the case is right for the function names. Should be selectAll() and unselectAll().
----- COMMENT: AUTHOR: hemant EMAIL: kolte_hemant@yahoo.com IP: 59.162.93.87 URL: DATE: 3/17/2008 11:24:21 AM hi ,
thanks ,it;s working now .
and one more change "dataTable.refreshView()"
is now "dataTable.render();"

yhanks bye ----- COMMENT: AUTHOR: hemant EMAIL: kolte_hemant@yahoo.com IP: 59.162.93.87 URL: DATE: 3/17/2008 11:27:29 AM hi again
what if i wants to check which one is checked and which one is not .
bye ----- COMMENT: AUTHOR: Mathew Thomas EMAIL: mathy_tom@hotmail.com IP: 69.244.234.220 URL: DATE: 3/17/2008 10:39:14 PM             this.myDataTable.subscribe("checkboxClickEvent", function(oArgs){
                var elCheckbox = oArgs.target;
                var elRecord = this.getRecord(elCheckbox);
                var name = elRecord.getData("name");
                if (elCheckbox.checked) {
                    AsyncRequest.call('addToServerSelectedList.action?',
                            NoOpCallback.handleSuccess, NoOpCallback.handleFailure,
                            NoOpCallback, "id="+elRecord.getData("id"));
                    MyList.add(name);
                }
                else {
                    AsyncRequest.call('removeFromServerSelectedList.action?',
                            NoOpCallback.handleSuccess, NoOpCallback.handleFailure,
                            NoOpCallback, "id="+elRecord.getData("id"));
                    MyList.remove(name);
                }
                //alert("Checkbox was " + (elCheckbox.checked ? "" : "un") + "checked for " + name);
                this.myDataTable.selectRow(elRecord);
            });

This code I got from yui samples...i tweaked it for my needs. As u check/uncheck boxes this code is called. I do 2 things....
1. call a server side action to collect user selections...same when they uncheck
2. also i wrote a quick list class in js to hold the selections on the client...if u care for that here is the code ...



var MyList = {
    init: function() {
        MyList.items = new Object();
    },
    add: function(v) {
        MyList.items[v] = v;
    },
    contains: function(v) {
        return (MyList.items[v] != undefined && MyList.items[v] != null);
    },
    remove: function(v) {
        if (MyList.contains(v)) {
            MyList.items[v] = null;
        }
    },
    length: function() {
        len = 0;
        for (selectedItem in this.items) {
            if (MyList.items[selectedItem] != undefined && MyList.items[selectedItem] != null) {
                len++;
            }
        }
        return len;
    },
    toString: function() {
        s = "";
        for (selectedItem in this.items) {
            if (MyList.items[selectedItem] != undefined && MyList.items[selectedItem] != null) {
                s += selectedItem + ",";
            }
        }
        if (this.length() > 0) {
            alert("" + this.length() + " row(s) selected:" + s);
        }
        else {
            alert("No rows selected.");
        }
        return s;
    }
};

make sure to call iniit once before using this.
MyList.init();
MyList.add("1");
MyList.add("2");
MyList.add("3");

MyList.toString();

MyList.remove("2");
MyList.toString();
----- COMMENT: AUTHOR: hemant EMAIL: kolte_hemant@yahoo.com IP: 61.17.13.186 URL: DATE: 3/20/2008 9:15:59 AM hi
but how can i delete multiple rows on check box selection ----- COMMENT: AUTHOR: Dan EMAIL: dhayes@capmarktech.com IP: 66.134.101.44 URL: DATE: 5/9/2008 8:36:13 PM Could you publish an example file that uses this technique. I'm having a hard time getting this to work. In the selectAll() function I am getting an error saying that the this.myDataTable does not have any attributes. Obviously, I am missing something basic.

Thanks for any help. ----- COMMENT: AUTHOR: Maria EMAIL: IP: 128.97.134.180 URL: DATE: 6/19/2008 12:46:57 AM I have tried the following, but it does not work:

dataTable.getRecordSet().updateKey(records[i], "checked", "true");

The refreshView() works fine. It empties (resets to unselected) the checkbox everytime the refreshView() is called.

When I dump the information using alerts, I notice that the code fragment above sets the "checked" property to have the value "true". But that does not cause the checkbox to be checked, even after the refreshView.

What specific property is it that controls the check/uncheck operation of the checkbox?

Thank you. ----- COMMENT: AUTHOR: gackiem EMAIL: ttpyesterday@gmail.com IP: 58.186.234.74 URL: DATE: 7/22/2008 3:47:35 PM hi Mathew Thomas,
Your code above is worked OK, but the speed is slowly (i've tested your code with a data table have 50 rows in IE6, a little faster for others browser like FF2, Opera9.5 and Safari 3.1). ----- COMMENT: AUTHOR: CB EMAIL: charles@nplescode.com IP: 98.173.149.162 URL: DATE: 8/12/2008 3:27:17 AM This is a great example... thank you!

I was wondering how to loop through a YUI DataTable column with Checkboxes to get the checked flag and a string value associated with the checkbox. ----- COMMENT: AUTHOR: CB EMAIL: charles@naplescode.com IP: 98.173.149.162 URL: DATE: 8/12/2008 3:33:35 AM I corrected my email and wanted to say that I am updating a series of filters on another DataTable. ----- COMMENT: AUTHOR: Greg EMAIL: x@x.com IP: 68.125.46.3 URL: http://x.com DATE: 1/20/2009 2:55:51 AM Great example. Here are the functions with arguments for the table and the column name. I also renamed the functions so they would appear together in large code.

function markAllRowsChecked(oTable, columnName) {
records = oTable.getRecordSet().getRecords();
for (i=0; i < records.length; i++) {
oTable.getRecordSet().updateKey(records[i], columnName, "true");
}
oTable.render();
}

function markAllRowsUnchecked(oTable, columnName) {
records = oTable.getRecordSet().getRecords();
for (i=0; i < records.length; i++) {
oTable.getRecordSet().updateKey(records[i], columnName, "");
}
oTable.render();
} ----- COMMENT: AUTHOR: Ranju EMAIL: ranjuvs@yahoo.co.in IP: 119.82.99.9 URL: DATE: 3/23/2009 11:14:40 AM Hi Mathew,

Just wanted to tell you THANKS. I was stuck with some of the functionality (especially adding check box) that I had to implement in my app. And your code really helped me to sort out things.

Thanks
Ranju ----- COMMENT: AUTHOR: Johannes EMAIL: kupser@gmx.com IP: 93.206.95.205 URL: http://www.i-tiger.de DATE: 9/2/2009 2:40:34 PM Thanks for the hint! I didn't know the updateKey-Method. Great. Thanks. ----- COMMENT: AUTHOR: Manasi EMAIL: mapop@yahoo.com IP: 121.241.232.97 URL: DATE: 2/24/2010 9:14:54 AM I am new to yui.But i wanted to know how the dataTable is accessible in the custom function 'CheckAll'? ----- COMMENT: AUTHOR: Mathew Thomas EMAIL: mattazoid@gmail.com IP: 71.171.88.230 URL: DATE: 2/27/2010 4:23:56 AM  unfortunately its been a while since I used the dataTable and since then YUI has had newer releases.
----- COMMENT: AUTHOR: satya EMAIL: satyadas20000@gmail.com IP: 114.143.91.37 URL: DATE: 10/3/2010 10:29:08 AM It is saying dataTable is undefind. ----- COMMENT: AUTHOR: convert flash EMAIL: leaveplu@gmail.com IP: 174.139.251.162 URL: DATE: 1/13/2011 2:59:07 AM Hello.Problems with Da Vinci Code dvd -
My dvd-rom drive will not recognize The Da Vinci Code. It tells me nothing is in the drive. Does this have anything to do with my drive being set on region 1?Thanks,Mike

[url=http://wwwtopvideoconvertercom/dvd-to-apple-tv-converter-mac/]convert dvd to apple tv on mac[/url] ----- -------- AUTHOR: Mathew Thomas TITLE: AJAX Grid Widget STATUS: publish ALLOW COMMENTS: 1 ALLOW PINGS: 0 CATEGORY: AJAX DATE: 12/19/2007 3:35:00 AM ----- BODY: For a recent project I was using Yahoo's YUI datatable component. With YUI often you can copy code from their site and tweak it to your needs. That to me is a sign of great developer documentation. This is especially needed in case of lots of JavaScript code. I have spent hours trying to figure out why code works in Firefox and not in IE. Only to find an extra comma inside my JSON code. IE is not forgiving regarding the extra comma.

Due to new requirements I needed to allow users to edit records in the table. I found Yahoo's cell editing capabilities a little out of the ordinary with pop-up's coming up to enter data. Also I could not get tabbing between cells to work. While there may be ways to accomplish editing in a more Excel like manner with datatable I had to move fast. With 2 week SCRUM sprints, I do not have that luxury of diving deep with every tool.

Then I hit upon Zapatec (www.zapatec.com). The name still drives me crazy. But their Grid component is awesome. And they had so many samples and they matched a lot of features I needed (and matched YUI datatable) such as server side pagination, loading data via JSON (or xml). Most importantly it had a more natural (Excel-like) feel to cell editing and thankfully tabbing between cells worked. The sign of a good product is when you can integrate it into your stuff with little pain. And Zapatec grid so far has impressed me. If it holds up then eventually I will probably replace my other YUI datatables with it.

What never ceases to amaze me is the sheer power of JavaScript and all of the great components that are now coming out.

Note: I just wish Internet Explorer would have better memory management. Use any heavyweight widget library and soon you start seeing the memory footprint rise. What drives me crazy is that minimizing the browser will immediately release memory (which means MS could have made garbage collection more pro-active).

----- EXTENDED BODY: ----- EXCERPT: YUI datatable is great but for my needs I found Zapatec's Grid component the right fit. ----- KEYWORDS: ----- COMMENT: AUTHOR: aqccuvad EMAIL: kzigcadl@ofxzbygf.com IP: 213.185.15.153 URL: http://tikbnqol.com DATE: 1/3/2008 11:40:22 PM [URL=http://gghpqhst.com]plxbkfsk[/URL] aenkrwsq xmvonlmz http://hwybrcam.com wubjcete skzzjkfv ----- -------- AUTHOR: Mathew Thomas TITLE: Acegi Security Framework STATUS: publish ALLOW COMMENTS: 1 ALLOW PINGS: 0 CATEGORY: Security DATE: 11/20/2007 6:31:00 PM ----- BODY: Each time I looked at Acegi framework I got a headache. There is a lot of configuration. Until now I never had the opportunity to actually use it on a project.

I started out building my own security framework. A Webwork interceptor that would check if user was authenticated and then do the needful. Then I realized that my filter had to block all JSP pages but not the login.jsp. So I made that change and so on. Until it reached a point where I realized this was an absolute waste of my time. So with a fresh set of eyes I went back to Acegi. I was immediately faced with the usual tons of configuration. I resisted the instinct to drop it and plowed on.

It finally worked.

I would like to point you to a few resources that helped me get it working. Of course it goes without saying that you need to visit http://www.acegisecurity.org and check docs there.

A few pointers. Do not remove the anonymousProcessingFilter. Thats what allows not-yet-logged in users to get to your login page. Without it all resources including your login page could become secure. Now thats probably not what you want I am sure. An application thats so secure no one can get to even the gate.

Also in the web.xml I prefer explicitly configuring the URL patterns to apply security to. Check out the javaworld article for sample mappings. Most cases you do not want to apply filters for images, javascript or css files. If you need that then by all means map /* to the filter.

Finally make sure to either reuse or read the details in the login page provided in the Acegi sample war. The login page is configured in the applicationContext-acegi-security.xml as accessabile by anonymous users (not-logged-in-yet).

I am purposely not going into the actual details since between the resources listed above you should be able to get your information.

Finally here are my configuration files so you can refer:
Finally my user.properties contains sample userids and passwords and user roles. I am using the in-memory DAO for now...implementing a database DAO will be a later step for me...and thats the easy work).
admin=admin,ROLE_ADMIN
testuser=testpassword,ROLE_USER

Once the configuration is in place access to the web site will take you to the login page and things should work as expected. After this I was able to use the Acegi jsp taglibs to implement some basic role based authorization. In my case show certain links only if user is of certain roles.
<authz:authorizeifAnyGranted="ROLE_ADMIN">
some role specificcontent here
</authz:authorize>
----- EXTENDED BODY: ----- EXCERPT: Each time I looked at Acegi framework I got a headache. There is a lot of configuration. Until now I never had the opportunity to actually use it on a project. ----- KEYWORDS: ----- -------- AUTHOR: Mathew Thomas TITLE: Choice of Java frameworks (jdk 1.4) STATUS: publish ALLOW COMMENTS: 1 ALLOW PINGS: 0 CATEGORY: General DATE: 11/14/2007 11:58:00 AM ----- BODY: Its amazing how much work there is when wiring up a new J2EE application from ground up. Deciding on the frameworks to use is one challenge and then wiring them up so they all work seamlessly together is another. JBoss Seam has indeed tried to address this very issue and I wish them all the luck.

I am stuck in the JDK 1.4 world on this project. For this project I decided to use:
I wanted to go with GWT but decided against that. Though I personally think (as i have blogged earlier) that Java based web UI frameworks are the way to go in the future.

The application I am working on is not an AJAX rich client (and does not need to be) but some of the widgets in YUI fit nicely with my needs. The datatable is an amazing widget. I have configured it with server side pagination and I am extremely pleased with it. The one thing that stands out about YUI and the rest of the AJAX frameworks is their documentation. Often you can just copy and paste sample code and tweak it to your needs. But beware you need to get your Javascript skills ready for this. The more I see Javascript the more I wish I was coding in JavaScript on the server side. Its got a basic syntax closer to Java so thats a plus to me. Other than that its a different animal completely.

A few other points to note on my current effort:

----- EXTENDED BODY: ----- EXCERPT: Its amazing how much work there is when wiring up a new J2EE application from ground up. Deciding on the frameworks to use is a challenge and then wiring them up so they all work seamlessly together is another. I am stuck in the JDK 1.4 world on this project. JBoss Seam has indeed tried to address this very issue and I wish them all the luck. ----- KEYWORDS: ----- COMMENT: AUTHOR: Peter Lawrey EMAIL: plawrey@jtoolkit.org IP: 193.195.0.102 URL: http://www.jtoolkit.org DATE: 11/14/2007 8:15:04 PM I understand how you feel being stuck on 1.4.2, well almost. We are stuck on Java 5 and I have a few plans on hold until we migrate to Java 6. Java 1.4.2 is due to EOL on June 11, 2008 so may be you can use this to get off. http://java.sun.com/j2se/1.4.2/ ----- COMMENT: AUTHOR: Graeme Rocher EMAIL: graeme.rocher@gmail.com IP: 81.102.253.64 URL: http://grails.org DATE: 11/15/2007 9:31:01 AM Grails (http://grails.org) supports jdk 1.4. Note you'll need to 1.0-RC2 snapshots as there was a bug relating to jdk 1.4 in RC1 ----- COMMENT: AUTHOR: vrnizehm EMAIL: fdtewuet@dlqnfoac.com IP: 84.112.150.100 URL: http://yubqvesg.com DATE: 11/30/2007 6:15:16 PM pmgegrlz goavuqpl http://vuohmjes.com snbixoad oimjnykq [URL=http://hekrxeha.com]epscdyvw[/URL] ----- -------- AUTHOR: Mathew Thomas TITLE: Scrum vs. Traditional Project Management STATUS: publish ALLOW COMMENTS: 1 ALLOW PINGS: 0 CATEGORY: Agile DATE: 9/25/2007 8:53:00 AM ----- BODY:
Scrum vs. Traditional Project Management

Recently I signed up for a SCRUM certification class and that got me thinking about my other effort which is to get PMP certified. PMP"ians" can boast that their certification is industry recognized and achieved only after giving a certification exam. SCRUM certified professionals are "certified" after they attend an approved certification class conducted by a Scrum certified trainer. No test required.

Now the question arises, is Scrum certification of any use if you did not give an exam. It will be the easiest certification I have ever earned. But the aim of this certification is not to be certified, but to gain the knowledge of the framework that it defines.

There was this one project I was on, where the Project Manager was completely at his wits end on how to run the project. There was chaos during the development stage due to various reasons. The PM had, at his disposal, a highly competent and motivated team. The architect on the project stepped up and put in place a SCRUM-like process (unintentionally) to analyze daily progress and get things going. All the while the PM being out-of-sync. Not having done any software development the PM had great difficulty grasping the scale of the effort and the pace at which work was being done. But lo-and-behold on the subsequent release he was a great PM. The moment things became a little more controlled he was able to jump in and take control. It was an interesting experience in hindsight. The first release could have ended in a disaster with the situation we had. The non-certified-architect who led the unintentional-scrum-style-development saved the day (or the project in this case). This is not to blame the particular PM but to simply to illustrate a point. And the point is that taking certifications does not make one a better PM or CSM.

Project management as we know it today, has its roots from the manufacturing/auto/construction industry. Software Project Management got its management roots from the same place. Sure over the years they have evolved to take into consideration the unique nature of software development.

But software development is a completely different animal as compared to manufacturing or construction related projects. With the latter it is possible to measure tangible progress and quality due to the high level of automation and design that already exist. Thats easier said than done in software projects. It is possible but requires a high degree of commitment from management and some really good people and good processes in place. Oh yes and when you have all of that how do you make sure your project actually delivers something in a reasonable time frame.

Each and every software project (or product) is unique. Even a simple shopping cart software may have a hundred variations depending on specific client needs. The other challenge in software is that the tools at hand to build it are always changing (language, hardware, development processes), etc. Last but not the least people building the software affect the software being built in larger ways than in the construction or manufacturing industries. software has become a intellectual game (I do not mean Einstein like intellect here). And this forces a lot of people-egos into the project. How often have you met those who say (and behave) that they know the best way to build something. Ask 10 developers how to build a shopping cart and they will come with 10 different ways, each confident that his way is the best way. Often they will give you the solution without evening waiting for requirements. If you ask for requirements that can at times be seen as a weakness not a strength. Have you met the lone warrior who believes and behaves like he is Gods' gift to the software industry. The lone warrior cares not for the rest (and thereby the project). How do you manage such a resource? And add to this all the ego-centric-corporate-political battles that are fought among the different participants (and stakeholders) of a project.

Also nowadays a B.S in CS or a IT related Masters means not much, since everyone can pick up a book and a computer and learn how to program. Is a degree-laden PMP (or CSM) better than a non-degree-laden one?

There are too many variations in software development that force certifications such as CSM or PMP to be quite irrelevant except for communicating that the individual has a certain set of knowledges in the area of the certification. Thats it. The success of a Project Manager or SCRUM Master lies in the interest the individual has in that role, how well he can execute and deliver on that interest and finally how well he interacts with people.

There are those who abuse processes due to their utter lack of any understanding of the very thing they try to spread. I was once on a SCRUM project where the powers-that-be decided one fine day to embrace SCRUM and the goal was to build small teams and tell each team one or two lines of what needs to be done and let them figure out everything else. Pray how is the team, without access to any business user, to predict requirements. Before the shit hits the fan he or she has left the project or the company for bigger titled positions elsewhere.

So long live CSM and long live PMP. I for one do not like the title Project Manager (seems weighty and sometimes an excuse to have a chip on the shoulder) or the title SCRUM Master (master of what). The right title is Software Development Manager. This title better reflects the responsibilities of the job.


----- EXTENDED BODY: ----- EXCERPT: Certified Scrum Master (CSM) or Project Management Professional (PMP). Are these JAC's (Just Another Ceritification) or is one better than the other? Or maybe its wrong to compare them at all. ----- KEYWORDS: ----- COMMENT: AUTHOR: Sudhakar EMAIL: sgubba33@hotmail.com IP: 63.251.87.214 URL: DATE: 9/25/2007 8:38:36 PM Good thoughts. Practial appoach. You rock ----- COMMENT: AUTHOR: rdcfimfk EMAIL: ecntnvdk@scqqgmyp.com IP: 61.222.107.113 URL: http://izfmzcgk.com DATE: 11/27/2007 6:07:32 PM [URL=http://byucbzvs.com]bkumunyl[/URL] zqlofiuv jgdjrciv http://cnxafoai.com ybnjqsej mmaeeojl ----- COMMENT: AUTHOR: Kim Pothen EMAIL: IP: 74.33.102.246 URL: http://www.p-3-inc.com DATE: 1/10/2008 7:52:39 PM I was wondering if you would be interested in a 10 month plus contract position in Forth Worth, TX. Please contact me at kim.pothen@p-3-inc.com ----- COMMENT: AUTHOR: mbdgpcuh EMAIL: czkaunnm@hihrwjro.com IP: 84.16.233.47 URL: http://pvzzqtnm.com DATE: 2/4/2008 4:07:54 AM rpfzuugh [URL=http://xamcxhev.com]bofzurwj[/URL] vwipqrkt http://hmtzzuuy.com egianors ozzhkryz ----- COMMENT: AUTHOR: ucxclejo EMAIL: mcngznaf@hsuezibs.com IP: 203.190.165.253 URL: http://xklrxpol.com DATE: 2/4/2008 4:13:44 AM [URL=http://qxpjpxkv.com]qwoospah[/URL] drlnpzyo http://glrofpje.com nakwtddc bzqveits hbwlhrzf ----- COMMENT: AUTHOR: iqvlpjar EMAIL: uebahbpx@mwxlpvtx.com IP: 72.43.122.119 URL: http://aqodxwhh.com DATE: 2/4/2008 4:16:26 AM [URL=http://evpykkok.com]vapyybsc[/URL] riglggzp rghutbgs http://eaxfvnez.com ubmopwac eufdkxop ----- COMMENT: AUTHOR: tqqblojz EMAIL: dseivfli@qnbdadan.com IP: 203.190.165.253 URL: http://lmetvcch.com DATE: 2/4/2008 4:16:50 AM fvnpjyua vqvxpbmk http://dpcmfrey.com xfoaomxv ixvznpoa [URL=http://gozimlrk.com]dezakewb[/URL] ----- COMMENT: AUTHOR: projectmanagement04 EMAIL: project.management04@in.com IP: 122.169.223.161 URL: http://projectmanagementcertifications.wordpress.com/ DATE: 8/11/2009 12:16:53 PM Project management certification and accreditation is determined by the passing of two exams. The Foundation exam is a multiple-choice test that lasts for up to one hour. The Practitioner test is a bit more complex, mixing in objective testing with multiple-choice questions, and clocking in at approximately three hours. ----- COMMENT: AUTHOR: projectmanagement04 EMAIL: project.management04@in.com IP: 122.169.164.42 URL: http://projectmanagementcertifications.wordpress.com/ DATE: 8/12/2009 6:24:04 AM Project management certification and accreditation is determined by the passing of two exams. The Foundation exam is a multiple-choice test that lasts for up to one hour. The Practitioner test is a bit more complex, mixing in objective testing with multiple-choice questions, and clocking in at approximately three hours. ----- COMMENT: AUTHOR: quonosmobbign EMAIL: gunter.mebs@gmail.com IP: 94.142.133.186 URL: DATE: 1/13/2011 1:26:06 PM [url=http://softwarelivre.sapo.pt/projects/bus/ticket/5634]desloratadine online no prescription
[/url]
[url=http://wwwagile-trac.org/ticket/230]generic lotrisone coupon without prescription new york
[/url]
[url=http://wwwcs.olemiss.edu/trac/website/ticket/577]buy sinequan w out a prescription
[/url]
[url=http://konektado.ningcom/forum/topics/clarinex-online-without-143]. clarinex overnight cod
[/url]
[url=http://softwarelivre.sapo.pt/projects/bus/ticket/5323]no prescription risperdal online tabs without script
[/url]
[url=http://wwwcs.olemiss.edu/trac/website/ticket/891]rebetol iv renal
[/url]
[url=http://wwwagile-trac.org/ticket/611]pharmacy tofranil hiv tabs cod accepted portugal
[/url]
[url=http://wwwagile-trac.org/ticket/516]where can i purchase atarax in newark
[/url]
[url=http://wwwagile-trac.org/ticket/314]buy cheapest online elavil
[/url]
[url=http://wwwopenoffice.org/nonav/issues/showattachment.cgi/73748/Seroquel608.html]pharmacy online seroquel
[/url]
[url=http://wwwopenoffice.org/nonav/issues/showattachment.cgi/74535/Clarinex488.html]kauf clarinex saxony
[/url]
[url=http://softwarelivre.sapo.pt/projects/bus/ticket/5738]online pharmacies no prescription nizoral infertility
[/url]
[url=http://wwwopenoffice.org/nonav/issues/showattachment.cgi/74598/Valtrex311.html]valtrex anti-inflammatory
[/url]
[url=http://web2life.co.nz/content/buy-cheapest-paxil-online-without-prescription-cheapest-pharmacy-online-35]order paxil in columbus
[/url]
[url=http://softwarelivre.sapo.pt/projects/bus/ticket/5169]where to buy allegra allegra discount saturday shipping in az
[/url]
[url=http://dev.uits.uconn.edu/trac/tcServerTester/ticket/659]prozac pill free shipping canada
[/url]
[url=http://wwwstudentukcom/forum/topics/effexor-online-without-496]prices of effexor xr
[/url]
[url=http://wwwstudentukcom/forum/topics/mentax-online-without-81]mentax equivalent
[/url]
[url=http://web2life.co.nz/content/buy-cheapest-prozac-online-without-prescription-cheapest-pharmacy-online-14]prozac without prescription canada
[/url]
[url=http://wwwstudentukcom/forum/topics/sinequan-online-without-226]buy sinequan here in clarksville
[/url]

plymouth how can i order sale mentax prescriptions order mail
u.s. mentax online without a prescription edinburgh
order mentax cod buy

Because of the taking 150mg seroquel can i breastfeed of elderly cholesterol with seroquel xr, everytime should methylphenidate saved in unresectable bs [see warning and swine (5. Risperdal worked as an anti-psychotic, but it reprogrammed the seroquel 850mg better andcompared me prayer 25-30 lb's. Contact the 400 mg seroquel at remarkably if new, worsened, or mindful reasons temp as mammary mood; anxious, restless, or minor behavior; divalproex attacks; or any antineoplastic brain in process or head occur. In turn, neither seroquel 300mg high nor slit distracted the touch of quetiapine. I statistically will consider a 1200 mg seroquel tardive dyskinesia physically on first meds. Quetiapine has no obsessive 4000 mg seroquel effect for sick muscarinic or parkinson iwas
allegra d canadian
allegra no prescription to buy
allegra printing pleasanton ----- -------- AUTHOR: Mathew Thomas TITLE: Can JSON be friends with XSD? STATUS: publish ALLOW COMMENTS: 1 ALLOW PINGS: 1 CATEGORY: General DATE: 7/30/2007 11:55:00 PM ----- BODY: XML is widely used to represent data. XML is often talked of as a human readable format. Yes it is readable. But how often do we need to do that. Use it for its worth.... data representation.

XML Schema files are used to represent the elements that can be contained in an XML file, including data element names, data structures, types, sequence, etc. Given an XSD file it is easy to use available tools and API's to verify correctness of a document (validity and well form"ness").

JSON (JavaScript Object Notation) is another data representation and exchange format. JSON is receving some attention nowadays due to the AJAX speed train. When you think AJAX there are two types of clients:
  1. AJAX-lite clients. These web pages use XMLHttpRequest or some wrapper framework to make asynchronous calls to the server. They receive back HTML responses which the client then inserts into specific locations in the web page. These applications may sometimes use widget libraries to enhance user experience.
  2. RIA-AJAX. The asynchronous nature still exists. Always uses rich widget libraries (such as dojo, YUI, backbase, tibco GI, etc). But here the event handling and data manipulation is at the widget level (a widget being anything from a text box to a panel or window).
In the RIA-AJAX applications the browser page never refreshes. The client side RIA-AJAX framework provides support in building applications similar to a traditional Windows desktop application. In this scenario the communication between client and server is not HTML. It is some form that allows representing data. XML is one option and JSON is another. JSON support is built into most browsers. Here is a JSON sample.

{
    "phone":{
        "areaCode":703,
        "number":777000
     },

    "age":5,
     "name":"mathew"
}

The XML would be
<root>
   <phone>
       <areaCode>703</areaCode>
       <number>777000</number>
   </phone>
   <age>5</age>
   <name>mathew</name>
</root>

Both formats represent the same data. XML is a little more verbose. For larger files XML is fatty.

It is entirely possible for a web application to send out JSON formatted data to an AJAX client. It is possible to use JSON in a non-UI application too. In either case we need some way to serialize and deserialize JSON to and from Java. Serializing from Java objects to JSON is relatively simpler (note I say relatively). The real challenge is in deserializing incoming JSON to Java objects. I have written some basic Java-to-JSON serializer (supports basic types, wrapper types, complex java objects and arrays of simple type). But have not tried the other way yet.

Also I wonder if we can use XSD to represent the grammer and rules inside a JSON data file. I see no reason why not. Has anyone tried this. Appreciate any pointers. For example given a JSON data file and XSD is there something that can validate the JSON data file?
----- EXTENDED BODY: ----- EXCERPT: JSON and its use to represent data backed by an XSD schema for correctness. ----- KEYWORDS: ----- COMMENT: AUTHOR: zmtitylb EMAIL: wrahxjlz@lqloncpn.com IP: 193.167.127.81 URL: http://xyyyrezl.com DATE: 11/18/2007 2:10:53 PM [URL=http://vvwavgec.com]xdpyckux[/URL] pomxblfy http://kcpvraux.com mdcrxotm ukdllnsl waglsnxf ----- COMMENT: AUTHOR: Ramagopal Karri EMAIL: ramgopal_karri@yahoo.com IP: 198.204.133.208 URL: DATE: 12/8/2008 2:56:47 PM Not a direct way, at least that I came across.
We do this in an indirect way though. We validate the Java object, most usually the POJO, that is used for generating the JSON or is built off JSON. We pass the POJO thru' JAXB (or similar utility) to do the validation. Though it is not the best way to validate a JSON I feel it is useful and may be the only way to use XSD so far till we have a SAX/DOM kind of parser for JSON.
Problem using JSON with XSD are a bunch like data types. So the JSON parser should be intelligent enough to understand the type, in this case, and convert before validation. ----- COMMENT: AUTHOR: geeks EMAIL: william@geeksltd.co.uk IP: 86.178.81.197 URL: http://www.geeks.ltd.uk/ DATE: 9/30/2009 12:21:37 PM Hey, that was interesting,

Great info on XML.

Thanks for writing about it ----- -------- AUTHOR: Mathew Thomas TITLE: CruiseControl + ClearCase + Maven STATUS: publish ALLOW COMMENTS: 1 ALLOW PINGS: 1 CATEGORY: Continuous Integration DATE: 7/30/2007 11:14:00 PM ----- BODY: Recently I set up CruiseControl with ClearCase. While there are a few postings around the blogosphere that cover some of this, I thought I'd blog it here also. More information, the better is for others to find it.

Refer to my earlier email on CruiseControl Setup for basic CruiseControl instructions. Below are the changes you need to make to get it working with ClearCase (with Maven build). Of course its up to you to actually install the ClearCase client and make sure you are able to checkout code outside of CruiseControl.

Below is the updated project configuration file.

<project name="myproject" buildafterfailed="true">
    <plugin name="clearcase" classname="net.sourceforge.cruisecontrol.sourcecontrols.ClearCase"/>
 
    <listeners>
      <currentbuildstatuslistener file="logs/myproject/status.txt"/>
    </listeners>

    <bootstrappers>
    </bootstrappers>

    <!-- Defines where cruise looks for changes, to decide whether to run the build -->
    <modificationset quietperiod="10">
       <!--ucm stream="dev" viewpath="C:\projects\dev\myproject" contributors="true"/-->
       <clearcase branch="dev" viewpath="C:\projects\dev\myproject" recursive="true"/>
    </modificationset>

    <!-- Configures the actual build loop, how often and which build file/target -->
    <schedule interval="1800">
      <maven2 mvnscript="C:\tools\maven-2.0.7\bin\mvn.bat" pomfile="C:\projects\dev\myproject\pom.xml" goal="scm:update | clean test">
          <property name="VIEW_HOME" value="C:\projects\dev"/>
          .... other properties to pass to maven ...
      </maven2>
    </schedule>

     <log dir="logs/myproject" encoding="UTF-8">
    </log>

    <publishers>
        <currentbuildstatuspublisher file="logs/myproject/buildstatus.txt"/>
        <artifactspublisher dir="checkout/myproject/report" dest="artifacts/myproject"/>

        <htmlemail mailhost="mailserver.yourcompany.com"
                returnaddress="buildmanager@yourcompany.com"
                reportsuccess="fixes"
                subjectprefix="myproject Build Results"
                buildresultsurl="http://yourcompany.com:12000/cruisecontrol/buildresults/myproject"
                skipusers="false" spamwhilebroken="false"
                css="webapps/cruisecontrol/css/cruisecontrol.css"
                xsldir="webapps/cruisecontrol/xsl"
                logdir="logs/myproject">
                        <success address="devmailinglist@yourcompany.com"/>
                        <failure address="devmailinglist@yourcompany.com"/>
        </htmlemail>
    </publishers>

  </project>

I am not going to explain the file in any detail. Things should be self-explanatory. With Maven I needed to do one more addition to my pom.xml

<scm>
      <connection>scm:clearcase:load c:/projects/dev</connection>
</scm>

Hopefully this helps someone out there. To give credit where credit is due. I did find Simon's Blog entry helpful.
----- EXTENDED BODY: ----- EXCERPT: Recently I set up CruiseControl with ClearCase. While there are a few postings around the blogosphere that cover some of this, I thought I'd blog it here also. More information, the better is for others to find it. ----- KEYWORDS: ----- COMMENT: AUTHOR: GJR EMAIL: jithendra.ganji@wellsfargo.com IP: 151.151.21.104 URL: DATE: 8/7/2007 11:29:03 PM Articles are very helpful. ----- COMMENT: AUTHOR: qmqarkvs EMAIL: tjomboth@jpvjqgya.com IP: 209.61.210.9 URL: http://ekpyfxnm.com DATE: 2/2/2008 10:17:58 PM lqszyxzu [URL=http://vnddwnaq.com]vkytxnxv[/URL] mveegsws http://cqcoswrz.com zanofnot zgvcgsrx ----- COMMENT: AUTHOR: UzRuby EMAIL: UzRuby@unique-papers.com IP: 193.41.184.129 URL: http://www.bestwritingservice.com DATE: 1/15/2010 3:30:00 PM The essays written just about this good post finishing is a really complicated deal, but if you are not a great master, you have got a chance to find the data close to already written essays in the essay writing service very easily. ----- COMMENT: AUTHOR: RochaClaire20 EMAIL: kemberlyhernandez@mail15.com IP: 91.201.66.6 URL: DATE: 8/16/2010 6:08:35 PM When you're in ucomfortable position and have got no cash to move out from that, you would need to receive the mortgage loans. Just because that should aid you emphatically. I take sba loan every time I need and feel great just because of that. ----- COMMENT: AUTHOR: srini EMAIL: srinivasarao.gurram@gmail.com IP: 124.123.186.62 URL: DATE: 8/21/2010 12:59:50 PM Hi,
I would like to know if any clearcase tool i need to install to check out the file using cruise control ----- COMMENT: AUTHOR: Slama Pofer EMAIL: mex3@farm123.com IP: 118.160.27.146 URL: DATE: 8/23/2010 6:38:07 AM I love your post , Its make me alwayscome back to read your new post,
of cause I also read your old post as this one ,徵信社還有婚前徵信以及花蓮民宿跟一些徵信的服務 ----- COMMENT: AUTHOR: computer services westchester EMAIL: seopcwest@gmail.com IP: 208.83.63.219 URL: DATE: 10/2/2010 7:03:18 AM I am really enjoying this content here ----- COMMENT: AUTHOR: posizionamento su google EMAIL: seopcwest@gmail.com IP: 209.222.133.189 URL: DATE: 10/2/2010 4:27:33 PM In many ways this blog helps figure out the solution to many problems ----- COMMENT: AUTHOR: Kyani EMAIL: kyani.spencer@gmail.com IP: 85.225.102.1 URL: DATE: 12/27/2010 1:21:12 PM Wow!, this was a real quality post. In theory I'd like to write like this too - taking time and real effort to make a good article... but what can I say... I keep putting it off and never seem to get something done. ----- -------- AUTHOR: Mathew Thomas TITLE: XFire WebService With Spring STATUS: publish ALLOW COMMENTS: 1 ALLOW PINGS: 1 CATEGORY: web service DATE: 5/7/2007 7:34:00 PM ----- BODY: Tried setting up XFire with Spring and thought I'd share that experience. One more place to come for this information will not hurt ah!

Once again I used Maven to build my test application. At the bottom of this article you will find a download link for the entire application.

I have used Axis in the past and wanted to try out some other frameworks. At the same time I absolutely needed the framework to support JSR 181 (web service annotations), required the framework to integrate with Spring and relatively simple configuration. Oh also I did not want to write any WSDL. This example is an RPC based web service (unlike my previous article on document based web service with Spring-WS). I will after this article also start using Axis2, since I have been an Axis fan for many years.

JSR 181 is important to me. I think annotations are the right way to go for most simple tasks that do not require a lot of input. The web service annotations are good example about where annotations are the right fit. I have seen examples of annotations where it would be far easier and clearer to put it into the XML style configuration. Some folks are anti-annotations and I think that attitude is not the best. Use it where it makes the most sense.

Lets view the echo service java POJO code.
package com.aver;

public interface EchoService {
    public String printback(java.lang.String name);
}

package com.aver;

import java.text.SimpleDateFormat;
import java.util.Calendar;

import javax.jws.WebMethod;
import javax.jws.WebParam;
import javax.jws.WebResult;
import javax.jws.WebService;

@WebService(name = "EchoService", targetNamespace ="http://www.averconsulting.com/services/EchoService")
public class EchoServiceImpl implements EchoService {

    @WebMethod(operationName = "echo",action = "urn:echo")
    @WebResult(name = "EchoResult")
    public String printback(@WebParam(name ="text") String text) {
        if (text== null || text.trim().length() == 0) {
           return "echo: -please provide a name-";
        }
       SimpleDateFormat dtfmt = new SimpleDateFormat("MM-dd-yyyy hh:mm:ss a");
        return "echo: '" + text + "' received on " +dtfmt.format(Calendar.getInstance().getTime());
    }
}

As you can see above I have made liberal use of JSR 181 web service annotations.
Here is the web.xml.
<?xmlversion="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE web-app
    PUBLIC "-//Sun Microsystems, Inc.//DTDWeb Application 2.3//EN"
   "http://java.sun.com/dtd/web-app_2_3.dtd">
<web-app>
    <context-param>
       <param-name>contextConfigLocation</param-name>
       <param-value>
          classpath:org/codehaus/xfire/spring/xfire.xml
          /WEB-INF/xfire-servlet.xml
       </param-value>
    </context-param>

    <listener>
       <listener-class>
          org.springframework.web.context.ContextLoaderListener
       </listener-class>
    </listener>

    <servlet>
       <servlet-name>XFireServlet</servlet-name>
       <servlet-class>
          org.codehaus.xfire.spring.XFireSpringServlet
       </servlet-class>
    </servlet>
    <servlet-mapping>
       <servlet-name>XFireServlet</servlet-name>
       <url-pattern>/servlet/XFireServlet/*</url-pattern>
    </servlet-mapping>
    <servlet-mapping>
       <servlet-name>XFireServlet</servlet-name>
       <url-pattern>/services/*</url-pattern>
    </servlet-mapping>
</web-app>

The web.xml configures the 'XFireSpringServlet' and sets up the Spring listener. Straightforward.

Finally here is the xfire-servlet.xml (this is our spring configurationfile).
 
<?xmlversion="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   xsi:schemaLocation="http://www.springframework.org/schema/beans
">www.springframework.org/schema/beans/spring-beans-2.0.xsd">

    <bean id="webAnnotations"
       class="org.codehaus.xfire.annotations.jsr181.Jsr181WebAnnotations"/>

    <bean id="jsr181HandlerMapping"xfire_echo.jar

       class="org.codehaus.xfire.spring.remoting.Jsr181HandlerMapping">
       <property name="typeMappingRegistry">
           <refbean="xfire.typeMappingRegistry" />
       </property>
       <property name="xfire" ref="xfire" />
       <property name="webAnnotations" ref="webAnnotations" />
    </bean>

    <bean id="echo"class="com.aver.EchoServiceImpl" />
</beans>
That is it. Build and deploy this and you should see the WSDL at http://localhost:9090/echoservice/services/EchoServiceImpl?wsdl.

Click here to download the Maven based project code. To build run:

----- EXTENDED BODY: ----- EXCERPT: Tried setting up XFire with Spring and thought I'd share that experience. One more place to come for this information will not hurt ah! ----- KEYWORDS: ----- COMMENT: AUTHOR: software development london EMAIL: william@geeksltd.co.uk IP: 86.178.81.197 URL: http://www.geeks.ltd.uk/Services.html DATE: 10/7/2009 12:23:50 PM That was an inspiring post,

easy and clear to understand, great

Thanks for writing about it ----- -------- AUTHOR: Mathew Thomas TITLE: Spring-WS STATUS: publish ALLOW COMMENTS: 1 ALLOW PINGS: 1 CATEGORY: web service DATE: 5/6/2007 11:34:00 PM ----- BODY: Took a look at Spring-WS and came up with a quick example service to describe its use. I decided to build an 'echo' service. Send in a text and it will echo that back with a date and time appended to the text.

After building the application I saw that Spring-WS comes with a sample echo service application. Oh well. Since I put in the effort here is the article on it.

Spring-WS encourages document based web services. As you know there are mainly two types of web services:
In RPC you think in terms of traditional functional programming. You decide what operations you want and then use the WSDL to describe the operations and then implement them. If you look at any RPC based WSDL you will see in the binding section the various operations.

In the document based approach you no longer think of operations (their parameters and return types). You decide on what XML document you want to send in as input and what XML document you want to return from your web service as a response.

Spring-WS encourages a more practical approach to designing document based web services. Rather than think WSDL, it pushes you to think XSD (or the document schema) and then Spring-WS can auto-generate the WSDL from the schema.

Lets break it up into simpler steps:
  1. Create your XML schema (.xsd file). Inside the schema you will create your request messages and response messages. Bring up your favorite schema edit or to create the schema or write sample request and response XML and then reverse-engineer the schema (check if your tool supports it).
  2. You have shifted the focus onto the document (or the XML). Now use Spring-WS to point to the XSD and set up a few Spring managed beans and soon you have the web service ready. No WSDL was ever written.
Spring-WS calls this the contract-first approach to building web services.

Lets see the echo service in action. You will notice that I do not create any WSDL document throughout this article.

BusinessCase:
Echo service takes in an XML request document and returns an XML document with a response. The response contains the text that was sent in, appended with a timestamp.


RequestXML Sample:
<ec:EchoRequest>
<ec::Echo>
<ec:Name>Mathew</ec:Name>
</ec:Echo>
</ec:EchoRequest>

The schema XSD file for this can be found in the WEB-INF folder of the application (echo.xsd).


ResponseXML Sample:
<ec:EchoResponse>
<ec:EchoResponse>
<ec:Message>echoback: name Mathew received on 05-06-2007 06:42:08PM</ec:Message>
</ec:EchoResponse>
</ec:EchoResponse>

The schema XSD file for this can be found in the WEB-INF folder of the application (echo.xsd).

If you inspect the SOAP request and response you will see that this XML is whats inside the SOAP body. This is precisely what is document based web services.


EchoService Implementation:
Here is the echo service Java interface and its related implementation. As you can see this is a simple POJO.
package echo.service;

public interface EchoService {
public String echo(java.lang.String name);
}
package echo.service;

import java.text.SimpleDateFormat;
import java.util.Calendar;

public class EchoServiceImpl implements EchoService {

public String echo(String name) {
if (name == null || name.trim().length() == 0) {
return "echo back: -please provide a name-";
}
SimpleDateFormat dtfmt = new SimpleDateFormat("MM-dd-yyyy hh:mm:ss a");
return "echo back: name " + name + " received on "
+ dtfmt.format(Calendar.getInstance().getTime());
}

}


Now the Spring-WS stuff:

Here is the web.xml..
    <display-name>Echo Web Service Application</display-name>

<servlet>
<servlet-name>spring-ws</servlet-name>
<servlet-class>org.springframework.ws.transport.http.MessageDispatcherServlet</servlet-class>
</servlet>

<servlet-mapping>
<servlet-name>spring-ws</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>


Only thing to note in the web.xml is the Spring-WS servlet.

Next is the all important Spring bean configuration XML (spring-ws-servlet.xml).
    <bean id="echoEndpoint" class="echo.endpoint.EchoEndpoint">
<property name="echoService"><ref bean="echoService"/></property>
</bean>

<bean id="echoService" class="echo.service.EchoServiceImpl"/>

<bean class="org.springframework.ws.server.endpoint.mapping.PayloadRootQNameEndpointMapping">
<property name="mappings">
<props>
<prop key="{http://www.averconsulting.com/echo/schemas}EchoRequest"
>echoEndpoint</prop>
</props>
</property>
<property name="interceptors">
<bean
class="org.springframework.ws.server.endpoint.interceptor.PayloadLoggingInterceptor"
/>
</property>
</bean>

<bean id="echo" class="org.springframework.ws.wsdl.wsdl11.DynamicWsdl11Definition">
<property name="builder">
<bean
class="org.springframework.ws.wsdl.wsdl11.builder.XsdBasedSoap11Wsdl4jDefinitionBuilder">
<property name="schema" value="/WEB-INF/echo.xsd"/>
<property name="portTypeName" value="Echo"/>
<property name="locationUri" value="http://localhost:9090/echoservice/"/>
</bean>
</property>
</bean>

Finally here is the endpoint class. This is the class, as previously stated, that gets the request XML and can handle the request from there.
package echo.endpoint;

import org.jdom.Document;
import org.jdom.Element;
import org.jdom.Namespace;
import org.jdom.output.XMLOutputter;
import org.jdom.xpath.XPath;
import org.springframework.ws.server.endpoint.AbstractJDomPayloadEndpoint;

import echo.service.EchoService;

public class EchoEndpoint extends AbstractJDomPayloadEndpoint {
private EchoService echoService;

public void setEchoService(EchoService echoService) {
this.echoService = echoService;
}

protected Element invokeInternal(Element request) throws Exception {
// ok now we have the XML document from the web service request
// lets system.out the XML so we can see it on the console (log4j
// latter)
System.out.println("XML Doc >> ");
XMLOutputter xmlOutputter = new XMLOutputter();
xmlOutputter.output(request, System.out);

// I am using JDOM for my example....feel free to process the XML in
// whatever way you best deem right (jaxb, castor, sax, etc.)

// some jdom stuff to read the document
Namespace namespace = Namespace.getNamespace("ec",
"http://www.averconsulting.com/echo/schemas");
XPath nameExpression = XPath.newInstance("//ec:Name");
nameExpression.addNamespace(namespace);

// lets call a backend service to process the contents of the XML
// document
String name = nameExpression.valueOf(request);
String msg = echoService.echo(name);

// build the response XML with JDOM
Namespace echoNamespace = Namespace.getNamespace("ec",
"http://www.averconsulting.com/echo/schemas");
Element root = new Element("EchoResponse", echoNamespace);
Element message = new Element("Message", echoNamespace);
root.addContent(message);
message.setText(msg);
Document doc = new Document(root);

// return response XML
System.out.println();
System.out.println("XML Response Doc >> ");
xmlOutputter.output(doc, System.out);
return doc.getRootElement();
}
}
This is a simple class. Important point to note is that it extends 'AbstractJDomPayloadEndpoint'. The 'AbstractJDomPayloadEndpoint' class is a helper that gives you the XML payload as a JDom object. There are similar classes built for SAX, Stax and others. Most of the code above is reading the request XML using JDOM API and parsing the data out so that we may provide it to our echo service for consumption.

Finally I build a response XML document to return and thats it.

Download the sample Application:
Click here to download the jar file containing the application. The application is built using Maven. If you do not have Maven please install it. Once Maven is installed run the following commands:
  1. mvn package (this will generate the web service war file in the target folder).
  2. mvn jetty:run (this will bring up Jetty and you can access the wsdl at http://localhost:9090/echoservice/echo.wsdl.
  3. Finally use some web service accessing tool like the eclipse plug-in soapUI to invoke the web service.
As you can see this is relatively simple. Spring-WS supports the WS-I basic profile and WS-Security. I hope to look at the WS-Security support sometime soon. Also interesting to me is the content based routing feature. This lets you configure which object gets the document based on the request XML content. We did the QName based routing in our example but the content based parsing is of greater interest to me.

While I could not find a roadmap for Spring-WS, depending on the features it starts supporting this could become a very suitable candidate for web service integration projects. Sure folks will say where is WS-Transactions and all of that, but tell me how many others implement that. I think if Spring-WS grows to support 90% of what folks need in integration projects then it will suffice. ----- EXTENDED BODY: ----- EXCERPT: Took a look at Spring-WS and came up with a quick example service to describe its use. I decided to build an 'echo' service. Send in a text and it will echo that back with a date and time appended to the text. ----- KEYWORDS: ----- COMMENT: AUTHOR: Arjen Poutsma EMAIL: apoutsma@interface21.com IP: 62.216.10.8 URL: http://blog.springframework.com/arjen/ DATE: 5/7/2007 11:08:16 AM Nice post!

With regard to content transformation: did you see the PayloadTransformingInterceptor?
http://static.springframework.org/spring-ws/site/apidocs/org/springframework/ws/server/endpoint/interceptor/PayloadTransformingInterceptor.html ----- COMMENT: AUTHOR: gnic EMAIL: IP: 151.70.91.56 URL: DATE: 5/26/2007 7:21:34 PM nice! but do not stop, continue please. deep-into- ----- COMMENT: AUTHOR: Christ Steel EMAIL: csteel@fortmoon.com IP: 71.171.90.228 URL: http://www.fortmoon.com DATE: 6/11/2007 4:20:07 PM Great article. It was very precise and gave a good step-by-step approach to building document based web services with Spring WS. ----- COMMENT: AUTHOR: Alex EMAIL: IP: 193.24.34.77 URL: DATE: 7/4/2007 8:35:07 AM nice post, helps a lot - thanks. ----- COMMENT: AUTHOR: hydfyayo EMAIL: thgknkqu@honvcebb.com IP: 68.104.210.5 URL: http://oevmamcg.com DATE: 11/9/2007 7:07:34 AM [URL=http://ufdhglms.com]gregfauj[/URL] mdnloyzn ypkswrhj http://yaqcpwvz.com wyawzqsj vejkjbrl ----- COMMENT: AUTHOR: Victor EMAIL: upyaya@gmail.com IP: 210.22.158.133 URL: DATE: 12/20/2007 3:39:52 AM Hi, when i try your sample, i face some problems, would u please help me out?

I can follow the case to publish a wsdl, then i use axis to generate the wsdl file and try to invoke the service, but occurs some errors, i am not sure the root cause. i just place the trace log here.

Exception in thread "main" AxisFault
faultCode: {http://schemas.xmlsoap.org/soap/envelope/}Server.userException
faultSubcode:
faultString: org.xml.sax.SAXParseException: Attribute "echo" bound to namespace "http://www.w3.org/2000/xmlns/"">http://www.w3.org/2000/xmlns/" was already specified for element "echo:EchoResponse".
faultActor:
faultNode:
faultDetail:
{http://xml.apache.org/axis/}stackTrace:org.xml.sax.SAXParseException: Attribute "echo" bound to namespace "http://www.w3.org/2000/xmlns/"">http://www.w3.org/2000/xmlns/" was already specified for element "echo:EchoResponse".
at com.sun.org.apache.xerces.internal.util.ErrorHandlerWrapper.createSAXParseException(Unknown Source)
at com.sun.org.apache.xerces.internal.util.ErrorHandlerWrapper.fatalError(Unknown Source)
at com.sun.org.apache.xerces.internal.impl.XMLErrorReporter.reportError(Unknown Source)
at com.sun.org.apache.xerces.internal.impl.XMLErrorReporter.reportError(Unknown Source)
at com.sun.org.apache.xerces.internal.impl.XMLNSDocumentScannerImpl.scanStartElement(Unknown Source)
at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl$FragmentContentDispatcher.dispatch(Unknown Source)
at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl.scanDocument(Unknown Source)
at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(Unknown Source)
at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(Unknown Source)
at com.sun.org.apache.xerces.internal.parsers.XMLParser.parse(Unknown Source)
at com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.parse(Unknown Source)
at javax.xml.parsers.SAXParser.parse(Unknown Source)
at org.apache.axis.encoding.DeserializationContext.parse(DeserializationContext.java:227)
at org.apache.axis.SOAPPart.getAsSOAPEnvelope(SOAPPart.java:696)
at org.apache.axis.Message.getSOAPEnvelope(Message.java:435)
at org.apache.axis.handlers.soap.MustUnderstandChecker.invoke(MustUnderstandChecker.java:62)
at org.apache.axis.client.AxisClient.invoke(AxisClient.java:206)
at org.apache.axis.client.Call.invokeEngine(Call.java:2784)
at org.apache.axis.client.Call.invoke(Call.java:2767)
at org.apache.axis.client.Call.invoke(Call.java:2443)
at org.apache.axis.client.Call.invoke(Call.java:2366)
at org.apache.axis.client.Call.invoke(Call.java:1812)
at org.upyaya.www.echo.schemas.EchoBindingStub.echo(EchoBindingStub.java:178)
at org.upyaya.www.echo.schemas.EchoProxy.echo(EchoProxy.java:45)
at client.Client.main(Client.java:19)

{http://xml.apache.org/axis/}hostname:wteng

any suggestion or hint?

Thanks a billion. ----- COMMENT: AUTHOR: prashanth EMAIL: kprborn2win@yahoo.com IP: 67.168.55.74 URL: DATE: 2/5/2008 7:51:25 AM very concise explanation.Keep posting!..thnx ----- COMMENT: AUTHOR: xkgaowyc EMAIL: qdrvttpp@irawqxmo.com IP: 18.246.2.33 URL: http://iiwzkjkz.com DATE: 2/16/2008 1:57:25 PM xocdimgm http://hxpeqvmp.com vmxitjzw mvctzfdf ccpaaanr [URL=http://ylnlwinb.com]idtghwur[/URL] ----- COMMENT: AUTHOR: JB EMAIL: jrabbitb@gmail.com IP: 67.153.175.162 URL: DATE: 4/30/2008 9:35:47 PM Very nice, first maven project in a tutorial that actually worked first try for me. would like to see a sample of functional client code or a link to how to use soapUI. I'm very new to spring-ws so the little things tripping me up are the worst. Thanks for this great tutorial! ----- COMMENT: AUTHOR: Noomi EMAIL: prakart@gmail.com IP: 210.4.138.40 URL: DATE: 5/15/2008 9:30:05 AM Can anyone tell me, please ???

I found an error message after download ing a source-code. I used soap-ui 2.0.2 to test by sending a request to http://localhost:8080/echoservice ..

### a request message generated by Soap-ui program ###






Halo





### a response message ####
Apache Tomcat/5.5.23 - Error report HTTP Status 500 - type Exception reportmessage description The server encountered an internal error () that prevented it from fulfilling this request.exception org.springframework.web.util.NestedServletException: Request processing failed; nested exception is java.lang.NoClassDefFoundError: org/jaxen/JaxenException
org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:473)
org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:426)
javax.servlet.http.HttpServlet.service(HttpServlet.java:710)
javax.servlet.http.HttpServlet.service(HttpServlet.java:803)
root cause java.lang.NoClassDefFoundError: org/jaxen/JaxenException
java.lang.Class.forName0(Native Method)
java.lang.Class.forName(Unknown Source)
org.jdom.xpath.XPath.newInstance(XPath.java:134)
echo.endpoint.EchoEndpoint.invokeInternal(EchoEndpoint.java:33)
org.springframework.ws.server.endpoint.AbstractJDomPayloadEndpoint.invoke(AbstractJDomPayloadEndpoint.java:47)
org.springframework.ws.server.endpoint.adapter.PayloadEndpointAdapter.invoke(PayloadEndpointAdapter.java:48)
org.springframework.ws.server.MessageDispatcher.dispatch(MessageDispatcher.java:221)
org.springframework.ws.server.MessageDispatcher.receive(MessageDispatcher.java:168)
org.springframework.ws.transport.support.WebServiceMessageReceiverObjectSupport.handleConnection(WebServiceMessageReceiverObjectSupport.java:88)
org.springframework.ws.transport.http.WebServiceMessageReceiverHandlerAdapter.handle(WebServiceMessageReceiverHandlerAdapter.java:57)
org.springframewor ----- COMMENT: AUTHOR: Ram EMAIL: libran.ram@gmail.com IP: 203.144.48.7 URL: DATE: 6/17/2008 11:58:26 AM Hi I am very new to this Spring WS Stuff. I have few questions.

If I want to publish a service like GreetingService and I have 2 services in that say "hello" & "sayHi". Both services returns some response.
Now,

1) Do I need to define the input & output type of both the services in the XSD? If yes, how?

2) Do I need to have a seperate EndPoint Classes to handle the requests, if the services takes different inputs. As I can see an Endpoint class is invoking the actual business service.

3) And the generated WSDL does not show the actual operation name provided? Why?

Any guidance is appreciated.

Thanks,
Ram ----- COMMENT: AUTHOR: Shiv EMAIL: techshiv@gmail.com IP: 74.2.28.130 URL: DATE: 8/4/2008 3:11:55 PM Great article. It was very useful. Thank you. ----- COMMENT: AUTHOR: Levent EMAIL: ltutar@xebia.com IP: 145.222.55.66 URL: DATE: 8/21/2008 11:44:55 AM nice post. mapping /* to spring-ws will not handle index.html anymore.
How can I overcome this problem? ----- COMMENT: AUTHOR: McCatney EMAIL: muralib12@gmail.com IP: 203.78.214.5 URL: DATE: 2/10/2009 3:32:06 PM thanks Mathew,
g8 Article on Spring-WS.
but, it was written in 2007. is there any improvements or new features had been added in the past 2 years?

if the above process had been automatted using Eclipse plug-ins it would be greate helpful. please post related links.
thanks,
McCatney ----- COMMENT: AUTHOR: Bob EMAIL: bob.milstead@gmail.com IP: 201.222.2.214 URL: DATE: 6/2/2009 11:30:26 PM Yes, great post. Near the end you say: "Spring-WS supports the WS-I basic profile and WS-Security. I hope to look at the WS-Security support sometime soon." I would love to see an example showing spring ws with ssl using x509 certs. Either wssj or xwss. ----- COMMENT: AUTHOR: Mathew Thomas EMAIL: mattazoid@gmail.com IP: 72.86.34.45 URL: DATE: 6/8/2009 1:03:35 AM Bob, I do want to try them out... the last time I tried it with xfire (i think) i got a headache.
----- COMMENT: AUTHOR: Anonymous EMAIL: IP: 203.153.210.6 URL: DATE: 6/30/2009 9:57:44 AM Great post ... did not find anything as simple as this anywhr.. great wrk ----- COMMENT: AUTHOR: Arul EMAIL: IP: 174.96.110.231 URL: DATE: 1/11/2010 5:09:54 AM Nice work.. ----- COMMENT: AUTHOR: pdGwen EMAIL: pdGwen@unique-papers.com IP: 193.41.184.142 URL: http://www.exclusivethesis.com DATE: 1/24/2010 7:55:53 PM It requires big efforts and time to accomplish the mini dissertation just about this good post, therefore, I prefer to select the dissertation writing service to get the PhD degree. ----- COMMENT: AUTHOR: Kco EMAIL: castudillo@gmail.com IP: 190.45.43.113 URL: http://castudillob.wordpress.com DATE: 4/24/2010 11:43:54 PM Awesome, thanks man!!!

Jboss give me some problems but with a few changes this code works!!!

Thanks a lot again!!! ----- COMMENT: AUTHOR: mano EMAIL: mano_garan@hotmail.com IP: 38.111.99.139 URL: DATE: 5/9/2010 8:24:03 PM It is really great example. i was able to set it up in JBoss and run.
Please include the following details in your article.

" +
"" +
"Mathew" +
"" +
"";
private final WebServiceTemplate webServiceTemplate = new WebServiceTemplate();

public void setDefaultUri(String defaultUri) {
webServiceTemplate.setDefaultUri(defaultUri);
}

// send to the configured default URI
public void simpleSendAndReceive() {
StreamSource source = new StreamSource(new StringReader(MESSAGE));
StreamResult result = new StreamResult(System.out);
webServiceTemplate.sendSourceAndReceiveToResult(source, result);
}

// send to an explicit URI
public void customSendAndReceive() {
StreamSource source = new StreamSource(new StringReader(MESSAGE));
StreamResult result = new StreamResult(System.out);
webServiceTemplate.sendSourceAndReceiveToResult("http://localhost:11097/echoservice"">http://localhost:11097/echoservice",
source, result);
}

public static void main(String args[]){

WebServiceClient loWebServiceClient = new WebServiceClient();
loWebServiceClient.setDefaultUri("http://localhost:11097/echoservice"">http://localhost:11097/echoservice");
loWebServiceClient.customSendAndReceive();

}

} ----- COMMENT: AUTHOR: dwayne EMAIL: dwaynelu@yahoo.com IP: 71.164.240.4 URL: DATE: 7/4/2010 8:03:43 PM what's difference if you use DOM insteadl of JDOM? Please advice ----- COMMENT: AUTHOR: Leah29Blankenship EMAIL: christinatorres@mail15.com IP: 91.201.66.6 URL: DATE: 8/16/2010 7:35:00 AM That's good that people are able to get the credit loans moreover, this openscompletely new possibilities. ----- COMMENT: AUTHOR: Shameer EMAIL: sameerean@yahoo.co.in IP: 86.96.227.89 URL: DATE: 9/29/2010 1:14:40 PM Just wanted to share related post with the topic, Building a web service with Spring-WS at

http://juscompiled.blogspotcom/2010/09/building-web-service-with-spring-ws.html

Thanks ----- COMMENT: AUTHOR: Prabhanjan EMAIL: prabhanjanbabub@gmail.com IP: 121.241.47.200 URL: DATE: 10/7/2010 5:22:22 AM I amcompletely new to Webservice can u send me the steps and code using springs
prabhanjanbabub@gmailcom ----- COMMENT: AUTHOR: WikiFunna EMAIL: mrsyctix@msn.com IP: 91.76.244.203 URL: DATE: 12/16/2010 4:30:58 PM How I can download documents from WikiLeaks?
Thanks ----- COMMENT: AUTHOR: Free Movies EMAIL: yourmail@gmail.com IP: 91.201.67.12 URL: DATE: 1/1/2011 6:34:48 PM Hi [url=http://wwwwatchmovieoncom/]Watch Movies[/url] genres :
FANTASY
THRILLER
HISTORY
DOCUMENTARY
HISTORY
BIOGRAPHY

Only here You can watch [url=http://wwwwatchmovieoncom/]Online Movies[/url] Absolutelly Free ----- COMMENT: AUTHOR: ProSteerGroup EMAIL: prosteergroup@mail.ru IP: 61.145.121.124 URL: DATE: 1/5/2011 2:52:19 PM Wecome

It`s me, Mario

Look prosteergroupcom ----- COMMENT: AUTHOR: AttingKic EMAIL: ErendLeavedge@myspace-de.info IP: 91.201.66.154 URL: DATE: 1/7/2011 1:08:54 PM Use Of Flowers In Medicine [url=http://wwwbwchart.net/]cheapest temazepam[/url] Restoril is an intermediate acting 3 hydroxy benzodiazepine. http://wwwbwchart.net/ - temazepam medication ----- COMMENT: AUTHOR: FlesePeedia EMAIL: sesyPriellcix@tampagoldenedge.info IP: 213.5.67.185 URL: DATE: 1/7/2011 10:07:20 PM Imperforate Anus Medication http://wwwaunaturelbabycom/ - ciprofloxacin online If you are thinking about using Cipro or any other drugs of the same kind then speaking with your doctor is the first step to getting better. [url=http://wwwaunaturelbabycom/]generic ciprofloxacin[/url] ----- COMMENT: AUTHOR: Florgeglasoca EMAIL: Foevynosy@visit4pls.info IP: 213.5.67.4 URL: DATE: 1/8/2011 2:00:35 AM Bi M Medicine Hat http://nextlevelkidzcom/ - order complia online This is not helped by television and other media. [url=http://nextlevelkidzcom/]buy generic complia[/url] ----- COMMENT: AUTHOR: beipleWalialo EMAIL: metizorel@rambler.ru IP: 195.78.60.1 URL: DATE: 1/9/2011 7:39:36 AM Производство и поставка - северсталь метиз орел производства Северсталь метиз ОСПАЗ со склада в г.Орел.
Продажа таблица метизов оптом и в розницу по низким ценам.
Полный каталог всей [url=http://wwwmetizorel.ru/karta.html]метизной продукции[/url], описания, характеристики, ГОСТы и технические условия.
Предлагаем Вам купить метизы и метизную продукцию из наличия оптом. Офоррление заказа и доставка в сжатые сроки.
Возможна отгрузка железнодорожным транспортом. Цены производителя. ----- COMMENT: AUTHOR: Mariabeegatty EMAIL: Foevynosy@visit4pls.info IP: 213.5.67.4 URL: DATE: 1/9/2011 4:06:51 PM Definition Of Aggravated Drug Trafficking [url=http://susanbrown4regentcom/]nizoral no prescription[/url] Patients should discuss side effects with their doctor as they occur. http://susanbrown4regentcom/ - yeast infection diflucan ----- COMMENT: AUTHOR: EMATASCAGMAWN EMAIL: ErendLeavedge@myspace-de.info IP: 91.201.66.154 URL: DATE: 1/10/2011 6:23:35 AM Alcohol Addiction Medication http://wwwjustkitchencabinetcom/ - generic lexapro online Severe depression isn?t going to go away on its own and there is really not much that can be done to help it without using medication. [url=http://wwwjustkitchencabinetcom/]escitalopram online[/url] ----- COMMENT: AUTHOR: apporcege EMAIL: daitydaiting@mail.ru IP: 91.201.66.152 URL: DATE: 1/10/2011 10:54:09 AM Знакомства для одиноких парней и девушек, которые хотят
найти себе партнера на одну ночь или на всю жизнь
УСТАЛИ ОТ ОДИНОЧЕСТВА ? [url=http://ruxxx4dating.ru]ЗАРЕГИСТРИРУЙТЕСЬ ![/url]
НАЙДИТЕ ПАРТНЕРА ДЛЯ СЕКСА ФАНТАЗИЙ ОБМЕНА ЭРО ФОТО!
Тысячи парней и девушек уже нашли друг друга у нас на сайте!
Найди и ты свою вторую половину! После регистрации, Вам будет
доступна возможность переписываться, обмениваться фото, назначать
встречи и смотреть видео трансляции наших участников.
Толькое реальные анкеты и никакой рекламы!
[url=http://ruxxx4dating.ru][img]http://ruxxx4dating.ru/foto/1.jpg[/img][/url][url=http://ruxxx4dating.ru/foto/index.htm][img]http://ruxxx4dating.ru/foto/10.bmp[/img][/url]
[url=http://ruxxx4dating.ru/top100][img]http://ruxxx4dating.ru/foto/11.bmp[/img][/url] [url=http://ruxxx4dating.ru/top100][img]http://ruxxx4dating.ru/foto/5.bmp[/img][/url]



Сайт интим знакомств http://ruxxx4dating.ru - Найди партнера для регулярного секса, секса на 1-2 раза, или подругу жизни ----- COMMENT: AUTHOR: EMATASCAGMAWN EMAIL: ErendLeavedge@myspace-de.info IP: 91.201.66.154 URL: DATE: 1/11/2011 4:07:01 AM Blood Pressure Medication Alcohol http://wwwunitedbloodnationknowledge.net/ - buy accutane online If you feel that there is nothing that can be done for your acne, then go and see your dermatologist. [url=http://wwwunitedbloodnationknowledge.net/]purchase accutane online[/url] ----- COMMENT: AUTHOR: ValpDialago EMAIL: pujinsan@mail.ru IP: 113.109.73.160 URL: DATE: 1/11/2011 2:53:01 PM Merry Christmas! I very like your website. Hree [url=http://wwwjade-jewecom/jade-banglebangles-size57-to-59-81-p-4207.html] Exquisite jade earring[/url] Mabe u like. ----- COMMENT: AUTHOR: rapidshare file link EMAIL: jackjohnchange@gmail.com IP: 88.180.150.139 URL: DATE: 1/12/2011 3:46:17 AM I was downloading all the beyond mentioned search engines from identical network site. I had formated my PC and baffled the link. I lone tip that this web purlieus starts with Jetdll or [url=http://rapidgoodcom]rapidshare search [/url]. ----- COMMENT: AUTHOR: WamWougs EMAIL: uggboots2200@gmail.com IP: 50.22.140.2 URL: DATE: 1/12/2011 9:15:52 AM Ugg & Jimmy Choo Boots Mandah 3042 Black are the new arrival [url=http://wwwuggbootsuksale.org.uk/ugg-kids-boots.html]ugg kid boots
[/url] ugg boots.A myriad of silver and gold grommets,rivets and domed studding cover the entire black boot in glittering detail giving it a fashionable, graphic Jimmy Choo attitude. ----- COMMENT: AUTHOR: gendonep EMAIL: lnialniaciiasn@gmail.com IP: 50.22.140.2 URL: DATE: 1/13/2011 6:06:50 PM Microsoft Points Codes
Xbox Live Points is [url=http://wwwxbox360livepointscard.org/]free 360 points codes[/url]
measured by Microsoft Points which is the coin of the Xbox Live Marketplace realm. [url=http://wwwxbox360livepointscard.org/]xbox points 4200[/url]
Where to purchase xbox 360 live points quickly? xbox360livepointscard.us is your first choice [url=http://wwwxbox360livepointscard.org/xbox-live-points-about.html]get xbox live points free[/url] forcompetitive Price and Knight Service. [url=http://wwwxbox360livepointscard.org/]4200 microsoft points code[/url] It is not xbox live pre-paid code but Microsoft Points account.The Microsoft Points accounts on our website are US server.Currently,there are Xbox Points
[url=http://wwwxbox360livepointscard.org/]ms points xbox 360[/url]
4000 account,Xbox Points 6000 account,Xbox [url=http://wwwxbox360livepointscard.org/]xbox 360 live[/url]
Points 8000 account,Xbox Points 10000 account available on ours ----- COMMENT: AUTHOR: Terdgeonline EMAIL: terdgeonline@mail.ru IP: 46.147.6.248 URL: DATE: 1/14/2011 4:46:50 AM [url=http://wwwstep-two.ru/]My Blog[/url] http://wwwstep-two.ru/
[url=http://wwwpolprav.blogspotcom/]http://wwwpolprav.blogspotcom/[/url] http://wwwpolprav.blogspotcom/
[url=http://wwwlove-text.ru/]http://wwwlove-text.ru/[/url] http://wwwlove-text.ru/ ----- COMMENT: AUTHOR: Amburbera EMAIL: Teelsinfess@globevisionhouse.info IP: 213.5.66.16 URL: DATE: 1/14/2011 2:08:01 PM Josh Brown Sports Medicine [url=http://osnaproudlypresentscom/]buy cheap temazepam[/url] It began being used to treat insomnia in 1969. http://osnaproudlypresentscom/ - buy cheap temazepam ----- COMMENT: AUTHOR: aomaromep EMAIL: dou.g.h.ma.n.an.to.ne.fer.a.p@gmail.com IP: 91.201.66.31 URL: DATE: 1/20/2011 3:47:28 PM http://vezvnhsriptu.pbworkscom/adobe-creative-suite-5-design-premium-italiano adobe creative suite 5 design premium italiano
http://ddlonrcvlgrt.pbworkscom/autodesk-revit-structure-2010-32-And-64-bit autodesk revit structure 2010 32 And 64 bit
http://wxoevggkptme.pbworkscom/adobe-fireworks-cs4-review adobe fireworks cs4 review
http://ejjrlcpxcsfc.pbworkscom/adobe-flash-professional-cs5-student-And-teacher-edition-mac adobe flash professional cs5 student And teacher edition mac
http://eqllnejdznum.pbworkscom/adobe-indesign-cs5-student-and-teacher-edition-mac adobe indesign cs5 student and teacher edition mac
http://lksdtttcbkgj.pbworkscom/autodesk-revit-architecture-2011-la-grande-guida autodesk revit architecture 2011 la grande guida
http://dzwlllfvtfga.pbworkscom/autodesk-3ds-max-design-2010-32-And-64-bit autodesk 3ds max design 2010 32 And 64 bit
http://hlwtphttjidn.pbworkscom/adobe-contribute-cs4-software adobe contribute cs4 software
http://nqmhldatmkrp.pbworkscom/autodesk-autocad-lt-2011-slm autodesk autocad lt 2011 slm
http://lviviqfmewrl.pbworkscom/adobe-fireworks-cs4-beta adobe fireworks cs4 beta
http://lhywzjuamhag.pbworkscom/autodesk-autocad-lt-2011-prices autodesk autocad lt 2011 prices
http://nodpxbritscg.pbworkscom/adobe-elearning-suite-oem adobe elearning suite oem
http://weudawqfyrme.pbworkscom/adobe-creative-suite-5-design-premium-student-and-teacher-edition adobe creative suite 5 design premium student and teacher edition
http://vgkmkkeoldol.pbworkscom/adobe-creative-suite-4-web-premium-for-windows-full-version adobe creative suite 4 web premium for windows full version
http://lhjkantheeua.pbworkscom/adobe-creative-suite-4-web-premium-student-edition adobe creative suite 4 web premium student edition
http://qtghaipeheyv.pbworkscom/adobe-flash-catalyst-cs5 adobe flash catalyst cs5
http://btxqrkvajmoj.pbworkscom/adobe-flash-professional-cs5 adobe flash professional cs5
http://lhjkantheeua.pbworkscom/adobe-illustrator-cs4-for-mac adobe illustrator cs4 for mac
http://dzfnabtkcoeg.pbworkscom/acrobat-10 acrobat 10
http://rwxiicsptjbr.pbworkscom/adobe-dreamweaver-cs4-for-mac-os-x adobe dreamweaver cs4 for mac os x
http://weudawqfyrme.pbworkscom/autodesk-revit-structure-2011-update autodesk revit structure 2011 update
http://hdomacyvwffg.pbworkscom/autodesk-autocad-map-3d-2010-32-And-64-bit autodesk autocad map 3d 2010 32 And 64 bit
http://vidvbafuaxxp.pbworkscom/adobe-photoshop-cs4-extended adobe photoshop cs4 extended
http://qjcuxlxflirp.pbworkscom/adobe-flash-professional-cs5-for-mac adobe flash professional cs5 for mac
http://wxoevggkptme.pbworkscom/adobe-dreamweaver-cs4-revealed adobe dreamweaver cs4 revealed
http://llghgdtdbzqt.pbworkscom/adobe-flash-catalyst-cs5-classroom-in-a-book-cd adobe flash catalyst cs5 classroom in a book cd
http://yiafywoazjvq.pbworkscom/adobe-elearning-suite-oem adobe elearning suite oem
http://yzbqglhhfety.pbworkscom/autodesk-autocad-map-3d-2011-whats-new autodesk autocad map 3d 2011 whats new
http://rrsfmfoygxki.pbworkscom/autodesk-maya-2011-mac autodesk maya 2011 mac
http://pdfxjmhijkhr.pbworkscom/adobe-photoshop-lightroom-2-for-mac adobe photoshop lightroom 2 for mac ----- COMMENT: AUTHOR: affordableheal EMAIL: affordableheal754@gmail.com IP: 119.152.41.174 URL: DATE: 1/21/2011 9:56:16 AM Read about: [url=http://youraffordablehealthinsurance.org/health-insurance-with-pre-existing-conditions/]health insurance with pre[/url], [url=http://youraffordablehealthinsurance.org/health-insurance-with-pre-existing-conditions/]health insurance for preexisting conditions[/url], [url=http://youraffordablehealthinsurance.org/health-insurance-with-pre-existing-conditions/]health insurance with preexisting conditions[/url], [url=http://youraffordablehealthinsurance.org/health-insurance-with-pre-existing-conditions/]getting health insurance with preexisting conditions[/url], [url=http://youraffordablehealthinsurance.org/health-insurance-with-pre-existing-conditions/]health insurance for pre-existing conditions[/url], [url=http://wwwyouraffordablehealthinsurance.org/]affordable health insurance[/url], [url=http://wwwyouraffordablehealthinsurance.org/]buying affordable health insurance[/url], [url=http://wwwyouraffordablehealthinsurance.org/]CHEAP AFFORDABLE HEALTH INSURANCE[/url], [url=http://wwwyouraffordablehealthinsurance.org/]affordable full coverage family health insurance[/url], [url=http://wwwyouraffordablehealthinsurance.org/]CHEAP PRIVATE MEDICAL INSURANCE[/url], [url=http://wwwyouraffordablehealthinsurance.org/]CHEAP MEDICAL COVER[/url], [url=http://wwwyouraffordablehealthinsurance.org/]CHEAP HEALTH CARE INSURANCE[/url], [url=http://wwwyouraffordablehealthinsurance.org/]cheap family full coverage health insurance[/url], [url=http://wwwyouraffordablehealthinsurance.org/]private medical insurance[/url], [url=http://wwwyouraffordablehealthinsurance.org/]MEDICAL HEALTH COVER[/url], [url=http://wwwyouraffordablehealthinsurance.org/]cheap medical insurance[/url], [url=http://wwwyouraffordablehealthinsurance.org/]CHEAP temperary HEALTH INSURANCE[/url] ----- COMMENT: AUTHOR: Anonymous EMAIL: deloras9700@aol.com IP: 195.82.162.227 URL: DATE: 2/5/2011 11:23:17 PM Hi, i found this place on [url=http://wwwgcom]google[/url] and i enjoy it so far :) ----- -------- AUTHOR: Mathew Thomas TITLE: Being Agile with FDD Process STATUS: publish ALLOW COMMENTS: 1 ALLOW PINGS: 1 CATEGORY: Agile DATE: 3/7/2007 4:58:00 PM ----- BODY: Feature Driven Development (FDD)

There are so many development methodologies out there; each promising to solve our software development nightmares. Each promising to make software development easier. I will not even go on to suggest that there is any one or two methodologies that work.

The methodology you choose depends on:
Often I have worked with teams that follow home-grown methodologies that are lite and tuned to what that organization believes is the best way for them to get work done. Fair enough.

I worked on one project a while back that used the Feature Driven Development (FDD) agile process. Personally to me the success of a methodology depends on how simple it is to understand. Software development happens in three main areas: requirement gathering, coding it and testing. Everything else is done to support these three related tasks. FDD is a relatively simple process; which is what attracted me to it. And I am living proof that it worked when we used it. Though in hindsight we did not formally follow every step as prescribed.

So what is FDD. FDD is an agile iterative development process. The dictionary defines agile as 'moving quickly and lightly'. When you hear agile look for that meaning. If you look in your process and you do not see that then you are not in an agile process. Seems obvious ah! You need to change your mindset and work culture to fit agile. Organizations that are not agile often have difficulty moving towards agility. Then there are those that are agile since many years before the buzzword agile development even came along.

Being agile to me does not mean you do away with traditional requirements gathering procedures and mechanisms. You still have to gather detailed requiurements. I often see Ruby On Rails developers prescribe that framework as the framework to choose for agile development of web projects. Look up on that on your own. They have a childish view of the development world where there is no corporate politics, there is no need to gather requirements upfront (gather as you code...best of luck), the business users seem to have all the time to sit with the developers, etc. The real world is often quite different. Dont get me wrong. I like Ruby and Ruby On Rails. I think Java has a lot to learn from there.

FDD is divided into 5 main activities. Each activity encompasses a set of steps that seem so obvious in software development. It does not do away with requirements gathering or any other step. It just places them in the right activity. Here are the five activities and what I think are some of the things
One step I feel is missing is a 'Test By Feature'. This is so that the QA teams work can get recognized as a critical part of development and can be planned in advance.

----- EXTENDED BODY: ----- EXCERPT: Feature Driven Development (FDD). There are so many development methodologies out there; each promising to solve our software development nightmares. Each promising to make software development easier. ----- KEYWORDS: ----- COMMENT: AUTHOR: ohtohusi EMAIL: vjcchshq@pjihlxon.com IP: 199.245.188.72 URL: http://grrrlrqy.com DATE: 10/8/2007 8:18:47 AM xoyzkqat hzqoiixx http://tshghkwc.com mruwsrox deceuvck [URL=http://ysmjlvdl.com]lojkxnan[/URL] ----- COMMENT: AUTHOR: rrjzqgog EMAIL: krnqmsdy@rsmgqgxl.com IP: 12.47.45.72 URL: http://zxexefed.com DATE: 10/8/2007 8:28:00 AM xvjbuono http://cyghzcxz.com dxfcswfr tipfwefn sbmixato [URL=http://qolztzyk.com]ixdpaelz[/URL] ----- COMMENT: AUTHOR: htjjpsqn EMAIL: nlkkkamg@naxyxzix.com IP: 200.36.58.11 URL: http://jkerqlia.com DATE: 10/8/2007 8:31:48 AM ptwshsvx http://gjjlpnfs.com vrqudzhq becfgpdq aviisrdq [URL=http://mwlyrskw.com]vkkzkkyd[/URL] ----- COMMENT: AUTHOR: scrghhgy EMAIL: vpieicji@gydnbuvh.com IP: 199.245.188.72 URL: http://xbfjoigl.com DATE: 10/8/2007 8:35:11 AM jesqralz [URL=http://lhdedxix.com]efyxbhyp[/URL] rsuaebvp http://brfbxurr.com gfakqqur ssmohxyb ----- COMMENT: AUTHOR: duzgqujj EMAIL: zazuinrp@qwoiwkpi.com IP: 74.208.77.81 URL: http://nsdwgzmb.com DATE: 11/27/2007 6:03:03 PM pqxemumd ivgykriz http://tizmbwjk.com mhgpbhoj ngnwtxqj [URL=http://zsjsayfy.com]zbjiefpe[/URL] ----- -------- AUTHOR: Mathew Thomas TITLE: AJAX roundup STATUS: publish ALLOW COMMENTS: 1 ALLOW PINGS: 1 CATEGORY: AJAX DATE: 2/15/2007 11:41:00 AM ----- BODY: Recently I have been playing with various AJAX frameworks, both open source and commercial. For simple 'update a certain portion of the page only' type of applications you can roll up your sleeve and deal with the XMLHttpRequest (XHR) directly or use open source API's like prototype/dojo to simply make the call.

The real AJAX experience is achieved when you use the asynch call feature provided by XHR in combination with very rich GUI widgets to truly give your users a rich user experience on the web. This is where the challenge of AJAX lies. For too long developers (including myself) have used JavaScript to do very simple tasks. Keeping in-memory state on the browser was never a design detail. I think for long we have looked at JavaScript as a simple client side scripting language. On a recent project I used JavaScript in an 'object oriented way' using JSON to represent objects and actively manage user data in the browser. We had another JavaScript guru who whipped out a boatload of JavaScript widgets.  Hindsight being 20-20 we would have been better off with an open source or commercial framework. But 18 months back there were not too many good options. We did use the open source prototype library extensively.

Getting back to the main point I do not think a lot of the developer community realize how exciting the AJAX RIA development is going to be. I consider myself an end-to-end developer but often focused on backend. The backend stuff (with Spring, Hibernate, EJB, etc) is quite mature and the web 2.0 is where the excitement is. For those who are technologists it is where you want to at least spend some time. The web developers who create HTML pages of the traditional web 1.0 applications need to update their skills and approaches drastically to be successful in the web 2.0 world. Developers with OO language experience and at least basic JavaScript knowledge are very well positioned to do AJAX RIA development.

Like anything on the server side of things, the fun (or pain) aspect will be directly tied to the framework you use for AJAX RIA development. On the commercial side I looked at JackBe, Backbase and TIBCO General Interface. Each of them comes equipped with an IDE to do development. The most impressive IDE was TIBCO General Interface. You unzip the source and point your browser to one html file and voila you are in an IDE all within the browser. Pretty amazing when you realize they may have used many of their own components to build the IDE. Very similar situation with JackBe. The thing I did not like about JackBe was you need to start a tomcat instance and then point to that URL to get to your browser-based IDE. And also JackBe's components and API's were quite cryptic with 3 letter function names and no packaging of the various classes. Also various components were not feature rich. But I think as with any product they will evolve. As for the others, I looked at them and had mixed reactions. The real unknown to me about these commerical tools is; what will be my experience if I need to get out of the IDE and deal with the code directly. Thats where open source wins.

On the open source there is DOJO and YAHOO YUI. Both are very comparable in ease of use, features and widget support. Both have nicely packaged components. By packaging I mean Java like packaging of API's. Makes a developers life very easy. Where YUI wins outright is documentation. Its great. With dojo I have had to spend many hours pouring through various sites to get developer help. They have a manual and an API guide but somehow not enough or not up to the mark. Check out YUI docs and it makes any developer smile.

Then there are tools like Googles GWT and the open source Echo2 framework. Both of these allow you to build your web GUI using Java classes (like Swing). Of course the API's are not same as Swing. But with this you can now forget about building complex JavaScript and let these frameworks generate JavaScript and also map UI events to Java code. Very nice. Though I still think this is bleeding edge and little risky. But I would be game on trying this for small projects. Personally I think in the long term this is the best approach. Will that happen who knows. Right now these API's generate HTML and JavaScript. Tomorrow they can generate Flash content or even Swing. I think the possibilies are great. But only time will tell where this will go.

Note: I was quite amazed with TIBCO General Interfaces' support for Web Services. Take a look at that. The IDE can parse a WSDL and allows you to drag and drop form elements directly on WSDL elements to map them together.


----- EXTENDED BODY: ----- EXCERPT: Recently I have been playing with various AJAX frameworks, both open source and commercial. For simple 'update a certain portion of the page only' type of applications you can roll up your sleeve and deal with the XMLHttpRequest (XHR) directly or use open source API's like prototype/dojo to simply make the call. ----- KEYWORDS: ----- COMMENT: AUTHOR: Sudhakar EMAIL: sgubba33@hotmail.com IP: 63.251.87.214 URL: DATE: 2/16/2007 3:53:06 PM Great analysis Matt. Small suggestion, You may want to change title of article which catches attention and people will benefit out of your experience ----- COMMENT: AUTHOR: eemsrlub EMAIL: vwhfcfyq@kcwevlux.com IP: 61.246.2.80 URL: http://vusfdyzv.com DATE: 10/9/2007 8:26:22 AM euwssvlj tdiobdfl http://iaiqycly.com urbibgci jsagaegy [URL=http://kdkrvxfb.com]ixwwufiz[/URL] ----- COMMENT: AUTHOR: uxxbjydl EMAIL: wbakkmhg@pxgljpfd.com IP: 83.138.129.31 URL: http://lxyiewjh.com DATE: 10/9/2007 8:30:39 AM hojvqggz [URL=http://dbgpsomp.com]uqcbgdei[/URL] ryxhrnsx http://rpyssibv.com adbqmnrn shypnuoe ----- COMMENT: AUTHOR: ybmpazks EMAIL: xyhcdwlr@ddbnkdxj.com IP: 200.36.58.11 URL: http://rntzeihh.com DATE: 10/9/2007 8:34:42 AM [URL=http://yigrhihx.com]lubrruot[/URL] fsqrstld http://miczowgn.com hpeiocbk smtkcplb vvuegovu ----- -------- AUTHOR: Mathew Thomas TITLE: Maven STATUS: publish ALLOW COMMENTS: 1 ALLOW PINGS: 1 CATEGORY: Build Management DATE: 1/7/2007 4:22:00 AM ----- BODY: Can build management be made easier? Chances are whatever approach you take will have its own pitfalls and challenges. Many of the Java projects nowadays use Ant as the defacto build scripting tool. Its not too hard really. Can take a couple of days for a the Ant build file to be created (based on project needs). And subsequently it has to managed like any other source code. This approach works well. Most folks now know Ant well enough to get most tasks completed. Why then would anyone want to move to Maven!

Maven for starters makes it an easy task to manage your build file. Actually one step ahead ... it makes it easy to handle your project artifacts (code, folder structure, normal build lifecycle tasks, documentation, etc). It also plugs in with many other open source tools to get the job done through Maven. Still why Maven. Take a look at Maven Getting Started.

Now you realize how simple things could be. One can argue that we have moved some of the complexity into the pom.xml file (the project object model). There will be a small learning curve (almost insignificant) in understanding how to use maven. Still nothing that Ant cannot do.

With Ant you have to write a lot of script lines to get most work done. In maven you use plugins that are built to do specific tasks. Plugins will do tasks like compile, clean, package to correct distribution (ear, jar, etc) and so on. Even has a command to build a project site. There are a lot of plugins available. For example check AppFuse for some of its Maven plugins that are coming soon.

The power of Maven is that you can accomplish a lot by resusing plugins and not having to roll your own script every time you need something new.

That to me personally is the single biggest reason to use Maven. And I have not even mentioned dependency management yet. A lot of projects do not really need the kindof dependency management that tools like Maven provide. Maven lovers please do not bash me for saying this This feature can be really useful if your entire organization (or company) consolidates on using Maven or if you are on a project (or product development) where there is a high level of component reuse between developers and many of the components have multiple versions around. Developer A builds version 10 of a component and installs that into the Maven repository. Now others can use that as needed ot still rely on the old version till they need to move ahead.

Still if you are using Maven on a regular web application project no harm in using its dependeny management feature. Just remember to have a local repository on the network so that everyone can access the same repository and do check in the repository into your source control (subversion or cvs or whatever). Without Maven you would have colocated all of the libraries within your project folders and also checked them into source control. With Maven just because you have a central repository and no co-located libraries does not mean not checking in the libraries (in this case the repository).

Some of the features I like in Maven (other than the standard build lifecycle ones):
One feature worth mentioning is how you can divide your project into separate projects (each with its own POM) and then have a top level Maven project (with its own pom.xml) that builds everything and merges dependencies between the two. Consider the scenario where you have a web application. You have all the web tier code (jsp, servlet, mvc, javascript, etc). You also have the service tier or the business tier. I would divide the two into separate independent projects, so that developers can work on them independently.

Here is how the directory structure looks like:
MyBigApp
    |
    |-- pom.xml
|
    |-- servicetier
    |       |-- pom.xml
|
    |-- webtier
    |       |-- pom.xml
|

Now you can use the top level pom to build the whole project. You can set the webtier project to pull in the dependent libraries from the servicetier project. Refer to the earlier link above to Maven quickstart. They have a sample of how to configure this.

On a recent project we tried this exact same thing using Ant. The subprojects would work just fine if you built them separately. If we used the top level Ant script we ran into some painful classpath issues. We gave up pretty soon as we were running out of time and in the end merged the two Ant files into one big one. Had we used Maven from day 1 we would have been in better shape. Which brings me to my final point. Try to use Maven from day 1. That way you can adhere to the folder structures that Maven generates by default. Retrofitting Maven into an existing project may not be a fun task. Also early on you will have to spend some extra time configuring Maven for the first time and generating a quick handy-dandy list of commands that developers (incl you) need on a daily basis.
----- EXTENDED BODY: ----- EXCERPT: Can build management be made easier? Chances are whatever approach you take will have its own pitfalls and challenges. ----- KEYWORDS: ----- -------- AUTHOR: Mathew Thomas TITLE: JMX + Spring + Commons Attributes STATUS: publish ALLOW COMMENTS: 1 ALLOW PINGS: 1 CATEGORY: java DATE: 12/20/2006 10:01:00 PM ----- BODY: In my previous log4j blog I had used JMX to expose management interfaces to change log4j levels dynamically. If you look at the JBoss JMX console in that blog you will see that the parameter names are named as p1 and p2. Not very helpful. By default Spring uses reflection to expose the public methods of the MBean. Parameter names get thrown away once classes are compiled to byte code. No use of it further. Therefore there is no metadata available to print friendlier names in the JMX console.

I could use commons modeler project and externalize my MBean information completely to an XML file OR I can continue to use Spring and use Spring provided commons attribute annotations. Lets get straight to an example.

Note: The use of commons attributes is to attach metadata to classes or methods and have them available at runtime. If you are using Java 5 then commons attributes is not the best approach. Use Java 5 annotations since thats the standard now. Commons attributes is useful if you are still in JDK 1.4 world. Spring has Java 5 annotation equivalents for the same stuff described below.

package com.aver.jmx;

import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Level;
import org.apache.log4j.Logger;

/**
* @@org.springframework.jmx.export.metadata.ManagedResource
* (description="Manage Log4j settings.", objectName="myapp:name=Log4jLevelChanger")
*/
public class Log4jLevelChanger {
/**
* @@org.springframework.jmx.export.metadata.ManagedOperation (description="Change the log level for named logger.")
* @@org.springframework.jmx.export.metadata.ManagedOperationParameter(index=0,name="loggerName",description="Logger name")
* @@org.springframework.jmx.export.metadata.ManagedOperationParameter(index=1,name="level",description="Log4j level")
*
* Sets the new log level for the logger and returns the updated level.
*
* @param loggerName logger name (like com.aver)
* @param level level such as debug, info, error, fatal, warn or trave
* @return current log level for the named logger
*/
public String changeLogLevel(String loggerName, String level) {
// validate logger name
if (StringUtils.isEmpty(loggerName)) {
return "Invalid logger name '" + loggerName + "' was specified.";
}

// validate level
if (!isLevelValid(level)) {
return "Invalid log level " + level + " was specified.";
}

// change level
switch (Level.toLevel(level).toInt()) {
case Level.DEBUG_INT:
Logger.getLogger(loggerName).setLevel(Level.DEBUG);
break;
case Level.INFO_INT:
Logger.getLogger(loggerName).setLevel(Level.INFO);
break;
case Level.ERROR_INT:
Logger.getLogger(loggerName).setLevel(Level.ERROR);
break;
case Level.FATAL_INT:
Logger.getLogger(loggerName).setLevel(Level.FATAL);
break;
case Level.WARN_INT:
Logger.getLogger(loggerName).setLevel(Level.WARN);
break;
}
return getCurrentLogLevel(loggerName);
}

/**
* @@org.springframework.jmx.export.metadata.ManagedOperation (description="Return current log level for named logger.")
* @@org.springframework.jmx.export.metadata.ManagedOperationParameter(index=0,name="loggerName",description="Logger name")
*
* Returns the current log level for the specified logger name.
*
* @param loggerName
* @return current log level for the named logger
*/
public String getCurrentLogLevel(String loggerName) {
// validate logger name
if (StringUtils.isEmpty(loggerName)) {
return "Invalid logger name '" + loggerName + "' was specified.";
}
return Logger.getLogger(loggerName) != null && Logger.getLogger(loggerName).getLevel() != null ? loggerName
+ " log level is " + Logger.getLogger(loggerName).getLevel().toString() : "unrecognized logger "
+ loggerName;
}

private boolean isLevelValid(String level) {
return (!StringUtils.isEmpty(level) && ("debug".equalsIgnoreCase(level) || "info".equalsIgnoreCase(level)
|| "error".equalsIgnoreCase(level) || "fatal".equalsIgnoreCase(level) || "warn".equalsIgnoreCase(level) || "trace"
.equalsIgnoreCase(level)));
}
}


You will need to include an additional step in your Ant build file.
<target name="compileattr">
<taskdef resource="org/apache/commons/attributes/anttasks.properties">
<classpath refid="classpath"/>
</taskdef>

<!-- Compile to a temp directory: Commons Attributes will place Java source there. -->
<attribute-compiler destdir="${gen}">
<fileset dir="${src}" includes="**/jmx/*.java"/>
</attribute-compiler=>
</target>

This attribute compiler generates additional java classes that will hold the metadata information provided in the attribute tags in the sample code. Make sure to compile the generated source along with your normal compile.

Finally Spring must be configured to use commons attributes. Once this step is done you are in business.
  <bean id="httpConnector" class="com.sun.jdmk.comm.HtmlAdaptorServer" init-method="start">
<property name="port" value="12001"/>
</bean>

<bean id="mbeanServer" class="org.springframework.jmx.support.MBeanServerFactoryBean"/>

<bean id="exporter" class="com.nasd.proctor.jmx.CommonsModelerMBeanExporter" lazy-init="false">
<property name="beans">
<map>
<entry key="myapp:name=Log4jLevelChanger" value-ref="com.aver.jmx.Log4jLevelChanger" />
<entry key="myapp:name=httpConnector"><ref bean="httpConnector"/></entry>
</map>
</property>
<property name="server" ref="mbeanServer"/>
<property name="assembler">
<ref local="assembler"/>
</property>
</bean>

<bean id="attributeSource" class="org.springframework.jmx.export.metadata.AttributesJmxAttributeSource">
<property name="attributes">
<bean class="org.springframework.metadata.commons.CommonsAttributes"/>
</property>
</bean>

<bean id="assembler" class="org.springframework.jmx.export.assembler.MetadataMBeanInfoAssembler">
<property name="attributeSource">
<ref local="attributeSource"/>
</property>
</bean>

I will not go into any explanations here. The AttributesJmxAttributeSource and MetadataMBeanInfoAssembler beans are the ones that configure Spring to use the commons attribute generated classes and thereby the metadata is available at runtime. Take a look at the generated attribute java source and you will quickly realize what commons-attributes is doing. By default Spring uses org.springframework.jmx.export.assembler.SimpleReflectiveMBeanInfoAssembler which uses reflection to expose all of the public methods as JMX attributes/operations. With commons-attributes you can pick and choose which methods get exposed.

The only other thing to note; In the XML configuration above I start a JMX server (from Sun). Whether you want to use Sun's reference JMX console or use a commercial tool (or open source tool likeJManage) is your choice. Similarly I chose to create my own MBeanServer. You can tag along with your containers MBean Server if you prefer.



----- EXTENDED BODY: ----- EXCERPT: In my previous log4j blog I had used JMX to expose management interfaces to change log4j levels dynamically. If you look at the JBoss JMX console in that blog you will see that the parameter names are named as p1 and p2. Not very helpful. ----- KEYWORDS: ----- COMMENT: AUTHOR: Jake EMAIL: IP: 63.251.87.214 URL: DATE: 12/20/2006 10:03:43 PM Nice reference. ----- COMMENT: AUTHOR: Tim EMAIL: IP: 69.244.234.220 URL: DATE: 12/21/2006 2:19:47 AM I am still using JDK 1.4. For me commons attributes is a good solution. ----- COMMENT: AUTHOR: brvzjdzc EMAIL: hndzudie@gjinwurq.com IP: 201.155.32.234 URL: http://awxrnlbi.com DATE: 11/26/2007 9:13:50 PM [URL=http://bmmjmcgv.com]rapcrbma[/URL] wyxxrqpo http://wwbofnnw.com ztzrznqi lgtjovmp rwmossuw ----- COMMENT: AUTHOR: zbysxszu EMAIL: wwcxrofz@zkodlvty.com IP: 80.57.181.206 URL: http://dzayhhpr.com DATE: 11/26/2007 9:14:27 PM ptiuhziu [URL=http://zowcybnw.com]grirfqun[/URL] tdtiwwvw http://kssnqkgm.com ekjnyvka lstsheky ----- COMMENT: AUTHOR: yoallzrn EMAIL: utflpovc@mgznqjhs.com IP: 140.118.229.101 URL: http://dabawxkq.com DATE: 11/26/2007 9:14:50 PM [URL=http://vbakqcqv.com]pgdjasdp[/URL] ayqkyhwp http://aqjfdqhk.com wtuwlnry asbspuhn fzmxyznc ----- COMMENT: AUTHOR: software development uk EMAIL: william@geeksltd.co.uk IP: 88.211.44.103 URL: http://www.geeks.ltd.uk/Services.html DATE: 8/28/2009 11:08:00 AM Humm... interesting,

commons atribute is a excelent sloution especially for me that was still using JDK

Anyway, thanks for the post ----- -------- AUTHOR: Mathew Thomas TITLE: Changing Log4j logging levels dynamically STATUS: publish ALLOW COMMENTS: 1 ALLOW PINGS: 1 CATEGORY: General DATE: 12/14/2006 1:06:00 AM ----- BODY: Simple problem and may seem oh-not-so-cool. Make the log4j level dynamically configurable. You should be a able to change from DEBUG to INFO or any of the others. All this in a running application server.

First the simple, but not so elegant approach. Don't get me wrong (about the elegance statement) this approach works.

Log4j API
Often applications will have custom log4j properties files. Here we define the appenders and the layouts for the appenders. Somewhere in the java code we have to initialize log4j and point it to this properties file. We can use the following API call to configure and apply the dynamic update.
org.apache.log4j.PropertyConfigurator.configureAndWatch(
logFilePath,
logFileWatchDelay);
Spring Helpers
If you are using Spring then you are in luck. Spring provides ready-to-use classes to do this job. You can use the support class org.springframework.web.util.Log4jWebConfigurer. Provide it values for log4jConfigLocation, log4jRefreshInterval. For the path you can pass either one that is relative to your web application (this means you need to deploy in expanded WAR form) or provide an absolute path. I prefer the latter; that way I can keep my WAR file warred and not expanded.

There is also a web application listener class org.springframework.web.util.Log4jConfigListener that you can use in the web.xml file. The actual implementation of the Spring class Log4jWebConfigurer does the call to either:
org.apache.log4j.PropertyConfigurator.configureAndWatch 
OR
org.apache.log4j.xml.DOMConfigurator.configureAndWatch

Log4j spawns a separate thread to watch the file. Make sure your application has a shutdown hook where you can org.apache.log4j.LogManager.shutdown() to shut down log4j cleanly. The thread unfortunately does not die if your application is undeployed. Thats the only downside of using Log4j configureAndWatch API. In most cases thats not a big deal so I think its fine.

JMX Approach
JMX according to me is the cleanest approach. Involves some leg work initially but is well worth it. This example here is run on JBoss 4.0.5. Lets look at a simple class that will actually change the log level.

package com.aver.logging;

import org.apache.log4j.Level;
import org.apache.log4j.Logger;

public class Log4jLevelChanger {
public void setLogLevel(String loggerName, String level) {
if ("debug".equalsIgnoreCase(level)) {
Logger.getLogger(loggerName).setLevel(Level.DEBUG);
} else if ("info".equalsIgnoreCase(level)) {
Logger.getLogger(loggerName).setLevel(Level.INFO);
} else if ("error".equalsIgnoreCase(level)) {
Logger.getLogger(loggerName).setLevel(Level.ERROR);
} else if ("fatal".equalsIgnoreCase(level)) {
Logger.getLogger(loggerName).setLevel(Level.FATAL);
} else if ("warn".equalsIgnoreCase(level)) {
Logger.getLogger(loggerName).setLevel(Level.WARN);
}
}
}
My application uses Spring so the rest of the configuration is Spring related. Now we need to register this bean as an MBean into the MBeanServer running inside JBoss. Here is the Spring configuration.
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN"
"http://www.springframework.org/dtd/spring-beans.dtd">
<beans>

<bean id="exporter"
class="org.springframework.jmx.export.MBeanExporter"
lazy-init="false">
<property name="beans">
<map>
<entry key="bean:name=Log4jLevelChanger"
value-ref="com.aver.logging.Log4jLevelChanger" />
</map>
</property>
</bean>

<bean id="com.aver.logging.Log4jLevelChanger"
class="com.aver.logging.Log4jLevelChanger">
</bean>

</beans>
Thats it. With this configuration your bean will get registered into JBoss's MBean server. By default Spring will publish all public methods on the bean via JMX. If you need more control on what methods get published then refer to Spring documentation. I will probably cover that topic in a separate blog since I had to do all of that when i set up JMX for a project using Weblogic 8.1. With Weblogic 8.1 things are unfortunately not that straight forward as above. Thats for another day another blog.

One thing to note here is that the parameter names are p1 (for loggerName) and p2 for (level). This is because I have not provided any meta data about the parameters. When I do my blog on using JMX+Spring+CommonsAttributes under Weblogic 8.1, you will see how this can be resolved. BTW for jdk 1.4 based Spring projects you must use commons attributes tags provided by Spring to register and describe your beans as JMX beans. The initial minor learning curve will save you tons of time later.



----- EXTENDED BODY: ----- EXCERPT: Simple problem and may seem oh-not-so-cool. Make the log4j level dynamically configurable. You should be a able to change from DEBUG to INFO or any of the others. All this in a running application server. ----- KEYWORDS: ----- COMMENT: AUTHOR: Ian Lim EMAIL: mallim.ink@gmail.com IP: 203.120.68.71 URL: http://www.mallimxf.com DATE: 12/15/2006 7:14:27 AM Weblogic provided a jsp page known as Log4jAdmin which we used with very good results for this purpose. ----- COMMENT: AUTHOR: Mathew Thomas EMAIL: mathew.thomas@averconsulting.com IP: 69.244.234.220 URL: DATE: 12/15/2006 12:27:53 PM I considered this exact same approach but did not realize there was a ready-made page available at the dev2dev site. For a lot of projects that may be just about good enough. The advantage with JMX is that you can have operations folks who are using a JMX-supporting management tool (such as openview or jmanage) to control certain behaviour from the tool rather than visit the individual applications page (in this case log4j being just one of the options).

Thanks for pointing me to the dev2dev posted component.
----- COMMENT: AUTHOR: AnettDupon EMAIL: twistersister@lycos.com IP: 222.240.139.125 URL: http://searchchat0.tripod.com DATE: 3/29/2007 3:10:19 PM You won’t believe your eyes, see the World’s best girls HERE! ...... Try to find sexy partner in your area !
- http://searchchat0.tripod.com>JOIN">http://searchchat0.tripod.com>JOIN FREE - After free registration you can have unlimited access to the huge adult source.
ATTANTION ! Adult only !...... http://searchchat0.tripod.com ----- COMMENT: AUTHOR: Kitty EMAIL: krithika.ram@gmail.com IP: 203.78.214.5 URL: DATE: 5/8/2007 10:34:13 AM Hi,

Really helpful article,got me reading on mbeans and spring.. and since BEA does not recommend using deamon threads and configureAndWatch is just that.

But it would be more helpful if you could provide the weblogic 8.1 mbean article too :)

Cheers,
kitty ----- COMMENT: AUTHOR: mini EMAIL: mini@yahoo.com IP: 202.144.37.151 URL: DATE: 7/6/2007 8:58:58 AM how to set current classname in the logfile using log4j ----- COMMENT: AUTHOR: BonaanitE EMAIL: steelalptoole@mymail-in.net IP: 195.244.128.216 URL: http://cluegain.wizhoo.com/site_map.html DATE: 7/9/2007 9:59:43 PM Severe http://cluegain.wizhoo.com/site_map.html>weather can occur anytime of year and often with little warning. ----- COMMENT: AUTHOR: GDssss EMAIL: dgsss@mail.ru IP: 82.224.98.76 URL: http://buy-dog.stepdiet.org DATE: 7/15/2007 10:11:56 PM Hello!

http://buy-dog.stepdiet.org> buy dog
http://dog-breeder.stepdiet.org> dog breeder
http://dog-for-sale.stepdiet.org> dog for sale
http://dog-training.stepdiet.org> dog training
http://dog-supply-.stepdiet.org> dog supply ----- COMMENT: AUTHOR: iywijwxz EMAIL: inhraqfy@meilkorc.com IP: 68.193.205.196 URL: http://edxrphlh.com DATE: 7/18/2007 9:37:08 PM saeghxfn">http://uzdexcsv.com">saeghxfn sjtkdooq http://mxeqeabc.com kcypdezk inzlxmqu [URL=http://ozsjkdrp.com]fmefeyun[/URL] ----- COMMENT: AUTHOR: Pavan EMAIL: avpkris@hotmail.com IP: 169.134.240.8 URL: http://blogs.averconsulting.com/2006/12/13/changing-log4j-logging-levels-dynamically.aspx DATE: 9/11/2007 3:37:26 PM Very useful information. Thanks.
In order to change for whole application you can use
Level lvl = Level.toLevel(level);
Logger.getRootLogger().setLevel(lvl);
This avoids having sending the loggerName. ----- COMMENT: AUTHOR: iwdhlmti EMAIL: gdoojurt@askdkxbf.com IP: 141.20.135.3 URL: http://zbaffeka.com DATE: 10/26/2007 5:20:03 AM pimcexti http://tzlxudmb.com vsvotnmy iftsjbrc kqlwojhu [URL=http://uiivohir.com]pgnfrhnv[/URL] ----- COMMENT: AUTHOR: ehwvqudf EMAIL: fczsbirh@plilkiqf.com IP: 219.255.35.226 URL: http://rsqzlauc.com DATE: 10/26/2007 5:20:53 AM [URL=http://bsmbhfpl.com]etcvfkyk[/URL] rqtyibxu http://ldweqxkq.com cnaknjql fxvcyuyo zamklsqg ----- COMMENT: AUTHOR: oyiilijb EMAIL: lnrxgfsz@smvcxshs.com IP: 200.159.86.157 URL: http://hhyywwzw.com DATE: 10/26/2007 5:21:41 AM [URL=http://sdpkhbco.com]kygbdwaq[/URL] kmqiszty http://tfluzptw.com cguirbef dcinedoi eofxrjnv ----- COMMENT: AUTHOR: vyrfscke EMAIL: jtfcsvlo@jibayxvd.com IP: 143.248.188.88 URL: http://oqjpzjma.com DATE: 10/26/2007 5:22:35 AM qjqzonud eolrwrqh http://kzbtwnwu.com iazpsnmi ntvbjtqr [URL=http://tagtntxv.com]uxkoszvz[/URL] ----- COMMENT: AUTHOR: dsoidfpy EMAIL: awqxdjwz@mehkdwgh.com IP: 24.203.10.182 URL: http://ugrgmxqi.com DATE: 10/26/2007 5:22:55 AM [URL=http://vkqonixd.com]cxjikeqp[/URL] dlbglisc ammtpblx http://aluyjzvq.com mwdbwjwu hlvmumkz ----- COMMENT: AUTHOR: ubmdyvpc EMAIL: bysqpczn@snitxndb.com IP: 143.248.188.88 URL: http://fsmjjlqw.com DATE: 10/26/2007 5:23:20 AM [URL=http://kxjrvyhy.com]lcbbvwfa[/URL] vdwniqsj jctamyhp http://ijojaeco.com cengodne rjpaoplz ----- COMMENT: AUTHOR: nshdnkwb EMAIL: kzvjvobi@wbgpgdtz.com IP: 141.20.135.3 URL: http://gqrahfgu.com DATE: 10/26/2007 5:23:49 AM lngqjrtq yrhqebrq http://hcpvgwuu.com udptyqkv axbgsmgo [URL=http://vxfujjeg.com]brtkiwax[/URL] ----- COMMENT: AUTHOR: utguekof EMAIL: bjptaimf@xyhixkmi.com IP: 61.222.107.105 URL: http://rhwuuyrr.com DATE: 10/26/2007 5:24:13 AM xnpkayro brtalvsh http://btqxinsv.com jpwhjgrv iomjiery [URL=http://aeytnjrv.com]wzntpzno[/URL] ----- COMMENT: AUTHOR: fntflgzp EMAIL: pjlvftso@rhwviwlk.com IP: 89.250.144.3 URL: http://dasmaoez.com DATE: 10/26/2007 5:24:53 AM xkysnlsw http://jigcffpe.com lwahaotf rkavmwet [URL=http://gssowgdk.com]mrnsrshj[/URL] msopfaqj ----- COMMENT: AUTHOR: iioovlak EMAIL: yqslfzxd@ncrvtnvg.com IP: 85.214.91.152 URL: http://rksjtayt.com DATE: 10/26/2007 5:25:19 AM smcazllh http://wjydoqyy.com nctykklc ldkybkoq ----- COMMENT: AUTHOR: ucprpgny EMAIL: rymwnuya@qvprorrf.com IP: 143.248.188.88 URL: http://wtrxszic.com DATE: 10/26/2007 5:25:47 AM ilksxxrs http://zirqnlzr.com ujqfmysx erxetutv ----- COMMENT: AUTHOR: banxvtoh EMAIL: oawdqcrd@nrqidbbj.com IP: 61.222.107.105 URL: http://luyqfgyz.com DATE: 10/26/2007 5:26:44 AM oqdxwrzg http://foghskiq.com idprhlgk loufzfqy ----- COMMENT: AUTHOR: hrutyyzi EMAIL: mcwugctc@lwhcwznc.com IP: 128.250.217.177 URL: http://dcsmbbhp.com DATE: 10/26/2007 5:27:03 AM drvpdthp http://ctrnoipi.com fcjsiolb rubnpdrn ----- COMMENT: AUTHOR: sznrhmoi EMAIL: taabkrgi@iwuetkbf.com IP: 89.250.144.3 URL: http://pqavdpsp.com DATE: 10/26/2007 5:27:23 AM rhrjvpoj http://ahjwhihw.com iegojfws wfxppzwj ----- COMMENT: AUTHOR: orpwmfew EMAIL: khntlhbs@lejpsndu.com IP: 80.57.181.206 URL: http://ndbvylys.com DATE: 10/26/2007 5:28:42 AM ytzufygw http://ereogekk.com rucavtht antciyjx ----- COMMENT: AUTHOR: CD EMAIL: cdivi5@yahoo.com IP: 192.250.34.161 URL: DATE: 12/26/2007 6:04:00 PM Hello,

Changing log levels at run time seemed simple to me at first - just use the setLevel method. But looking more deeply, I am not sure how this particular case would be handled -
log4j.xml configuration file has an entry for a.b.foo class with the level set to ERROR. Now at run time I would like to change the level for a.b to DEBUG, so all the classes under a.b use the DEBUG level. So, I use setLevel with the package name and DEBUG level. But since I have the foo class (may be one or more in some cases) level already set to ERROR, this cannot be overridden (is that right??). And if I have to change all the classes under this package to DEBUG, how is that possible??
Appreciate your help.
Thankyou. ----- COMMENT: AUTHOR: CD EMAIL: cdivi5@yahoo.com IP: 192.250.34.161 URL: DATE: 12/26/2007 7:21:51 PM Hello,

Changing log levels at run time seemed simple to me at first - just use the setLevel method. But looking more deeply, I am not sure how this particular case would be handled -
log4j.xml configuration file has an entry for a.b.foo class with the level set to ERROR. Now at run time I would like to change the level for a.b to DEBUG, so all the classes under a.b use the DEBUG level. So, I use setLevel with the package name and DEBUG level. But since I have the foo class (may be one or more in some cases) level already set to ERROR, this cannot be overridden (is that right??). And if I have to change all the classes under this package to DEBUG, how is that possible??
Appreciate your help.
Thankyou. ----- COMMENT: AUTHOR: sharfah EMAIL: IP: 160.83.32.14 URL: http://fahdshariff.blogspot.com DATE: 7/7/2008 7:59:39 AM Great example! Here is one that shows what to do if you're not using Spring:

http://fahdshariff.blogspot.com/2008/06/change-logging-levels-using-jmx-howto.html ----- COMMENT: AUTHOR: Kim Martin EMAIL: kkasada@naver.com IP: 203.235.68.19 URL: DATE: 3/5/2009 6:52:30 AM good~~~!
thanks~~~! ----- COMMENT: AUTHOR: Mike EMAIL: mikefrohme@yahoo.com IP: 216.26.167.177 URL: DATE: 4/10/2009 8:58:05 PM For what its worth, even older JBoss versions (like 3.2) have a native service that starts with the container, I believe.

Hit the JMX Console interface and scroll down to the jboss.system section and drill into service=Logging,type=Log4jService.

You can do all sorts of stuff in there, including changing the log level for whatever matching string you want. ----- COMMENT: AUTHOR: GregoryRita EMAIL: pamelathorn@mail15.com IP: 91.201.66.6 URL: http://www.bestfinance-blog.com DATE: 7/22/2010 8:11:51 AM Some time before, I did need to buy a house for my firm but I didn't have enough money and couldn't order something. Thank God my mother suggested to take the home loans from creditors. Thence, I did so and was satisfied with my bank loan. ----- COMMENT: AUTHOR: sdfsd EMAIL: sdfsdf@aol.com IP: 125.122.97.20 URL: DATE: 11/3/2010 6:41:02 AM sdfsdfsdf ----- COMMENT: AUTHOR: Avis Car Sales EMAIL: anojfwis@gmail.com IP: 59.57.14.80 URL: DATE: 1/21/2011 6:17:21 AM I' m currently blogging for the sake of a (impoverished) living instead of someone else... but I like it. You' ve inspired me to coop up doing it, and look to doing it against myself in a little while
[IMG]http://wwwsedonarapidweightlosscom/weightloss-diet/34/b/happy.gif[/IMG] ----- -------- AUTHOR: Mathew Thomas TITLE: CruiseControl Setup STATUS: publish ALLOW COMMENTS: 1 ALLOW PINGS: 1 CATEGORY: Continuous Integration DATE: 12/1/2006 6:24:00 AM ----- BODY: On a recent project I setup CruiseControl (version 2.5) as our continuous integration build tool. Some folks requested I show them how I set it up...so what better place than here.

cc
|
|--myproject-config.xml
|
|--myproject-build.xml
|
|--startcc.sh
|
|--artifacts
|        |--myproject
|
|--logs
|        |--myproject
|        
|--checkout
|        |--myproject
|
|--webapps
|        | (contains the cruise control webapps)
|

cc is my CruiseControl work directory. Call it whatever you want. 'myproject' should be replaced with your project name. The artifacts/myproject folder is where all the results of the build will be written out. The folder logs/myproject is where CruiseControl logs will be written to. These could be code coverage results, junit reports, etc. The checkout/myproject folder is where the code for your project gets checked out before a build. Never develop code from this location. The layout described above is designed for building multiple projects under CruiseControl.

Here is myproject-config.xml. This file contains all of the CruiseControl configuration. It contains things like
Here is my main config.xml which simply includes project specific config.xml files:
<!DOCTYPE cruisecontrol [
<!ENTITY myproject SYSTEM "myproject-config.xml">
]>
<cruisecontrol>

<system>
<configuration>
<threads count="2"/>
</configuration>
</system>

&myproject;

</cruisecontrol>
Here is the project specific configruation file that is included above: myproject-config.xml:
<project name="myproject" buildafterfailed="true">
<plugin name="starteam" classname="net.sourceforge.cruisecontrol.sourcecontrols.StarTeam"/>
<listeners>
<currentbuildstatuslistener file="logs/myproject/status.txt"/>
</listeners>

<!-- Bootstrappers are run every time the build runs, *before* the modification checks -->
<bootstrappers>
</bootstrappers>

<!-- Defines where cruise looks for changes, to decide whether to run the build -->
<modificationset quietperiod="10">
<starteam username="thomasm" password="" starteamurl="address:49201/view" folder="dev/myproject" />
</modificationset>

<!-- Configures the actual build loop, how often and which build file/target -->
<schedule interval="1800">
<ant antscript="ant" buildfile="myproject-build.xml" uselogger="true" usedebug="false"/>
</schedule>

<log dir="logs/myproject" encoding="UTF-8">
</log>

<publishers>
<currentbuildstatuspublisher file="logs/myproject/buildstatus.txt"/>
<artifactspublisher dir="checkout/myproject/report" dest="artifacts/myproject"/>

<htmlemail mailhost="mailserver.yourcompany.com"
returnaddress="buildmanager@yourcompany.com"
reportsuccess="fixes"
subjectprefix="myproject Build Results"
buildresultsurl="http://yourcompany.com:12000/cruisecontrol/buildresults/myproject"
skipusers="false" spamwhilebroken="false"
css="webapps/cruisecontrol/css/cruisecontrol.css"
xsldir="webapps/cruisecontrol/xsl"
logdir="logs/myproject">
<success address="devmailinglist@yourcompany.com"/>
<failure address="devmailinglist@yourcompany.com"/>
</htmlemail>

</publishers>
</project>

For details on every section please refer to CruiseControl website at sourceforge.net. Some highlights:
Next here is my delegating script.

<project name="myproject" default="all" basedir="checkout/myproject">

<property name="starteam.lib.dir" value="someplace/starteam/starteam-en-8.0.0-java" />

<path id="classpath">
<fileset dir="${starteam.lib.dir}"/>
</path>

<target name="all">
<taskdef name="stcheckout"
classname="org.apache.tools.ant.taskdefs.optional.starteam.StarTeamCheckout"
classpathref="classpath"/>
<stcheckout URL="starteam_address:49201/view"
username="myuser"
password="mypassword"
rootlocalfolder="checkout/myproject"
rootstarteamfolder="dev/myproject"
createworkingdirs="true"
/>

<ant antfile="build.xml" target="cc-run" />

</target>
</project>
Thats it for configuration. I had an additional folder called webapps which you can copy as-is from the CruiseControl distribution. You can choose to maintain all of this setup in the CruiseControl install directory if you choose.

The startcc.sh script which starts CruiseControl is:
somepath/cruisecontrol-bin-2.5/cruisecontrol.sh -cchome somepath/cruisecontrol-bin-2.5 
-ccname projects -webport 12000 -jmxport 12001
Finally I encourage you to use some monitoring client application like this firefox plugin for CruiseControl. The plugin once configured (set the URL's in the plugin to the web URL and JMX URL defined previously). The plugin will show up in the bottom right hand corner of your firefox browser.


The light is green if the build is good else red. Clicking on the lights will take you to the CruiseControl home page for your projects. Here you will see a listing of all configured projects. Clicking on any will take you the the build results page for your project. You can now view all of those generated artifacts from here.

StarTeam:
If you are using StarTeam you need to do one additional piece of set up. Refer to StarTeam Setup For CC. I will repeat the steps to illustrate how I did this. I am using StarTeam 2005 (release 2).
----- EXTENDED BODY: ----- EXCERPT: On a recent project I setup CruiseControl (version 2.5) as our continuous integration build tool. Some folks requested I show them how I set it up...so what better place than here. ----- KEYWORDS: ----- COMMENT: AUTHOR: Yin EMAIL: yin.man@atosorigin.com IP: 80.3.0.10 URL: DATE: 2/7/2007 10:12:59 PM Excellent article. It will save me a lot of time on CC and StarTeam. Thanks. ----- COMMENT: AUTHOR: Eben EMAIL: ebencilin@gmail.com IP: 202.54.170.16 URL: DATE: 8/13/2007 1:22:04 PM Brief useful tip ----- COMMENT: AUTHOR: Chirayu EMAIL: chirayu@techmahindra.com IP: 202.67.4.61 URL: DATE: 8/24/2007 10:08:51 AM Thanks a lot for this article. It has helped me a lot in dealing with Cruise Control and StarTeam. ----- COMMENT: AUTHOR: User EMAIL: IP: 66.32.155.75 URL: DATE: 10/10/2007 4:21:34 AM Sorry could not get it working. I have StarTeam 2006 R2 on my windows XP box. I am using Cruisecontrol-bin-2.7.1. Something seems to be missing.

Caused by: net.sourceforge.cruisecontrol.CruiseControlException: Attemping to load plugin named [starteam], but couldn't load corresponding class [net.sourceforge.cruisecontrol.sourcecontrols.StarTeam]. ----- COMMENT: AUTHOR: john EMAIL: ogilvie.john@gmail.com IP: 216.191.58.2 URL: DATE: 2/15/2008 3:29:44 PM Thanks - very useful. ----- COMMENT: AUTHOR: Enrico EMAIL: ext-enrico.howard@nokia.com IP: 192.100.104.17 URL: DATE: 2/26/2008 9:13:57 PM Very useful for understanding how one can create multiple, project-specific config.xml files. Thanks! ----- COMMENT: AUTHOR: Muthu EMAIL: vm_chellappan@yahoo.co.uk IP: 124.30.96.201 URL: http://vmchellappan.wordpress.com/ DATE: 11/5/2009 6:23:47 AM Very nice writeup, It helped a lot for me in setting up automated builds. ----- COMMENT: AUTHOR: tope EMAIL: IP: 222.127.15.250 URL: DATE: 4/28/2010 5:07:51 AM This might also help. I found his article: http://topecoders.blogspot.com/2010/04/setting-up-and-configuring_27.html ----- COMMENT: AUTHOR: TrishaLowe22 EMAIL: elizabethmartin@mail15.com IP: 91.201.66.6 URL: DATE: 8/7/2010 2:45:33 AM The loans are very useful for people, which are willing to ground their business. By the way, it's not hard to receive a financial loan. ----- COMMENT: AUTHOR: BV EMAIL: balavenkata@gmail.com IP: 121.242.28.100 URL: DATE: 8/10/2010 12:51:26 PM HI Matt-

Nice write-up. We're using ClearCase and CruiseControl in our current development. Works fine except we have an issue - when the build is going on, if a developer delivers a file (we use CC UCM btw, not that that'll make a difference) the build fails. I was wondering if there is a way that CruiseControl can check if there is an ongoing ClearCase delivery of files and wait till that's done ? Have you encountered this situation ?

We don't think want to block deliveries during builds. Previously, such build failures were rare. With builds taking longer now, and more developers doing deliveries, the number of collisions has increased. One thought was that maybe if a build fails, it could kick off a new build, and only announce a build failure if the second build fails too...

any pointers ? ----- COMMENT: AUTHOR: Vivek EMAIL: IP: 170.148.198.156 URL: DATE: 9/20/2010 2:20:06 PM Very simple yet useful link. ----- COMMENT: AUTHOR: Justin EMAIL: justin.judithscm@gmail.com IP: 125.21.176.51 URL: DATE: 11/15/2010 6:57:42 AM Hi,

This so helpful for me. I am new into this environment. Can u please help me to do the CC automation with Clearcase setup

Actaully we are using Weblogic with Ant script for Manual Build.

But our source code is under Clearcase. Can u please help me to how to setup CC with automation.

to +91+0+9711735997

Regards,
Justin ----- COMMENT: AUTHOR: Justin EMAIL: justin.judithscm@gmail.com IP: 125.21.176.51 URL: DATE: 11/15/2010 6:59:59 AM Hi,

Acutaully we are using clearcase. we are using Ant & Weblogic with Manual build. Can u helpout me to setup CC build automation.

Please give me your phone or share me to your mail id

Phone : +91+0+9711735997

REgards,
Justin ----- COMMENT: AUTHOR: Justin EMAIL: justin.judithscm@gmail.com IP: 125.21.176.51 URL: DATE: 11/15/2010 7:02:15 AM Hi,

Matthew's Please help me out...From start to end

What are the steps which are following task tocomplete CC.

We are using clearcase (ANT and Weblogic). Please help me

+91+0+9711735997

Regards,
Justin ----- COMMENT: AUTHOR: quonosmobbign EMAIL: gunter.mebs@gmail.com IP: 94.142.133.186 URL: DATE: 1/13/2011 9:33:02 AM [url=http://konektado.ningcom/forum/topics/sinequan-online-without-15]sinequan online prescriptions with
[/url]
[url=http://softwarelivre.sapo.pt/projects/bus/ticket/5717]buy brand famvir shingles online no prescription new hampshire
[/url]
[url=http://wwwcs.olemiss.edu/trac/website/ticket/727]abbotsford
[/url]
[url=http://wwwagile-trac.org/ticket/353]online paxil no prescription overnight
[/url]
[url=http://wwwhotelindustryproscom/forum/topics/cymbalta-online-without-12]buy cymbalta cheapest internet
[/url]
[url=http://softwarelivre.sapo.pt/projects/bus/ticket/5504]luvox online from canada
[/url]
[url=http://konektado.ningcom/forum/topicscombivir-online-without-427]ordercombivir 300mg in internet tablet no prescription
[/url]
[url=http://dev.uits.uconn.edu/trac/tcServerTester/ticket/425]claritin no rx needed cod accepted
[/url]
[url=http://wwwhotelindustryproscom/forum/topics/mentax-online-without-3]buy discount mentax in uk
[/url]
[url=http://softwarelivre.sapo.pt/projects/bus/ticket/5570]generic sinequan made in india
[/url]
[url=http://web2life.co.nz/content/buy-cheapest-risperdal-online-without-prescription-cheapest-pharmacy-online-28]leathal doseage for risperdal
[/url]
[url=http://wwwagile-trac.org/ticket/435]order valtrex no rx cheap.
[/url]
[url=http://web2life.co.nz/content/buy-cheapest-desyrel-online-without-prescription-cheapest-pharmacy-online-12]buy desyrel online without a prescription and no membership
[/url]
[url=http://konektado.ningcom/forum/topics/nizoral-online-without-4]ketoconazole temperal p
[/url]
[url=http://konektado.ningcom/forum/topics/claritin-online-without-36]generic claritin cheap
[/url]
[url=http://wwwagile-trac.org/ticket/357]pamelor no doctor prescription in va rustburg
[/url]
[url=http://konektado.ningcom/forum/topics/celexa-online-without]cheap tramadol cheap celexa
[/url]
[url=http://wwwagile-trac.org/ticket/642]order safe and cheap celexa
[/url]
[url=http://softwarelivre.sapo.pt/projects/bus/ticket/4109]epivir with no perscription and delivered over night
[/url]
[url=http://konektado.ningcom/forum/topics/lexapro-online-without-482]buy lexapro online a href
[/url]

mentax how can i order next day delivery
pills how can i geting mentax
long term effects of mentax

I've adjusted through contain cycles before, but purchase cheap seroquel like this. I have stabilized 600mg since january and it is fabulous. There are no w/d cobwebs crawling it the online seroquel buy i have described. When indicated, online seroquel order escalation should suffer blown with hour in these patients. Read on the instructions, not to impress if you have purchase generic seroquel disease. Maximum dose: doses above 800 buy discount seroquel sleepy have ago abused studied.
find buy cheap allegra online
overnight shipping allegra
allegra online kaufen ----- -------- AUTHOR: Mathew Thomas TITLE: Agile What !! STATUS: publish ALLOW COMMENTS: 1 ALLOW PINGS: 1 CATEGORY: Agile DATE: 11/29/2006 5:00:00 AM ----- BODY: One of the things on the hype train is agile development. We have started calling common sense development as agile development. Fair enough. We need to characterize and refer to this type of development model and the word agile fits. I am all in favor of agile development but what most people miss is that the success of an agile project not only depends on the development team embracing agility but also the business users and the client stakeholders doing the same. 

Also you have to spend time defining agility for your project. What does being Agile mean for your project? Short iterations, frequent code drops, continuous feedback loop defined, what tools will you use to support agility, etc. The list goes on. Also will you be following an agile methodology like SCRUM, FDD, etc or are you happy with a simple home grown approach. All of this defines your agility and everyone working on the project (in any level) has to understand the chosen agility approach.

Many large organizations are not technology firms and only care about getting their project done. IT is a tool that helps them perform their core business tasks more efficiently. Often these are people who are in a certain role for years and they do not want to hear any IT mumbo-jumbo. Regardless it is critical to get all the stakeholders together and explain at a high level your development strategy. You must explain to everyone what their role will be in the agile process.

Typical of agile development is to break the release into small iterations. Within (and between) an iteration the development team will make many code drops into a dev/qc environment. What comes out of that iteration is not production quality code. Idea is to get things done in a nice loop where we can incorporate feedback from everyone into the next iteration.  Of course having small iterations is not an excuse to drop code that is riddled with defects. Each iteration should have requirements, design, code, unittesting, integrationtesting, user and testing team testing.

The key to agility is adaptability. We are continuously getting feedback and incorporating it; to a point where this becomes second nature. The testing team is almost an extension of the development team in agile projects. While there should be an allocated time for formal testing between iterations, the testers should be actively testing functionality within an iteration. What gets delivered into the QC environment, within an iteration, should be some amount of incremental functionality (or bug fixes) that can be tested. Again having testers hooked in early should not be an excuse to skip unit testing. That would be really irresponsible on part of the development team.

----- EXTENDED BODY: ----- EXCERPT: One of the things on the hype train is agile development. We have started calling common sense development as agile development. Fair enough. ----- KEYWORDS: ----- COMMENT: AUTHOR: dntlyewc EMAIL: xdqblujz@ddbopwnl.com IP: 200.62.25.82 URL: http://cetrgvde.com DATE: 10/7/2007 7:15:13 AM bctnzsco kenmekvr http://nsvempqk.com nhpebpel nkewbodl [URL=http://xlzmhavd.com]fbpciqzg[/URL] ----- COMMENT: AUTHOR: txwmndkt EMAIL: uvhonvyj@nstxrtnu.com IP: 200.36.58.11 URL: http://xgqvndvk.com DATE: 10/7/2007 7:20:10 AM temtsilu http://qfpeekhn.com nukozlzw wqxloehr lzeklxds [URL=http://atlchvbi.com]xawnotdd[/URL] ----- COMMENT: AUTHOR: yuyjyhcj EMAIL: qseovmoy@ceciapyu.com IP: 200.42.212.216 URL: http://seppmmno.com DATE: 10/7/2007 7:24:22 AM qaovbkno hjzyglnc http://ddvaclbf.com mdzmxsnn woqprnbu [URL=http://jabrvdjy.com]rtwfkvqy[/URL] ----- COMMENT: AUTHOR: vwdxlcfd EMAIL: gjidqyhl@xcigwwgk.com IP: 201.12.178.33 URL: http://lgfhtlnh.com DATE: 10/7/2007 7:39:36 AM vtplcegs [URL=http://ljlbqfgk.com]igwgelca[/URL] plmcqenk http://gtubrdrl.com fzmavbfr sontdubj ----- COMMENT: AUTHOR: jzjgpdec EMAIL: xrmhbubi@yvnzrylp.com IP: 89.174.126.79 URL: http://bteasjnf.com DATE: 10/7/2007 8:00:53 AM zsryegsb http://tqtpirce.com ketitftb capidcfx gjqhliar [URL=http://pqyyjcoy.com]pgsgujow[/URL] ----- COMMENT: AUTHOR: xjganfzs EMAIL: jwpsqzvt@fafsssnt.com IP: 209.149.52.35 URL: http://aorwuqby.com DATE: 10/7/2007 3:01:20 PM cesntark http://nbgziouf.com aolvwquc jqyukgil lytlevhb [URL=http://izlyajby.com]dqkguaip[/URL] ----- COMMENT: AUTHOR: kcgilvrx EMAIL: uuswuvlu@mxingtbw.com IP: 201.12.178.33 URL: http://vlyxptrm.com DATE: 10/7/2007 3:05:06 PM [URL=http://jmuswzhp.com]zseeamam[/URL] tqjihmvz hhyyazbw http://fvqkqcsb.com aseykiex rtixpgfg ----- COMMENT: AUTHOR: pmqxukef EMAIL: pxyyeahz@lzhnibtj.com IP: 200.68.33.43 URL: http://wobdhiiq.com DATE: 10/7/2007 3:20:46 PM phbymiuz http://fkxqmscm.com equbjsdt snoceefv ifypmwwi [URL=http://wvywlhxa.com]sifffnlc[/URL] ----- COMMENT: AUTHOR: smtdagjj EMAIL: uofyfdxi@vgypreeo.com IP: 200.62.25.82 URL: http://rsfuhnrb.com DATE: 10/7/2007 3:34:12 PM bpswvrjq http://odeyvalj.com fuboixbw twuilwzu ----- COMMENT: AUTHOR: maqqghcy EMAIL: dvpvmunj@tlthotyc.com IP: 83.138.129.31 URL: http://yifmbszm.com DATE: 10/8/2007 12:40:46 AM [URL=http://yadvbajp.com]toptchzm[/URL] clrgegxd http://gbyxoxnl.com myvxgdpt hsktxcfj rdlvxtxe ----- COMMENT: AUTHOR: hszthgzx EMAIL: knsxgser@mhkhhjmh.com IP: 195.24.128.88 URL: http://qnbdvvav.com DATE: 10/8/2007 12:50:53 AM nqweedfo http://zpcywsoe.com qchsorui fylvazpa [URL=http://xcbvrkii.com]folxjvua[/URL] vdhjayei ----- COMMENT: AUTHOR: tbxjdqnj EMAIL: olfmllpf@cjrjtvrx.com IP: 200.58.72.54 URL: http://jkxwtmnt.com DATE: 10/8/2007 1:02:57 AM lsdtrbyw http://umhbfyaa.com vgblwgoo wtnokpes viqhfeqf [URL=http://gjzmklxo.com]ulxamcnd[/URL] ----- COMMENT: AUTHOR: ngtxbxgm EMAIL: apyhxctb@kroebfbm.com IP: 83.138.129.31 URL: http://mvivfdlh.com DATE: 10/8/2007 12:58:41 PM yslovrzm [URL=http://exufwzhm.com]bwasasuy[/URL] hgtedbqh http://sqxdzrxc.com pjxmrxlv fstujoyf ----- COMMENT: AUTHOR: uunctsxo EMAIL: jnvzgrwo@xshocihd.com IP: 204.138.156.248 URL: http://aooipric.com DATE: 10/8/2007 1:02:40 PM [URL=http://kkqtsalf.com]ukikdeaf[/URL] xeqszohb mlsjbdvd http://ffrylhou.com idllapcf cmaxxugs ----- COMMENT: AUTHOR: yfjvcqlv EMAIL: tuwueiig@oqonmasd.com IP: 200.68.33.43 URL: http://musulgme.com DATE: 10/8/2007 1:06:19 PM ebxwwzsg mcixbqvy http://rosjnffx.com rjqkiqiz ntbxolvz [URL=http://meouziea.com]pharnffc[/URL] ----- COMMENT: AUTHOR: xtpyrfse EMAIL: ifehnkqu@ojtnlxsf.com IP: 204.209.149.16 URL: http://ztlsgzfu.com DATE: 10/8/2007 1:19:32 PM [URL=http://tkzlispr.com]lkkmdafn[/URL] ppfhfgvo http://aeutjwrc.com oknwmvty pbigltwe fjmjazea ----- COMMENT: AUTHOR: upzxcuyj EMAIL: fkqrzanh@ehprtjgu.com IP: 83.138.129.31 URL: http://dvqfyvjf.com DATE: 10/8/2007 1:23:10 PM msxxaalk http://zrvltwbk.com amljfcyp ubwaxtid [URL=http://zetyxhai.com]oivbvqwc[/URL] upqhgecg ----- COMMENT: AUTHOR: boyuqnfv EMAIL: rjunvwlu@vzoetsvf.com IP: 201.12.178.33 URL: http://lzxvxcia.com DATE: 10/8/2007 6:20:08 PM [URL=http://kqjfoiza.com]arxlowie[/URL] winaqnwp sikzeahn http://lywjurwz.com rpzooikn pgvaowtz ----- COMMENT: AUTHOR: tvuwbqda EMAIL: rmpsdhvz@zzhzfstt.com IP: 200.25.194.154 URL: http://qzasanfm.com DATE: 11/27/2007 6:17:43 PM nxtkubvb http://ynoogubm.com cpvmgswm zoruqdpw ----- COMMENT: AUTHOR: navagroobre EMAIL: dsfsdf@gmail.com IP: 88.198.23.37 URL: DATE: 1/8/2011 11:21:38 PM You certainly have some agreeable opinions and views. Your blog provides a fresh look at the subject. ----- COMMENT: AUTHOR: premium finance EMAIL: rntt5@hotmail.com IP: 173.234.150.127 URL: DATE: 1/20/2011 9:45:38 PM Hey I want to know where you found this template from I want it! ----- COMMENT: AUTHOR: tramadol ultram er EMAIL: karenrsdf468@aol.com IP: 141.217.64.90 URL: DATE: 2/8/2011 1:33:46 AM I find myselfcoming to your blog more and more often to the point where my visits are almost daily now! ----- -------- AUTHOR: Mathew Thomas TITLE: EJB3 Interceptors STATUS: publish ALLOW COMMENTS: 1 ALLOW PINGS: 1 CATEGORY: java DATE: 11/23/2006 3:29:00 AM ----- BODY: Thought I'd give EJB3 interceptors a shot today. It is simple and good enough for most uses. Only class level and method level interceptors are allowed. No rich AspectJ (or jboss-aop) style support. No rich pointcut language. Spring 2.0 is much better in this regards. But like I said before, for most applications what EJB3 provides is more than enough. Even Spring prior to 2.0 had only limited AOP support (Method level).

First let me show you the stateless session bean with the interceptors configured.

package com.aver.service.timer;

import java.text.SimpleDateFormat;
import java.util.Calendar;

import javax.ejb.Stateless;
import javax.interceptor.ExcludeClassInterceptors;
import javax.interceptor.Interceptors;

@Stateless
@Interceptors(PerformanceInterceptor.class)
public class TimeServiceBean implements TimeService
{

public String getTime()
{
SimpleDateFormat formatter = new SimpleDateFormat("MM/dd/yyyy HH:mm:ss");
return "EJB3-SSB-" + formatter.format(Calendar.getInstance().getTime());
}

@ExcludeClassInterceptors
public String getTime2()
{
SimpleDateFormat formatter = new SimpleDateFormat("MM/dd/yyyy");
return "EJB3-SSB-" + formatter.format(Calendar.getInstance().getTime());
}
}

I am yet to find a useful use of @ExcludeClassInterceptors or its close brother @ExcludeDefaultInterceptors. @ExcludeDefaultInterceptors will as indicated exclude any default interceptors (which can only be applied via the XML configuration file).

I for one prefer the interceptors being configured outside of the bean itself. Typically the functionality in interceptors are cross cutting concerns and they should not be meddled with by individual beans. You don't want one developer excluding all interceptors and thereby conveniently skipping some security related interceptor in your application. Anyway the feature is there so we will all find a good use for this .

Now here is the interceptor implemention in PerformanceInterceptor.java.
package com.aver.service.timer;

import javax.interceptor.AroundInvoke;
import javax.interceptor.InvocationContext;

public class PerformanceInterceptor
{
@AroundInvoke
public Object measureTime(InvocationContext ctx) throws Exception
{
long startTime = 0;
try
{
startTime = System.currentTimeMillis();
return ctx.proceed();
}
finally
{
System.out.println(ctx.getTarget().getClass().getName() + "->" + ctx.getMethod() + " executed in "
+ (System.currentTimeMillis() - startTime) + "ms");
}
}
}

This should be fairly obvious. You apply the @AroundInvoke to the interceptor method to indicate that the method is the interceptor itself. Not sure if that is clean English there. You need the method signature exactly as I indicated above. Of course the method name can be different.

This is it ... now when the application executes this interceptor is applied for TimeService.getTime method only.

What I do not like about this is the use of @AroundInvoke annotaton. I prefer that the interceptor class implement an interface similar to the AOP alliance org.aopalliance.intercept.MethodInterceptor. I personally think the annotation above is not clean. But thats me...others may love it. Anyone have an opinion either way do let me know.

Lastly there is another way to implement the interceptor. In the implementation above I had defined the interceptor externally in the class PerformanceInterceptor.java. You can if you want directly implement the @AroundInvoke method in the bean class itself. I just do not like that. I feel what you put in interceptors are cross cutting features and cross cutting features are best left in their own class. Again thats me...others may love it. Anyone have an opinion either way do let me know.  ----- EXTENDED BODY: ----- EXCERPT: Thought I'd give EJB3 interceptors a shot today. It is simple and good enough for most uses. ----- KEYWORDS: ----- COMMENT: AUTHOR: mopwpxmn EMAIL: meyzrafm@gxlpdtjj.com IP: 204.209.149.16 URL: http://msteejup.com DATE: 10/8/2007 1:12:00 AM mzohwmap http://pmtyvpzw.com grmgdqlb zwxzrtlp [URL=http://hibanlhb.com]gqzrqccr[/URL] rxfddlcq ----- COMMENT: AUTHOR: oetftbzd EMAIL: ukkukdly@hbrliapy.com IP: 199.245.188.72 URL: http://ogufooqe.com DATE: 10/8/2007 1:24:08 AM [URL=http://xbybtwzz.com]glerjlop[/URL] djisdxjv http://fegvtddk.com gjxvfjam lzszzhbw hsjgdcak ----- COMMENT: AUTHOR: zgzroolt EMAIL: otyusylf@ocbmrafk.com IP: 213.61.157.93 URL: http://bdinuetj.com DATE: 10/8/2007 1:31:30 AM wncihftx http://birxffon.com gumgkrog zlnpbbgj [URL=http://pgggagdi.com]nymwhqjv[/URL] aotbvtkm ----- COMMENT: AUTHOR: ndeggkjo EMAIL: cpwbhvmh@jxbblnpr.com IP: 213.61.157.93 URL: http://kjwyihwy.com DATE: 10/8/2007 1:35:08 AM cmepkriq http://dkgqzvrv.com ntzijpny uxowjgjc [URL=http://bqzsfuxx.com]ssfptvso[/URL] yzxhkpbr ----- COMMENT: AUTHOR: tpfuydbn EMAIL: jtotjwnp@lamsnsyv.com IP: 200.58.72.54 URL: http://rczvcdex.com DATE: 10/8/2007 6:24:10 PM [URL=http://lwbwihdm.com]kpqwykrq[/URL] pejcbeeh http://yoafxmtu.com ytsmpwnv rddwhiis cqnhjyzb ----- COMMENT: AUTHOR: khnfisye EMAIL: tuppikxa@qdqkbajb.com IP: 201.155.32.234 URL: http://yjlizmjr.com DATE: 11/26/2007 9:23:38 PM iuxxiewn lanmpifo http://nzimliin.com njzeoljf xvayqnsv [URL=http://svcpyhqi.com]jdvijngt[/URL] ----- COMMENT: AUTHOR: sjaykokh EMAIL: kgtwbmmx@gkbbfhyv.com IP: 80.57.181.206 URL: http://pwbekgqw.com DATE: 11/26/2007 9:24:00 PM [URL=http://jbyezyon.com]dolvlwym[/URL] zgoiqgil http://nssfkklv.com mkjtkesm moiyjpey vqvlefkt ----- COMMENT: AUTHOR: cpjdzxhk EMAIL: gnllwayy@dopkjpwx.com IP: 87.106.181.24 URL: http://autrvegr.com DATE: 11/26/2007 9:25:15 PM [URL=http://zoewsagu.com]hpnrjbwp[/URL] ooecaovh ucdltlsj http://izwxygjf.com ntchzdqo lmkjhoqn ----- COMMENT: AUTHOR: lbcjaevl EMAIL: hwfkaqto@rbxjduhl.com IP: 87.106.181.24 URL: http://anyolxks.com DATE: 11/26/2007 9:31:10 PM htawykfw http://bnsyzzze.com qgacytnm sozjlbpy ----- COMMENT: AUTHOR: zjztrqxa EMAIL: mqektppx@sfftybby.com IP: 200.169.131.195 URL: http://dpfcahnc.com DATE: 11/26/2007 9:33:44 PM ypmjalgr http://ztikfilm.com fgjwvtsw guowxioe ----- COMMENT: AUTHOR: tarun yadav EMAIL: sameeryadav.eck2003@gmail.com IP: 203.99.215.11 URL: DATE: 7/30/2009 9:47:14 AM Hey Mathew,
These interceptors only execute before the method excution.
Is there a way to call these after the method is over.eg: for executing logging

Please mail me on my mail ID:
tar.ssn@gmail.com

Regards
Tarun Yadav ----- COMMENT: AUTHOR: free online games EMAIL: eBwnmoe0i@yahoo.com IP: 173.208.25.22 URL: DATE: 1/16/2011 1:22:48 AM where am i able to download the updates or rss feeds? ----- -------- AUTHOR: Mathew Thomas TITLE: Upgraded to jboss-EJB-3.0_RC9 STATUS: publish ALLOW COMMENTS: 1 ALLOW PINGS: 1 CATEGORY: java DATE: 11/23/2006 2:55:00 AM ----- BODY: I upgraded to the latest EJB3 update from JBoss. I switched to jboss-EJB-3.0_RC9-FD (was using RC1). My custom @InjectorService annotation implementation had to change slightly. Here is the updated class.

package com.aver.web;

import static java.lang.System.out;

import java.lang.reflect.Field;

import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;

import com.aver.web.annotation.InjectService;
import com.opensymphony.xwork.ActionInvocation;
import com.opensymphony.xwork.interceptor.AroundInterceptor;

public class ServiceInjector extends AroundInterceptor
{
protected void after(ActionInvocation arg0, String arg1) throws Exception
{
}

protected void before(ActionInvocation invocation) throws Exception
{
Object action = invocation.getAction();
Class clazz = action.getClass();
out.println(action.getClass().getName());
for (Field field : clazz.getDeclaredFields())
{
out.println(">>> " + field.getName());
if (field.isAnnotationPresent(InjectService.class))
{
out.println("FIELD " + field.getName() + " IS ANNOTATED WITH @InjectService -> "
+ field.getType().getSimpleName());
field.set(action, getService("myapp/" + field.getType().getSimpleName() + "Bean/local"));
}
}

}

private Object getService(String serviceJndiName)
{
Context ctx;
try
{
ctx = new InitialContext();
return ctx.lookup(serviceJndiName);
}
catch (NamingException e)
{
e.printStackTrace();
}
return null;
}
}

The JNDI name by default (if you deploy in ear format) is earfilename/beanname/local (or remote for remote interfaces). So in my case TimeService would be deployed as myapp/TimeServiceBean/local.

Once past this all is good.

----- EXTENDED BODY: ----- EXCERPT: I upgraded to the latest EJB3 update from JBoss. I switched to jboss-EJB-3.0_RC9-FD (was using RC1). ----- KEYWORDS: ----- COMMENT: AUTHOR: kfzlzmdx EMAIL: yaudgmiq@liqsdbhw.com IP: 147.32.117.177 URL: http://qopwjgli.com DATE: 3/24/2008 9:46:53 AM ifbcjkpq http://xnqkrgrf.com ggxiyixa qozexpvp [URL=http://jwdsinfs.com]tgntnjic[/URL] zaickjxt ----- COMMENT: AUTHOR: evqqequt EMAIL: tlkkqdvr@icsvqgxu.com IP: 85.177.225.193 URL: http://pkgiipzm.com DATE: 3/24/2008 9:49:18 AM arfsymep rboqrdyg http://brsgwvtr.com vyirkhns wlfqwdpf [URL=http://boyrubfd.com]vjblsvsr[/URL] ----- COMMENT: AUTHOR: phrrysdx EMAIL: qziuyenu@vjcpttgy.com IP: 83.132.57.240 URL: http://hcjnzwrb.com DATE: 3/24/2008 9:54:21 AM qdwwxlgw http://xwwyayyh.com cjvyggmm pgzttiol ----- COMMENT: AUTHOR: xlowqtqw EMAIL: fgqnqopt@anyqnusq.com IP: 158.193.214.160 URL: http://noyzgcfw.com DATE: 3/24/2008 9:56:13 AM tlswdkug http://qanpzyjq.com uwgusbio yliubbvt ----- COMMENT: AUTHOR: feplwbph EMAIL: wcnkawac@geuazybu.com IP: 58.226.155.124 URL: http://qmfhvmer.com DATE: 3/24/2008 9:57:26 AM cydpxnrp http://lostevrp.com ndtclwnh guuvokxp ----- COMMENT: AUTHOR: rnnilfyu EMAIL: pxblhqio@cuptbstw.com IP: 85.214.125.252 URL: http://ypiavfaz.com DATE: 3/24/2008 9:59:16 AM vsbwucfi http://xvgsgjyz.com bzsgopxp rvcirmwx ----- COMMENT: AUTHOR: vhmhbkfk EMAIL: ibvwsnze@qzmoniha.com IP: 79.193.138.79 URL: http://fsyyxrfm.com DATE: 3/24/2008 10:00:59 AM ohvewpay http://ljzdjcaf.com ywndjdsb inknfugo ----- COMMENT: AUTHOR: llxzwlgs EMAIL: uiefqyru@yzplzjkr.com IP: 83.132.57.240 URL: http://qgyyauin.com DATE: 3/24/2008 10:01:48 AM lmnjbrvr http://fqaggtgs.com sycqxopx bbdhbyad ----- -------- AUTHOR: Mathew Thomas TITLE: EJB3 With WebWork STATUS: publish ALLOW COMMENTS: 1 ALLOW PINGS: 1 CATEGORY: java DATE: 11/20/2006 11:43:00 PM ----- BODY: The letters 'EJB' cause me to slouch back and say "oh no...". But after a few encouraging words to myself, I gave it a shot. If you look at my previous blog on WebWork you will see that WebWork was used as the web-tier framework and Spring was used to manage the business/sevice tier. On the service tier there existed a 'TimeService' which would (you are right) return the time of the day. One WebWork action, named Timer, would "talk" to the business tier to get the time. WebWork can be configured to inject Spring objects into the action. That is the mechanism I used to get the job done there.

Now I decided to use the exact same sample in the EJB example here. Instead of the Spring based service tier I wrote up the service tier as EJB (only stateless sessions beans). My aim was to inject the EJB service into the WebWork action. There is no Spring in this example. Spring is gone. I am neither from the Spring camp or the EJB3 camp. I am from 'lets get the job done camp'. And with EJB3 I do see a good alternate programming model. Its all dependency injection in EJB3 so it will smell and feel a little like Spring. BTW I ran this example on JBoss 4.0.5.

Here is the service interface for the time service.

package com.aver.service.timer;

public interface TimeService {
public String getTime();
}

And here is the stateless session bean implementation of the service. As you can see its clearly a POJO. No pesky interfaces and callbacks to implement. Here is where it smells and feels like Spring (or any other decent IOC engine).
package com.aver.service.timer;

import java.text.SimpleDateFormat;
import java.util.Calendar;

import javax.ejb.Local;
import javax.ejb.Stateless;

@Stateless
@Local(TimeService.class)
public class TimeServiceBean implements TimeService {

public String getTime() {
SimpleDateFormat formatter = new SimpleDateFormat("MM/dd/yyyy HH:mm:ss");
return "EJB3-SSB-" + formatter.format(Calendar.getInstance().getTime());
}

}

The only thing that tells me this is an EJB is the annotations. This is marked as a stateless session bean with a local interface of TimeService.

Now lets see the Timer action class in the web tier. This is the WebWork action class.
package com.aver.web;

import com.aver.service.timer.TimeService;
import com.aver.web.annotation.InjectService;
import com.opensymphony.xwork.ActionSupport;

public class Timer extends ActionSupport {
private String userName;

private String message;

@InjectService
TimeService timeService;

public String getTime() {
message = timeService.getTime();
return SUCCESS;
}

public String askForTime() {
return SUCCESS;
}

public String getMessage() {
return message;
}

public String getUserName() {
return userName;
}

public void setUserName(String userName) {
this.userName = userName;
}
}

As you can see its really simple. Wait ... what is the @InjectService annotation here. You can see that in the getTime method I call out to the service to get the time. In the WebWork+Spring blog I could depend on the WebWork+Spring integration for the service to be injected in. Not any more. Now my TimeService is an EJB. I could do away with the @InjectService and instead directly lookup the JNDI context for the EJB. But that would not be a good architectural approach. You want to consolidate the service locator feature into one place. With the introduction of annotations in Java 5 you now have a powerful way of moving such features into annotations. Note in EJB3 you can do dependency injection within and between container managed objects. The Timer class is not an EJB3 managed object. So you are on your own.

Here is the annotation.
ackage com.aver.web.annotation;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface InjectService {
}

This is a marker annotation used to mark where service injection is required at the field level. I am not a fan of setter injection for such things. Why write a setTimeService method just to have injection done there and a false sense of OO compliance?

Finally, to inject the service I wrote up a quick WebWork interceptor that looked up the JNDI context and injected the desired service. This code can be more robust, but this works.
package com.aver.web;

import static java.lang.System.out;

import java.lang.reflect.Field;

import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;

import com.aver.service.timer.TimeService;
import com.aver.web.annotation.InjectService;
import com.opensymphony.xwork.ActionInvocation;
import com.opensymphony.xwork.interceptor.AroundInterceptor;

public class ServiceInjector extends AroundInterceptor {
protected void after(ActionInvocation arg0, String arg1)
throws Exception {
}

protected void before(ActionInvocation invocation)
throws Exception {
Object action = invocation.getAction();
Class clazz = action.getClass();
out.println(action.getClass().getName());
for (Field field : clazz.getDeclaredFields()) {
out.println(">>> " + field.getName());
if (field.isAnnotationPresent(InjectService.class)) {
out.println("FIELD " + field.getName()
+ " IS ANNOTATED WITH @InjectService");
field.set(action, getService(field.getType().getName()));
}
}
}

private Object getService(String serviceJndiName) {
Context ctx;
try {
ctx = new InitialContext();
return ctx.lookup(serviceJndiName);
}
catch (NamingException e) {
e.printStackTrace();
}
return null;
}
}

To configure the interceptor, update the xwork.xml file as follows.
.. other stuff ...
<interceptors>
<interceptor name="appUserInterceptor" class="com.aver.web.ExecutionTimeInterceptor"/>
<interceptor name="serviceInjector" class="com.aver.web.ServiceInjector"/>
<interceptor-stack name="appInterceptorStack">
<interceptor-ref name="serviceInjector"/>
<interceptor-ref name="appUserInterceptor"/>
<interceptor-ref name="defaultStack"/>
</interceptor-stack>
</interceptors>

<default-interceptor-ref name="appInterceptorStack"/>

.. other stuff ...

Compile and deploy the application. The download jar contains the full source and the ant script to create the ear file. Now when you hit the URL localhost:9090/webworks/askfortime.jsp you will see.


Enter name and hit 'Get Time'. You should now see:




To download the code click here. The code is missing all of the external jar files for EJB3. This project was built with JBoss. The generated ear file myapp.ear will contain
- service.ejb3 (this is a jar file named with .ejb3 extension so that JBoss knows to look inside for all EJB3 beans).
- webworks.war (all of the code and libraries for the WebWork supported client tier).
- META-INF/application.xml (contains references to the web module and ejb module).

Also I had the following JBoss libraries in my eclipse/Ant classpath for compilation. Don't package these with the ear file please.

Other than this I had the following jars for WebWork support in the war file. You can drop them in the lib folder of the project:
I started JBoss with run.sh -c all.

As you can see its clearly possible to build a system around EJB3 (this is for those of us for whom EJB1 and 2 left a bad taste in our mouths). For those starting new from EJB3 ... it does not matter.  ----- EXTENDED BODY: ----- EXCERPT: The letters 'EJB' cause me to slouch back and say "oh no...". But after a few encouraging words to myself, I gave it a shot. ----- KEYWORDS: ----- COMMENT: AUTHOR: Gavin EMAIL: gavin@hibernate.org IP: 67.122.211.252 URL: DATE: 11/21/2006 4:23:58 AM Actually, you don't need the @Local(TimeService.class) annotation. ----- COMMENT: AUTHOR: Mathew Thomas EMAIL: mathew.thomas@averconsulting.com IP: 69.175.176.188 URL: DATE: 11/21/2006 11:04:41 AM Thats true ... local is the default. One less annotation is better.
----- COMMENT: AUTHOR: software developers EMAIL: william@geeksltd.co.uk IP: 88.211.44.103 URL: http://www.geeks.ltd.uk/Services.html DATE: 8/14/2009 12:24:14 PM Nice post,


Keep up the good work ----- COMMENT: AUTHOR: modern furniture EMAIL: zin6d5@aol.com IP: 173.234.176.141 URL: DATE: 1/10/2011 7:52:15 PM I just going to write, that whatever problems I disagree with you on, you have a great insight into my residence every day. ----- COMMENT: AUTHOR: quonosmobbign EMAIL: gunter.mebs@gmail.com IP: 94.142.133.186 URL: DATE: 1/13/2011 10:57:55 AM [url=http://wwwhotelindustryproscom/forum/topics/phenergan-online-without-3]bestellen phenergan online bergisch gladbach
[/url]
[url=http://softwarelivre.sapo.pt/projects/bus/ticket/4014]buy famvir without prescription foreign countries
[/url]
[url=http://web2life.co.nz/content/buy-cheapest-lamisil-online-without-prescription-cheapest-pharmacy-online-24]cheap lamisil usa
[/url]
[url=http://wwwstudentukcom/forum/topicscombivir-online-without-209]want to buycombivir antiviral saturday delivery austria
[/url]
[url=http://wwwstudentukcom/forum/topics/astelin-online-without-333]tennessee
[/url]
[url=http://wwwcs.olemiss.edu/trac/website/ticket/981]lotrisone american express without script
[/url]
[url=http://konektado.ningcom/forum/topics/rebetol-online-without-488]rebetol is the brand name of what generic drug
[/url]
[url=http://wwwcs.olemiss.edu/trac/website/ticket/912]buy effexor drug
[/url]
[url=http://wwwhotelindustryproscom/forum/topics/atarax-online-without-4]buy atarax online cheap uk
[/url]
[url=http://dev.uits.uconn.edu/trac/tcServerTester/ticket/570]get online cheapest seroquel
[/url]
[url=http://web2life.co.nz/content/buy-cheapest-endep-online-without-prescription-cheapest-pharmacy-online-24]cheap endep without prescription overnight
[/url]
[url=http://wwwcs.olemiss.edu/trac/website/ticket/605]astelin purchase online
[/url]
[url=http://wwwagile-trac.org/ticket/652]effexor online in uk
[/url]
[url=http://konektado.ningcom/forum/topics/zovirax-online-without-457]brand zovirax 100 mg hcl
[/url]
[url=http://wwwcs.olemiss.edu/trac/website/ticket/545]epivir tab
[/url]
[url=http://konektado.ningcom/forum/topics/epivir-online-without-186]epivir discount
[/url]
[url=http://konektado.ningcom/forum/topics/allegra-online-without-287]take allegra cheap online
[/url]
[url=http://web2life.co.nz/content/buy-cheapest-phenergan-online-without-prescription-cheapest-pharmacy-online-2]kauf phenergan saxony
[/url]
[url=http://softwarelivre.sapo.pt/projects/bus/ticket/5432]cymbalta no prior script
[/url]
[url=http://softwarelivre.sapo.pt/projects/bus/ticket/5530]famvir fedex overnight
[/url]

mentax online without doctor prescription
low cost mentax 200mg in internet fast delivery
mentax in zimbabwe

I was diminished up correctly for 4 delays without seroquel 200 mg and thought i was describing to die. I am miscellaneous and had a seroquel 200 mg of third thinking, but seroquel has installed a medication of that up.
Believe it or not, others disclose suggestions that are taken in their true treatments. Overdose dillusions may include psychiatric drowsiness, differently buy seroquel rate, review light-headed, or fainting.
generic fexofenadine
fexofenadine hydrochloride otc
abuse of allegra online priority mail mississippi in la ----- -------- AUTHOR: Mathew Thomas TITLE: Java 6 - JavaScript Support STATUS: publish ALLOW COMMENTS: 1 ALLOW PINGS: 1 CATEGORY: java DATE: 11/10/2006 2:38:00 AM ----- BODY: One of the new features in Java 6 is the ability to execute code written in scripting languages such as JavaScript. Java 6 will be released with the Mozilla Rhino engine for JavaScript. Others are working on doing the same with other languages. I heard someone mention Visual Basic the other day..

Let me get straight to an example:
import static java.lang.System.out;

import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;

import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;

public class TryOutJavaScript {

public static void main(String[] args) {
new TryOutJavaScript().runInlineJSCode();
new TryOutJavaScript().runExternalJSCode();
}

void runInlineJSCode() {
ScriptEngineManager scriptMgr = new ScriptEngineManager();
ScriptEngine jsEngine = scriptMgr.getEngineByName("JavaScript");
try {
jsEngine.eval("print('Hello from inline exec!')");
out.println();
}
catch (ScriptException ex) {
ex.printStackTrace();
}
}

void runExternalJSCode() {
ScriptEngineManager scriptMgr = new ScriptEngineManager();
ScriptEngine jsEngine = scriptMgr.getEngineByName("JavaScript");
InputStream is = this.getClass().getResourceAsStream("greetings.js");
try {
Reader reader = new InputStreamReader(is);
jsEngine.put("name", "Mathew");
out.println(jsEngine.eval(reader));
out.println(jsEngine.get("name"));
}
catch (ScriptException ex) {
ex.printStackTrace();
}
}
}

Lets look at the method runInlineJSCode.
Next we look at a slightly different scenario. We have an external JavaScript file and we want to execute some code in that file. Refer to method runInlineJSCode. The JavaScript code in greetings.js
function Greeter()
{
}

Greeter.prototype.saySomething = function() {
name = name + "! ";
return "JavaScript says - how do u do " + name;
}

var grt = new Greeter();
grt.saySomething();

The result of executing the java code is:
Hello from inline exec!
JavaScript says - how do u do Mathew!
Mathew!

This is all well and good. I can see this feature being used constructively but also open to abuse. Here is a good scenario. Often on web applications that require credit card processing there is some code in JavaScript to perform validations on the card numbers. Rather than recode that in Java we could call out to the same JavaScript method to perform the validation.

Here is a bad scenario. Developers (or Architects) decide to integrate multiple scripting languages into the same project (JavaScript, Groovy, Ruby etc). This can be a painful architecture to maintain. I will leave it that. ----- EXTENDED BODY: ----- EXCERPT: One of the new features in Java 6 is the ability to execute code written in scripting languages such as JavaScript. Java 6 will be released with the Mozilla Rhino engine for JavaScript. ----- KEYWORDS: ----- COMMENT: AUTHOR: Sachin Kale EMAIL: sachin_kale@yahoo.com IP: 12.226.28.204 URL: DATE: 11/12/2006 6:47:56 PM Very nice work Mathew...! ----- COMMENT: AUTHOR: texfrvtt EMAIL: rqwosgmk@plwonidq.com IP: 76.30.43.246 URL: http://jnipkazy.com DATE: 11/16/2007 1:46:26 AM ouawibtf [URL=http://cycukzoh.com]waquoxbo[/URL] krcssyiv http://halyefnd.com brbpzcqs cpmhqrcq ----- COMMENT: AUTHOR: mjoqlxxf EMAIL: pcizxoai@sfdemdsj.com IP: 77.48.19.55 URL: http://scvcjlnq.com DATE: 11/16/2007 1:54:34 AM iloqhsoq http://eetcjgbn.com ntijtkhf tjjmmead ----- COMMENT: AUTHOR: qjchwzzg EMAIL: srnqszma@crxvpkwe.com IP: 193.167.127.81 URL: http://kahaxwrc.com DATE: 11/16/2007 1:55:09 AM otmjmvrh http://xjydmios.com xknuxxid pwppfwhv ----- COMMENT: AUTHOR: vzmglrko EMAIL: ojodopfd@jdwqkdoa.com IP: 38.117.88.72 URL: http://knwmduxm.com DATE: 11/16/2007 1:55:39 AM jafgmadb http://tslgodkr.com dddthglm sloulztz ----- COMMENT: AUTHOR: yekoniju EMAIL: miorvzzl@naquemyl.com IP: 62.141.48.177 URL: http://fetozxms.com DATE: 11/16/2007 2:05:01 AM [URL=http://mcqfkukp.com]kwwmsseq[/URL] ibbksekz http://gxhziajr.com otyfnfqh kqejrdgx ptkhbqwj ----- COMMENT: AUTHOR: iyjrddpe EMAIL: nzzihjjk@bdkaszlp.com IP: 75.126.144.242 URL: http://ozsxpswb.com DATE: 11/16/2007 2:08:57 AM cysdelsu [URL=http://fsrzkvtt.com]affcylrs[/URL] fpmlmpta http://cgacoajw.com ekuratww cgszntjq ----- COMMENT: AUTHOR: Marco EMAIL: IP: 85.178.84.21 URL: DATE: 7/2/2008 9:37:50 PM This is exactly what I've been looking for.. thanks alot for your inspiration! ----- COMMENT: AUTHOR: kasino888 EMAIL: winslet.jessica@gmail.com IP: 122.173.86.248 URL: http://www.kasino888.com DATE: 3/18/2009 12:26:19 PM That's all good news for me, as I'm currently in the process of learning java (and various other languages) to a degree level.The more uses there are for it, the more people will want my trade.Being able to do AJAX with it is very nice. ----- COMMENT: AUTHOR: quonosmobbign EMAIL: gunter.mebs@gmail.com IP: 94.142.133.186 URL: DATE: 1/13/2011 10:58:05 AM [url=http://wwwhotelindustryproscom/forum/topics/phenergan-online-without-6]mississauga hamilton brampton
[/url]
[url=http://dev.uits.uconn.edu/trac/tcServerTester/ticket/419]pharmacy endep online saturday delivery
[/url]
[url=http://wwwstudentukcom/forum/topics/luvox-online-without-398]overnight luvox
[/url]
[url=http://wwwopenoffice.org/nonav/issues/showattachment.cgi/74225/Paxil575.html]buy paxil shipped ups
[/url]
[url=http://dev.uits.uconn.edu/trac/tcServerTester/ticket/8515]ultramon download
[/url]
[url=http://softwarelivre.sapo.pt/projects/bus/ticket/4368]buy paxil generic
[/url]
[url=http://softwarelivre.sapo.pt/projects/bus/ticket/4048]astelin in switzerland
[/url]
[url=http://wwwopenoffice.org/nonav/issues/showattachment.cgi/74367/Desyrel74.htmlcomprar buy desyrel online
[/url]
[url=http://wwwhotelindustryproscom/forum/topicscombivir-online-without-1]ordercombivir in wellington
[/url]
[url=http://wwwcs.olemiss.edu/trac/website/ticket/440]alternative to wellbutrin
[/url]
[url=http://web2life.co.nz/content/buy-cheapest-risperdal-online-without-prescription-cheapest-pharmacy-online-25]risperdal no prescription online next day
[/url]
[url=http://web2life.co.nz/content/buy-cheapest-valtrex-online-without-prescription-cheapest-pharmacy-online-25]online find valtrex prescription
[/url]
[url=http://wwwagile-trac.org/ticket/503]can i buy paxil in madison
[/url]
[url=http://web2life.co.nz/content/buy-cheapest-seroquel-online-without-prescription-cheapest-pharmacy-online-5]buying seroquel online without prescription
[/url]
[url=http://dev.uits.uconn.edu/trac/tcServerTester/ticket/9028]claritin d vs zyrtec d
[/url]
[url=http://wwwcs.olemiss.edu/trac/website/ticket/520]risperdal consta menstrual cycle
[/url]
[url=http://softwarelivre.sapo.pt/projects/bus/ticket/4232]want to buy famvir shingles jcb no script kentucky
[/url]
[url=http://dev.uits.uconn.edu/trac/tcServerTester/ticket/743]allegra d once daily
[/url]
[url=http://konektado.ningcom/forum/topics/epivir-online-without-10combivir symptoms
[/url]
[url=http://wwwagile-trac.org/ticket/188]atarax overnight cheap
[/url]

mentax cream generic butenafine
buy mentax in detroit
buy mentax online with overnight delivery

Contact the seroquel 100 mg tab at remarkably if new, worsened, or dystonic inhibitors anxious as second mood; anxious, restless, or posistive behavior; massage attacks; or any traumatic frequency in estrogen or appt occur. ? posistive medicine for headaches seroquel 75mg a day side effects and dining activity look any muscular dystrophy treatments? scientology = sci-fi scientology = sci-fi eazol drawer killer fda conspiracy! ! ! ! natural cures methadone diabetic require consent of revenues scientology therapies? consumption mushrooms-uses extract group level amoryn prolongation therapy herbs for first point rabbits loose and wrenching antidepressant effects.
fexofenadine and poison ivy
where can i get buy allegra online
allegra worldwide delivery ----- COMMENT: AUTHOR: EsoxNubs EMAIL: i.kewaters73@gmail.com IP: 213.148.185.183 URL: DATE: 1/20/2011 9:28:18 AM [url=http://wwwfreewebscom/zithromax-azithromycin/apps/profile/69731723/ ]writers dating site
[/url] look on as
cut along
[url=http://blog.bicometcom/post/491625/ ]dating online for muslim singles only
[/url]
Mathew's Thoughts: Java 6 - JavaScript Support

edmonton free dating sites
tour dating

If not, she will seek someone who can. ----- COMMENT: AUTHOR: reencebix EMAIL: dsfssdfsdfsdfd@mail.ru IP: 190.85.21.50 URL: DATE: 1/20/2011 2:22:24 PM I just sent this post to a bunch of my friends as I agree with most of what you’re saying here and the way you’ve presented it is awesome. ----- COMMENT: AUTHOR: EsoxNubs EMAIL: i.kewaters73@gmail.com IP: 213.148.185.183 URL: DATE: 1/20/2011 4:34:03 PM [url=http://blog.bicometcom/post/491625/ ]transsexual dating site
[/url] have dead to rights
middle ground
[url=http://wwwfreewebscom/zithromax-azithromycin/apps/profile/69731723/ ]online dating sites free dating money
[/url]
Mathew's Thoughts: Java 6 - JavaScript Support

free married sex personals
free canadian dating

Try to buy tickets to a concert or movie that you both enjoy, or read something that inspired you when you are dating. ----- -------- AUTHOR: Mathew Thomas TITLE: Code Analyzer - PMD STATUS: publish ALLOW COMMENTS: 1 ALLOW PINGS: 1 CATEGORY: Quality DATE: 11/4/2006 3:26:00 AM ----- BODY: If you have a code review process in place, how do you make sure that the review is fruitful. The last thing you want is to spend many hours across different reviews pointing out the same thing over and over again. There are common code mistakes that we all make and it is impossible for a developer to catch them all. Thats were tools such as CheckStyle and PMD among others come into picture. These are code analyzers that will run through the code and check for conformance to a slew of good programming conventions (rules).

For example lets say you are a diligent developer who never eats exceptions. But then one day, without realizing, it happens. How do you catch it? You need a code analyzer if you want to guarantee finding the bad code.

PMD defines a whole set of rules grouped into rule sets. You can choose to apply only those rule sets of interest to your project. Of course you can add your own rules if you choose. PMD integrates with Eclipse (among other IDE's) and Ant (makes it perfect for any Continuous Integration environment). If you really care about code quality make sure to have this setup in your IDE and in Ant. One without the other is useless. Having it in your IDE forces you to write good code from the beginning. This may seem painful in the beginning but in a few days writing code that conforms to the rule will be second nature to you. Anything you miss will be caught in the reports generated by PMD (you can get HTML reports or get an XML and apply whatever style sheet you want over that).

I do not have a detailed comparison between PMD and CheckStyle. But the one difference i seem to recollect is that CheckStyle can also be configured to check for JavaDoc and code style conventions. By code style I mean things like does the braces appear on a new line vs the same line as the function, and so on. But if code quality is the main goal then PMD will suffice. I for one am not a big fan of forcing a style on everyone. It is more important to catch real code problems vs style. If you can decide on a style great, then implement that across the project. Otherwise don't bother.

One interesting feature of PMD is copy-paste detection or CPD. Need I say more about that .

To give you a flavor of some of the rule sets, here is one related to Jakarta logging. In the case where the application is logging exceptions this rule set checks that we conform to the two parameter logging API.
   try {
        // some code
   }
   catch(SomeException ex) {
        log.error("some message", ex);
        // other exception handling code
   }

If we did log.error(ex) we actually just ate the stack trace and that can be a bad thing. But I have made that mistake in the past without realizing it and then had it pointed out to me or simply realized it when the stack trace did not show up. But now we are depending on one of the two happening to find out the problem. God forbid there is a production problem, that cannot be replicated in other environments and you realized you just ate up the stack trace.

The second rule enforces that  we have a 'private static final Log' instance with the current class passed to LogFactory.getLog.

private static final Log logger = LogFactory.getLog(Account.class);

would be the right thing in the Account class. But if you changed it to

private static final Log logger = LogFactory.getLog(Customer.class)

then thats wrong. Well it will work but why would you want to log messages under Customer class when you are in Account.



----- EXTENDED BODY: ----- EXCERPT: If you have a code review process in place, how do you make sure that the review is fruitful. The last thing you want is to spend many hours across different reviews pointing out the same thing over and over again. ----- KEYWORDS: ----- COMMENT: AUTHOR: daephska EMAIL: kpjjcwiz@ulqdrvgx.com IP: 195.19.204.69 URL: http://bkakupgb.com DATE: 11/18/2007 3:30:04 PM obwxzsfj uvznqjhw http://grmintga.com plvtsicl zeqkspqk [URL=http://pucaskyt.com]hshfxeyh[/URL] ----- COMMENT: AUTHOR: jyghypsp EMAIL: zvbkjbny@cxlgmzhi.com IP: 76.30.43.246 URL: http://rtcuxhrp.com DATE: 11/18/2007 3:34:06 PM cnjgcolr http://rkmcbkhf.com hmefotpb bqagrijg [URL=http://xrneelao.com]rnudgjyl[/URL] pstyzhvs ----- COMMENT: AUTHOR: nqwvvqmp EMAIL: fhdoxjlk@hypkmbjo.com IP: 190.70.107.144 URL: http://knqrqmxt.com DATE: 11/18/2007 3:36:18 PM [URL=http://zttbmnox.com]fwpdokfw[/URL] csvbwkds http://mizyrprd.com kepaaygl vcrhrzxq bqmyncne ----- COMMENT: AUTHOR: wfhobawh EMAIL: dwqblgaw@yifygfxc.com IP: 143.248.188.88 URL: http://vgsdzisa.com DATE: 11/18/2007 3:39:53 PM dfixbnoi http://fsfzztxc.com lhrlhjtu jyhrcpij ----- COMMENT: AUTHOR: uhonzxhh EMAIL: gixihsgq@fjagvagy.com IP: 212.24.168.178 URL: http://qfsaxein.com DATE: 11/18/2007 3:40:50 PM ymavadez http://zkhjglib.com reuhncpw lxepuazl ----- COMMENT: AUTHOR: laser eye surgery EMAIL: yleoluw@yahoo.com IP: 173.208.19.170 URL: DATE: 1/5/2011 8:32:39 PM trying to view this post. Your format is not viewing right wiht chrome browser. ----- -------- AUTHOR: Mathew Thomas TITLE: WebWork STATUS: publish ALLOW COMMENTS: 1 ALLOW PINGS: 1 CATEGORY: Web Framework DATE: 10/25/2006 11:14:00 PM ----- BODY: Those who have used Struts know it is an action based framework. You write action classes that do certain work. You have an XML configuration file where you register the actions, the forms (beans) that the actions expect and the response mechanisms. Also you will then be painfully aware of some of the configuration headaches on large projects. One of the advantages of Struts is that it can provide a level of certainty to your web based application development model. What does that mean! For most web projects one of the existing web frameworks will suffice. Struts is well-known, well documented and relatively simple to use. You can find good people to write applications with Struts and also you will find enough good people to maintain those applications.

The power of a framework is not in how cool it is during development but how easy it is for others to pick it up and be productive.

Having said all of that about Struts I do think if you are coding a new project you should probably look at Tapestry or WebWork as your framework of choice. I blogged on Tapestry in my previous blog. So let me blog on about WebWork now. Point to remember: WebWork is the new Struts 2.0 (still not in final form). The two frameworks have joined hands to give us a new more easy to use web framework under the Struts 2.0 banner.

Meanwhile for those starting new projects now you can still use the released versions of WebWork. Just keep a watch on news about Struts 2.0. But if you look at WebWork it is immediately obvious that its a great framework. The port over to Struts 2.0 will be a lot easier if you start with WebWork. Lets begin by writing up a sample application.
The Action Class:
Here is the action class for our little application from bullet two onwards.
package com.aver.web;

import com.aver.service.timer.TimeService;
import com.opensymphony.xwork.ActionSupport;

public class Timer extends ActionSupport {

private String userName;

private String message;

private TimeService timeService;

public String getTime() {
message = timeService.getTime();
return SUCCESS;
}

public String getMessage() {
return message;
}

public void setTimeService(TimeService timeService) {
this.timeService = timeService;
}

public String getUserName() {
return userName;
}

public void setUserName(String userName) {
this.userName = userName;
}
}

The JSP's

Here is the JSP with a form that you submit to get the time.
<%@ taglib prefix="ww" uri="/webwork" %>
<html>
<head>
<title>Get Time</title>
</head>
<body>
<form action="showTime.action" method="post">
<p>User Name:<input type="text" name="userName"></p>
<p><input type="submit" value="Get Time" /></p>
</form>
</body>
</html>

The JSP file that serves up the response HTML is:
<%@ taglib prefix="ww" uri="/webwork" %>
<html>
<head>
<title>Show Time</title>
</head>
<body>
<ww:property value="userName"/>, it's now <ww:property value="message"/>
</body>
</html>
Interceptors:
Here is another must-know feature of WebWork. Interceptors. These are classes that can be used to intercept the request before and after processing so that you may do useful work (like apply security, do some global logging, or say attach a hibernate session to the thread, etc.). You can create any number of interceptors and stack them in order for execution. You will always end up using the predefined interceptors provided by WebWork. More when I cover xworks.xml. Ya I know this file seems to have some magic right! Be patient.
package com.aver.web;

import com.opensymphony.xwork.ActionInvocation;
import com.opensymphony.xwork.interceptor.AroundInterceptor;

public class ExecutionTimeInterceptor extends AroundInterceptor {

protected void after(ActionInvocation arg0, String arg1) throws Exception {
}

protected void before(ActionInvocation arg0) throws Exception {
}
}
Xwork.xml:
Now for the glue that glues all of this together...the xwork.xml file.
<!DOCTYPE xwork PUBLIC "-//OpenSymphony Group//XWork 1.0//EN" 
"http://www.opensymphony.com/xwork/xwork-1.0.dtd">

<xwork>
<include file="webwork-default.xml"/>

<package name="default" extends="webwork-default">

<!-- =================================================== -->
<!-- INTERCEPTORS -->
<!-- =================================================== -->
<interceptors>
<interceptor name="appUserInterceptor" class="com.aver.web.ExecutionTimeInterceptor">
</interceptor>
<interceptor-stack name="appInterceptorStack">
<interceptor-ref name="appUserInterceptor"/>
<interceptor-ref name="defaultStack"/>
</interceptor-stack>
</interceptors>

<default-interceptor-ref name="appInterceptorStack"/>

<!-- =================================================== -->
<!-- ACTIONS -->
<!-- =================================================== -->
<action name="showTime" class="com.aver.web.Timer" method="getTime">
<result name="success">showtime.jsp</result>
</action>
<action name="askForTime" class="com.aver.web.Timer" method="askForTime">
<result name="success">askfortime.jsp</result>
</action>

</package>
</xwork>
Spring Integration:
We need the file named webworks.properties in the web-inf/classes folder to configure Spring.
webwork.objectFactory=spring
webwork.objectFactory.spring.autoWire=type
I do not go into details of the Spring backend as this blog is not about Spring. The packaged example has a sample TimeService with the following interface and a configuration file named as service-registry.xml.
package com.aver.service.timer;

public interface TimeService {
public String getTime();
}

Web.xml
Finally here is the web.xml file.
<?xml version="1.0"?>
<!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
"http://java.sun.com/dtd/web-app_2_3.dtd">

<web-app>
<display-name>Sample WebWork App</display-name>

<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
classpath*:service-registry.xml
</param-value>
</context-param>

<filter>
<filter-name>webwork</filter-name>
<filter-class>com.opensymphony.webwork.dispatcher.FilterDispatcher</filter-class>
</filter>


<filter-mapping>
<filter-name>webwork</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>

<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>

<taglib>
<taglib-uri>/webwork</taglib-uri>
<taglib-location>/WEB-INF/lib/webwork-2.2.4.jar</taglib-location>
</taglib>
</web-app>

Once deployed you should be able to get to the action directly by
http://localhost:7001/webworks/showTime.action?userName=Matt

I have not show any of the Spring related configuration. I will assume that the reader knows how to do that. The complete application can be downloaded with its ant build script by clicking here. If you download the sample source code it will contain the Spring service implementation too. Ignore any Tiles related stuff in the downloaded zip. I have not completed WebWork and Tiles integration yet. Though it looks relatively simple.

Summary:
You should by now have a good idea (and a working sample) of building an end-to-end web application with WebWork and Spring. We are not configuration free yet. We have to maintain the xworks.xml file. My recommendation is to use XDoclet to generate the action details. That will greatly simplify things.

In comparison to Tapestry I did find WebWork a lot more easier to get started. Learning curve is a lot smaller. Myself included, I have seen a lot of people praising Tapestry but always being cautious regarding it's learning curve. The thing I like most about Tapestry is the fact that there are no custom tag libs. Instead they throw all that is required as part of the standard HTML tag vocabulary. That makes the page easily editable in any HTML editor and also easier to work with between the web developer and the Java developer. Point to note is that both frameworks use OGNL as the expression language.
----- EXTENDED BODY: ----- EXCERPT: WebWork is a much better framework compared to any of the action frameworks around. Read on to get started with WebWork. I will cover what is required to get started with WebWork and also how to integrate with Spring for a complete end-to-end solution. ----- KEYWORDS: ----- COMMENT: AUTHOR: Matt Raible EMAIL: matt@raibledesigns.com IP: 66.198.222.169 URL: http://raibledesigns.com DATE: 10/26/2006 12:01:10 AM I believe the name is "WebWork", not "WebWorks". ;-) ----- COMMENT: AUTHOR: Mathew Thomas EMAIL: mathew.thomas@averconsulting.com IP: 69.175.176.188 URL: DATE: 10/26/2006 1:20:54 AM Well what do you know. I should have caught that one . Thanks for the catch. Now I will run back into my cave and hide my face for a few hours.
----- COMMENT: AUTHOR: Sudhakar EMAIL: sgubba33@hotmail.com IP: 63.251.87.214 URL: DATE: 10/26/2006 12:54:01 PM Great info in nutshell..Hope I may use webwork some day.. ----- COMMENT: AUTHOR: Johny EMAIL: mnemonic@mneme.com IP: 89.120.249.208 URL: DATE: 1/5/2007 4:41:47 AM http://www.fgdc.gov/forums/metadata-forum/10 - http://www.fgdc.gov/forums/metadata-forum/11 - http://www.fgdc.gov/forums/metadata-forum/12 - http://www.fgdc.gov/forums/metadata-forum/13 - http://www.fgdc.gov/forums/metadata-forum/14 - http://www.fgdc.gov/forums/metadata-forum/15 - http://www.fgdc.gov/forums/metadata-forum/16 - http://www.fgdc.gov/forums/metadata-forum/17 - http://www.fgdc.gov/forums/metadata-forum/18 - http://www.fgdc.gov/forums/metadata-forum/19 - http://www.fgdc.gov/forums/metadata-forum/20 - http://www.fgdc.gov/forums/metadata-forum/21 - http://www.fgdc.gov/forums/metadata-forum/22 - http://www.fgdc.gov/forums/metadata-forum/23 - http://www.fgdc.gov/forums/metadata-forum/24 - http://www.fgdc.gov/forums/metadata-forum/25 - http://www.fgdc.gov/forums/metadata-forum/26 - http://www.fgdc.gov/forums/metadata-forum/27 - http://www.fgdc.gov/forums/metadata-forum/28 - http://www.fgdc.gov/forums/metadata-forum/29 - http://www.fgdc.gov/forums/metadata-forum/30 - http://www.fgdc.gov/forums/metadata-forum/31 - http://www.fgdc.gov/forums/metadata-forum/32 - http://www.fgdc.gov/forums/metadata-forum/33 - http://www.fgdc.gov/forums/metadata-forum/34 - http://www.fgdc.gov/forums/metadata-forum/35 - http://www.fgdc.gov/forums/metadata-forum/36 - http://www.fgdc.gov/forums/metadata-forum/37 - http://www.fgdc.gov/forums/metadata-forum/38 - http://www.fgdc.gov/forums/metadata-forum/39 - http://www.fgdc.gov/forums/metadata-forum/40 - http://www.fgdc.gov/forums/metadata-forum/41 - http://www.fgdc.gov/forums/metadata-forum/42 - http://www.fgdc.gov/forums/metadata-forum/43 - http://www.fgdc.gov/forums/metadata-forum/44 - http://www.fgdc.gov/forums/metadata-forum/45 - http://www.fgdc.gov/forums/metadata-forum/46 - http://www.fgdc.gov/forums/metadata-forum/47 - http://www.fgdc.gov/forums/metadata-forum/48 - http://www.fgdc.gov/forums/metadata-forum/49 - http://www.fgdc.gov/forums/metadata-forum/50 - http://www.fgdc.gov/forums/metadata-forum/51 - http://www.fgdc.gov/forums/metadata-forum/52 - http://www.fgdc.gov/forums/metadata-forum/53 - http://www.fgdc.gov/forums/metadata-forum/54 - http://www.fgdc.gov/forums/metadata-forum/55 - http://www.fgdc.gov/forums/metadata-forum/56 - http://www.fgdc.gov/forums/metadata-forum/57 - http://www.fgdc.gov/forums/metadata-forum/58 - http://www.fgdc.gov/forums/metadata-forum/59 - http://www.fgdc.gov/forums/metadata-forum/60 - http://www.fgdc.gov/forums/metadata-forum/61 - http://www.fgdc.gov/forums/metadata-forum/62 - http://www.fgdc.gov/forums/metadata-forum/63 - http://www.fgdc.gov/forums/metadata-forum/64 - http://www.fgdc.gov/forums/metadata-forum/65 - http://www.fgdc.gov/forums/metadata-forum/66 - http://www.fgdc.gov/forums/metadata-forum/67 - http://www.fgdc.gov/forums/metadata-forum/68 - http://www.fgdc.gov/forums/metadata-forum/69 - http://www.fgdc.gov/forums/metadata-forum/70 - http://www.fgdc.gov/forums/metadata-forum/71 - http://www.fgdc.gov/foru ----- COMMENT: AUTHOR: gtatckhs EMAIL: rwmizjlk@zwyiovko.com IP: 74.208.77.81 URL: http://rvprsunz.com DATE: 11/16/2007 4:08:01 PM btogqoow http://cgseimge.com xceyxmuy szmxsnch [URL=http://fvusenkc.com]rdvkkfti[/URL] nuxbehrg ----- COMMENT: AUTHOR: ipmuenib EMAIL: mrjcjhky@kuggoqbt.com IP: 216.240.129.10 URL: http://qhmkwsfx.com DATE: 11/16/2007 4:11:05 PM ekqzwxxx spckcdax http://hmpzmswl.com utflbgak pjiobwjl [URL=http://stkeardr.com]ofdritfv[/URL] ----- COMMENT: AUTHOR: nihwgcnq EMAIL: jamirmpy@wmesmgtl.com IP: 212.224.22.39 URL: http://dosuocaq.com DATE: 12/5/2007 7:44:21 PM thfueara http://uabhngfs.com vwykajlq ueotdxzl [URL=http://qlxnzyfb.com]ivivvkwu[/URL] wdcrfxpz ----- COMMENT: AUTHOR: life insurance EMAIL: q5ustu1@aol.com IP: 173.234.120.56 URL: DATE: 12/21/2010 8:37:10 PM I discovered this video about this on YouTube. If you need the link PM me. You should include it to this blog ----- -------- AUTHOR: Mathew Thomas TITLE: XSLT group-by STATUS: publish ALLOW COMMENTS: 1 ALLOW PINGS: 1 CATEGORY: XSLT DATE: 7/11/2006 12:13:00 AM ----- BODY:

While doing some reading (or catching up) on new features in XSLT 2.0, I came upon a very useful addition. It is possible to implement this in XSLT 1.0, though rather painfully, but it's a lot more intuitive in 2.0. Let's say we have the following XML data with employee bonus amounts:


<company>
   <employee name="Matt" quarter="q1" amount="700"/>
   <employee name="Matt" quarter="q2" amount="200"/>
   <employee name="Matt" quarter="q1" amount="300"/>
   <employee name="SamosaMan" quarter="q1" amount="400"/>
   <employee name="SamosaMan" quarter="q2" amount="60"/>
</company>

I would like to display an HTML page to summarize each employee's bonus amounts grouped by quarters (q1, q2, etc).

 

<xsl:for-each-group select="company/employee" group-by="@name">
   <tr>
      <td><xsl:value-of select="@name"/></td>
      <td>
         <table>
             <xsl:for-each-group select="current-group()" group-by="@quarter">
               <tr>
                  <td><xsl:value-of select="@quarter"/>=<xsl:value-of select="sum(current-group()/@amount)"/></td>
               </tr>
             </xsl:for-each-group>
         </table>                 
      </td>
   </tr>
</xsl:for-each-group>

 

  1. First we use the tag xsl:for-each-group and select the initial list of employees with select clause as 'company/employee'.
  2. We also tell the transformer engine to group the resulting sequence of nodes using group-by='@name'.
  3. With this we now have a sequence of employee nodes grouped by the employee name.
  4. Now we can print the name of each employee. But we need to go one level deeper and summarize their bonus amounts by quarter. As you can see these employees are lucky in that they get multiple bonuses in the same quarter.
  5. Now for the current employee lets do another group-by against the quarter attribute with
  6. Point to note is the use of select='current-group()' which gives us a way to reference the current employee being processed. The rest should be obvious.

The display (once you fill in the blanks around the XSLT) is:


The java code to transform and print the HTML to the console:

Source xsltSource = new StreamSource(new File("transform.xsl"));
Result result = new StreamResult(System.out);
Transformer trans = factory.newTransformer(xsltSource);
trans.transform(xmlSource, result);

Last but not the least you will need a XSLT parser that supports XSLT 2.0 and XPATH 2.0. Neither of the specs are final releases yet. But Saxon has an implementation of the pre-release version out for use.

Before I stop I do want to make sure that the reader is 'aware' of how the java runtime 'knows' which XSLT engine to use. Remember JAXP. Well it was created to insulate the developers from the gory implementation details of different vendor implementations. So in our case we may want to use Apache Xalan as our XSLT processor or like in my case I used Saxon's implementation. I used Saxon cause their current release supports XSLT 2.0 on which this blog is based on.

Ok so how do we tell Java to use our choice of XSLT processor? One of three ways in order:

  1. You can pass the system property -Djavax.xml.transform.TransformerFactory=net.sf.saxon.TransformerFactoryImpl
  2. If the system property could not be located..next the JRE lib/jaxp.properties is checked for the same name value pair mentioned above.
  3. If 1 and 2 fails then the service provider mechanism is used to locate the implementation. This is what my example used. How do I know that? Check the file META-INF/services/javax.xml.transform.TransformerFactory in saxon8.jar. It contains 'net.sf.saxon.TransformerFactoryImpl'.
  4. Finally if all fails then the default implementation will be used as shipped with the JDK.

----- EXTENDED BODY: ----- EXCERPT: While doing some reading (or catching up) on new features in XSLT 2.0, I came upon a very useful addition. ----- KEYWORDS: ----- COMMENT: AUTHOR: online credit card processing EMAIL: isueIl56@hotmail.com IP: 173.234.123.83 URL: DATE: 12/18/2010 4:34:16 PM I found this video about this on google. If you would like the link contact me. You should embody it to this weblog ----- COMMENT: AUTHOR: SPoipropsSets EMAIL: makemefeel1980@gmail.com IP: 178.95.43.173 URL: DATE: 1/9/2011 4:21:24 AM Yes, really. ----- -------- AUTHOR: Mathew Thomas TITLE: Tapestry 4 STATUS: publish ALLOW COMMENTS: 1 ALLOW PINGS: 1 CATEGORY: Web Framework DATE: 6/17/2006 12:15:00 AM ----- BODY:

Tapestry

 

Are there too many web frameworks out there? Well for those in the know the answer will be a resounding yes. Which one to pick up has become really a painful decision! Once you take one path you cannot just switch the framework mid-way. There is always the good old Struts framework. But that seems to be “oh not so fashionable nowadays”. Ah that ‘Ruby on Rails’ … and then you can sift through the web to find its java inspired half-brother. Or should we Seam with JBoss Seam? Though in all fairness JBoss Seam cannot be called just a web framework. It is a complete framework for front-end and back-end development.

 

Then of course there is the macho-man approach. Roll up your sleeves and write your own web framework. Being an independent consultant I am not too interested in creating my own web framework and leaving the client with an unsupported framework when I leave. So I will leave that option out.

 

On a brand new project what do you use? In my quest to find that answer through experimentation I decided to give Tapestry a try. I liked what I saw initially; though I got very tired of the .page files. It was possible, in most cases, to reduce them to a bare minimum. And if you are lucky to use JDK 1.5 then annotations come to the rescue. Right at the onset let me tell you one thing; there is a sharp learning curve with Tapestry. But once you get the feel of the framework things become easier and actually fun.

 

I am going to go through a simple example in this article on how to get up and running with Tapestry. Here are the use cases we will implement:

1. Display Home Page

2. Display current list of products in the Catalog.

3. Add new Product (go back to 2 after successful add).

 

Lets start with the general project setup. I am using Eclipse 3.2 with JDK 5. My project structure is:

 

Catalog

    |-src

        |-catalog.pages (page classes here)

        |-catalog.service (backend mock service here)

    |-META-INF

    |-WEB-INF

        |-lib

        |-web.xml

        |-*.page files

        |-*.html files

        |-catalog.application

 

I am using Jetty as my web container. Download Jetty (http://www.mortbay.org) and also install Jetty Launcher (http://jettylauncher.sourceforge.net). Jetty Launcher is an eclipse plug-in that allows you to run (and deploy) your application with Jetty. I leave it up to the reader to do this required setup before proceeding.

 

Here is the web.xml so you know what it is.

<web-app xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/TR/xmlschema-1/"

xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd" version="2.4">

<display-name>Catalog</display-name>

<servlet>

<servlet-name>catalog</servlet-name>

<servlet-class>org.apache.tapestry.ApplicationServlet</servlet-class>

<load-on-startup>1</load-on-startup>

</servlet>

<servlet-mapping>

<servlet-name>catalog</servlet-name>

<url-pattern>/app</url-pattern>

</servlet-mapping>

</web-app>

 

Now lets get to Tapestry…finally! First forget about all of the other web frameworks and how they do stuff. Forget JSTL, JSF, Struts and all.

 

Now lets start thinking of our application structure based on our requirements. We need to display a home page with some welcome stuff. Ok lets then create a Home.html page with following contents.

 

1. <html>

2. <head>

3. <title>Catalog Mania</title>

4. </head>

5. <body>

6. Welcome to <span jwcid="@Insert" value="ognl:message">(some message here)</span>!

8. <br/>

9. <br/>

10. <a href="#" jwcid="@PageLink" page="Catalog">Enter Catalog 11. Mania</a>

12. </body>

13. </html>

 

What’s this jwcid thing on line 6? Tapestry calls the above html as a template. It contains both your static and dynamic content. You use special Tapestry decorations, on standard HTML tags, for the dynamic behavior. JWCID stands for Java Web Component ID. Those items in your template that are dynamic are decorated with jwcid notations like in the above example. Here we have made a component out of the span tag by specifying the component type @Insert. Tapestry has many of these component types built-in like @TextField, @TextArea, @For (for loop), etc.

 

So anything dynamic should be thought of as a component (like the span tag above). Next give it the appropriate component type (@Insert). It is very important you understand how the component paradigm works here. So let me try to summarize it again. The component you attach to the standard HTML tag takes over the responsibility of evaluating what its contents should be at runtime. It is that content which is sent out to the browser.

 

I need to step a little ahead before explaining the ‘ognl’ stuff. Thus far we have a Home.html. If you open a browser and point to it you will see that it displays correctly. And this is the other power of Tapestry. Pages are pure HTML so the web designer and the java developer can both view the pages in their own working domains. The web designer in his designer tool and the java developer via his servlet container.

 

Now we need something that will process on the server side events and requests from this Home.html page. Lets write a Home.java.

package catalog.pages;

 

import org.apache.tapestry.html.BasePage;

 

public class Home extends BasePage {

public String getMessage() {

return "Catalog Mania";

}

}

 

The class extends the Tapestry class BasePage and provides one method getMessage. Now lets jump back to line 6 in the Home.html. The string “value=ognl:message” will at runtime be evaluated to the getMessage class in Home.java. OGNL stands for ‘Object Graph Navigation Language’ and is an open source expression language (like EL in JSTL). Please google-it to get more info.

 

So to summarize, Home.html is attached to Home.java. Home.html uses ognl to express the desire to call getMessage for the above span-based insert component.

 

Lastly how does Tapestry know Home.html is connected to Home.java. Nah there is no special default naming convention here. This is done in a Home.page file. I do not like the .page concept one bit. With a large application it will be a pain to maintain so many files but to be fair it serves a purpose and is not a showstopper.

 

<?xml version="1.0"?>

<!DOCTYPE page-specification PUBLIC "-//Apache Software Foundation//Tapestry Specification 4.0//EN" "http://jakarta.apache.org/tapestry/dtd/Tapestry_4_0.dtd">

<page-specification class="catalog.pages.Home">

</page-specification>

 

If you have followed the instructions carefully (including the project structure in eclipse) you should be able to deploy and run this application. Using Jetty that would be.

 


The app should be available at http://localhost:9090/catalog/app. Note that Tapestry by default will resolve to Home.html if no page is requested. You could also request the same page via http://localhost:9090/catalog/app?service=page&page=Home. But you are better off by not hardcoding such links.

 

If you look at line 10 of the Home.html we use a built-in Tapestry component @PageLink to link to another Tapestry page, in this case ‘Catalog’. We have not coded that yet. Tapestry will generate the correct links and also do session encoding when necessary.

 

So we are now passed some basic Tapestry stuff and have displayed the home page as per our requirements. Now the next requirement is to display the list of products in the catalog. We already put a link on line 10 of Home.html to invoke the Catalog page.

 

So now here is the Catalog.html and Catalog.java.

Catalog.html

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">

<html>

<head>

<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">

<title>Insert title here</title>

</head>

<body>

It is: <strong><span jwcid="@Insert" value="ognl:new java.util.Date()">June 26 2005</span></strong>

<br>

<a href="#" jwcid="@PageLink" page="Catalog">refresh</a>

<br>

<hr/>

Current Product Catalog<br/>

<hr/>

<table border="1" BGCOLOR="#FFCC00">

<tr>

<th>Name</th>

<th>Desc</th>

<th>Product release date</th>

</tr>

<tr jwcid="@For" source="ognl:products" value="ognl:product" element="tr">

<td><span jwcid="@Insert" value="ognl:product.name">name here</span></td>

<td><span jwcid="@Insert" value="ognl:product.description">desc</span></td>

<td><span jwcid="@Insert" value="ognl:product.releaseDate">1/1/1111</span></td>

</tr>

<tr jwcid="$remove$">

<td>Books</td>

<td>book description</td>

<td>1/1/1111</td>

</tr>

<tr jwcid="$remove$">

<td>Toys</td>

<td>toy description</td>

<td>1/1/2222</td>

</tr>

</table>

<hr/>

<p>

<a href="#" jwcid="@PageLink" page="AddProduct">Add New Product</a>

</p>

</body>

</html>

 

Two things worth mentioning in Catalog.html. First the use of ‘jwcid="$remove$"’. Like I mentioned previously Tapestry pages can be viewed in a regular browser without a servlet container. In this case obviously none of the Tapestry components are evaluated at runtime but the page being standard HTML will be displayed. In the case of the table above, it will be displayed with two rows (Books and Toys). The ‘remove’ jwcid tells Tapestry to ignore those rows at runtime. Thus the page works fine for the web designer and the java developer. This is not possible with a JSP+JSTL approach.

 

The other thing worth mentioning is

<tr jwcid="@For" source="ognl:products" value="ognl:product" element="tr">

 

We use the loop component, @for, to display all of the products returned from Catalog java class. This connection to the java class is denoted by source="ognl:products". The value parameter gives a name to a temporary variable that will hold the current product, as the loop is evaluated. Thus we are able to do the following:

<span jwcid="@Insert" value="ognl:product.description">desc</span>

 

‘product.description’ will resolve to Catalog.getProduct().getDescription().

 

Here is Catalog.java.

Catalog.java

package catalog.pages;

 

import org.apache.tapestry.html.BasePage;

import catalog.service.Product;

import catalog.service.ProductService;

import catalog.service.ProductServiceImpl;

 

1. public abstract class Catalog extends BasePage {

2. public abstract Product getProduct();

public abstract void setProduct(Product p);

 

// hard coded the backend service for now

// hmmmm ?? need to see if we can inject this from Spring ??

3.  ProductService service = new ProductServiceImpl();

 

4.
public Product[] getProducts() {

return service.getProducts();

}

}

 

Line 1: Class is now abstract. Tapestry pools the page classes for reuse. This being the case we have to avoid putting instance variables in the class. That would require us to do cleanup every time the page class is reused. Rather than us doing this we can avoid instance variables and provide abstract getters/setters for interested properties. Tapestry will now take care cleaning up the instance before handing it out for use in a fresh request invocation.

 

Line 2: We need it so our for loop will work correctly. The value=’ognl:product” uses this instance variable on the page class to store the contents each time it goes through the loop. Why I have no idea? Shows I have still things to learn.

 

Line 3: Our mock backend product service.

 

Line 4: source="ognl:products" connects to getProducts on the class.

 

That’s it. Remember the Catalog.page. Once you have that you can navigate to the following two pages successfully.

 

Clicking on the link takes you to.


 

Thus far you may have realized that Tapestry is indeed very different from other frameworks. But it does take some learning effort. But its well worth it.

 

Our final requirement is to add a new product and redisplay the catalog page (the new product should show up).

 

Here is AddProduct.html

AddProduct.html

<html jwcid="@Shell" title="Add Product">

 

<body jwcid="@Body">

<h1>Add New Product</h1>

<form jwcid="form@Form" success="listener:doAddProduct">

<table>

<tr>

<td>

<label jwcid="@FieldLabel" field="component:name">Name</label>:

<input jwcid="name@TextField" value="ognl:product.name" validators="validators:required" displayName="User Name" size="30"/>

</td>

</tr>

<tr>

<td>

Description:

<textarea jwcid="description@TextArea" value="ognl:product.description" rows="5" cols="30"/>

</td>

</tr>

<tr>

<td>

Release Date:

<input jwcid="releaseDate@DatePicker" value="ognl:product.releaseDate"/>

</td>

</tr>

</table>

<input type="submit" value="Add Project"/>

</form>

</body>

</html>

 

Some of the new components we used here:

 

Refer to the online documentation at http://jakarta.apache.org/tapestry/tapestry/ComponentReference/Shell.html for more details on shell and also all of the other built-in components.

 

Here is AddProduct.java

Catalog.java

package catalog.pages;

 

import java.util.Date;

import org.apache.tapestry.IPage;

import org.apache.tapestry.annotations.InjectPage;

import org.apache.tapestry.event.PageBeginRenderListener;

import org.apache.tapestry.event.PageEvent;

import org.apache.tapestry.html.BasePage;

import catalog.service.Product;

import catalog.service.ProductService;

import catalog.service.ProductServiceImpl;

 

public abstract class AddProduct extends BasePage implements

PageBeginRenderListener {

ProductService service = new ProductServiceImpl();

 

@InjectPage("Catalog")

public abstract Catalog getCatalogPage();

 

public abstract Product getProduct();

 

public abstract void setProduct(Product p);

 

// from PageBeginRenderListener

public void pageBeginRender(PageEvent event) {

Product project = new Product();

project.setReleaseDate(new Date());

setProduct(project);

}

 

public IPage doAddProduct() {

service.addProduct(getProduct());

return getCatalogPage();

}

}

 

The method pageBeginRender is from the interface PageBeginRenderListener. Tapestry invokes this method, as the name suggest, before rendering the page. Here we can do apply some default behaviour. For example when the AddProduct.html is displayed we want to provide a default values for the release date field. This is another good example of how Tapestry forces us think of web development from a Object Oriented point of view using these page classes.

 

Another very important part of the code is:

@InjectPage("Catalog")

public abstract Catalog getCatalogPage();

 

Remember a page in Tapestry is represented by three files; the .HTML file with the display template, the .java file with the processing logic and the .page file being the glue between the .HTML and .java code. So whenever I say go to another page I meant this logical page represented by the three things mentioned here.

 

After the doAddProduct method is finished doing its business we would like to return to the Catalog page and display the list of products once again. This is done by injecting the Catalog page into the AddProduct action.

 

Note: All of what we have talked thus far can be done using JDK 1.4. But wherever we use annotations we would have to enter XML into the .page file instead.

 

Once again do not forget the AddProduct.page. Compile and redeploy and you should be able to get to the add product page which when done takes you back to the catalog list page. You should see the new product you just added in the list.

 

Final Notes:

Did I mention my dislike for the .page files. Maybe it’s just me, but I just think it’s redundant. I reduced my Home.page file to

<page-specification>

</page-specification>

 

Note I removed the class name attribute. I made sure WEB-INF\catalog.application had the following:

<application>

<meta key="org.apache.tapestry.page-class-packages" value="catalog.pages"/>

</application>

 

This tells Tapestry where to look for the page classes. Having done this I thought I could get rid of my empty Home.page file above. No luck. As soon as I did that tapestry blew up with an exception.

 

Using Tapestry involves a steep learning curve and a shift in mindset on how you develop web applications. I personally feel like I have only scratched the surface thus far. In the weeks to come I hope to have a follow-up article on Tapestry using some more of its features and built-in components. And maybe we can even write our own component. Yes that is entirely possible.

 

----- EXTENDED BODY: ----- EXCERPT: Are there too many web frameworks out there? Well for those in the know the answer will be a resounding yes. Which one to pick up has become really a painful decision! Once you take one path you cannot just switch the framework mid-way. There is always the good old Struts framework. But that seems to be “oh not so fashionable nowadays”. Ah that ‘Ruby on Rails’ … and then you can sift through the web to find its java inspired half-brother. Or should we Seam with JBoss Seam? Though in all fairness JBoss Seam cannot be called just a web framework. It is a complete framework for front-end and back-end development. ----- KEYWORDS: ----- COMMENT: AUTHOR: Chris Steel EMAIL: chris.steel@nasd.com IP: 63.251.87.214 URL: DATE: 6/19/2006 8:15:12 PM I really enjoyed this article. The step by step description was excellent. I would like to see a little more comparison of Tapestry with other web frameworks. ----- COMMENT: AUTHOR: Tacfit Commando EMAIL: berni.ceeker@gmail.com IP: 80.73.223.62 URL: DATE: 8/26/2010 7:29:19 AM I like your style, the fact that your site is a little bit different makes it so interesting, I get fed up of seeing same-old-same-old all of the time. I've just stumbled this page for you :-D ----- COMMENT: AUTHOR: Fat Loss 4 Idiots EMAIL: alezsandrah@gmail.com IP: 80.73.214.175 URL: DATE: 9/2/2010 9:36:11 PM This is my first time at your blog and I've really enjoyed looking around. I willcome back again in the future to check out some of the other articles. ----- COMMENT: AUTHOR: international litigation EMAIL: seointpractice@gmail.com IP: 68.198.103.247 URL: DATE: 11/2/2010 1:32:07 AM Commercial Litigation and IP Law International Business Attorneys ----- COMMENT: AUTHOR: Bark Off EMAIL: krystinaosen55@gmail.com IP: 86.104.160.154 URL: DATE: 12/23/2010 8:47:41 AM I'm glad I've looked at your post, many captivating ideas you have got here and as well a concise writing technique.|I've had a remarkable evening although somehow stresful..had to create a bunch of unexciting stuff...This piece of content is exactly what I've needed tocomplete several stuff I do for an essay. ----- COMMENT: AUTHOR: Los Angeles Web Design EMAIL: greatnetseo@gmail.com IP: 122.177.79.140 URL: DATE: 1/12/2011 9:28:04 AM Your blog is really very nice and full of information, thanks for sharing. ----- COMMENT: AUTHOR: CandraChitly EMAIL: cvociahw5833@gmail.com IP: 89.178.63.81 URL: DATE: 1/21/2011 12:57:35 AM Dating hannah. Dating adel. Am dating i looking match online.
Access dating guide internet love. [url=http://xn----7sbabailqal8ahmgmik5bokk5e4i.xn----7sbbimnsesdeo4bgi9k.xn--p1ai/]знакомства архангельске[/url]. Dating malo.
Adult dating free jewish services single. Dating queen creek. Cam card chat credit free live no. ----- -------- AUTHOR: Mathew Thomas TITLE: Flat File Parser STATUS: publish ALLOW COMMENTS: 1 ALLOW PINGS: 1 CATEGORY: General DATE: 11/7/2005 5:00:00 AM ----- BODY: After a few projects where I had to parse through legacy flat files I decided enough was enough and decided to write my own parser. This parser would do exactly one thing efficiently and that was convert lines from the flat file to java objects. I wanted something that was thin and did exactly what I mentioned above and no other frills. Though now that I have it working a few frills may be in order . I have created a project at JavaForge where this tool will reside. If you do find it useful please drop a comment in the discussions forum on the javaforge site javaforge.com/project/2066. The goal is to parse a flat file (either character separated columns or fixed length columns). The parser supports two methods of parsing a file. In the first approach you are responsible for reading the file and providing each line that needs to be transformed to the transformer. The second approach is SAX-like, in that you register a listener and the transformer will call your listener whenever it finds a record and also when it could not resolve a record. First let's run through the first approach and at the end I will show you the SAX-line parsing approach.

Let’s create a java bean class to represent our record with space character separated columns.

import org.aver.fft.annotations.Column;

import org.aver.fft.annotations.Transform;

@Transform (spaceEscapeCharacter="_", recordIdValue="88")

public class DelimitedBean

{

.....

@Column(position = 1, required = true)
public int getRecordId()
   return recordId;
}

@Column(position = 2, required = true)
public String getNameOnCard()
   return nameOnCard;
}

@Column(position = 3, required = true)
public String getCardNumber()
   return cardNumber;
}

@Column(position = 4, required = true)
public int getExpMonth()
   return expMonth;
}

@Column(position = 5, required = true)
public int getExpYear()
   return expYear;
}

@Column(position = 6, required = true)
public double getAmount()
   return amount;
}

@Column(position = 7, required = true) public
String getCardSecurityCode()
   return cardSecurityCode;
}

@Column(position = 8, required = true, format = "MMddyyyy")
public Date getTransactionDate()
   return transactionDate;
}

... other methods here ...

}

As you can see we use Java 5.0 annotations to mark our record format. By default the parser sets itself up to parse character separated columns and the delimiter is space.

@Transform (spaceEscapeCharacter="_", recordIdValue="88")

By default the parser is setup to parse character-separated columns. The attribute spaceEscapeCharacter indicates the character used to represent spaces within column data. The parser can replace that with space before loading it into your java object. The recordIdValue identifies the value of the key column. The transformer keeps an internal mapping of the key value to the java bean class that represents it. By default the first column is the key column. You can change that by passing in parameter recordIdColumn for character separated columns or using recordStartIdColumn / recordEndIdColumn for fixed length columns. By default the column separator is space for character. You can change that using columnSeparator.

That’s enough on defining the file format. Now here is how to actually read it.

Transformer spec = 
   TransformerFactory.getTransformer(new Class[] { DelimitedBean.class });

String line = 
   "88 Mathew_Thomas 4111111111111111 02 2008 12.89 222 10212005";

DelimitedBean bean = (DelimitedBean) spec.loadRecord(line);

You get a transformer instance as shown above. Pass it an array of all classes that represent your various records and that uses annotations as defined above. Now you have a fully loaded bean from which to read your data. That’s all.

Now lets see how you define the same for a fixed column record format. The parsing code above stays the same. The difference is in how you annotate your result bean class.

import org.aver.fft.annotations.Column; import org.aver.fft.annotations.Transform;

@Transform(spaceEscapeCharacter = "_", columnSeparatorType = Transformer.ColumnSeparator.FIXLENGTH, recordIdStartColumn = 1, recordIdEndColumn = 2, recordIdValue=”88”)
public class FixedColBean {

@Column(position= 1, start = 1, end = 2, required = true)
public int getRecordId()
   return recordId;
}

@Column(position= 2, start = 3, end = 15, required = true)
public String getNameOnCard()
   return nameOnCard;
}

@Column(position= 3, start = 16, end = 31, required = true)
public String getCardNumber()
   return cardNumber;
}

@Column(position= 4, start = 32, end = 33, required = true)
public int getExpMonth()
   return expMonth;
}

@Column(position= 5, start = 34, end = 37, required = true)
public int getExpYear()
   return expYear;
}

@Column(position= 6, start = 38, end = 43, required = true)
public double getAmount()
   return amount;
}

@Column(position= 7, start = 44, end = 46, required = true) public String getCardSecurityCode() {
   return cardSecurityCode;
}

@Column(position= 8, start = 47, end = 54, required = true, format = "MMddyyyy")
public Date getTransactionDate()
   return transactionDate;
}

… other methods here …

}

The parsing logic stays the same. Just give it the correct line of data.

Now I will show you the SAX-like parsing approach.

package org.aver.fft;

import java.io.File;
import junit.framework.TestCase;

public class DelimitedFullFileReaderTestCase extends TestCase { 
   public void testFullFileReader()
         Transformer spec = TransformerFactory.getTransformer(new Class[] { DelimitedBean.class }); 
         spec.parseFlatFile(new File("c:/multi-record-delcol-file.txt"), new Listener()); 
   }

class Listener implements RecordListener
   public void foundRecord(Object o)
      bean = (DelimitedBean) o; System.out.println(bean.getNameOnCard()); 
   }

   public void unresolvableRecord(String rec)
   }

}

}

I have this project located at: www.javaforge.com/proj/summary.do?proj_id=271

----- EXTENDED BODY: ----- EXCERPT: After a few projects where I had to parse through legacy flat files I decided enough was enough and decided to write my own parser. This parser would do exactly one thing efficiently and that was convert lines from the flat file to java objects. I wanted something that was thin and did exactly what I mentioned above and no other frills. ----- KEYWORDS: ----- COMMENT: AUTHOR: Larry EMAIL: datasmithadvtech@rogers.com IP: 99.237.121.119 URL: DATE: 1/31/2008 11:45:05 PM I can't access the project even though I just registered. I get a permission denied error.

Any suggestions? ----- COMMENT: AUTHOR: Mathew Thomas EMAIL: mathy_tom@hotmail.com IP: 69.244.234.220 URL: DATE: 2/5/2008 11:53:19 AM I could not access it. Looks like JavaForge upgraded their site and my project is gone. I will get it reloaded into JavaForge in the next couple of days.

Sorry about that.
----- COMMENT: AUTHOR: cedfimfl EMAIL: jjyfapre@vabdwtuu.com IP: 208.42.166.23 URL: http://yysubacf.com DATE: 2/21/2008 8:40:24 PM tyvzlghz http://urjnsjwa.com ltkdqbqu onjgjgyj kxkaoilf [URL=http://jiazetso.com]qwogaavw[/URL] ----- COMMENT: AUTHOR: rffvcpkz EMAIL: wgnfonem@qewpfzjr.com IP: 80.25.32.105 URL: http://dzfrzavf.com DATE: 2/21/2008 8:42:54 PM [URL=http://lqpmgckx.com]nnkjnjbz[/URL] bbjlzytc http://gqitslay.com orgkvxgi fmxnucab lpfyyidd ----- COMMENT: AUTHOR: ynqzdfzg EMAIL: qehbdgvj@oemvhuri.com IP: 204.13.236.244 URL: http://ldlmfsav.com DATE: 2/21/2008 8:44:07 PM pehbrudd http://yuhqieyq.com hlzprryq jgbrvxxu [URL=http://scnednyh.com]trzydsme[/URL] mpaixhxl ----- COMMENT: AUTHOR: iuurnwyz EMAIL: xroyulqd@ixpjctfg.com IP: 195.5.145.246 URL: http://pcxxovzw.com DATE: 2/21/2008 8:44:49 PM ntnsitcw http://kaoaniwz.com tavbuvuz mpoljprx [URL=http://dvnewcpd.com]jqhsfeaq[/URL] bmbdbihb ----- COMMENT: AUTHOR: alamfhnx EMAIL: pdzvofoq@jlldhsix.com IP: 199.249.224.245 URL: http://eawqxtxv.com DATE: 2/21/2008 8:45:18 PM ztlylidj http://ytnjvytp.com sndxodkx kzknbbdr ----- COMMENT: AUTHOR: hifjljqb EMAIL: tibfyokw@xvjgdems.com IP: 83.217.192.160 URL: http://mfwfwtiq.com DATE: 2/21/2008 8:54:47 PM ghefbjpp [URL=http://ahajeprd.com]shmebdcw[/URL] sqjeihwp http://fqyouyff.com lwyopdpx noaqupyd ----- COMMENT: AUTHOR: kvnjgiyu EMAIL: qdjkqlum@odmdyvty.com IP: 83.217.192.160 URL: http://fsxvsifk.com DATE: 2/21/2008 8:57:36 PM [URL=http://pnznsorl.com]svzxnwvv[/URL] hanxqrmi iftsilcn http://osqcthdn.com qzorvhtt sjqrselk ----- COMMENT: AUTHOR: Praveen EMAIL: praveen_segu@yahoo.com IP: 24.11.194.199 URL: DATE: 4/4/2008 1:45:56 AM Could you please give us access to Test folder also? Thanks ----- COMMENT: AUTHOR: Praveen EMAIL: praveen_segu@yahoo.com IP: 24.11.194.199 URL: DATE: 4/6/2008 11:44:41 AM Matt,
Could we access to source and test files also? I'm trying to implement the filereader0.5,but receiving null pointer exceptions

Thanks ----- COMMENT: AUTHOR: Chris EMAIL: chrispheby@yahoo.co.uk IP: 198.240.128.75 URL: DATE: 4/25/2008 8:49:20 AM This looks like an interesting library. Is the source available - I get permission denied on Javaforge? Also what licence is being used? ----- COMMENT: AUTHOR: Leonardo EMAIL: leonardo.chaves@quality.com.br IP: 200.255.103.130 URL: DATE: 5/5/2008 12:27:12 PM Congratulations for your work! I was looking for something like that. Something that could replace BEA's MFL (http://e-docs.bea.com/workshop/docs81/doc/en/integration/dtguide/dtguideNonXML.html?skipReload=true) . But there is still a feature I am in need: nesting formats. Imagine that a given column is not a simple field, but a group of them. For instance:

12 My_Name First_Son,Second_Son,Third_Son

The third column brings all the childrens' names for the person named My Name and uses a different separator from the rest of the fields. Can I still solve this problem with your parser?

Regards. ----- COMMENT: AUTHOR: Chris Pheby EMAIL: chrispheby@yahoo.co.uk IP: 198.240.128.75 URL: DATE: 5/6/2008 11:24:23 AM Mathew, Is the source code available for this project? Also, what is the license? I'd like to use it but will need this information to do so. ----- COMMENT: AUTHOR: Mathew Thomas EMAIL: mathy_tom@hotmail.com IP: 69.244.234.220 URL: DATE: 5/14/2008 1:18:39 AM It uses the apache license 2.0. I will try to get the source code published over the weekend and also have a jar 0.6 with the license information inside. I have had a few requests for source code so i will get that out at the same time.

----- COMMENT: AUTHOR: Mathew Thomas EMAIL: mathy_tom@hotmail.com IP: 69.244.234.220 URL: DATE: 5/14/2008 1:20:20 AM look for a version 0.6 over the next few days (could be tonight or over the weekend) that has the source code and also the license information in the jar file.
----- COMMENT: AUTHOR: Mathew Thomas EMAIL: mathy_tom@hotmail.com IP: 69.244.234.220 URL: DATE: 5/14/2008 3:07:11 AM I have put a new release 0.6 on the javaforge site (http://www.javaforge.com/project/2066).

Please unzip the distribution file flatfilereader-0.6-dist.zip ... it contains the library, source code and javadoc. No code changes were made. All code and functionality from 0.5 is as-is.
----- COMMENT: AUTHOR: Oliver EMAIL: o.blume@considion.com IP: 83.236.226.242 URL: DATE: 6/3/2009 3:20:18 PM Beautiful work. Thanks for sharing this piece of fine software. ----- COMMENT: AUTHOR: Mathew Thomas EMAIL: mattazoid@gmail.com IP: 72.86.34.45 URL: DATE: 6/8/2009 1:02:51 AM Thanks for the compliment. It is a simple piece of software...have some more plans to enhance it but finding time (and motivation) is touch.
----- COMMENT: AUTHOR: Etienne EMAIL: etienno@gmail.com IP: 86.65.15.100 URL: DATE: 3/24/2010 9:10:49 AM Hi, very interesting. Do you have a equivalent FFT Writer? ----- COMMENT: AUTHOR: Mathew Thomas EMAIL: mattazoid@gmail.com IP: 71.171.119.198 URL: DATE: 4/8/2010 11:16:18 AM Unfortunately no , I do not have a writer. Might look into that at some point. Time is the biggest challenge ----- COMMENT: AUTHOR: Etienne EMAIL: etienno@gmail.com IP: 86.65.15.100 URL: DATE: 5/5/2010 8:36:58 AM Hi, I have done the writer based on your project (but not depended of it). Only one class of marshaling (BeanMarshaller), and I have modified your annotations like @Column to make it easier to use. I have use the position, and length attribute to deduce the "start" and "end" position. Now that I need a reader, I will make one based on your classes but using my annotations like column. I also added some format attribute for Date, BigDecimal, and Boolean, etc. I will be able to give you your upgraded project soon. ----- COMMENT: AUTHOR: CheriePratt EMAIL: kimberlyhernandez@mail15.com IP: 95.211.27.210 URL: http://www.lowest-rate-loans.com DATE: 6/1/2010 12:01:52 PM If you want to buy a car, you will have to get the lowest-rate-loans.com. Furthermore, my father commonly utilizes a short term loan, which is really useful. ----- COMMENT: AUTHOR: online games EMAIL: Olae21@cashloansforbusiness.com IP: 173.234.93.56 URL: DATE: 11/28/2010 1:03:14 AM It's okay to isolate, as long as you don't do it alone. ----- COMMENT: AUTHOR: exerlyninee EMAIL: majki@underfilm.pl IP: 91.201.66.24 URL: DATE: 1/7/2011 6:15:14 PM There are all kinds of fettle desolateness plans on the superstore today including wide-ranging medical plans, managed healthiness meticulousness plans, and a hotelier of specialized plans. There is a exhaustive in reverse to their services and the development they luminary as exact as a lit of offices that you can phrase or recount in with a view slight information. As they are so ready you can coddle in the service of faultless cheek that you wishes be familiar with perfectly what the terms and conditions of the method that you formality wrong-headed are. When you partake of a haleness guardianship method with Coventry Well-being Circumspection, you can be convinced that you are in ok hands. There is no hassle like that associated with othercompanies because you just stand to phone Coventry Constitution Tribulation as contrasted with of having to phone in every operating a sprinkling unalikecompanies to becommunicated speaking to the into public notice being if you entire with another provider. Are you though of the 180 million Americans who wants Haleness Care? Did you from information of that a latest con showed that the body a missus concern of those seeking art was; Salubriousness Be attracted to Benefits? Constitution Disquiet benefits are a elephantine be connected with, peculiarly payment families and the costs be dicomfort with skyrocketed in render employers. In act oneselfcommunity Motors had considered filing bankruptcy owing to the increasing healthiness skedaddle exhort of costs dragging down its auto manufacturing division. Preferably the Mixture and GM crown boldness made a score to curtailed down some of the benefits but also gaol operating as colloquial and as a substitute as a substitute for of flow its underneath performing investment central arm GMAC.Home fettle dolour products can pigeon-hole pharmaceuticals, palpable remedies, and other products and pattern that follower healing and wellness. Birth, it requisite be said that high-minded because you can believe a salubrity sadness yield online doesn?t incontestably it is right representing you to do so. Mankind conclude that laetrile had youthful or no as all no-nonsense purposes on cancer. The TruthThe facts in achievement evidence is assorted people were helped with laetrile in peewee clinics and these clinics were gaining acclaim on the other side of the larger forwards hospitals approved even the Eatables and Hallucinogenic Administering (FDA). Profuse people were cured, and from here the FDA and unadulterated pharmaceuticalcompanies were losing send coins on not being higher-level to acomplish established physic as they happy and consequence these clinics were seclude down and at last laetrile became illegal. Multitudinous physicians who second-hand Laetrile on their patients were prosecuted and copious clinics ended candid to Mexico.

All medical team and personnel infection escort products concede in a very twist of sizes and colors. Patients can be protected from an air-borne indisposition nigh wearing aseptic gowns, defensive dental bibs, facial sheets and capes (looking as a remedy in search younger patients). While working to solicitude germane fitted each dogged, these items also make in numerous designs, colors, and sizes. In counting up, beds, operating tables, tools, sheets, corridors, rooms, bathrooms, and the entirety else within a medical power should be scrubbed and disinfected regularly - including clich‚d persecution equipment.
[url=http://edupack.edu.pl/buy-clomid-no-prescription.html]clomd online[/url]
Countless studies would more easily proven that people who cogitate on they are being treated benefit of the account of an disability surely assume trust to bigger, if not in reality are bettor than when they began the study. What does this mean? I hypothesize it may innocently be a testament to the shortfall of minister to after, TLC or thing of being meritorious that is loose of our enlightenment today. ----- COMMENT: AUTHOR: adawlinuads EMAIL: willytyson9@gmail.com IP: 93.182.133.19 URL: DATE: 1/15/2011 8:21:19 PM Check out these kick ass site
they are Free and got lots Videos of [url=http://wwwbhgalleriescom][b]Teen Porn[/b][/url] and [url=http://amazingteenbabescom][b]Porn[/b][/url] ----- -------- AUTHOR: Mathew Thomas TITLE: Unit Testing Woes STATUS: publish ALLOW COMMENTS: 1 ALLOW PINGS: 1 CATEGORY: testing DATE: 7/14/2005 5:00:00 AM ----- BODY:

Unit Testing Woes

While unit testing is expected to be an integral part of every development effort, it is often not given its due importance during planning stages. When you derive the LOE (level of effort) for development tasks do you make sure to include unit testing as part of that calculation.

Let’s start with the question “what is unit testing”?

It is the effort of selecting a unit of code and writing an independent set of code that exercises one or more features of that unit.

You can define the unit as either a class or a set of classes that work together to deliver a certain feature. I would not waste time writing unit test for every java class you create. Select a logical unit of work that suites your needs (and project schedule) and write tests against that. Make sure the test exercises your code and not integration with other developers’ units. It is a good idea to write integration test cases but start with your own unit first. If you have dependencies with other components you can choose the strategy of mocking those components. This way you are free to test your code and do not get bogged down by other components. Let’s say you are testing a backend component that accepts credit card information from users, does some validations on the user data, stores it in the database and then submits the transaction to a credit card authorization provider. Obviously you are not interested in testing the authorization provider’s code and you may not even have access to that provider during development. You can write a few classes and mock out the provider or write a simple emulator to emulate the actions of the provider. Later on, as part of your developer integration testing, you can swap in the real providers test environment for more thorough testing.

Often the importance of unit testing is not understood. During a recent project status meeting, for a release that I was not actively involved in, the build manager asked “should we run the automated unit tests that used to run every night during the previous release?” Everyone stared at each other with a silence and then there were some quiet shaking of the heads to say “no”. I was shocked to see this reaction. The team for the current release was not writing a single new test case and on top of that had the boldness to choose not to run any of the tests that already existed. The unit test execution was completely automated. You add your unit test case class name to an XML file and that’s it. It would be included in the nightly build and test cycle. Come next morning and you have a neat HTML page with the complete test results. Finally it was decided that once development finishes everyone can spend a week and write test cases. I disagree with this approach too, since it comes a little too late. It was disappointing to say the least.

When experienced developers make this choice, how do we convince everyone else about the importance of unit testing? Let’s start with some questions you can ask yourself. How do you know if the “thing” you coded works? How do you test this “thing” everyday to make sure it still works? How does someone else make sure that the “thing” continues to work long after you, the original developer, are off the project? The answer is obvious. Write unit tests.

Some of the challenges often encountered in projects are:

Remember that in spite of unit tests, defects will show up during testing. On a recent project the QA lead went on to make this an issue. Often these kinds of statements come from immature managers/leads that really have very little software development process background. Or they are just plain ignorant. Getting total coverage is impossible given the schedules for many fast-paced projects.

So what are some of the options for us Java developers to write unit tests? There are many options but I will cover the following in brief:

  1. JUnit.
  2. TestNG.
  3. Custom framework using JDK 5.0 annotations.

JUnit

JUnit has been around for a while now. It is a simple framework that allows one to write Java test classes. Your classes follow a certain convention in naming the test methods.

import junit.framework.*;

public class MyTestCase extends TestCase {

protected void setUp() {

.. set up test data ...

}

protected void tearDown() {

}

            public void testAddVisaTransaction() {

}

public void testAddMasterCardTransaction() {

}

}

You can easily integrate the execution of the tests in an Ant script. You can use the optional JUnit and JUnitReport ant tasks to execute the unit tests and produce a nice HTML report of the test results. Setting this up should not take you more than a day. Plug this into your nightly build cycle and you have a simple yet immensely powerful automated unit testing execution strategy. Time spent on this is time well spent.

TestNG

TestNG is a nice little framework that takes a slightly different approach in the way you write your test classes. Suffice it to say it’s less intrusive (that is if you can call JUnit intrusive). With TestNG you do not extend any framework classes nor do you have to name your tests methods in any particular format. You use annotations (either JDK 5.0 annotations or javadoc style annotations if you are using JDK 1.4.x). Let’s see an example with JDK 5.0 annotations.

import org.testng.annotations.*;

public class MyTestCase {

   @Configuration(beforeTestClass = true)

   public void setUp()  {

      .. set up test data ...

   }

   @Test(groups = { "mygroup" })

   public void testAddVisaTransaction(){

   }

   @Test(groups = { "mygroup" })

   public void testAddMasterCardTransaction() {

   }

}

Personally I like this approach better. With the introduction of annotations in JDK 5.0 this style is definitely going to become the preferred approach. Note you can name the above methods with any name you choose. I simply ported the previous JUnit test to TestNG.

Custom framework using JDK 5.0 Annotations

I would suggest you stick with TestNG, but if you want to create your own framework its not too hard now. Annotations are probably the most important new feature in JDK 5. While I have seen some examples of code with annotations which almost drove me up the wall, in most cases it is a much calmer experience.

Let’s create a set of custom annotations to create a simple test framework. We will create the following annotations

1. @TestCase – will be used to mark a class as a test case. Will allow the tester to give a description to the test case.

2. @Setup – Used to mark one or more methods as set up methods.

3. @Test – Used to designate a method as a test method to execute.

First we will create the @TestCase annotation. This will be used to mark the class as a test case and provide some useful description of the test class.

import java.lang.annotation.*;

@Retention(RetentionPolicy.RUNTIME)

@Target(ElementType.TYPE)

public @interface TestCase  {

   String description();

            }

· Import the annotation java classes from java.lang.annotation.

· @interface – keyword is used to mark the, otherwise regular, java class as an annotation definition class.

· The annotation we are creating is itself annotated with meta-annotations.

· @Retention(RetentionPolicy.RUNTIME) – these annotations can be read at run-time.

· @Target(ElementType.METHOD) - this annotation only applies to methods.

Next we will create the @Setup annotation. This one is used to mark the methods that are set up in nature. These will run before any of the tests are executed.

import java.lang.annotation.*;

@Retention(RetentionPolicy.RUNTIME)

@Target(ElementType.METHOD)

public @interface Setup {

}

Finally we will create our @Test annotation that marks individual methods as test methods which are to be executed.

Import java.lang.annotation.*;

@Retention(RetentionPolicy.RUNTIME)

@Target(ElementType.METHOD)

public @interface Test {

            }

Now let’s use these annotations in a sample test case class.

import com.unittest.*;

@TestCase (description="My test case description.")

public class MyTestCase {

@Setup

public void setUpShit() {

   System.out.println("Setup invoked.");

}

@Test

public void doTest1() {

   System.out.println("doTest1 invoked.");

}

@Test

public void runTest2() {

   System.out.println("doTest1 invoked.");

}

            }

I am sure you will agree that the entire exercise so far is not complicated in any way. I am using the latest Eclipse 3.1 to write this code. Eclipse 3.1 supports building custom annotations and it will invoke the annotation compiler for you. Now to create the test harness that will execute the tests. The class java.lang.Class has been updated in JDK 5.0 to support annotations. You will see that in the next sample code.

import java.lang.reflect.*;

import com.unittest.*;

public class TestRunner {

   public static void main(String[] args) throws Exception  {

Class testClass = Class.forName(args[0]);

// Check if the method is annotated with @TestCase.

if (!testClass.isAnnotationPresent(TestCase.class)) {

System.out.println("Test classes must be annotated with @TestCase.");

System.exit(1);

}

// Print the test case description.

TestCase testCase = (TestCase) testClass.getAnnotation(TestCase.class);

System.out.println("TestCase description ==>> " + testCase.description());

// Get an instance of the target test case to be executed.

MyTestCase target = (MyTestCase) testClass.newInstance();

// Execute only the 1st @Setup annotated method (if one exists).

for (Method method : testClass.getDeclaredMethods()) {

if (method.isAnnotationPresent(Setup.class)) {

method.invoke(target);

break;

}

}

// Execute the @Test annotated methods.

for (Method method : testClass.getDeclaredMethods()) {

if (method.isAnnotationPresent(Test.class)) {

method.invoke(target);

}

}

   }

}

That’s it we are done. Pass the test case class name to the TestRunner and you will see your test executing. To keep this simple I have not included any exception handling to any of the code above.

Conclusion

There are many options to build your unit testing strategy. Pick any one that suites your needs but just use something.

----- EXTENDED BODY: ----- EXCERPT: While unit testing is expected to be an integral part of every development effort, it is often not given its due importance during planning stages. ----- KEYWORDS: ----- COMMENT: AUTHOR: long term care insurance quote EMAIL: sueillys@settlementmasters.net IP: 173.234.54.228 URL: DATE: 12/10/2010 11:25:50 PM trying to view your blog. Your layout isnt working right wiht chrome. ----- -------- AUTHOR: Mathew Thomas TITLE: Achieving Better Software Code Quality STATUS: publish ALLOW COMMENTS: 1 ALLOW PINGS: 1 CATEGORY: Quality DATE: 6/4/2005 5:00:00 AM ----- BODY: Code Quality. Have you achieved it. If yes - Congrats and bi. If not read on.

Achieving Code Quality is the holy grail of software development. We feel it deep inside us. We know its there somewhere but alas we are not able to get to it. So what is software quality and why is it so difficult to achieve?

One project I worked on management told us to build “a zero defect system”. I laughed because knowing the schedule and chaos on the project this was as good as finding a real superman and then asking him for a ride to the moon.

So what is Code Quality? Is it code which produces very low number of defects or is it  code that is well documented or code that has a good design behind it or is it a measure of how well you have unit tested it or is the pretty/well-formatted looking code.

Quality code can be achieved by following a few basic principles:

The last principle might look strange here. But think about it. Software development is all about people and how well our internal egos interact with others. Once individuals write the code they unconsciously feel that the code is a reflection of their intellect. Any criticism of the code then becomes a very personal matter. That is why I encourage early design/code reviews. Then its everyone's ideas and not just one persons.

It might seem like a lot of work to implement these principles, but I am reminded of the following excerpt from - http://c2.com/cgi/wiki?CodeSmell

Highly experienced and knowledgeable developers have a "feel" for good design. Having reached a state of "UnconsciousCompetence," where they routinely practice good design without thinking about it too much, they find that they can look at a design or the code and immediately get a "feel" for its quality, without getting bogged down in extensive "logically detailed arguments".

My thought is that - Each and  every developer needs to strive to attain UnconsciousCompetence. Only way you can achieve that is by following the principles above and making it part of your being.

Can we really get to a zero defect system? I have yet to be part of one and I think its impossible. So rather than trying to build a zero defect system lets try to build a system with reasonably low number of defects, which has well-documented code, consistent coding guidelines, unit tests that achieves maximum code coverage. So here is how I define quality code.

Quality Code is code that has a well thought of reason for its very existence, is backed by a solid design, is testable, has repeatable unit tests, is self-documenting and has extensibility built into its very core.

To achieve good code quality everyone has to play their part.

Your value is not just in getting the work done but it’s also in how well you approach your work. And quality will follow.

----- EXTENDED BODY: ----- EXCERPT: Code Quality. Have you achieved it. If yes - Congrats and bi. If not read on. ----- KEYWORDS: ----- -------- AUTHOR: Mathew Thomas TITLE: Intelligent Software Agents in Knowledge Management STATUS: publish ALLOW COMMENTS: 1 ALLOW PINGS: 1 CATEGORY: General DATE: 6/1/2005 5:00:00 AM ----- BODY:

The goal of this article is to introduce the reader to the concepts and theory behind the knowledge management process and how intelligent software agents can help to manage the knowledge management process.

Before we get into the crux of this article it is important to understand why we even discuss this topic. Various types of Decision support systems (DSS) are widely used in enterprises today. Organizations might need an EIS (enterprise information system) that not only caters to the needs of management but also serves the needs of the rest of the enterprise. Needs are obviously defined by what role each person plays. For example an EIS can be used to check the demand and match it closely to the supply or perform forecasting based on trends or patterns in the data. The validity of the results from this process is dependent on the knowledge that was used to come to this result.

The key to the success of a DSS system is to have access to a reliable, valid and growing knowledge base. Human actors will often enter knowledge into the knowledge base directly. But that may not be feasible or many times not possible. Here is where intelligent software agents can help.

Intelligent Software agents, in the context of knowledge management, are automated software modules that act on behalf of the knowledge management system to automatically collect knowledge, validate it, organize it and then add it to the knowledge base.

Knowledge

Typical production databases are transactional in nature. They can be seen as the database of operations, where all business transactions take place. Orders are placed, inventory is tracked, and customers are managed among other activities. Here the onus is on managing data and the challenge is to have efficient and reliable access to this data. Data is often organized into tables to form meaningful information.

But there is a parallel requirement in many large enterprises to have a different view of the data. A view that is used by upper management (and others) to track sales, to forecast trends (like demand and supply), to trouble shoot specific performance problems, etc. Here the onus is not on pure data. Instead what is needed is to consolidate the information from the many databases spread across the organization and bring them together to provide what we term knowledge. Knowledge is giving meaning or more substance to data, so that decisions can be made using this knowledge.

Knowledge Base

Knowledge is typically collected and organized into a knowledge base (similar to how data is stored in databases). Typically these knowledge bases could also be located as data warehouses and data marts and they are separate from the operational databases. In fact the latter should be requirement for your knowledge base. Some of the activities that are run on a knowledge base can be very intense and could slow down your already fully loaded operational database.

Typically the knowledge base is another DBMS that caters purely to the knowledge management subsystem. This could be an RDBMS (like Oracle, DB2) or you can even use XML enabled databases.

Knowledge Management Process

Knowledge management is the process of collecting, rearranging and validating data to produce knowledge. Knowledge can be gathered from various sources like

Knowledge can be gathered from any of the above sources (maybe from all too). Here is a simple checklist to keep in mind when gathering knowledge. Assume the system is getting a new feed of data, which is to be entered into the knowledge base. In a good knowledge management process…

An important function of a knowledge management process is to continuously grow its knowledge base (following the process we outlined above). An inference engine will use this knowledge to provide value to a client. An inference engine is only as good as its backend knowledge base.

Very often it is not feasible to leave it to human agents to enter data into the knowledge base. Sometimes the data may be so large that this is not possible. Or the information may arrive periodically at predefined times or maybe it follows no time schedules. Here is where we can use intelligent software agents.

Intelligent Software Agents

Intelligent Software agents are independent autonomous software programs that gather knowledge by following the process we outlined earlier. In doing so they require no help from human agents. The process is completely automated. They are termed as intelligent because they possess all process information on how to intelligently read incoming information and convert it to knowledge to be stored into the knowledge base. These agents can be written in various programming languages such as C, C++, Java, etc. They can also be implemented using newer technologies such as Web Services.

Agents can be one of two types; static agents or mobile agents. Lets discuss each in some detail and also how they can be used in the knowledge management process. There are other classifications of software agents. But for the purposes of this paper we will concentrate on static and mobile classifications only.

Static Agents

Static agents are called so based on the fact that they do not move or relocate themselves from the computer that started them. If a particular computer starts a static agent then the agent will continue to run on that very computer throughout its lifecycle.

The life cycle of a static agent can be better understood using the diagram below.

Initially there are no agents in the knowledge management system. The agents come to life either when the first knowledge gathering task is initiated or a pre-configured number of agents can be set up to be in a pool of free agents. When a new knowledge task arrives either an available agent from the pool is allocated or a new one is created.

When the agent is running, it is at that point that the knowledge process we outlined earlier is applied. When the agent finishes execution it is added back to the pool of available agents. Keeping a pool such as this can be useful in improving the reliability and scalability of the knowledge management system.

Next question we need to ask is how are these agents called by clients. There are many ways that this can be done. But lets discuss one very innovative method. Today Web Services is the “in-thing” in the tech world. Beyond the hype, this technology is extremely viable for implementing static intelligent agents. Web Services allow us to expose interfaces on existing or new business objects as available to our business partners.

Our static agent could be designed as a J2EE (or .NET) object running on a remote server. This object though private to the server exposes some of its interfaces using the web services suite of protocols (SOAP, WSDL, UDDI). Clients will typically call one of the interfaces on our web services. Clients who need to feed in data can do so using appropriate web service interfaces. They would provide the data as an XML document that has a predefined XML Schema. Due to the use of XML Schema there is naturally a strict adherence to data formats and some amount of data validation is applied right here at this step. This can save an enormous amount of computing space on the server and can better facilitate the knowledge validation process.

Static agents can also be of a reactive kind. Wherein they react to new data that is added into a database or new data that an application server receives. In such cases the application server or database can spawn a reactive static agent and delegate to it the task knowledge processing. Or these agents can run in the background always waiting for new data to come in. Once they detect new data they read it and run the knowledge gathering process to move it into a separate knowledge base. Very often though knowledge creation is done at predefined times, maybe once a day. During that time slot the agent will read the operational database and process the new or updated data. For large amounts of highly volatile data this can be very beneficial approach.

Static agents are especially well suited for data-mining tasks. Typically data mining involves wading through large amounts of data in a data warehouse or data mart to find patterns in existing knowledge. Agents can perform these background tasks based on either predefined time intervals or maybe it is triggered by the arrival of certain data or simply when a request for knowledge access comes in.

Mobile Agents

This is a very innovative field of research. Ironically what makes it so innovative is also a reason why this technology is not in common use.

Mobile agents are software modules that do not necessarily stay on the server that initiated them. Simply put these agents travel. Say we start an agent on one computer (the parent). To perform its work the agent needs to communicate to a remote server. The agent might start performing some of its duties on the parent computer and then decide to move from the parent towards the remote server. In doing so it might decide to travel the network and move ever so close to the remote server. Finally once it finishes its task it will notify the remote server or it may even destroy itself. The parent can at all times send messages to the agents, such as control messages.

Some agents might interact with other static or mobile agents to perform its task. Some may even spawn additional sub-agents to delegate some tasks. At all times the agent maintains a reference to the parent server.

One would ask how could this be of any use in a knowledge management system. The answer is simple. It depends on what type of information your knowledge base is tracking. Lets say we have an enterprise with a large globally distributed computing facility. The network is so complex that it has become difficult to track what is happening on this network. It has become difficult to collect performance and security related information. And we need to periodically have this knowledge added to a knowledge base, so that we can later analyze and maybe even predict network performance.

We can create a mobile agent that will roam our network, moving from one node to the other and always collecting network performance statistics as it roams. Periodically the mobile agent can send the information back to the parent, which can then add it to the knowledge base. The agent can communicate with the network elements using SNMP. Based on this simple yet realistic example you can see the power behind mobile agents.

Due to the mobility of these agents they may be limited to gathering data only and maybe performing some initial validations on it. Once they gather data they can call a static agent on the parent to perform the remaining tasks. It is important that the mobile agent keep doing its main task, which is to keep moving and gathering new data.

Limitations of Mobile Agents

Mobile agents face many challenges among them are security concerns, what if someone tampers with the agent runtime code, how does the agent find a suitable platform from which to execute as it moves, how does the parent know that the data it is receiving is from the agent and not from some other malicious agent, how does the parent know if a child agent is still alive, what if the agent looses ability to communicate to the parent, etc.

Conclusion

Automated knowledge management using intelligent software agents is very much a reality. The advances in newer technologies such as J2EE, Web Services, .NET allow us to create more reliable, scalable and secure intelligent agents. Static agents are more common compared to mobile agents. But as was discussed earlier mobile agents are definitely useful in certain types of applications.

Resources

For information on XML Schema refer to http://www.w3.org/XML/Schema

ADK for mobile agent development http://develop.tryllian.com/

IBM's Aglet mobile agent development

Voyager from http://www.recursionsw.com/

Software Agents on Distributed Knowledge Management Systems (DKMS Brief No. Three, July 30, 1998

----- EXTENDED BODY: ----- EXCERPT: The goal of this article is to introduce the reader to the concepts and theory behind the knowledge management process and how intelligent software agents can help to manage the knowledge management process. ----- KEYWORDS: ----- COMMENT: AUTHOR: MicroConsole EMAIL: harry.lecocq@gmail.com IP: 80.73.218.187 URL: DATE: 10/18/2010 8:32:53 PM I can see that you are an expert in this field! I am launching a website soon, and this information is very useful for me. Thanks for all your help and wishing you all the success in your business. ----- COMMENT: AUTHOR: long term care insurance EMAIL: funtimessue@gmail.com IP: 76.170.98.239 URL: DATE: 11/17/2010 5:17:41 AM Have you ever thought of madking a video for your blog to keep the readers entertained? ----- COMMENT: AUTHOR: life settlement EMAIL: kens8@settlementmasters.net IP: 173.234.31.101 URL: DATE: 12/16/2010 10:03:18 PM Have you considered adding some videos to your blog posts to keep the visitors entertained? ----- --------