DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Refcards Trend Reports
Events Video Library
Refcards
Trend Reports

Events

View Events Video Library

The Latest Career Development Topics

article thumbnail
10 Tricky Java Interview Questions
Here are some Java interview questions which are un-common What is the performance effect of a large number of import statements which are not used? Answer: They are ignored if the corresponding class is not used. Give a scenario where hotspot will optimize your code? Answer: If we have defined a variable as static and then initialized this variable in a static block then the Hotspot will merge the variable and the initialization in a single statement and hence reduce the code. What will happen if an exception is thrown from the finally block? Answer: The program will exit if the exception is not catched in the finally block. How does decorator design pattern works in I/O classes? Answer: The various classes like BufferedReader , BufferedWriter workk on the underlying stream classes. Thus Buffered* class will provide a Buffer for Reader/Writer classes. If I give you an assignment to design Shopping cart web application, how will you define the architecture of this application. You are free to choose any framework, tool or server? Answer: Usually I will choose a MVC framework which will make me use other design patterns like Front Controller, Business Delegate, Service Locater, DAO, DTO, Loose Coupling etc. Struts 2 is very easy to configure and comes with other plugins like Tiles, Velocity and Validator etc. The architecture of Struts becomes the architecture of my application with various actions and corresponding JSP pages in place. What is a deadlock in Java? How will you detect and get rid of deadlocks? Answer: Deadlock exists when two threads try to get hold of a object which is already held by another object. Why is it better to use hibernate than JDBC for database interaction in various Java applications? Answer: Hibernate provides an OO view of the database by mapping the various classes to the database tables. This helps in thinking in terms of the OO language then in RDBMS terms and hence increases productivity. How can one call one constructor from another constructor in a class? Answer: Use the this() method to refer to constructors. What is the purpose of intern() method in the String class? Answer: It helps in moving the normal string objects to move to the String literal pool How will you make your web application to use the https protocol? Answer: This has more to do with the particular server being used than the application itself. Here is how it can be done on tomcat: http://tomcat.apache.org/tomcat-4.1-doc/ssl-howto.html From http://extreme-java.blogspot.com/2011/05/10-tricky-java-interview-questions.html
May 10, 2011
by Sandeep Bhandari
· 101,832 Views · 1 Like
article thumbnail
Eradicating Non-Determinism in Tests
An automated regression suite can play a vital role on a software project, valuable both for reducing defects in production and essential for evolutionary design. In talking with development teams I've often heard about the problem of non-deterministic tests - tests that sometimes pass and sometimes fail. Left uncontrolled, non-deterministic tests can completely destroy the value of an automated regression suite. In this article I outline how to deal with non-deterministic tests. Initially quarantine helps to reduce their damage to other tests, but you still have to fix them soon. Therefore I discuss treatments for the common causes for non-determinism: lack of isolation, asynchronous behavior, remote services, time, and resource leaks. I've enjoyed watching ThoughtWorks tackle many difficult enterprise applications, bringing successful deliveries to many clients who have rarely seen success. Our experiences have been a great demonstration that agile methods, deeply controversial and distrusted when we wrote the manifesto a decade ago, can be used successfully. There are many flavors of agile development out there, but in what we do there is a central role for automated testing. Automated testing was a core approach to Extreme Programming from the beginning, and that philosophy has been the biggest inspiration to our agile work. So we've gained a lot of experience in using automated testing as a core part of software development. Automated testing can look easy when presented in a text book. And indeed the basic ideas are really quite simple. But in the pressure-cooker of a delivery project, trials come up that are often not given much attention in texts. As I know too well, authors have a habit of skimming over many details in order to get a core point across. In my conversations with our delivery teams, one recurring problem that we've run into is tests which have become unreliable, so unreliable that people don't pay much attention to whether they pass or fail. A primary cause of this unreliability is that some tests have become non-deterministic. A test is non-deterministic when it passes sometimes and fails sometimes, without any noticeable change in the code, tests, or environment. Such tests fail, then you re-run them and they pass. Test failures for such tests are seemingly random. Non-determinism can plague any kind of test, but it's particularly prone to affect tests with a broad scope, such as acceptance or functional tests. Why non-deterministic tests are a problem Non-deterministic tests have two problems, firstly they are useless, secondly they are a virulent infection that can completely ruin your entire test suite. As a result they need to be dealt with as soon as you can, before your entire deployment pipeline is compromised. I'll start with expanding on their uselessness. The primary benefit of having automated tests is that they provide bug detection mechanism by acting as regression tests[1]. When a regression test goes red, you know you've got an immediate problem, often because a bug has crept into the system without you realizing. Having such a bug detector has huge benefits. Most obviously it means that you can find and fix bugs just after they are introduced. Not just does this give you the warm fuzzies because you kill bugs quickly, it also makes it easier to remove them since you know the bug got in with the last set of changes that are fresh in your mind. As a result you know where to look for the bug, which is more than half the battle in squashing it. The second level of benefit is that as you gain confidence in your bug detector, you gain the courage to make big changes knowing that when you goof, the bug detector will go off and you can fix the mistake quickly. [2] Without this teams are frightened to make the changes code needs in order to be kept clean, which leads to a rotting of the code base and plummeting development speed. The trouble with non-deterministic tests is that when they go red, you have no idea whether its due to a bug, or just part of the non-deterministic behavior. Usually with these tests a non-deterministic failure is relatively common, so you end up shrugging your shoulders when these tests go red. Once you start ignoring a regression test failure, then that test is useless and you might as well throw it away. Indeed you really ought to throw a non-deterministic test away, since if you don't it has an infectious quality. If you have a suite of 100 tests with 10 non-deterministic tests in them, than that suite will often fail. Initially people will look at the failure report and notice that the failures are in non-deterministic tests, but soon they'll lose the discipline to do that. Once that discipline is lost, then a failure in the healthy deterministic tests will get ignored too. At that point you've lots the whole game and might as well get rid of all the tests. Quarantine My principal aim in this article is to outline common cases of non-deterministic tests and how to eliminate the non-determinism. But before I get there I offer one piece of essential advice: quarantine your non-deterministic tests. If you have non-deterministic tests keep them in a different test suite to your healthy tests. That way you'll you can continue to pay attention to what's going on with your healthy tests and get good feedback from them. Place any non-deterministic test in a quarantined area. (But fix quarantined tests quickly.) Then the question is what to do with the quarantined test suites. They are useless as regression tests, but they do have a future as work items for cleaning up. You should not abandon such tests, since any tests you have in quarantine are not helping you with your regression coverage. A danger here is that tests keep getting thrown into quarantine and forgotten, which means your bug detection system is eroding. As a result it's worthwhile to have a mechanism that ensures that tests don't stay in quarantine too long. I've come across various ways to do this. One is a simple numeric limit: e.g. only allow 8 tests in quarantine. Once you hit the limit you must spend time to clear all the tests out. This has the advantage of batching up your test-cleaning if that's how you like to do things. Another route is to put a time limit on how long a test may be in quarantine, such as no longer than a week. The general approach with quarantine is to take the quarantined tests out of the main deployment pipeline so that you still get your regular build process. However a good team can be more aggressive. Our Mingle team puts its quarantine suite into the deployment pipeline one stage after its healthy tests. That way it can get the feedback from the healthy tests but is also forced to ensure that it sorts out the quarantined tests quickly. [3] Lack of Isolation In order to get tests to run reliably, you must have clear control over the environment in which they run, so you have a well-known state at the beginning of the test. If one test creates some data in the database and leaves it lying around, it can corrupt the run of another test which may rely on a different database state. Therefore I find it's really important to focus on keeping tests isolated. Properly isolated tests can be run in any sequence. As you get to larger operational scope of functional tests, it gets progressively harder to keep tests isolated. When you are tracking down a non-determinism, lack of isolation is a common and frustrating cause. Keep your tests isolated from each other, so that execution of one test will not affect any others. There are a couple of ways to get isolation - either always rebuild your starting state from scratch, or ensure that each test cleans up properly after itself. In general I prefer the former, as it's often easier - and in particular easier to find the source of a problem. If a test fails because it didn't build up the initial state properly, then it's easy to see which test contains the bug. With clean-up, however, one test will contain the bug, but another test will fail - so it's hard to find the real problem. Starting from a blank state is usually easy with unit tests, but can be much harder with functional tests [4] - particularly if you have a lot of data in a database that needs to be there. Rebuilding the database each time can add a lot of time to test runs, so that argues for switching to a clean-up strategy. One trick that's handy when you're using databases, is to conduct your tests inside a transaction, and then to rollback the transaction at the end of the test. That way the transaction manager cleans up for you, reducing the chance of errors[5]. Another approach is to do a single build of a mostly-immutable starting fixture before running a group of tests. Then ensure that the tests don't change that initial state (or if they do, they reverse the changes in tear-down). This tactic is more error-prone than rebuilding the fixture for each test, but it may be worthwhile iff it takes too long to build the fixture each time. Although databases are a common cause for isolation problems, there are plenty of times you can get these in-memory too. In particular be aware with static data and singletons. A good example for this kind of problem is contextual environment, such as the currently logged in user. If you have an explicit tear-down in a test, be wary of exceptions that occur during the tear-down. If this happens the test can pass, but cause isolation failures for subsequent tests. So ensure that if you do get a problem in a tear-down, it makes a loud noise. Some people prefer to put less emphasis on isolation and more on defining clear dependencies to force tests to run in a specified order. I prefer isolation because it gives you more flexibility in running subsets of tests and parallelizing tests. Asynchronous Behavior Asynchrony is a boon that allows you to keep software responsive while taking on long term tasks. Ajax calls allow a browser to stay responsive while going back to the server for more data, asynchronous message allow a server process to communicate with other system without being tied to their laggardly latency. But in testing, asynchrony can be curse. The common mistake here is to throw in a sleep: //pseudo-code makeAsyncCall; sleep(aWhile); readResponse; This can bite you two ways. First off you'll want to set the sleep time to long enough that it gives plenty of time to get the response. But that means that you'll spend a lot of time idly waiting for the response, thus slowing down your tests. The second bite is that, however long you sleep, sometimes it won't be enough. There will be some change in environment that will cause you to exceed the sleep - and you'll get false failure. As a result I strongly urge you to never use bare sleeps like this. Never use bare sleeps to wait for asynchonous responses: use a callback or polling. There are basically two tactics you can do for testing an asynchronous response. The first is for the asynchronous service to take a callback which it can call when done. This is the best since it means you'll never have to wait any longer than you need to [6]. The biggest problem with this is that the environment needs to be able to do this and then the service provider needs to do it. This is one of the advantages of having the development team integrated with testing - if they can provide a callback then they will. The second option is to poll on the answer. This is more than just looking once, but looking regularly, something like this //pseudo-code makeAsyncCall startTime = Time.now; while(! responseReceived) { if (Time.now - startTime > waitLimit) throw new TestTimeoutException; sleep (pollingInterval); } readResponse The point of this approach is that you can set the pollingInterval to a pretty small value, and know that that's the maximum amount of dead time you'll lose to waiting for a response. This means you can set the waitLimit very high, which minimizes the chance of hitting it unless something serious has gone wrong. [7] Make sure you use a clear exception class that indicates this is a test timeout that's failing. This will help make it clear what's gone wrong should it happen, and perhaps allow a more sophisticated test harness to take account of this information in its display. The time values, in particular the waitLimit, should never be literal values. Make sure they are always values that can be easily set in bulk, either by using constants or set through the runtime environment. That way if you need to tweak them (and you will) you can tweak them all quickly. All this advice is handy for async calls where you expect a response from the provider, but how about those where there is no response. These are calls where we invoke a command on something and expect it to happen without any acknowledgment. This is the trickiest case since you can test for your expected response, but there's nothing to do to detect a failure other than timing-out. If the provider is something you're building you can handle this by ensuring the provider implements some way of indicating that it's done - essentially some form of callback. Even if only the testing code uses it, it's worth it - although often you'll find this kind of functionality is valuable for other purposes too[8]. If the provider is someone else's work, you can try persuasion, but otherwise may be stuck. Although this is also a case when using Test Doubles for remote services is worthwhile (which I'll discuss more in the next section). If you have a general failure in something asynchronous, such that it's not responding at all, then you'll always be waiting for timeouts and your test suite will take a long time to fail. To combat this it's a good idea to use a smoke test to check that the asynchronous service is responding at all and stop the test run right away if it isn't. Gerard Meszaros's book, xUnit Test Patterns, contains lots of good patterns for constructing tests. You can also often side-step the asynchrony completely. Gerard Meszaros's Humble Object pattern says that whenever you have some logic that's in a hard-to-test environment, you should isolate the logic you need to test from that environment. In this case it means put most of the logic you need to test in a place where you can test it synchronously. The asynchronous behavior should be as minimal (humble) as possible, that way you don't need that much testing of it. Remote Services Sometimes I'm asked if ThoughtWorks does any integration work, which I find somewhat amusing since there's hardly any project we do that doesn't involve a fair bit of integration. By their nature, enterprise applications involve a great deal of combining data from different systems. These systems are maintained by other teams operating to their own schedules, teams that often use a very different software philosophy to our heavily test-driven agile approach. Testing with such remote systems brings a number of problems, and non-determinism is high on the list. Often remote systems don't have test system we can call, which means hitting a live system. If there is a test system, it may not be stable enough to provide deterministic responses. In this situation it's vital to ensure determinism, so it's time to reach for a Test Double - a component that looks like the remote service, but is really just a pretend version that mimics the remote system's behavior. The double needs to be setup so that provides the right kind of response in interaction with our system, but in a way we control. In this manner we can ensure determinism. Using a double has a downside, in particular when we are testing across a broad scope. How can we be sure that the double behaves in the same way that remote system does? We can tackle this again using tests, a form of test that I call Integration Contract Tests. These run the same interaction with the remote system and the double, and check that the two match. In this case 'match' may not mean coming up with the same result (due to the non-determinisms), but results that share the same essential structure. Integration Contract Tests need to be run frequently, but not part of our system's deployment pipeline. Periodic running based on the rate of the change of the remote system is usually best. For writing these kinds of test doubles, I'm a big fan of Self Initializing Fakes - since these are very simple to manage. Some people are firmly against using Test Doubles in functional tests, believing that you must test with real connection in order to ensure end-to-end behavior. While I sympathize with their argument, automated tests are useless if they are non-deterministic. So any advantage you gain by talking to the real system is overwhelmed by the need to stamp out non-determinism[9]. Time Few things are more non-deterministic than a call to the system clock. Each time you call it, you get a new result, and any tests that depend on it can thus change. Ask for all the todos due in the next hour, and you regularly get a different answer[10]. The most important thing here is to ensure that you always wrap the system clock with routines that can be replaced with a seeded value for testing. A clock stub can be set to particular time and frozen at that time, allowing your tests to have complete control over its movements. That way you can synchronize your test data to the values in the seeded clock.[11][12] Always wrap the system clock, so it can be easily substituted for testing. One thing to watch with this, is that eventually your test data might start having problems because it's too old, and you get conflicts with other time based factors in your application. In this case you can move the data, and your clock seeds to new values. When you do this, ensure that this is the only thing you do. That way you can be sure that any tests that fail are due to time-movement in the test data. Another area where time can be a problem is when you rely on other behaviors from the clock. I once saw a system that generated random keys based on clock values. This systems started failing when it was moved to a faster machine that could allocate multiple ids within a single clock tick.[13] I've heard so many problems due to direct calls to the system clock that I'd argue for finding a way to use code analysis to detect any direct calls to the system clock and failing the build right there. Even a simple regex check might save you a frustrating debugging session after a call at an ungodly hour. Resource Leaks If your application has some kind of resource leak, this will lead to random tests failing, since it's just which test causes the resource leak to go over a limit that gets the failure. This case is awkward because any test can fail intermittently due to this problem. If it isn't a case of one test being non-deterministic then resource leaks are a good candidate to investigate. By resource leak, I mean any resource that the application has to manage by acquiring and releasing. In non-memory-managed environments, the obvious example is memory. Memory-management did much to remove this problem, but other resources still need to be managed, such as database connections. Usually the best way to handle these kind of resources is through a Resource Pool. If you do this then a good tactic is to configure the pool to a size of 1 and make it throw an exception should it get a request for a resource when it has none left to give. That way the first test to request a resource after the leak will fail - which makes it a lot easier to find the problem test. This idea of limiting resource pool sizes, is about increasing constraints to make errors more likely to crop up in tests. This is good because we want errors to show in tests so we can fix them before they manifest themselves in production. This principle can be used in other ways too. One story I heard was of a system which generated randomly named temporary files, didn't clean them up properly, and crashed on a collision. This kind of bug is very hard to find, but one way to manifest it is to stub the randomizer for testing so it always returns the same value. That way you can surface the problem more quickly.
April 14, 2011
by Martin Fowler
· 6,748 Views · 1 Like
article thumbnail
A story about User Stories; Where do you start and what about the planning?
In this multi-part post, I’m going to share my personal experiences while working with user stories for gathering, tracking and planning requirements. It currently consists out of three parts: What are they and why do you need them? Who writes them and how do you control scope? Where do you start and what about the planning? You can also download all parts as one comprehensive PDF for easy printing or e-reading. Where do you start? Suppose that after intensive discussions and tough scoping sessions you ended up with a list of user stories and are about to start building the system. The first story not only needs to realize some particular feature, but also involves building a skeleton implementation of the system’s architecture. How do you avoid spending way too much time on plumbing and other general purpose stuff you need for the rest of the stories? The article Managing the Bootstrap Story by Jennitta Andrea addressed this challenge in more detail and offers some alternative solutions. One of these solutions is to find and define a user story with the product owner that offers minimal functionality yet still has project value. Such a story is often referred to as the backbone story because you realize the backbone of your system in it. It’s quite common to use the backbone story to realize a proof-of-concept (PoC) that verifies the chosen architecture. Since a working PoC can give the product owner confidence that the team is able to build such a product, that fact alone may be enough project value for the product owner. More storyotypes? You might have suspected it already, but that backbone story is just an example of another storyotype. In fact, after I started looking for an approach to capture the non-functional requirements of a project or system, I ran into a slide deck that mentioned a whole set of additional storyotypes. Dan Rawsthorne, the author, tried to define a storyotype for virtually every possible thing you might need to do in a project. Personally I think he went a bit too far, but a small set of additional storyotypes proved to be very useful anyway. Storyotype Description Compound Epic A composite user story that groups a number of stories in a logical sense. Complex Epic A user story whose content and impact must be determined later in the project, but for which it is clear that it involves a significant amount of work. Setup A story that is used to setup the project environment, including a source control environment, a project website, a build server. Technical A story that involves making a technical improvement or adjustment. Examples include introducing a coding standard, refactoring a poor design, executing a performance test. Documentation A story for writing a user manual, installation manual, etc. Training A story for developing and/or hosting a training, or having a workshop with end users. Quality Improvements A story which objective is to fix a collection of related bugs, or spent a fixed amount of time to improve the quality of the code base. Spike A story that aims to do a technical investigation to determine the usability of a specific technology, or for trying an alternative technical solution. When is the story complete? So how do you know that a user story has been successfully realized? Well, if all is good, all stories will conform with INVEST and are associated with a number of acceptance criteria (typically written down as the how-to demo) specified by the product owner. That should be enough to determine if it is functionally sound. But what you still miss is a way of explaining the stakeholders, including the product owner, when the team treats the story as finished. That may differ by team, but usually includes some or more of the following criteria. The code compiles and there are no warnings or errors. The code meets the coding standards setup by the project or the organization. The code is reviewed by a peer developer. All automated unit and integration tests have completed successfully. Visual Studio’s static code analysis tool does not report any violations. ReSharper reports no potential errors (a.k.a. everything is 'green'). The daily integration build has completed successfully. The functionality was tested by another member of the team (anybody but the developer). The feature or functionality has been signed off using the project checklist. The system functionality is tested by a tester. The visual look and feel is has been approved by an employee of the communications department. Together with the story’s how-to demo these criteria are commonly referred to as the definition-of-done. Usually, a team or project will have a default definition-of-done that applies to all stories and only mentions the particulars of that story if necessary. Then what about the planning? User stories are an excellent unit for tracking progress within your project. However, purists within the Agile community will tell you that an Agile project will have no long term plan. Instead, the functionality is realized iteratively according to the priority defined by the product owner. I agree with the latter and believe that its iterative nature is essential for dealing with the changing requirements that are common in all projects. It allows deferring decisions to the last responsible moment, and that’s always a good thing. But in reality you often can’t escape from providing at least a rough schedule to your management. How should you deal with that? What I often do to get all stakeholders to join me in a number of workshops. Using use case diagrams to illustrate the context of the discussions, I try to get enough stories on paper to represent the entire scope of the project. You need to beware though that you don’t write down too much details or have too much in-depth discussions. That would give the stakeholders a false sense of precision, and consequently, will cause them to see the stories as a formal functional design. Also, if you run into some high-level chunk of functionality for which nobody really knows what it will look like, add an epic story for it and include a spike to elaborate on the epic later on in the project. Then organize a number of shorter meetings with the team or, if the team hasn’t been formed yet, with a few experienced developers. Let them discuss every story one by one and then try to estimate the size of each story in so called story points. Some people from the Agile community say you should estimate using relative sizes only. In other words, a story that seems to require twice as much work as another story should also have twice as many story points. The story point as a unit does not have value. It’s the relative differences that are important. What works for me is that every story point corresponds to the ideal day of an experienced senior software developer. In other words, one story point means that an experienced developer familiar with the chosen architecture, technology and project methodology needs to work for 8 hours without being disturbed by telephone, email, coffee breaks, or any other distractions. Mike Cohn, author of User Stories Applied, has dedicated many chapters to this estimation technique. Ideally, each story is between 1 and 8 story points, but at the beginning of the project you still may have some epics to break up. After finishing those meetings you should have an estimate of the total size of the project. Now, in order to get from those story points to a total number of hours you need to estimate the expected productivity of the team. Mike Cohn does this by creating a table with the expected roles, their availability (to deal with part time employees), and the expected productivity compared to the ideal senior developer (as a percentage). By calculating the average productivity and multiplying it with the number of story points you’ll end up with the total number of estimated man-hours. It’s only an estimate and both the productivity can be disappointing as well as the estimate in story points may appear to be wrong. But it still gives you an initial estimate that can be used for global planning and budget discussions. Obviously it is important to ensure that you keep on continuously measuring the actual productivity. Wow, now what? By now, it should be clear that a user story is not an independent concept but something that closely resonates with many of the aspects of our work in the software industry. In this multi-part post I have tried to explain a number of those aspects and to clarify the relationship between them. But even though I’ve not touched everything as detailed as possible, I still hope I've managed to convince you about the power and potential of user stories. Last but not least, if you have any questions or comments, please do not hesitate to email me at [email protected] or tweet me at my Twitter ID ddoomen.
March 17, 2011
by Dennis Doomen
· 7,456 Views
article thumbnail
HOWTO: Partially Clone an SVN Repo to Git, and Work With Branches
I've blogged a few times now about Git (which I pronounce with a hard 'g' a la "get", as it's supposed to be named for Linus Torvalds, a self-described git, but which I've also heard called pronounced with a soft 'g' like "jet"). Either way, I'm finding it way more efficient and less painful than either CVS or SVN combined. So, to continue this series ([1], [2], [3]), here is how (and why) to pull an SVN repo down as a Git repo, but with the omission of old (irrelevant) revisions and branches. Using SVN for SVN repos In days of yore when working with the JBoss Tools and JBoss Developer Studio SVN repos, I would keep a copy of everything in trunk on disk, plus the current active branch (most recent milestone or stable branch maintenance). With all the SVN metadata, this would eat up substantial amounts of disk space but still require network access to pull any old history of files. The two repos were about 2G of space on disk, for each branch. Sure, there's tooling to be able to diff and merge between branches w/o having both branches physically checked out, but nothing beats the ability to place two folders side by side OFFLINE for deep comparisons. So, at times, I would burn as much as 6-8G of disk simply to have a few branches of source for comparison and merging. With my painfullly slow IDE drive, this would grind my machine to a halt, especially when doing any SVN operation or counting files / disk usage. Using Git for SVN repos naively Recently, I started using git-svn to pull the whole JBDS repo into a local Git repo, but it was slow to create and still unwieldy. And the JBoss Tools repo was too large to even create as a Git repo - the operation would run out of memory while processing old revisions of code to play forward. At this point, I was stuck having individual Git repos for each JBoss Tools component (major source folder) in SVN: archives, as, birt, bpel, build, etc. It worked, but replicating it when I needed to create a matching repo-collection for a branch was painful and time-consuming. As well, all the old revision information was eating even more disk than before: jbosstools' trunk as multiple git-svn clones: 6.1G devstudio's trunk as single git-svn clone: 1.3G So, now, instead of a couple Gb per branch, I was at nearly 4x as much disk usage. But at least I could work offline and not deal w/ network-intense activity just to check history or commit a change. Still, far from ideal. Cloning SVN with standard layout & partial history This past week, I discovered two ways to make the git-svn experience at least an order of magnitude better: Standard layout (-s) - this allows your generated Git repo to contain the usual trunk, branches/* and tags/* layout that's present in the source SVN repo. This is a win because it means your repo will contain the branch information so you can easily switch between branches within the same repo on disk. No more remote network access needed! Revision filter (-r) - this allows your generated Git repo to start from a known revision number instead of starting at its birth. Now instead of taking hours to generate, you can get a repo in minutes by excluding irrelevant (ancient) revisions. So, why is this cool? Because now, instead of having 2G of source+metadata to copy when I want to do a local comparison between branches, the size on disk is merely: jbosstools' trunk as single git-svn clone w/ trunk and single branch: 1.3G devstudio's trunk as single git-svn clone w/ trunk and single branch: 0.13G So, not only is the footprint smaller, but the performance is better and I need never do a full clone (or svn checkout) again - instead, I can just copy the existing Git repo, and rebase it to a different branch. Instead of hours, this operation takes seconds (or minutes) and happens without the need for a network connection. Okay, enough blather. Show me the code! Check out the repo, including only the trunk & most recent branch # Figure out the revision number based on when a branch was created, then # from r28571, returns -r28571:HEAD rev=$(svn log --stop-on-copy \ http://svn.jboss.org/repos/jbosstools/branches/jbosstools-3.2.x \ | egrep "r[0-9]+" | tail -1 | sed -e "s#\(r[0-9]\+\).\+#-\1:HEAD#") # now, fetch repo starting from the branch's initial commit git svn clone -s $rev http://svn.jboss.org/repos/jbosstools jbosstools_GIT Now you have a repo which contains trunk & a single branch git branch -a # list local (Git) and remote (SVN) branches * master remotes/jbosstools-3.2.x remotes/trunk Switch to the branch git checkout -b local/jbosstools-3.2.x jbosstools-3.2.x # connect a new local branch to remote one Checking out files: 100% (609/609), done. Switched to a new branch 'local/jbosstools-3.2.x' git svn info # verify now working in branch URL: http://svn.jboss.org/repos/jbosstools/branches/jbosstools-3.2.x Repository Root: http://svn.jboss.org/repos/jbosstools Switch back to trunk git checkout -b local/trunk trunk # connect a new local branch to remote trunk Switched to a new branch 'local/trunk' git svn info # verify now working in branch URL: http://svn.jboss.org/repos/jbosstools/trunk Repository Root: http://svn.jboss.org/repos/jbosstools Rewind your changes, pull updates from SVN repo, apply your changes; won't work if you have local uncommitted changes git svn rebase Fetch updates from SVN repo (ignoring local changes?) git svn fetch Create a new branch (remotely with SVN) svn copy \ http://svn.jboss.org/repos/jbosstools/branches/jbosstools-3.2.x \ http://svn.jboss.org/repos/jbosstools/branches/some-new-branch From http://divby0.blogspot.com/2011/01/howto-partially-clone-svn-repo-to-git.html
January 28, 2011
by Nick Boldt
· 35,698 Views
article thumbnail
Interview: Troy Giunipero, Author of NetBeans E-commerce Tutorial
Troy Giunipero (pictured, right) is a student at the University of Edinburgh studying toward an MSc in Computer Science. Formerly, he was one of the NetBeans Docs writers based in Prague, Czech Republic, where he spent most of his time writing Java web tutorials. In this interview, Troy introduces you to The NetBeans E-commerce Tutorial. This is a very detailed tutorial describing just about everything you need to know when creating an e-commerce web application in Java. It has received a lot of very positive feedback. Let's find out about the background of this tutorial and what Troy learnt in writing it. Hi Troy! During your time on the NetBeans team, you wrote a very large tutorial describing how to create an e-commerce site. How and why did you start writing it? Well, there’s a short answer and a long answer to this. The short answer is that I was lucky to take part in Sun’s SEED (Sun Engineering Enrichment and Development) program. I wanted to focus on technical aspects, so I based my curriculum on developing an e-commerce application using Java technologies. I documented my efforts and applied them toward deliverables for the IDE’s 6.8 and 6.9 releases, resulting in the 13-part NetBeans E-commerce Tutorial. The long answer is that I had previously been tasked with creating an e-commerce application for my degree project (I was studying toward a BSc in IT and Computing), and ran into loads of trouble trying to integrate the various technologies into a cohesive, functioning application. I was coming from a non-technical background and found there was a steep learning curve involved in web development. My work was fraught with problems which I can now attribute to poor time-management, and a lack of good, practical, hands-on learning resources. So in a way, working on the AffableBean project (this is the project used in the NetBeans E-commerce Tutorial) was a way for me to go back and attempt to do the whole thing right. With the tutorial, I had two goals in mind: one, I wanted to consolidate my understanding of everything by writing about it, and two, I wanted to help others avoid the problems and pitfalls that I’d earlier ran into by designing a piece of documentation that puts everything together. Can you run us through the basic parts and what they provide? Certainly. First I want to point out that there’s a live demo application (http://dot.netbeans.org:8080/AffableBean/) which I managed to get up and running with help from Honza Pirek from the NetBeans Web Team (thanks Honza!): The application is modeled on the well-known MVC architecture: The tutorial refers to the above diagram at various points, and covers a bunch of different concepts and technologies along the way, including: Project design and planning (unit 2) Designing a data model (using MySQL WorkBench) (unit 4) Forward-engineering the data model into a database schema (unit 4) Database connectivity (units 3, 4, 6) Servlet, JSP/EL and JSTL technologies (units 3, 5, 6) EJB 3 and JPA 2 technologies (unit 7), and transactional support (unit 9) Session management (i.e., for the shopping cart mechanism) (unit 8) Form validation and data conversion (unit 9) Multilingual support (unit 10) Security (i.e., using form-based authentication and encrypted communication) (unit 11) Load testing with JMeter (unit 12) Monitoring the application with the IDE’s Profiler (unit 12) Tips for deployment to a production server (units 12, 13) Also, the tutorial aims to provide ample background information on the whole “Java specifications” concept, with an introduction to the Java Community Process, how final releases include reference implementations, and how these relate to the tutorial application using the IDE’s bundled GlassFish server (units 1, 7). Finally, the tutorial is as much about the above concepts and technologies as it is about learning to make best use of the IDE. I really tried to squeeze as much IDE-centric information in there as possible. So for example you’ll find: An introduction to the IDE’s main windows and their functions (unit 3) A section dedicated to editor tips and tricks (unit 5), and abundant usage of keyboard shortcuts in steps throughout the tutorial Use of the debugger (unit 8) Special “tip boxes” that discuss IDE functionality that is sometimes difficult to fit into conventional documentation. For example, there are tips on using the IDE’s Template Manager (unit 5), GUI support for database tables (unit 6), Javadoc support (unit 8), and support for code templates (unit 9). Did you learn any new things yourself while writing it? Yes! Three things immediately come to mind: EJB 3 technology. Initially this was a big hurdle for me. Using EJB 3 effectively seems to be something of an art form. If you know what you’re doing and understand exactly how to use the EntityManager to handle persistence operations on a database, EJB lets you do some amazingly smart things with just a few lines of code. But there seems to be a lack of good free documentation online—especially since EJB 3 is a significant departure from EJB 2. Therefore, almost all of the tutorial’s information on EJB comes from the very excellent book, EJB in Action by Debu Panda and Reza Rahman. Interpreting the NetBeans Profiler. The final hands-on unit, Testing an Profiling, was the most difficult for me to write, primarily because I just wasn’t familiar with the Profiler at all. I spent an unhealthy amount of time just watching the Telemetry graph run against my JMeter test plan, which is only slightly more stimulating than watching water come to boil. That being said, I feel that by just examining the graphs and other windows over time, critical logical associations start to jump out at you after a while. Likewise with JMeter. Hopefully unit 12 was able to capture and relay some of these. How to search online for decent articles and learning materials. The old Sun Technical Articles site was a great resource. Many of the links in the See Also sections at the bottom of tutorial units were found by adding site:java.sun.com/developer/technicalArticles/ to a Google search. Also the official forums (found at forums.sun.com) became a good place for questions I couldn’t find ready answers to. I had both the Java EE 5 and 6 Tutorials bookmarked. And Marty Hall’s Core Servlets and JavaServer Pages became an invaluable resource for the first half of the tutorial. What are your personal favorite features of the technologies discussed in the tutorial? I particularly liked learning about session management—using the HttpSession object to carry user-specific data between requests, and working with JSP’s corresponding implicit objects in the front-end pages. Session management is a defining aspect for e-commerce applications, as they need to provide some sort of shopping cart mechanism... ...and so the Managing Sessions unit (unit 8) was a key chapter in the tutorial. It’s extremely useful to be able to suspend the debugger on a portion of code that includes session-scoped variables, then hover the mouse over a given variable in the editor to determine its current value. I used the debugger continuously during this phase, and so I went so far as to incorporate use of the debugger throughout the Managing Sessions unit. What kind of background does someone starting the tutorial need to have? Someone can come to the tutorial with little or absolutely no experience using NetBeans. I’ve tried to be particularly careful in providing clear and easy-to-follow instructions in this respect. But one would be best off having some background or knowledge in basic web technologies, and at least some exposure to relational databases. With this foundation, I think that the topics covered in the second half of the tutorial, like applying entity classes and session beans, language support and security, won’t seem too daunting. I’ve noticed that the vast majority of feedback that comes in relates to the first half of the tutorial, and I sometimes get the impression that people feel they need to follow the tutorial units consecutively. Not so. The units are 90% modular. In other words, if somebody just wants to run through the security unit (unit 11), they can do so by downloading the associated project snapshot, follow the setup instructions, and then just follow along without needing to even look at other parts of the tutorial. What will they be able to do at the end of it? Naturally, anybody who completes individual tutorial units will be able to apply the concepts and technologies to their own work. But anyone who completes the tutorial in its entirety will gain an insight into the development process as a whole, and I think will also get a certain confidence that comes with knowing how “all the pieces fit together”—from gathering customer requirements all the way to deployment of the completed app to a production server. They’ll also have gained a solid familiarity with the NetBeans IDE, and be in a good position to explore popular Java web frameworks that work on top of servlet technology or impose an MVC architecture on their own, such as JSF, Spring, Struts, or Wicket. Do you see any problems in the technologies discussed and what would be your suggestions for enhancements? Well there’s one thing that comes to mind. When I started working on this project, I was studying the Duke’s BookStore example from the Java EE 5 Tutorial. A wonderful example that demonstrates how to progressively implement the same application using various technologies and combinations thereof. So for example you start out with an all-servlet implementation, then move on to a JSP/servlet version. Then there’s a JSTL implementation and ultimately, a version using JavaServer Faces. It’s great learning material, but also terrifically outdated. Right around this time, Sun was gearing up for the big Java EE 6 release (Dec. 2009), and I was also trying to learn about the new upcoming technologies, namely CDI, JSF 2, and EJB 3, for my regular NetBeans documentation work. I was getting the definite sense that JSP and JSTL were slowly being pushed aside—in the case of JavaServer Faces, Facelets templating was the new page authoring technology. So really, the E-commerce Tutorial application has become a sort of EE 5/EE 6 hybrid by combining JSP/JSTL with EJB 3 and JPA 2. Now the problem I see from the perspective of a student trying to learn this stuff from scratch, is that the leap from basic servlet technology to a full-blown JSF/EJB/JPA solution is tremendous, and cannot readily be taught through a single tutorial. Naturally, others may disagree with me here. I’m not sure if there’s a solution other than to compensate by producing a lot of quality learning material that covers lots of different use-cases. I’d suggest that the E-commerce Tutorial puts one in a very advantageous position to begin learning about Java-based frameworks, such as GWT, Spring, and JSF, which is a natural course of action for people looking to get a job with this knowledge. Planning any more parts to the tutorial or a new one? No more parts. The E-commerce Tutorial is done. Upon committing the final installments and changes last November, I rejoiced. However, I’m still actively responding to feedback [the ‘Send Us Your Feedback’ links at the bottom of tutorials] and plan to maintain it indefinitely, so if anyone spots any typos, has questions or comments, recommendations for improvement, etc., please write in! :-)
January 9, 2011
by Geertjan Wielenga
· 30,232 Views
article thumbnail
Implementing Retries with a MDB or an MQ Batch Job? (WAS 7, MQ 6)
Both approaches have some advantages and disadvantages and so it’s a question of the likelihood of particular problems and business requirements and priorities.
November 10, 2010
by Jakub Holý
· 27,328 Views
article thumbnail
Exposing a POJO as a JMX MBean Easily With Spring
JMX is a great way to check or change state variables or invoke a method in a (remote) running application via a management GUI such as JConsole. And Spring makes it trivial to expose any POJO as a JMX MBean with only little configuration in a few minutes. The Spring JMX documentation is very good, however there are few points that I struggled with for a while and would therefore like to record here the right solutions. I needed to monitor a command-line java application using Spring 2.5 on IBM JVM 1.4 1.5 running on a server with a jconsole on Sun JVM 1.6 as the JMX client on my PC. All the XML snippets are from a Spring application-context.xml. If you haven’t used Spring before, read a tutorial on its configuration and dependency injection. Turning a POJO into an MBean JMX makes it possible to expose getters, setters and operations taking primitive or complex data types as parameters (though types other then few special ones require the client to have the classes). You tell Spring to expose a POJO as an MBean as follows: First you declare an instance of the POJO class – the myMBean (for other reasons I’ve an old-fashioned singleton and use JobPerformanceStats.instance() to access the bean). Next you declare an MBeanExporter with lazy-init=”false” and tell it about your bean. (There are also other ways to do it, including auto-discovery.) The bean will be then visible under its key, i.e. “bean:name=MyMBeanName”, which JConsole displays as “MyMBeanName”. Notice that the MBeanExporter only works under JVM 1.5+ because it uses the new java.lang.management package. Under 1.4 Spring would fail with java.lang.NoClassDefFoundError: javax/management/MBeanServerFactory at org.springframework.jmx.support.MBeanServerFactoryBean.createMBeanServer By default it will expose all public methods and attributes. You can change that in various ways, for example with the help of an interface. If you are not running in a container that already provides an MBean server, which is my case here, you must tell Spring to start one: Enabling remote access To make the MBean accessible from another machine, you must expose it to the world by declaring a ConnectorServerFactoryBean configured with an appropriate communication mechanism. Remote access over JMXMP By default the ConnectorServerFactoryBean exposes MBeans over JMXMP with the address service:jmx:jmxmp://localhost:9875 : However this protocol isn’t supported out of the box and you must include jmxremote_optional.jar, a part of OpenDMK, on the classpath of both the MBean application and the jconsole client to avoid the exception org.springframework.beans.factory.BeanCreationException: Error creating bean with name ‘org.springframework.jmx.support.ConnectorServerFactoryBean#0′ defined in class path resource [application-context.xml]: Invocation of init method failed; nested exception is java.net.MalformedURLException: Unsupported protocol: jmxmp Remote access over RMI Alternatively you can expose the MBeans over RMI, which has no additional dependencies: However there are also some catches you must avoid: You must start an RMI registry so that the connector can register the MBean there; it won’t start one for you You must make sure that the registry is started before the connector tries to use either by declaring it before the connector or by making this dependency explicit with the depends-on attribute If you don’t set it up correctly you will get an exception like org.springframework.beans.factory.BeanCreationException: Error creating bean with name ‘org.springframework.jmx.support.ConnectorServerFactoryBean#0′ defined in class path resource [application-context.xml]: Invocation of init method failed; nested exception is java.io.IOException: Cannot bind to URL [rmi://localhost:10099/jmxrmi]: javax.naming.ServiceUnavailableException [Root exception is java.rmi.ConnectException: Connection refused to host: localhost; nested exception is: java.net.ConnectException: Connection refused: connect]. Local MBean server accessed over an SSH tunnel For increased security you may want to prefer not to expose your MBeans to remote access by making them accessible only from the local machine (127.0.0.1) and use na SSH tunnel so that a remote JConsole can access them as a local application. This is certainly possible but may be difficult because normally JMX goes over RMI, which uses two ports: one for the RMI Registry and another one for the actual service (MBean server here), which is usually chosen randomly at the runtime, and you’d need to tunnel both. Fortunately, Spring makes it possible to configure both the ports: Replace STUBPORT and REGISTRYPORT with suitable numbers and tunnel those two. Notice that the REGISTRYPORT number is same in the connector’s serviceUrl and in the RMI registry’s port attribute. WARNING: The configuration above actually doesn’t prevent direct access from a remote application. To really force the RMI registry to only listen for connection from the local host we would likely need to set – under Sun JVM without Spring – the system property com.sun.management.jmxremote. Additionally, to force the registry to use the IP 120.0.0.1, we’d need to set java.rmi.server.hostname=localhost (applies to Spring too). See this discussion about forcing local access. I’m not sure how to achieve the same result with Spring while still preserving the ability to specify both the RMI ports. Check also the JavaDoc for Spring’s RmiServiceExporter . Related posts and docs: Tunneling Debug and JMX for Alfresco (A. uses Spring)- see the second section, SSH Tunneling for JMX A custom tunneling RMI agent – uses a configured port instead of a random one Monitoring ActiveMQ Using JMX Over SSH JMX 1.2 specification and JMX 1.0 Remote API specification; from the JMX spec.: “The MBean server relies on protocol adaptors and connectors to make the agent accessible from management applications outside the agent’s JVM.” On the other hand, the Oracle JMX page reads that if you set com.sun.management.jmxremote (as opposed to …jmxremote.port), you make it possible “to monitor a local Java platform, that is, a JVM running on the same machine” – thus not necessarily from the same JVM. Connecting with JConsole Fire up JConsole and type the appropriate remote address, for example service:jmx:rmi:///jndi/rmi://your.server.com:10099/myconnector, if connecting to an application on the remote machine your.server.com accessible via RMI. Regarding the connection URL, if you have a a connector with the serviceUrl of "service:jmx:rmi://myhost:9999/jndi/rmi://localhost:10099/myconnector" then, from a client, you can use either service:jmx:rmi://myhost:9999/jndi/rmi://your.server.com:10099/myconnector or simply service:jmx:rmi:///jndi/rmi://your.server.com:10099/myconnector because, according to the JMX 1.2 Remote API specification (page 90): ... the hostname and port number # (myhost:9999 in the examples) are not used by the client and, if # present, are essentially comments. The connector server address # is actually stored in the serialized stub (/stub/ form) or in the # directory entry (/jndi/ form). IBM JVM, JConsole and JMX configuration The IBM JVM 5 SDK guide indicates that the IBM SDK also contains JConsole and recognizes the same JMX-related system properties, namely com.sun.management.jmxremote.* (though “com.sun.management.jmxremote” itself isn’t mentioned). Notice that the IBM JConsole is a bit different, for instance it’s missing the Local tab, which is replaced by specifying the command-line option connection=localhost (search the SDK guide for “JConsole monitoring tool Local tab”). Further improvements JVM 1.5: Exposing the MemoryMXBean Since Java 5.0 there is a couple of useful platform MBeans that provide information about the JVM, including also the java.lang.management.MemoryMXBean, that let you see the heap usage, invoke GC etc. You can make it available to JConsole and other JMX agents as follows (though there must be an easier way): Update: There indeed seems to be a better way of exposing the platform MBeans directly by replacing the Spring’s MBeanServerFactoryBean with java.lang.management.ManagementFactory using its factory-method getPlatformMBeanServer. Of course this requires JVM 1.5+. Improving security with password authentication Access to your MBeans over RMI may be protected with a password. According to a discussion, authentication is configured on the server connector: The passwd and access files follow the templates that can be found in the JDK/jre/lib/management folder. Summary Exposing a POJO as a MBean with Spring is easy, just don’t forget to start an MBean server and a connector. For JMXMP, include the jmxmp impl. jar on the classpath and for RMI make sure to start a RMI registry before the connector. From http://theholyjava.wordpress.com/2010/09/16/exposing-a-pojo-as-a-jmx-mbean-easily-with-spring/
September 17, 2010
by Jakub Holý
· 37,693 Views
article thumbnail
Are You A Starter, A Finisher Or An Implementer?
There are three parts to every project, starting, finishing and everything in between. Two parts of the process are very difficult to complete, starting and finishing. This is not a tutorial on project management, as much as it is a general guide for people involved in a project. For example, lots of people have ideas. Ideas are easy because they require very little risk. But, what happens after the idea? You are supposed to start the project. However, most people stop with the idea because they “don’t have time” or even “I wouldn’t know where to begin”. Kat French explains how she does her best creative work: The super-secret, hush-hush, “I could tell you, but then I’d have to kill you” secret of how I do my best creative work. Ready? It’s called “starting.” The recipe is.. there is no recipe. This isn’t science. It’s more like alchemy. There are ingredients. Usually those ingredients have certain effects. When you put them all together and apply heat…”results may vary,” Starting does not mean that everything will go well or that you will be successful. Starting just means that you took the initiative to start, and that probably puts you ahead of the majority of workers out there. In order for a project to be successful, you have to start at some point. Most people are not good starters, they need some core foundation or baseline to start with. Some people also need the structure of a formal project management methodology or a detailed task list. The term “self-starter” has been abused by the whole recruitment/HR industry to become someone who can do their own work without significant prodding. What do you call someone who can take an idea and start a project? Some people may throw the title “entrepreneur” at that person, but it also has other meanings. The key is that this person can start something. Are you that person? One problem is that the starter may not be very good at filling in the various details of the project or finishing the project. Starters may be excited by the novelty of a project, but once you get mired in details, the novelty has worn off. By the time you are trying to finish the project, the starter is probably bored or even hates his job. Given that we know that no project is ever really done, you might be able to keep the starter happy by having them begin work on the next phase of the project or a significant new feature. At the other end of the project is completion. Starters typically do not fare well as a finisher of a project. As an example, look at the typical software development project. At the beginning of the project, there is a lot of technology research and foundation or framework code that needs to be completed. Starters love that work. At the end of a project, most of the work is in validating and correcting defects, and working with other departments to ensure deployment goes smoothly. A finisher is the person that works well juggling multiple tasks, fixing defects and managing processes to completion. Obviously, this is a very different person than the starter. The finisher loves a detailed task list as it gives them a goal. If they complete all of these tasks, it is likely that the project has reached its conclusion and the application has been deployed. However, you cannot always be really finishing a project, so how do you keep the finisher happy? Similar to the starter, you can have the finisher move from one project or feature to another. They are a nice complement to the starter in terms of the tasks to be completed. Are you a finisher? But how do you have one project look like several? In project management, a large project is broken into phases, which are really just smaller projects. If you do not have a really large project, you can create smaller projects by looking for milestones in your project. Agile methodologies take this concept to the extreme by ensuring that there is a fixed time for each iteration. In some cases, an iteration could be long enough to implement one feature. So, each feature in your product could become an iteration or a small project. So, we have talked about starting and finishing, but what about the stuff in between? Someone needs to fill in the details. I started by calling this person a filler, but that does not sound like a good name for someone. So, I will call this person an implementer. This person takes the basic infrastructure and puts the application features on top of it. They create the web forms and the code to save the data, using the frameworks provided by the starter. Most people fall into this category because it has the broadest spectrum of work. Each web page or feature may look like a new project for them. They may not require a detailed task list, depending upon experience, but they look at the requirements and fill in the details. Are you an implementer? Because most projects are full of details, the implementer has plenty of work to do. They can be moved from project to project filling in the gaps that the starter and finisher do not complete. Given that there are so many details in projects, this is where a project manager will spend a bulk of their time, managing the implementers. Implementers will also be the most diverse group of people, so management of these people could be a daunting task as well. Of course, the next question from people would be who is most valuable. For that question, I give you a quote from a Seth Godin post about linchpins: A newspaper asked me the following, which practically set my hair on fire: What inherent traits would make it easier for someone to becoming a linchpin? Surely not everyone can be a linchpin? Why not? Each of these types of people are important. What good is a starter if there is nobody there to finish? If you have a finisher, who starts the project in the right direction? Once the project is started someone needs to fill in the details, and that is not the starter or the finisher. There are some of those rare people that can take a project from start to finish, and there are others that overlap into two of the three groups. But you should be honest with yourself. What are you good at? Starting? Finishing? The stuff in between? From http://regulargeek.com/2010/06/24/are-you-a-starter-a-finisher-or-an-implementer
July 5, 2010
by Robert Diana
· 18,302 Views
article thumbnail
Interview: Music Composer on the NetBeans Platform
Steven Yi (pictured right) is a programmer and composer living in Rochester, NY. He studied music composition in college and became a programmer afterwards. He started off as a Flash and server side developer (which he did for about 7 years), and has spent the past few years at his current company doing mobile development with J2ME, Android, and iPhone, as well as server-side development with Spring, Hibernate, etc. He started learning and using Java and Swing for personal work in 2000 and has been using it since then for the development of blue, the focus of the interview that follows below. In the interview, Steven talks about the "blue" music composer, how it works, and how the NetBeans Platform and Python form the basis of this cool open-sourced Java music composer. What's "blue"? blue is a music composition environment I started in the fall of 2000. It was actually my very first Java program! At the time, I had started using the music software Csound (http://www.csounds.com) to compose, but found it slow to work with when it came to accomplishing what I was interested in musically. I had the idea to create a simple program that would have a timeline and the ability to scale musical score material in time. Fast forward many years later: in trying to solve other musical problems, and responding to feedback from the community of users, I've expanded blue's features a great deal. It now includes things like a mixer and effects system, a GUI builder tool for creating synthesizer interfaces, embedded Jython processing of musical scripts, and more. It's been quite satisfying to create a tool that can express my musical interests and to find a community of users who have found value in this program for their own musical work. Some screenshots: The Orchestra manager shows a BlueSynthBuilder instrument being edited. The "Reson 6" instrument is shown in edit mode. The BSB Object Properties panel shows the properties for the selected knob: The Score timeline shows a project using multiple parameter automations. The values automated include things like volume, panning, and a time pointer for a phase-vocoder instrument. All BlueSynthBuilder instruments, Effects, and the Mixer volume sliders can be automated: The Score timeline showing the author's composition "Reminiscences". The timeline shows multiple Python SoundObjects used. The SoundObject Editor shows the editor for the selected SoundObject in the timeline. The SoundObject Properties panel shows different properties for the selected SoundObject: The Score timeline showing a Tracker SoundObject being used. The timeline is configured to snap at every 4 beats and the time bar has been configured to show in numbers rather than time: The Score timeline showing a PianoRoll SoundObject being used. The PianoRoll is unique in that it is microtonal, meaning it can adapt the number of steps per "octave", depending on the values configured from a tuning file. In this screenshot, the scale loaded was a Bohlen-Pierce scale, which has 13-tones per tritave (octave and a half): The blue Mixer is shown docked into the bottom bar and in an open state. The interfaces for user-created Chorus and Reverb effects are shown. The interfaces were created using the same GUI builder tool that is found in the BlueSynthBuilder instrument: It's got a very special appearance. How did that come about? blue's custom look and feel started off one day when I was using my Palm PDA. I remember thinking that I enjoyed the look of the device with the backlight on, and so I wanted to recreate that kind of look for my program. Later, I modified the color scheme to tone it down in some ways, but I also introduced more colors than white and cyan to highlight secondary and tertiary features. Maybe now it is now more like Tron than it is like Palm. :) Overall, I enjoy the darker look of the application when I'm working on music. I tend to work on music when I have free time, and that is usually only late at night—I've found having a darker screen has been easier on my eyes. Also, if anyone was wondering, yes, blue is my favorite color. The blue look and feel is encapsulated in a module named "blue-plaf" and is available in the "blue" Mercurial repository (http://bluemusic.hg.sourceforge.net/hgweb/bluemusic/blue). The look and feel is quite hacked up (redoing it properly has been another item on my todo list), but it can be dropped into another application and it should work, as shown below with the CRUD Sample (which can be created from a tutorial found here): Can you explain how blue's timeline works? blue has a concept of SoundLayers and SoundObjects. SoundObjects are objects that primarily produce notes and have a start and duration. There are many different types of SoundObjects in blue and each has an editor (viewed in the SoundObject Editor TopComponent when a SoundObject is selected), and a BarRenderer, which is used to draw the content area of the bar on the timeline. A PolyObject is a special SoundObject. It consists of SoundLayers, which contain SoundObjects. The root timeline is itself just a PolyObject that you can add as many layers to as you like. You can also group individual SoundObjects into their own PolyObjects, and then use the resulting PolyObjects just like any other SoundObject on the timeline. If you double-click a PolyObject, the timeline is then reset with the timeline of the PolyObject you selected. As a result, PolyObjects allow timelines to be embedded within other timelines. If you think about how music is grouped into motives, phrases, sections, and even larger groupings, you can see how PolyObjects might represent these kinds of musical abstractions. For the component design, the ScoreTopComponent starts off with a JSplitPane to split between a SoundLayerListPanel on the left and a JScrollPane on the right. The JScrollPane has a ScoreTimeCanvas (the main timeline) in the main viewPort's view, a panel with the the time bar and tempo editor in the column header, and the corner is used to open up an extra panel to modify properties for the timeline. The JScrollPane has customized JScrollBars used to add the ± buttons that perform zooming on the timeline. There are a number of other features involved that are implemented amongst a number of classes, but the details of how viewPorts are synchronized (among other things) may be a bit too technical to discuss here. For those who are interested, the code can be viewed within the blue.ui.core.score package within the blue-ui-core module. How did blue come to find itself atop the NetBeans Platform? I first started to be interested in NetBeans IDE around the time 4.1 came out, but didn't really get into using it until the release of 5.0. At that time, I had hand-written Swing components for about 4-5 years (I don't really remember when 5.0 was released), and I found Matisse to be quite nice and began using it here and there. I had looked at the NetBeans Platform as an RCP at that time, but found it to be quite a bit to understand. However, I still kept it on my radar. Around the time 6.0 or 6.5 came out, I started to reconsider migrating to the NetBeans Platform once again. By this time, I had moved over to using NetBeans IDE full time for blue development and had been using NetBeans IDE more in general—particularly Java Web development and Ruby on Rails. One of the biggest things I found attractive about NetBeans IDE is its windowing system... and the things I read about in the platform development articles I'd seen online made me curious once again to see what the NetBeans Platform offered. I still felt that there was going to be a big learning curve to learn the NetBeans Platform, but the NetBeans Platform tutorials online were really quite helpful, as were the members of the NetBeans Platform mailing list, and there were also many more books available to help me get started. I think I ultimately spent about 6-8 months migrating blue to using the NetBeans Platform. Granted, it was a busy time in my life and I was working on this only in my spare time, so I think in the end it was a reasonable amount of time. Users have been very positive about the new blue interface and application as a whole, and I think it has been worth spending the time to use the NetBeans Platform. blue's window layout is quite unexpected for a NetBeans Platform application. By the time I had started migrating blue to the NetBeans Platform, the application was already some 7-8 years old. The interface I designed for blue in pure Swing was influenced by my experiences in using Flash, looking at other music composition environments (Digital Audio Workstations and Sequencing Programs), and evaluating the different aspects of working with Csound. Mapping the components from the Swing-based application to the NetBeans Platform was a little tricky in that I couldn't quite get the exact same design of panels as I had in pure Swing. In the end, I tried to think about where most of the components resided physically, and created TopComponents and placed them in the center, left, right, or bottom parts of the main window. I kept some of the dialogs from the old codebase as-is, but I migrated others to be TopComponents so that they could be docked, opened, or dragged out into a dialog as the user wished. In the end, the GUI is different and took a little getting used to after years of using and building the old interface, but I quickly adjusted to the changes and I think there is much greater consistency and usability now. The users have responded very positively to the general polish of the application and to being able to customize their environment. I myself have very much enjoyed being able to dock all of the windows as well as using full-screen mode, especially when I am on my netbook and composing. Excellent! What features of the NetBeans Platform are you using and what do you find to be most useful? Currently, I am using only a very small part of the NetBeans Platform. By the time I started to move my code to the NetBeans Platform, the codebase was already some 7 or 8 years old. I took the approach recommended to me on the mailing list and started off small, focusing primarily on migrating my project to using the Windows System API, the Options API, and a few other utility API's like IO and Dialogs. Having an old codebase, I found that I spent most of my time during migration just reorganizing my UI into TopComponents and working out communications between the components. I also spent time looking at API's that I had developed myself and seeing which ones could be replaced with API's provided by the NetBeans Platform. At this time, the application is still using a number of API's I wrote from the old codebase, but over time I would like to migrate more of the appplication to use the Nodes and Visual Library API's. I think migrating a codebase of this size in phases really worked out well. In the first phase, I was able to take advantage of the Window System API and have a very visible result on the application and gained a lot for usability. Also, a big part of the migration involved moving the codebase from a monolithic source tree and partitioning it into logical modules. I think there really is a great deal of benefit to working with a codebase with modular design, and that too is a very positive result of working with the NetBeans Platform. Please say something about how Jython relates to this application, how you are using it (what the benefits are), and your general opinions on Jython. I have had a Python SoundObject in blue for quite some time—I think since 2002. For me, it is one of the most important tools in blue when it comes to accomplishing what I want musically. With computer music, we have a lot of tools for what I call Common Practice computer music: PianoRolls, Pattern Editors, and Notation Objects. For computer musicians who are interested in Uncommon Practice music, the ability to use a scripting language opens up a number of ways to express musical ideas that cannot be easily conveyed using those other tools. In blue, Jython is primarily used to allow users to write scripts that will generate notes. For myself, I use Python scripts to model orchestral composition, creating Performer and PerformerGroup objects that I write in Python. I also write performance functions, usually per-project, to perform different musical material in different ways. Other users have used Python scripts in exploring things like algorithmic composition and genetic algorithms in their work. A blue project can contain any number of Python objects. The score generated by each Python object is translated and scaled in time by moving and resizing the SoundObject in the timeline. This allows a user who may want to use scripting to create musical material to also take advantage of blue's timeline to organize how the different musical objects will work together. One of the things I most appreciate about Jython (and scripting languages on the JVM in general) is that it is embeddable within a Java application. By packaging and embedding the Jython interpreter within the blue application, users can rest assured that the Python scripts they write can be interpreted anywhere that blue is installed. It's an extra assurance that their musical projects will be long-lasting, but they can still take advantage of a full programming language like Python in their work. Overall, I think that Jython is a fine piece of software and I hope that it will continue to grow and develop for years to come. Is the application open source and are you looking for code contributions and, if so, in which areas? Yes, the application is available under the GPL v2 license, and the source code can be viewed from the Mercurial repository on SourceForge at http://bluemusic.hg.sourceforge.net/hgweb/bluemusic/blue/. I am a strong proponent of open source, especially for creative work. In the same way that we can today look at and study musical works by composers of the past (like Josquin and Bach), I would like to imagine that the work composers and other artists are now creating with computers will also be open and available for study in the future. I believe that using open source software for creative work greatly helps in making musical projects available for the years ahead. I have done most of the development of blue myself, and over the years I've certainly built up a long list of things that I would like to implement. Users have also made wonderful feature requests that I would love to see in the program—but unfortunately, there are only so many hours in the day. It would certainly be nice to have others contributing code! Beyond new features, there are a number of infrastructural things that would be nice to address. The codebase is many years old, and while the application has been refactored multiple times over its lifetime, there are still some areas of the application that could be much more cleanly implemented. Also, in moving over to the NetBeans Platforms, I only really took the first steps. There are a number of components within the application that could probably be better served by migrating to using more of the NetBeans API's. For internal work, things like modifying the timeline to implement zooming to use Graphics2d and transforms, implementing a better waveform renderer for audio files, and further enhancing the instrument GUI builder are all things I'd like to see. I'd also love to get help in migrating all of the tables and trees to using the Nodes API, something that I have not yet had the time to do. It would also be nice to get the manual (currently in HTML and PDF, generated from DocBook) integrated into the application as JavaHelp, but this is another thing that I have had to postpone due to lack of time. For features, some interesting things I'd love to see are a Notation SoundObject, a separate graphical instrument builder using the Visual Library API, and a Sampler instrument. There's also a sound drawing SoundObject, enhancements to existing SoundObjects, and more I'd love to see moving forward. Maybe someone will find these kinds of things interesting and will take a look at blue's code sometime! Thanks Steven and happy music making with blue!
May 25, 2010
by Geertjan Wielenga
· 17,928 Views
article thumbnail
Interview: Intelligence Gathering Software on the NetBeans Platform
Chris Bohme is the chief software architect at Pinkmatter Solutions – a small, specialized software development company in South Africa. Pinkmatter has been working with a company called Paterva for the past few years to build Maltego - a tool for data visualization, reconnaissance and intelligence gathering. Maltego is used by law enforcement and intelligence agencies, network security professionals and large corporates to discover and analyze information. In a nutshell, how does Maltego work? Maltego models information as entities (e.g., persons, e-mail addresses) and relationships between them. Relationships are discovered by running pluggable functions (called transforms) on the entities. For example, when running a social network transform on my e-mail address, one would discover my Facebook and LinkedIn profiles. Out of the box, Maltego ships with over 150 transforms that mainly relate to open source intelligence. However, an organization using Maltego user can easily create their own transforms that run on their internal data. The concept of transforms makes data gathering very quick and easy which is one of the aspects that sets it apart from some of its competitors like Analyst Notebook, which has been the de-facto tool for investigation and intelligence analysis. Why and how did you choose to use the NetBeans Platform as the basis of this application? We have actually been using the NetBeans Platform at Pinkmatter since 2002, back in the days of NetBeans 3.2, when the NetBeans Platform was not really separate from the IDE and the only real documentation for NetBeans Platform users was the source code. Back then Pinkmatter was building a network security management tool we called “Palantir”, which was never released but which would later form the basis framework for Maltego. (Ironically one of Maltego’s competitors is now made by a company called Palantir Tech.) I was using Forte (Sun’s customized version of NetBeans) as my IDE for Java development and realized that I would need very similar features in Palantir – global selection management, runtime composition (i.e., modules), copy/paste/undo/redo, auto-update, property grid, window manager, system palette etc. So I began reading through the sources and building Palantir as a NetBeans module while trying to remove as much of the IDE parts as possible. I immediately fell in love with its design and complexity (yes, complexity – no matter how long you have been using the NetBeans Platform, there is something new you can learn every day) – but there was a definite beauty to it and I knew that following its architecture guidelines would save me from the certain “spaghetti-death” to which all large UI applications I had seen thus far were doomed from the start. What are the main advantages of the NetBeans Platform to you? On a personal level, working with the NetBeans Platform early on in my developer career has shaped my mindset around application design. As such, the NetBeans Platform source code was one of my most influential teachers when it comes to API design and architecture of large complex applications. I started looking for similar patterns in the frameworks I was building using other programming languages and it has helped me identify designs that are “right” and those that are “wrong”. (When it comes to API design I believe that “truth, like beauty, is not a matter of opinion” :-) ) On the level of Maltego, I think the benefits are fairly obvious – there is a platform that comes with lots “free stuff” right out of the box. And hey, the best thing is, someone else improves, fixes and supports all this free stuff while you can focus on your specific problem domain. If I were to rephrase the question to read “what in the NetBeans Platform couldn’t I live without?” – well, it would be the features related to runtime composition. The fact that components can be registered declaratively (for example in layer files) and are added as modules that get loaded at runtime shapes the overall design and maintainability and is something a modern application cannot do without. As Maltego matures, instead of removing the dependency on some NetBeans APIs and replacing them with our own, we tend to use more and more of what the NetBeans Platform (and even the IDE) has to offer. This is a very good indication to me that a) NetBeans Platform was the right choice to build Maltego on and b) that the evolution of the NetBeans Platform is in line with the needs of its users (well, at least for us). Continue to part 2 of this interview... Were there things that pleasantly surprised you while working with the NetBeans Platform? There were many.... but let’s start with backward compatibility. A lot of the Palantir code from 2002 can still run in NetBeans 6 – that is 3 major versions and 8 years later! – not a small feat to achieve for an API designer. As another example, for the upcoming 3.0 of Maltego we redesigned our underlying information model to allow a user to model entities with a multitude of properties. We needed to allow the user to configure these using many kinds of weird and wonderful type editors... and actually the good old PropertySheet works well for that, can be highly customized and takes up very little screen real estate. In general I am amazed every time how efficiently NetBeans can handle so many modules (and merged layer files)! What could be improved? Well, I have this gripe with the wizard framework. Although sufficient for the IDE, there is a lot to be desired from wizards when used in other applications. How about re-using wizard panels for editing something in a dialog (panels as tabbed panes for example)? Or quick and dirty mechanisms to disable the Cancel button or intercept it to cancel a background thread? (I know, I know, stop complaining, Chris, and contribute something of that sort – yes... one day when Maltego has grown up and I am no longer working nights.) But in the end I think that in spite of all the great efforts that have been made, documentation is still a limiting factor when it comes to the adoption and effective use of the NetBeans Platform. There are a number of really good books, blogs and tutorials, however, I feel there is a need for something like “An Architect’s Guide for Designing Applications for the NetBeans Platform” – something that focuses more on core design decisions that have to be made before getting started. For example, “how is your global selection management to work?” and “what mechanisms does the NetBeans Platform provide for that?” Any tips or tricks for other NetBeans Platform developers? Read every book that has ever been published about the NetBeans Platform. Read and take note of tips published on blogs – you might not need them today but in 6 months time you will remember that there is a smart way to do something. I check planetnetbeans.org every day for interesting articles. Keep a copy of the NetBeans Platform sources around (you can download them in a handy ZIP file and don’t even have to do a checkout). Whenever there is something that you don’t understand or that seemingly does not work, grep the sources for the relevant classes. Don’t feel you have to make use of NetBeans APIs all the time. Sometimes it makes sense to just use a JTable instead of creating a Node implementation with OutlineView. As that component gets more full featured, you can always refactor it and replace it with a suitable View. The default lookup is your friend! Finish this sentence: "If I had known..." Actually, if I had known that it is possible (and easy) to replace the default implementation of ContextGlobalProvider I would have more hair left on my head! (Before I read Tim’s blog entry, activating a TopComponent would amount to changing the global selection – something that is not valid for all applications – and boy did I struggle...) What's the future of the application? We are close to releasing Maltego 3.0 – the next big milestone in the life of our beloved baby. This release brings many new features with it, not least of all a slick new look (thanks to some of the beautiful work done by the likes of Gunnar Reinseth, Mikael Tollefsen and Kirill Grouchnikov): Our ultimate vision is to evolve Maltego into an autonomous information monitoring system – something like an IDS (intrusion detection system), but for information. The threats to organizations (or governments) on the internet are no longer constrained to attacks on their network infrastructure (the origin of the term IDS) but information about them, their competitors or employees floating around on the internet can seriously harm them. Think of it as a highly customizable, intelligent Google Alert, which is fed from the internet as well as private, internal databases. Subsequent releases will bring us closer to that vision with geo-spatial data, time base analyses and live, real time data feeds.
February 15, 2010
by Geertjan Wielenga
· 38,913 Views
article thumbnail
How to Create a Scheduler Module in a Java EE 6 Application with TimerService
Many a time, in a Java EE application, besides the user-triggered transactions via the UI (e.g. from the JSF), there's a need for a mechanism to execute long running jobs triggered over time, e.g., batch jobs. Although in the EJB specs there's a Timer service, where Session Beans can be scheduled to run at intervals through annotations as well as programmatically, the schedule and intervals to execute the jobs have to be pre-determined during development time and Glassfish does not provide the framework and the means to do that out-of-the-box. So it is left to the developer to code that functionality or to choose a 3rd party product to do that. In one of my previous projects using a different application server, I implemented a scheduler module for the application. So with that experience, I will discuss in this article how to create a simple scheduler called SchedulerApp in NetBeans IDE 6.8 that can be deployed in Glassfish v3. The example comes with a framework and the JSF2 PrimeFaces-based UI to schedule and manage (CRUD) your batch jobs implemented by Stateless Session Beans without having to pre-determine the time and interval to execute them during development time. Below is the Class Diagram to give you an overview of the application: Through this exercise, I also hope that you will have a better understanding of the Timer Service in the EJB specs and how you can use it in your projects. Note: If you cannot get your copy running, not to worry, you can get a working copy here. Tutorial Requirements Before we proceed, make sure you review the requirements in this section. Prerequisites This tutorial assumes that you have some basic knowledge of, or programming experience with, the following technologies. JavaServer Faces (JSF) with Facelets Enterprise Java Beans (EJB) 3/3.1 esp. the Timer Service Basic knowledge of using NetBeans IDE will help to reduce the time required to do this tutorial Software needed for this Tutorial Before you begin, you need to download and install the following software on your computer: NetBeans IDE 6.8 (Java pack), http://www.netbeans.org Glassfish Enterprise Server v3, https://glassfish.dev.java.net PrimeFaces Component Library, http://www.primefaces.org Notes: The Glassfish Enterprise Server is included in the Java pack of NetBeans IDE, however, Glassfish can be installed separately from the IDE and added later into Servers services in the IDE. A copy of the working solution is included here if needed. Creating the Enterprise Projects The approach for developing the demo app, SchedulerApp, will be from the back end, i.e., the artifacts and services needed by the front-end UI will be created first, then working forward to the User Interface, i.e., the Ajax-based Web UI will be done last. The first step in creating the application is to create the necessary projects in NetBeans IDE. Choose "File > New Project" to open the New Project Wizard. Under Categories, select Java EE; under Projects select Enterprise Application. Click Next. Select the project location and name the project, SchedulerApp, and click Next. Select the installed Glassfish v3 as the server, and Java EE 6 as the Java EE Version, and click Finish. The above steps will create 3 projects, namely SchedulerApp (Enterprise Application project), SchedulerApp-ejb (EJB project), and SchedulerApp-war (Web project). Creating the Session Beans Before creating the necessary session bean classes, let's look at one of the main classes, JobInfo, which will be heavily used in the application both at the front-end and back. Basically this is a Value Object class that stores information required to configure the timer. Below is an abstract of the class: package com.schedulerapp.common; public class JobInfo implements java.io.Serializable { private static SimpleDateFormat sdf = new SimpleDateFormat("MM/dd/yyyy"); private static SimpleDateFormat sdf2 = new SimpleDateFormat("MM/dd/yyyy HH:mm:ss"); private String jobId; private String jobName; private String jobClassName; private String description; //Details required by the SchedulerExpression private Date startDate; private Date endDate; private String second; private String minute; private String hour; private String dayOfWeek; private String dayOfMonth; private String month; private String year; private Date nextTimeout; public JobInfo() { this("", "", "java:module/"); } public JobInfo(String jobId, String jobName, String jobClassName) { this.jobId = jobId; this.jobName = jobName; this.jobClassName = jobClassName; this.description = ""; //Default values, everyday midnight this.startDate = new Date(); this.endDate = null; this.second = "0"; this.minute = "0"; this.hour = "0"; this.dayOfMonth = "*"; //Every Day this.month = "*"; //Every Month this.year = "*"; //Every Year this.dayOfWeek = "*"; //Every Day of Week (Sun-Sat) } //Getter and Setter methods for the above attributes... /* * Expression of the schedule set in the object */ public String getExpression() { return "sec=" + second + ";min=" + minute + ";hour=" + hour + ";dayOfMonth=" + dayOfMonth + ";month=" + month + ";year=" + year + ";dayOfWeek=" + dayOfWeek; } @Override public boolean equals(Object anotherObj) { if (anotherObj instanceof JobInfo) { return jobId.equals(((JobInfo) anotherObj).jobId); } return false; } @Override public String toString() { return jobId + "-" + jobName + "-" + jobClassName; } } Notice the class holds the information about the job and its schedule. Create the above class in the EJB project, SchedulerApp-ejb with the package name, com.schedulerapp.common. After creating this class, we are ready to create the session beans. Creating the BatchJob Session Beans In this demo, we will be creating THREE batch jobs, namely: BatchJobA, BatchJobB and BatchJobC, where each is a Stateless Session Bean that implements a Local Interface, BatchJobInterface. The Interface will have a method, executeJob(javax.ejb.Timer timer), so each of the batch job session bean will need to implement it and this becomes the starting point for the batch jobs. Let's proceed to create them and you will see what I mean. In the Projects window, right-click on the SchedulerApp-ejb project and select "New > Session Bean..." In the New Session Bean dialog, specify the EJB Name as BatchJobA, the package as "com.schedulerapp.batchjob", Session Type as Stateless and select Local for Create Interface option Notice 2 files are created: BatchJobA (Implementation class) and BatchJobALocal (Local Interface). Here I want to rename the Interface so that it has a generic name like BatchJobInterface In the project view, navigate to the BatchJobALocal file. Right-click on the item and select "Refactor > Rename...", and change the name to BatchJobInterface. Open the renamed file, BatchJobInterface in the editor, and add the method: @Local public interface BatchJobInterface { public void executeJob(javax.ejb.Timer timer); } Notice the file, BatchJobA becomes errorneous after the above is performed. Open the file, BatchJobA and you should see the error hint (lightbulb with exclamation icon) on the left side of the editor. Click on the icon and select "Implement all abstract methods" and edit the file so that it looks like this: @Stateless public class BatchJobA implements BatchJobInterface { static Logger logger = Logger.getLogger("BatchJobA"); @Asynchronous public void executeJob(Timer timer) { logger.info("Start of BatchJobA at " + new Date() + "..."); JobInfo jobInfo = (JobInfo) timer.getInfo(); try { logger.info("Running job: " + jobInfo); Thread.sleep(30000); //Sleep for 30 seconds } catch (InterruptedException ex) { } logger.info("End of BatchJobA at " + new Date()); } } As you can see, the executeJob method does nothing but just sleeps for 30 sec to simulate a long running job. And because of that, it is made an asynchronous method thru the @Asynchronous annotation so that it doesn't block the calling Session Bean. Notice also that the JobInfo object is extracted from the Timer object so that you have the information to execute your job. We will see later how the JobInfo object got into the Timer object. We will next create the other 2 batch job session beans: BatchJobA and BatchJobB using the Copy/Paste and Refactor features of NB6.8. In the project view, navigate to the file, BatchJobA. Right-click on the item and select "Copy" In the same view, right-click the package, "com.schedulerapp.batchjob" and select "Paste > Refactor Copy..." In the Copy Class dialog, enter "BatchJobB" for the New Name field and click on the Refactor button. Notice the new Session Bean, BatchJobB is created with a few easy clicks of a button. The only thing to change in the new class is the print statements, where "BatchJobA" will be changed to "BatchJobB". Repeat the above steps to create BatchJobC session bean. So we now have THREE batch job session beans: BatchJobA, BatchJobB and BatchJobC that implements the Local Interface, BatchJobInterface. We will next create the last Session Bean for this project. Creating the Job Session Bean Here, we will create the Job Session Bean whose main responsibility is to provide the necessary services to the front-end UI to manage (CRUD) the jobs and also provide the timeout method for the TimerService. In the Projects window, right-click on the SchedulerApp-ejb project and select "New > Session Bean..." In the New Session Bean dialog, specify the EJB Name as JobSessionBean, the package as "com.schedulerapp.ejb", Session Type as Stateless and leave Create Interface unchecked, i.e. no Interface (New in EJB 3.1), and click Finish. Open the newly created file, JobSessionBean in the editor and edit the content so that it looks like the following: @Stateless @LocalBean public class JobSessionBean { @Resource TimerService timerService; //Resource Injection static Logger logger = Logger.getLogger("JobSessionBean"); /* * Callback method for the timers. Calls the corresponding Batch Job Session Bean based on the JobInfo * bounded to the timer */ @Timeout public void timeout(Timer timer) { System.out.println("###Timer <" + timer.getInfo() + "> timeout at " + new Date()); try { JobInfo jobInfo = (JobInfo) timer.getInfo(); BatchJobInterface batchJob = (BatchJobInterface) InitialContext.doLookup( jobInfo.getJobClassName()); batchJob.executeJob(timer); //Asynchronous method } catch (NamingException ex) { logger.log(Level.SEVERE, null, ex); } catch (Exception ex1) { logger.severe("Exception caught: " + ex1); } } /* * Returns the Timer object based on the given JobInfo */ private Timer getTimer(JobInfo jobInfo) { Collection timers = timerService.getTimers(); for (Timer t : timers) { if (jobInfo.equals((JobInfo) t.getInfo())) { return t; } } return null; } /* * Creates a timer based on the information in the JobInfo */ public JobInfo createJob(JobInfo jobInfo) throws Exception { //Check for duplicates if (getTimer(jobInfo) != null) { throw new DuplicateKeyException("Job with the ID already exist!"); } TimerConfig timerAConf = new TimerConfig(jobInfo, true); ScheduleExpression schedExp = new ScheduleExpression(); schedExp.start(jobInfo.getStartDate()); schedExp.end(jobInfo.getEndDate()); schedExp.second(jobInfo.getSecond()); schedExp.minute(jobInfo.getMinute()); schedExp.hour(jobInfo.getHour()); schedExp.dayOfMonth(jobInfo.getDayOfMonth()); schedExp.month(jobInfo.getMonth()); schedExp.year(jobInfo.getYear()); schedExp.dayOfWeek(jobInfo.getDayOfWeek()); logger.info("### Scheduler expr: " + schedExp.toString()); Timer newTimer = timerService.createCalendarTimer(schedExp, timerAConf); logger.info("New timer created: " + newTimer.getInfo()); jobInfo.setNextTimeout(newTimer.getNextTimeout()); return jobInfo; } /* * Returns a list of JobInfo for the active timers */ public List getJobList() { logger.info("getJobList() called!!!"); ArrayList jobList = new ArrayList(); Collection timers = timerService.getTimers(); for (Timer t : timers) { JobInfo jobInfo = (JobInfo) t.getInfo(); jobInfo.setNextTimeout(t.getNextTimeout()); jobList.add(jobInfo); } return jobList; } /* * Returns the updated JobInfo from the timer */ public JobInfo getJobInfo(JobInfo jobInfo) { Timer t = getTimer(jobInfo); if (t != null) { JobInfo j = (JobInfo) t.getInfo(); j.setNextTimeout(t.getNextTimeout()); return j; } return null; } /* * Updates a timer with the given JobInfo */ public JobInfo updateJob(JobInfo jobInfo) throws Exception { Timer t = getTimer(jobInfo); if (t != null) { logger.info("Removing timer: " + t.getInfo()); t.cancel(); return createJob(jobInfo); } return null; } /* * Remove a timer with the given JobInfo */ public void deleteJob(JobInfo jobInfo) { Timer t = getTimer(jobInfo); if (t != null) { t.cancel(); } } } Take note of the followings in the above code: Timer Service is made available thru Resource Injection near the top of the class The callback method for the timers created is timeout thru the use of the @Timeout annotation Notice how the JobInfo object gets into the timer thru the TimerConfig object in the createJob method Notice how the Batch Job session beans are being lookup and accessed in the timeout method. The job class name will be the Portable JNDI name provided by the user in the UI later At this point, we are done with the EJB project, and will now move on to the Web project. Creating the Web UI using JSF 2.0 with PrimeFaces At the time of writing this tutorial, there are not many choices of Ajax-based frameworks that works with JSF 2.0 as it is still quite new. But I have found PrimeFaces to be the most complete and suitable for this demo as it has implemented the dataTable UI component and it seems to be the easiest to integrate into the NetBeans IDE. Preparing the Web project to use JSF 2.0 and PrimeFaces Before creating the web pages, ensure the JavaServer Faces framework is added to the Web project, SchedulerApp-war. In the Project view, right-click on the Web project, SchedulerApp-war, and select Properties (last item). Under the Categories items, select Frameworks, and ensure the JavaServer Faces is added to the Used Frameworks list: Before we are able to use PrimeFaces components in our facelets, we need to include its library in NetBeans IDE and set up a few things. Download the PrimeFaces library (primefaces-2.0.0.RC.jar) from http://www.primefaces.org/downloads.html [13] and store it somewhere on the local disk. To allow future projects to use PrimeFaces, I chose to create a Global library in NetBeans for PrimeFaces. Select "Tools > Libraries" from the NetBeans IDE main menu. In the Library Manager dialog, choose "New Library" and provide a name for the library, e.g. "PrimeFaces2". With the new "PrimeFaces2" library selected, click on the "Add JAR/Folder..." button and select the jar file that was downloaded earlier and click OK to complete: Next, we need to add the newly created library, PrimeFaces2 to the Web project: Select the Web project, SchedulerApp-war, from the Project window, right-click and select "Properties". Under the Libraries category, click on the "Add Library..." button (on the right), and choose the PrimeFaces2 library and click OK to complete: Because we will be using Facelets in our demo, we will update the XHTML template in NetBeans so that all the XHTML files created subsequently will already have the required namespaces and resources needed for the development. Choose "Tools > Templates" from the NetBeans menu. In the Template Manager dialog, select "Web > XHTML" and click the "Open in Editor" button. Edit the content of the file so that it looks like this: <#assign licenseFirst = ""> <#include "../Licenses/license-${project.license}.txt"> TODO write content Lastly, we need to add the following statements in the web.xml file of the Web project for the PrimeFaces components to work properly: Faces Servlet /faces/* *.jsf Resource Servlet org.primefaces.resource.ResourceServlet Resource Servlet /primefaces_resource/* com.sun.faces.allowTextChildren true At this point, we are done setting up and configuring the environment for PrimeFaces to work in NetBeans. In the sections below, we will create the JSF pages to present the screens to perform the CRUD functions. To achieve this, we will be creating THREE web pages: JobList - listing of all the active Jobs/Timers created in a tabular form JobDetails - view/update/delete the selected Job JobNew - create a new Job Creating the Backing Beans for the JSF pages Before creating the actual JSF pages, we first need to create the backing beans that provides the properties and action handlers for the JSF pages (XHTML). Here we will create TWO backing beans: JobList - RequestScoped backing bean for the Job Listing page JobMBean - SessionScoped backing bean for the rest of the JSF pages Steps to create the beans: In the Project view, right-click on the Web project, SchedulerApp-war, and select "New > JSF Managed Bean...", specify JobList as the Class Name, "com.schedulerapp.web" as the Package Name, and the scope to be request Repeat the steps to create the second backing bean, name it JobMBean and set the scope to be session instead. Edit the class, JobList, so that it looks like this: @ManagedBean(name = "JobList") @RequestScoped public class JobList implements java.io.Serializable { @EJB private JobSessionBean jobSessionBean; private List jobList = null; /** Creates a new instance of JobList */ public JobList() { } @PostConstruct public void initialize() { jobList = jobSessionBean.getJobList(); } /* * Returns a list of active Jobs/Timers */ public List getJobs() { return jobList; } } Edit the class, JobMBean, so that it looks like this: @ManagedBean(name = "JobMBean") @SessionScoped public class JobMBean implements java.io.Serializable { @EJB private JobSessionBean jobSessionBean; private JobInfo selectedJob; private JobInfo newJob; /** Creates a new instance of JobMBean */ public JobMBean() { } /* * Getter method for the newJob property */ public JobInfo getNewJob() { return newJob; } /* * Setter method for the newJob property */ public void setNewJob(JobInfo newJob) { this.newJob = newJob; } /* * Getter method for the selectedJob property */ public JobInfo getSelectedJob() { return selectedJob; } /* * Setter method for the selectedJob property */ public String setSelectedJob(JobInfo selectedJob) { this.selectedJob = jobSessionBean.getJobInfo(selectedJob); return "JobDetails"; } /* * Action handler for back to Listing Page */ public String gotoListing() { return "JobList"; } /* * Action handler for New Job button */ public String gotoNew() { System.out.println("gotoNew() called!!!"); newJob = new JobInfo(); return "JobNew"; } /* * Action handler for Duplicate button in the Details page */ public String duplicateJob() { newJob = selectedJob; newJob.setJobId(""); return "JobNew"; } /* * Action handler for Update button in the Details page */ public String updateJob() { FacesContext context = FacesContext.getCurrentInstance(); try { selectedJob = jobSessionBean.updateJob(selectedJob); context.addMessage(null, new FacesMessage(FacesMessage.SEVERITY_INFO, "Success", "Job successfully updated!")); } catch (Exception ex) { Logger.getLogger(JobMBean.class.getName()).log(Level.SEVERE, null, ex); context.addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, "Failed", ex.getCause().getMessage())); } return null; } /* * Action handler for Delete button in the Details page */ public String deleteJob() { jobSessionBean.deleteJob(selectedJob); return "JobList"; } /* * Action handler for Create button in the New page */ public String createJob() { FacesContext context = FacesContext.getCurrentInstance(); try { selectedJob = jobSessionBean.createJob(newJob); context.addMessage(null, new FacesMessage(FacesMessage.SEVERITY_INFO, "Sucess", "Job successfully created!")); return "JobDetails"; } catch (Exception ex) { Logger.getLogger(JobMBean.class.getName()).log(Level.SEVERE, null, ex); context.addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, "Failed", ex.getCause().getMessage())); } return null; } } Now, we have all the services and properties ready to be used by the JSF pages. Creating the JSF pages Finally, we are ready to create the THREE JSF pages: JobList, JobDetails and JobNew. In the Project view, right-click on the Web project, SchedulerApp-war, and select "New > XHTML...", specify JobList as the File Name. Note: If the item "XHTML..." doesn't appear in your menu list, select "New > Others..." instead, then in the New File dialog, select Web under Categories and you should be able to see the XHTML file type on the right. Repeat the above step for JobDetails and JobNew. Edit the file, JobList.xhtml to look like this: Job List Edit the file, JobDetails.xhtml to look like this: Help Edit the file, JobNew.xhtml to look like this: Help At this point, we are done with all the coding, and it's now time to verify the results. Perform a "Clean and Build" of the project and deploy it to the Glassfish v3 server. Testing the application Here, we will do a simple test to verify that the application is working. We will schedule 3 jobs as follows: Job 1 - run BatchJobA every 2 minutes (just to make sure we see the job running) Job 2 - run BatchJobB everyday at 11pm Job 3 - run BatchJobC every Sunday at 1am Steps to create the jobs: Go to the listing page, http://localhost:8080/SchedulerApp-war/JobList.jsf and you should see the following screen: Click on the "New Job" button below the table. Enter the details for Job 1 as follows and click on the "Create" button Click on the "Duplicate" button below to create a new Job using the current information. Enter the details for Job 2 as follows and click on the "Create" button Click on the "Duplicate" button below to create a new Job using the current information. Enter the details for Job 3 as follows and click on the "Create" button At this point, we are done creating the jobs, click on the "Back" button to see the listing. The Job List page should consists of 3 jobs that was created in the above steps Things to Note The Portable JNDI syntax for accessing the Session Beans: BatchJobA, BatchJobB and BatchJobC The "*" in the text fields represents "Every", see Java EE 6 Tutorial for details You should be able see in the log file, server.log, that BatchJobA now runs every 2 minutes The timers(jobs) are persistent, i.e. they will survive server restarts. Try restarting ther server and view the Job list again Try out the other functions of the CRUD and schedule your own jobs to see it in action. Summary Congratulations! You now have a simple scheduler to schedule your long running jobs in your application. With this framework and the GUI, you can have the flexibility and full control over the jobs you want to manage without having to pre-determine the time and interval to run them during Design and Development phase. Although the timers are persistent, the server may remove them when changes, such as new deployments, are detected. As such, you can further extend the scheduler to persist information in the database in a more dynamic and complex environment, e.g., a cluster. Good luck and have fun using the Scheduler. If you cannot get your copy running, not to worry, you can get a working copy here. See Also For other related resources, see the following: Develop Java EE 5 application with Visual JSF, EJB3 and JPA Securing Java EE 6 application with JEE Security and LDAP How to Create a Java EE 6 Application with JSF 2, EJB 3.1, JPA, and NetBeans IDE 6.8
January 10, 2010
by Christopher Lam
· 109,704 Views · 1 Like
article thumbnail
Maven Repository Manager: Nexus Vs. Artifactory
My goal is to compare Sonatype Nexus and JFrog Artifactory,the two leading open source Maven repository managers.
December 14, 2009
by Ori Dar
· 136,637 Views · 4 Likes
article thumbnail
Leader vs Ruler
When I was trying to search for "leaders vs. rulers" on Google, I found many references to governments, royalty, and the military, throughout history. But the strange thing is that none of the articles seemed to distinguish between leaders and rulers. As if leaders and rulers are the same kind of people. They are not. Leaders Last week I was reading the book Tribes, by Seth Godin. In his book Seth says that never in history has it been so easy for anyone to be a leader. These days, with the use of social media, each of us is able to attract our own followers. And on Twitter, this is exactly what we're doing (quite literally). Seth explains that a crowd becomes a tribe when it has a leader that the people are following out of their own free will. And the interesting thing is that people can follow different leaders for different causes. In software projects it is the same. Some people can take the lead on an architectural level, while some have the lead on a functional level. Still others may be the first ones to turn to when people need advice about tools or processes. A complex system does not need a single leader. In fact, I believe a cross-functional team functions best when it has multiple leaders, each with his own area(s) of interest. Rulers In social systems the rulers are of an entirely different breed. While leaders use the power of attraction to convince people what to do, rulers use the power of authority to tell people what to do. Ruling people's lives is the very purpose of the ruler's job. With ruling comes law-making, enforcement and sanctioning, also called the trias politica (legislature, executive, judiciary). Unfortunately, rulers have gotten a bit of a bad name over the centuries. (Much of it deserved, by the way.) But ruling isn't all that bad. Laws, enforcement and sanctions are necessary evils, and in many social systems rulers can peacefully co-exist with leaders. For example: in any football (or soccer) match you will find leaders (one in each team) and rulers (the referees). They all play their parts in making the game work for everyone. Are managers rulers? There's no doubt in my mind that managers are rulers. They are (usually) the only ones with the authority to hire and fire people, and to place them in (or remove them from) teams or departments. They are able to tell people what software to use, what clothes to wear, and how much to pay for a place at the parking lot. Are managers leaders? This is a more interesting question. Lots of management book have been trying hard to turn managers into leaders. The last one I read was Good to Great, by Jim Collins. In his book Jim listed a 5-level hierarchy: Level 5 Executive: Builds enduring greatness through a paradoxical blend of personal humility and professional will. Level 4 Effective Leader: Catalyzes commitment to and vigorous pursuit of a clear and compelling vision, stimulating higher performance standards. Level 3 Manager: Organizes people and resources toward the effective and efficient pursuit of pre-determined objectives. Level 2 Contributing Team Member: Contributes individual capabilities to the achievement of group objectives and works effectively with others in a group setting. Level 1 Highly Capable Individual: Makes productive contributions through talent, knowledge, skills, and good work habits. The problem I have with Jim's hierarchy is that it suggests a linear progression to "higher" levels (where a leader is on a "higher" level than a manager). This doesn't fit with my observations of how social networks operate. In a software project, or any other social network, there can be many leaders, each with his or her own goals and desires. Some are taking initiatives for better architectures, some are leading the way to better user interface design, and some are guiding their followers towards better customer service, better processes, better software tools, or better coffee. To be a leader is not the next step for managers It is the manager's job to give room to leaders There are thousands of leaders on Twitter, and they all have their own huge numbers of followers. But who are the managers of Twitter? Only Evan Williams, Biz Stone and Jack Dorsey are. It's their platform. It's their game. They are the referees, making the laws, enforcing them, and sanctioning, while thousands of leaders and tribes are running around trying to score. Sure, it's ok when managers are trying to be leaders. Nothing wrong with that. Evan, Biz and Jack have a large number of followers themselves too. But they don't have the largest tribes. Managers are on top of things, but they are not on top. Rulers don't need to have the largest tribes themselves. Being a great ruler is hard enough already. If you think you need to be a great leader too, you're just making it hard for yourself. Referees contribute to great football/soccer games by being great rulers. They don't attempt to lead. It's not their job. They are in charge, but they are not the ones with the biggest egos. In his presentation Step Back from Chaos Jonathan Whitty shows that managers are often not the hubs in a social network. It's the informal leaders in a network through which most of the communication flows. It's the managers' job to make sure that leadership is cultivated, and that the emerging leaders are following the rules. So, you can be a leader, or you can be a ruler. And if you're exceptionally talented, perhaps you can be both. Which one will you be?
April 28, 2009
by Jurgen Appelo
· 6,673 Views
article thumbnail
Compute Grids vs. Data Grids
in a nutshell, grid computing is a way to distribute your computations across multiple computers (nodes). however, even jms does that, but jms is not a grid computing product - it's a messaging protocol. to correctly classify grid computing products we have to split them into 2 categories: compute grids and data grids. compute grid compute grids allow you to take a computation, optionally split it into multiple parts, and execute them on different grid nodes in parallel. the obvious benefit here is that your computation will perform faster as it now can use resources from all grid nodes in parallel. one of the most common design patterns for parallel execution is mapreduce . however, compute grids are useful even if you don't need to split your computation - they help you improve overall scalability and fault-tolerance of your system by offloading your computations onto most available nodes. some of the "must have" compute grid features are: automatic deployment - allows for automatic deployment of classes and resources onto grid without any extra steps from user. this feature alone provides one of the largest productivity boosts in distributed systems. users usually are able to simply execute a task from one grid node and as task execution penetrates the grid, all classes and resources are also automatically deployed. topology resolution - allows to provision nodes based on any node characteristic or user-specific configuration. for example, you can decide to only include linux nodes for execution, or to only include a certain group of nodes within certain time window. you should also be able to choose all nodes with cpu loaded, say, under 50% that have more than 2gb of available heap memory. collision resolution - allows users to control which jobs get executed, which jobs get rejected, how many jobs can be executed in parallel, order of overall execution, etc. load balancing - allows to balance properly balance your system load within grid. usually range of load balancing policies varies within products. some of the most common ones are round robin, random, or adaptive. more advanced vendors also provide affinity load balancing where grid jobs always end up on the same node based on job's affinity key. this policy works well with data grids described below. fail-over - grid jobs should automatically fail-over onto other nodes in case of node crash or some other job failure. checkpoints - long running jobs should be able to periodically store their intermediate state. this is useful for fail-overs, when a failed job should be able to pick up its execution from the latest checkpoint, rather than start from scratch. grid events - a querying mechanism for all grid events is essential. any grid node should be able to query all events that happened on remote grid nodes during grid task execution. node metrics - a good compute grid solution should be able to provide dynamic grid metrics for all grid nodes. metrics should include vital node statistics, from cpu load to average job execution time. this is especially useful for load balancing, when the system or user need to pick the least loaded node for execution. pluggability - in order to blend into any environment a good compute grid should have well thought out pluggability points. for example, if running on top of jboss, a compute grid should totally reuse jboss communication and discovery protocols. data grid integration - it is important that compute grid are able to natively integrate with data grids as quite often businesses will need both, computational and data features working within same application. some compute grid vendors: - gridgain - professional open source - jppf - open source data grid data grids allow you to distribute your data across the grid. most of us are used to the term distributed cache rather than data grid (data grid does sound more savvy though). the main goal of data grid is to provide as much data as possible from memory on every grid node and to ensure data coherency. some of the important data grid features include: data replication - all data is fully replicated to all nodes in the grid. this strategy consumes the most resources, however it is the most effective solution for read-mostly scenarios, as data is available everywhere for immediate access. data invalidation - in this scenario, nodes load data on demand. whenever data changes on one of the nodes, then the same data on all other nodes is purged (invalidated). then this data will be loaded on-demand the next time it is accessed. distributed transactions - transactions are required to ensure data coherency. cache updates must work just like database updates - whenever an update failed, then the whole transaction must be rolled back. most data grid support various transaction policies, such as read committed, write committed, serializable, etc... data backups - useful for fail-over. some data grid products provide ability to assign backup nodes for the data. this way whenever a node crashes, the data is immediately available from another node. data affinity/partitioning - data affinity allows you to split/partition your whole data set into multiple subsets and assign every subset to a grid node. in the purest form, data is not replicated between nodes at all, every node is only responsible for it's own subset of data. however, various data grid products may provide different flavors of data affinity, such as replication only to back up nodes for example. data affinity is one of the more advanced features, and is not provided by every vendor. to my knowledge, according to product websites, out of commercial vendors oracle coherence and gemstone have it (there may be others). in professional open source space you can take a look at combination of gridgain with affinity load balancing and jbosscache . some data grid/cache vendors: - oracle coherence - commercial - gemstone - commercial - gigaspaces - commercial - jbosscache - professional open source - ehcache - open source
July 31, 2008
by Dmitriy Setrakyan
· 28,412 Views · 3 Likes
article thumbnail
Spring Batch - Hello World
This is an introductory tutorial to Spring Batch. It does not aim to provide a complete guide to the framework but rather to facilitate the first contact. Spring Batch is quite rich in functionalities, and this is basically how I started learning it. Keep in mind that we will only be scratching the surface. Before we start All the examples will have the lofty task of printing "Hello World!" though in different ways. They were developed with Spring Batch 1.0. I'll provide a Maven 2 project and I'll run the examples with Maven but of course it is not a requirement to work with Spring Batch. Spring Batch in 2 Words Fortunately, Spring Batch model objects have self-explanatory names. Let's try to enumerate the most important and to link them together: A batch Job is composed of one or more Steps. A JobInstance represents a given Job, parametrized with a set of typed properties called JobParameters. Each run of of a JobInstance is a JobExecution. Imagine a job reading entries from a data base and generating an xml representation of it and then doing some clean-up. We have a Job composed of 2 steps: reading/writing and clean-up. If we parametrize this job by the date of the generated data then our Friday the 13th job is a JobInstance. Each time we run this instance (if a failure occurs for instance) is a JobExecution. This model gives a great flexibility regarding how jobs are launched and run. This naturally brings us to launching jobs with their job parameters, which is the responsibility of JobLauncher. Finally, various objects in the framework require a JobRepository to store runtime information related to the batch execution. In fact, Spring Batch domain model is much more elaborate but this will suffice for our purpose. Well, it took more than 2 words and I feel compelled to make a joke about it, but I won't. So let's move to the next section. Common Objects For each job, we will use a separate xml context definition file. However there is a number of common objects that we will need recurrently. I will group them in an applicationContext.xml which will be imported from within job definitions. Let's go through these common objects: JobLauncher JobLaunchers are responsible for starting a Job with a given job parameters. The provided implementation, SimpleJobLauncher, relies on a TaskExecutor to launch the jobs. If no specific TaskExecutor is set then a SyncTaskExecutor is used. JobRepository We will use the SimpleJobRepository implementation which requires a set of execution Daos to store its information. JobInstanceDao, JobExecutionDao, StepExecutionDao These data access objects are used by SimpleJobRepository to store execution related information. Two sets of implementations are provided by Spring Batch: Map based (in-memory) and Jdbc based. In a real application the Jdbc variants are more suitable but we will use the simpler in-memory alternative in this example. Here's our applicationContext.xml: Hello World with Tasklets A tasklet is an object containing any custom logic to be executed as a part of a job. Tasklets are built by implementing the Tasklet interface. Let's implement a simple tasklet that simply prints a message: public class PrintTasklet implements Tasklet{ private String message; public void setMessage(String message) { this.message = message; } public ExitStatus execute() throws Exception { System.out.print(message); return ExitStatus.FINISHED; } } Notice that the execute method returns an ExitStatus to indicate the status of the execution of the tasklet. We will define our first job now in a simpleJob.xml application context. We will use the SimpleJob implementation which executes all of its steps sequentailly. In order to plug a tasklet into a job, we need a TaskletStep. I also added an abstract bean definition for tasklet steps in order to simplify the configuration: ; Running the Job Now we need something to kick-start the execution of our jobs. Spring Batch provides a convenient class to achieve that from the command line: CommandLineJobRunner. In its simplest form this class takes 2 arguments: the xml application context containing the job to launch and the bean id of that job. It naturally requires a JobLauncher to be configured in the application context. Here's how to launch the job with Maven. Of course, it can be run with the java command directly (you need to specify the class path then): mvn exec:java -Dexec.mainClass=org.springframework.batch.core.launch.support.CommandLineJobRunner -Dexec.args="simpleJob.xml simpleJob" Hopefully, your efforts will be rewarded with a "Hello World!" printed on the console. The code source can be downloaded here. What's Next? This is the first part of 3. In the next part we will improve on this example while the third part will be dedicated to item oriented steps and flat files readers and writers. Hope you find it useful.
May 23, 2008
by Tareq Abedrabbo
· 299,486 Views
article thumbnail
Interview: Game Over for the JDK's Date and Time Classes
JSR 310 aims to modernize the date and calendar classes. The goal is to provide a more advanced and comprehensive model for date and time than those found in the Date and Calendar APIs. The JSR's leaders, Stephen Colebourne and Michael Nascimento, are presenting their work at JavaOne and give an overview below. Firstly, please briefly introduce yourselves. Michael Nascimento. I'm a senior technical consultant at Summa technologies and the founder of the Genesis open source project. I have also served as an expert on a few JSRs, such as the Common Annotations for the Java Platform (JSR-250). Stephen Colebourne. I am employed building travel e-commerce booking engines and am involved with many open source projects, such as Apache Commons and JodaTime. I am involved in this JSR because of my JodaTime project. JodaTime? What's that? Stephen: JodaTime provides a complete replacement of the date and time classes in the JDK: public boolean isAfterPayDay(DateTime datetime) { if (datetime.getMonthOfYear() == 2) { // February is month 2!! return datetime.getDayOfMonth() > 26; } return datetime.getDayOfMonth() > 28; } public Days daysToNewYear(LocalDate fromDate) { LocalDate newYear = fromDate.plusYears(1).withDayOfYear(1); return Days.daysBetween(fromDate, newYear); } public boolean isRentalOverdue(DateTime datetimeRented) { Period rentalPeriod = new Period().withDays(2).withHours(12); return datetimeRented.plus(rentalPeriod).isBeforeNow(); } public String getBirthMonthText(LocalDate dateOfBirth) { return dateOfBirth.monthOfYear().getAsText(Locale.ENGLISH); } What are the main things that are wrong with the current date and time classes? Stephen: The existing classes are pretty bad—probably the worst APIs in the JDK. They're buggy, mutable, cumbersome, many bugs, and they tend not to be threadsafe. Michael: The original date class comes from JDK 1.0. At the time, James Gosling tried to follow the related functions in C and didn't put much force into designing them from scratch. For example, they can't be internationalized and only local timezones are supported. Stephen: Right. The Gregorian calendar class is a direct port of the C-class, such as "January = 0". So, if you enter the month "12", the month is January because the algorithm wraps around. The algorithm performs calculations such as this that you don't expect. For example, with the Gregorian calendar class, getYear(), getMonth(), and getDay() are quick, while if you call combinations of getyear(), setyear() (and getMonth() setMonth(), and so on), performance will be bad because lots of calculations are done unexpectedly. Politely put, one can describe these classes as exhibiting "unusual performance characteristics". Why has it taken so long to fix these various problems? Stephen: People have known of these problems for several years. Some attempts have been made to fix the Calendar class, but it only got worse. Fixing these issues once and for all has never been a high enough priority. So why now and why you? Stephen: I started JodaTime in 2000/2001 and gradually solved the standard date and time class problems, releasing it in 2003. My solution has been picked up across the board, from small applications to the largest advertizing systems in the world. The point is that I wanted the solution to exist a few years as JodaTime, before heading into a JSR so that all the issues would have been identified in preparation for the JSR. In a nutshell, what does JodaTime offer me? Michael: Firstly, a better quality API. Stephen: Secondly, JodaTime supports a number of additional concepts. Firstly, "periods", such as if you wanted to store the concept of 5 weeks and 3 days. Secondly, "intervals", so that you'll be able to store the interval between the start of JavaOne and its end, i.e., for example, from Monday May 5, 9 a.m. to May 9, 3 p.m. Thirdly, an updated timezone implementation to make it easy to pick up timezone changes, which could even be on an annual basis. Finally, handling of different calendar systems, such as Islamic calendar systems / Coptic calendar systems, and so on, which don't exist in the standard JDK. Michael: The third point is why I got interested in this JSR in the first place. I'm from Brazil where the daylight saving systems change each year and there's always one or two weeks of chaos. I asked myself why things go wrong every year around this issue. Stephen. Possibly we could offer a solution consisting of a JAR file with the latest set of rules, which you could then put on the classpath. However, sometimes you'd need both sets of rules at the same time. We're still thinking about these situations and ought to be able to come up with something. By the way, where does the name "Joda" come from? Stephen: "Joda" was a 4 letter domain name starting with "J" that was free in 2003. I simply typed random things beginning with "J" and found that that one was free... Where is the JSR process now? Michael: We are progressing it in an open manner. All discussions are on public mailing lists and Wikis. All repositories are open and Issuezilla is open. Stephen: We are using java.net to build a reference implementation and a testing kit in Subversion. People can go there and try it out. It is all "work in progress". The basic API is there. Right now, parsing needs to be finished and some loose ends need to be tidied up. Parsing, intervals, and multiple calendar systems are missing at the moment. Can you say something about the JSR's timeline? Stephen: We hope that we'll be in Java 7, but given that there's no date for it, there's no guarantee that we'll finish in time. We received a little bit of funding from the OpenJDK challenge to get to early draft review by August. Michael: It's really important that people get involved, the last chance to influence design aspects is the early draft review, scheduled for August, which is coming near. Two previous attempts have been made for rewriting these classes and it's unlikely there'll be another one after ours. So it is really important to let your voice be heard because the more feedback we get the better. Stephen: There's been good quality feedback. We've had suggestions consisting of sample implementations of intervals, people pointing to different ISO specifications, and suggestions to expand into areas outside our scope. People should take a look at the algorithms too. Maybe someone could come up with better algorithms than those that we already have. Michael: We've also been nominated for a JCP Program Award, probably because we're the main examples of individuals, rather than a company, leading a JSR. The results will be announced on Tuesday during JavaOne. Will you present something around your JSR at JavaOne? Michael: Our technical session on Thursday at 1.30 is completely full and there's a repeat session on Friday at the same time, that is, at 1.30. In the session, we will cover all the basic classes, show examples of the code and how to get started with it. Stephen: There'll be little bit of explanation around the design principles, with examples of how bad the current date and time classes are. There'll also be a small puzzler, asking participants to identify the number of bugs in an existing bit of JDK code... Further Reading JSR 310 JSR 310 Technical Sessions at JavaOne JSR 310 General Purpose Area for Anyone to Leave Messages JSR 310 Mailing List Stephen Colebourne's blog Michael Nascimento's blog JCP Program's Award Nominations
May 5, 2008
by Geertjan Wielenga
· 13,330 Views
  • Previous
  • ...
  • 48
  • 49
  • 50
  • 51
  • 52
  • RSS
  • X
  • Facebook

ABOUT US

  • About DZone
  • Support and feedback
  • Community research

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Core Program
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 3343 Perimeter Hill Drive
  • Suite 215
  • Nashville, TN 37211
  • [email protected]

Let's be friends:

  • RSS
  • X
  • Facebook
×