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 Software Design and Architecture Topics

article thumbnail
SOA Anti-pattern: Nanoservices
After a long hiatus, I guess it is time for another SOA anti-pattern to see the light. It is probably also a good time to remind you that I am looking for your insights on this project. In any event I hope you’d find this anti-pattern useful and as always comments are more than welcomed (do keep in mind this is an unedited draft :) ) ------------------------------------- There are many unsolved mysteries, you’ve probably heard about some of them like the Loch Ness monster, Bigfoot etc. However, the greatest mystery, or so I’ve heard, is getting the granularity of services right… Kidding aside, getting right-sized services is indeed one of the toughest tasks designing services – there’s a lot to balance here e.g. the communications overhead, the flexibility of the system, reuse potential etc. I don’t have the service granularity codex and deciding the best granularity depends on the specific context and decisions (e.g. the examples in the Knot anti-pattern above). It is an easier task to define what shouldn’t be a service for instance, calling all of your existing ERP system a single service should definitely be shunned. The Nanoservices anti-pattern talks about the other extreme… the smaller services Consider, for instance, the “calculator service” which appears in samples web-wide (I’ve personally seen examples in .NET, Java, PHP, C++ and a few more). A basic desk calculator, as we all know, supports several simple operations like add, subtract, multiply and divide and sometimes a few more. Implementing a calculator service isn’t very complicated - Listing 10.1 below, for example, shows part of WSDL for a java calculator service that, lo and behold, accepts two numbers and adds them. Listing 10.1 excerpt from a WSDL of a stateless calculator service example. The sample only includes the data needed for the “Add” operation. The add operation accepts two numbers and returns a result (http://cwiki.apache.org/GMOxDOC21/jaxws-calculator-simple-web-service-with-jax-ws.html) Calculator services can be even more advanced and have memory - consider listing 10.2 below, which shows an interface definition for a .NET (WCF) sample that uses workflow services and accepts a single value at a time Listing 10.2 a Service contract definition for a statufil calculator service (http://msdn.microsoft.com/en-us/library/bb410782.aspx). The service accepts a single number at a time and remembers the former state from operation to operation. [ServiceContract(Namespace = "http://Microsoft.WorkflowServices.Samples")] public interface ICalculator { [OperationContract()] int PowerOn(); [OperationContract()] int Add(int value); [OperationContract()] int Subtract(int value); [OperationContract()] int Multiply(int value); [OperationContract()] int Divide(int value); [OperationContract()] void PowerOff(); } The calculator service (both versions of it) is a very fine grained service. Naturally, or hopefully anyway, the calculator examples are just over simplified services used to demonstrate SOA related technologies (JAX-WS in the first excerpt and WCF and WF in the second one). The problem is when we see this level of granularity in real life services 1.1.1Consequences Problem? Why is “fine granularity” a problem anyway? Isn’t SOA all about breaking down monolith “silos” into small reusable services? More so, the finer grained a service is, the less context it carries. The less context a service carries the more reuse potential it has – and reuse is one of the holy grails of SOA isn’t it? The calculator service above seems like the epitome of a reusable service. There’s no doubt we can reuse it over and over and over. Reuse is indeed a noble goal (I’ll leave discussing how real it is for another occasion), the culprit of fine grained services, however, is the network. Services are consumed over networks – both local (LANs) and remote (extranets, WANs etc.). The result is that services are bound by the limitations and costs incurred by those network. Trying to disregard these costs is exactly what ailed most, if not all, RPC distributed system approaches that predated SOA (Corba, DCOM etc.) - The calculator service and other similarly sized services are nanoserivces. Nonoservice is an Anti-pattern where a service is too fine grained. Nanoservice is a service whose overhead (communications, maintenance etc.) out-weights its utility. So how can nanoservices harm your SOA? Nanoservices cause many problems, the major ones being poor performance, fragmented logic and overhead. Let’s look at them one by one Every time we send a request to a service we incur a few costs such as serialization on caller, moving caller process to the OS network service, translation to the underlying network protocol, traveling on the network, moving from the OS network service to the called process, deserialization on the called process – and that’s before adding security (encryption, firewalls etc), routing , retries etc. Modern networks and servers can make all this happen rather fast but if we have a lot of nano-services running around these numbers add-up to a significant performance nightmare, Nano-services cause fragmented logic - almost by definition. As we break what should have been a meaningful cohesive service, into miniscule steps our logic is scattered between the bits that are needed to complete the business service. The fact that you need to haul over several services to accomplish something meaningful also spell increased chances of the Knot anti-pattern, mentioned above. Proliferation of Nanoservices also causes development and management overhead. Just look at the amount of WSDL needed to define the calculator services in listing 10.1 above and for what? A service that adds a couple of numbers… There is a relatively fixed overhead associated with managing a service. This include things like keeping track of a service in a service registry, making sure it adheres to policy, writing the cruft (things we have to write around the business logic) for configuring it etc. Having nano-services around means we have to do this a whole-lot more times (i.e. per service) compared with having fewer coarser grained services. The point of overhead out-weighing utility that appears in the Nano-services definition above is subtle but important. The fact that a contract does not have a lot of operations means we want to make sure we don't have a nano-service, but it doesn't automatically mean that it is. For instance, a fraud detection service contract might only accept transaction details and decide whether to authorize the transaction, deny it or move to further investigation. However the innards of this service involve a complex process like running the details in a rule engine checking for fraudulent behavior patterns, matching to black lists etc. In fact Fraud detection is such a complicated issue that these are actually systems and a SOA based one would be comprised of several services in itself. The other side of the equation is also true a comprehensive contract does not guarantee a service is not a nano-service. For instance, in a system I designed on the initial iterations we developed a resource management service. It supported some very nice operations like getting status of all the services in the system, running sagas and of course allocating services. Allocating services meant that whenever an event went out that needed a (new) service instance to handle it, we had to make a call to the resource manager to get one. This provides for a neat centralized management and also for a performance bottleneck that slows the whole system. To solve this we went with distributed resource management but that't beyond the scope of this discussion. The point, however that is that the utility of the resource management (e.g. easy management of running sagas ) vs. overhead associated with the service (the number of calls and performance hit on the system) was not worth it – Hench a nano-service. 1.1.2Causes From a more technical point of view, we get to nanoservices from not paying attention to at least a couple of the fallacies of distributed computing. Mentioned in chapter 1, the fallacies of distributed computing are a few false assumptions that are easy to make and prove to be wrong and costly down the road. Specifically, we are talking here about assuming that § Bandwidth is infinite – Even though bandwidth gets better and better, it is still not infinite within a specific setup. For instance in one project we were sending images over the wire and distribute them to computational services (a la map/reduce – see also Gridable Service in chapter 3). Things were working ok when we sent small images, but when we sent larger images we understood we were sending them as bitmaps and not as much more compact jpegs which caused a burden on the backbone of our switches which wasn’t ready for that load. § Transport cost is zero – As explained in the previous section every over-the-wire call incurs a lot of costs vs. a local call (also see figure 10.5 below).The costs of the transport can be considered both from the time it take to make each of these calls but even the real dollar value attached to making sure you have enough bandwidth (connection/routers, firewalls) to handle the traffic incurred Figure 10.5 Local objects can “afford” to have intricate interactions with their surroundings. A similar functionality delivered over a network is more likely than not to cause poor performance because of the network related overhead. Another reason to get Nano-Services, at least for beginners are poor examples – as, noted the calculator services above are taken from real examples provided by various vendors. SOA newcomers and/or people without a lot of distributed systems development experience can be easily take these samples at face value, and go about implementing services with similar granularity. The fact that that web-service framework mostly map service calls to object method calls makes this even more tempting. Nano-services is also an inherent risk when applying the orchestrated choreography pattern. Adding an orchestration engine, capable of controlling flow and external to services tempts us to think that we can use it to drive all flow as little as it may seem. Couple this with the fact that the smaller the services are the more “Reuseable” they are (less context) and, again, you may end up with a lot of nano-services on your hands. Lastly, since the nano-services boundary is soft (remember utility vs. overhead weight) behaviors that can look promising at design time can prove to be nano-services moving along (like the resource manager example above). This can be an acceptable if your SOA is developed iteratively (see 10.2.4 exceptions below) but it still mean that we have to come up with ways to refactor nano-services. 1.1.3Refactoring There are basically two main ways to solve the nano-services problem. One, which is relatively easy, is to group related nano-services into a larger service. The second option, which is more complicated, is to redistribute its functionality among other services. Let's take a look at them one by one. On one project I was working on we needed to send out notifications to users and admins via SMS messages. Since the software component that did the actual SMS dissemination was a 3rd party app we’ve decided to create a simple service (not unlike OO adapter) that accepts requests for SMS and talks to the 3rd party software. A nano-service was born, it even got a nice little name Post Office Service (ok, ok the original name was Spam Server but I thought it would look bad in presentations J). Why is this a nano service? Well, it really doesn’t do much and it would be even simpler to package this as a library that other services can use and it does have all the management overhead of maintain as another system service. What we did about it was to add similar functionality to the service so it also learned to send emails, tweets and MMSs. A serendipitous effect of this was that now instead of sending a request like TweetMessage or SendSMS to this service we could now raise more meaningful events such as SystemFailureEvent and have the service make decisions on how to alert administrators based on the severity of the problem etc. So combining the related functionality helped make the overall service even more meaningful. Unfortunately it isn’t always possible to take the functionality of Nano-services and find suitable “other services” (nano-or right-sized) that can assimilate them. In those cases getting rid of a nano-service is more of an exercise in redesign than is a refactoring. For instance, in a project we’ve built we had a services allocation service (SAS). The SAS role was to know about other services location and health status and utilization and upon a request, such as beginning a Saga (see chapter 5 for the saga pattern) decide what service instances should be used. The service also provided “reporting” capabilities for active sagas, services utilization etc. This might not sound like a nano-service, and at first we thought so too, but as the project progressed we found that being a central hub, as seen in figure 10.6 below, made the SAS a performance bottleneck, incurring additional costs (in latency) on a lot of the calls and interactions made by other services. The utility of the SAS, of finding what service instance to talk to, was being diminished by the cost – yep it is a nano-service after all. Figure 10.6 An example for a nano-service. The SAS service is a performance bottleneck as a lot of calls go through it. It provides an important service but the costs of its are too dear. To solve the SAS problem we had to put in quite a lot of work. The solution, essentially was to move to distributed resource management, so that each service had some knowledge of what the world looks like so that it could decide what service instant to talk to by itself. To sum this section, sometimes it is easy to notice that something is a nano-services, chances are that in these cases it would also be easy to take the functionality and group it with related functionality in other services. However on other occasions the fact that a service provides too little benefit is not as apparent and only becomes clear as we move along. In those cases it is also harder to fix the problem. One question we still need to cover is are there any situations where we would go with a nano-service even if we know it is one on the onset. 1.1.4Known Exceptions When is it ok to have Nano-services? When you are starting out. When your approach to SOA is evolutionary and you don’t plan everything in advance (something that rarely work anyway, but that’s another story), there’s a good chance that first versions of services you build will not show a lot of business benefit, but they will already need the full overhead of a service. The post office service in the example above is a good example for that as starting out it only dealt with a single type of message and it didn’t do a whole lot with it either. The post office service is also a good example for another reason to have a nano-service which is when you want to build an adapter or bridge to other systems be that legacy systems or 3rd party ones. In these cases you need to weight the advantage of using a service vs. building the same functionality as a library that can be used within services, but in many cases keeping the flexibility and composability of SOA can triumph over the overhead associated with having an additional service to manage. Lastly, one point to keep in mind is that NanoServices is a rather soft pattern and the value of a small service can radically change from system to system or even in a certain system as time and requirements progress. It is worthwhile questioning our assumptions and looking at the services that we grow from time to time to validate the usefulness of what we’re building.
April 29, 2010
by Arnon Rotem-gal-oz
· 19,635 Views · 3 Likes
article thumbnail
Get Warnings About Unused Method Arguments From Eclipse to Keep Code Clean
unused variables and methods should alway be unwelcome. removing them keeps the code cleaner and easier to read. now, by default eclipse warns you about unused private variables and methods, but it doesn’t warn you (by default) about unused method arguments. but there is a compiler setting in eclipse that can warn you when you don’t use an argument in a method. you can even handle arguments on inherited methods, especially useful when using 3rd party libraries. setup the compiler preferences to get warnings of unused arguments: go to window > preferences > java > compiler > errors/warnings . open up the section unnecessary code . change the setting for parameter is never read from ignore to warning. (recommended, but optional) deselect ignore overriding and implementing methods . i recommend deselecting this option. you can leave it selected if you want to, but the feature loses a bit of its usefulness. i discuss this option a bit more in the next section. here’s what the preference should look like: and here’s an example of such a warning. in the example, the argument capacity isn’t used so is annotated as a warning. what’s the easiest way to get rid of the warning? well, just remove the argument using the eclipse change method signature refactoring . this will remove the argument from the method declaration and any method callers in one go. however, if you can’t remove the argument from the method then read the next section. on an old codebase you may get lots of warnings initially. i’d normally handle these on a class-by-class basis only for the classes i’m currently working on, unless the team has a specific cleanup project/task. just something to bear in mind, especially if you share workspace settings across the team via svn or similar. what about method signatures that can’t be changed? when you deselected ignore overriding and implementing methods, you told eclipse to warn you about unused arguments in implemented/overridden methods. it’s a good indicator that your superclass/interface method is passing in more than it needs to (ie. remove the argument from the method signature) or that you’re ignoring something important about the interface contract (ie. use it somewhere in your method). but sometimes you can’t remove the argument because you don’t have control over inherited methods, especially if you implement/override a 3rd party library’s method or if the method is part of a bigger framework that’s difficult to change. other times you won’t have any need for the argument in very isolated cases. so you don’t want a warning to appear for these. that’s why you can use the @suppresswarning compiler annotation to stop eclipse from reporting the warning. here’s an example: public string process(@suppresswarnings("unused") int capacity, int max) {...} you can apply suppresswarning to an individual argument or the whole method. i’d recommend annotating only the argument that you want to ignore. eclipse makes it easy to add the compiler annotation. just navigate to the warning , press ctrl+1 and choose add @suppresswarning ‘unused’ to ‘variable’ (quick fix does its job again). from http://eclipseone.wordpress.com/2010/04/27/get-warnings-about-unused-method-arguments-from-eclipse/
April 28, 2010
by Byron M
· 20,202 Views · 1 Like
article thumbnail
DRY and Skinny War
In this article, I will show you how the DRY principle can be applied when using the skinny war configuration of the maven-war-plugin. While packaging an EAR, it is sometimes suitable that all libraries of the different WARs be contained not in their respective WEB-INF/lib folders but at the EAR level so they are usable by all WARs. Some organizations even enforce this rule so that this is not merely desiarable but mandatory. Using Maven, nothing could be simpler. The maven-war-plugin documents such a use case and calls it skinny war. Briefly, you have two actions to take: you have to configure every WAR POM so that the artifact will not include any library like so: ... maven-war-plugin WEB-INF/lib/*.jar true lib/ you have to add every dependency of all you WARs in the EAR The last action is the real nuisance since you have to do it manually. In the course of the project, a desynchronization is sure to happen as you add/remove dependencies from the WAR(s) and forget to repeat the action on the EAR. The DRY principle should be applied here, the problem lies in how to realize it. There's an easy solution to this problem: if a POM could regroup all my WAR dependencies, I would only have to draw a dependency from the WAR to it, and another from the EAR to it and it would fulfill my DRY requirement. Let’s do it! The pomlib itself Like I said before, the pomlib is just a project whose packaging is POM and that happens to have dependencies. To be simple, our only dependency will be Log4J 1.2.12 (so as not have transitive dependency, let’s keep it simple). The POM will be: 4.0.0 ch.frankel.blog.pomlib pomlib-parent 1.0.0 pomlib-lib pom log4j log4j Like for any other project module, I put the versions in the parent POM. The EAR and the WAR Both should now add a dependency to the pomlib. For brevity, only the EAR POM is displayed, the WAR POM can be found in the sources if the need be. 4.0.0 ch.frankel.blog.pomlib pomlib-parent 1.0.0 pomlib-ear ear ${project.groupId} pomlib-lib pom import ${project.groupId} pomlib-war war Likewise, versions are put in the parent POM. Notice the import scope on the pomlib dependency, it’s the only magic. Using mvn install from this point on will put the log4j dependency at the root of the generated EAR artifact and not in the WEB-INF/lib folder of the WAR. Conclusion Now that all dependencies are described in the pomlib, should you need to add/remove a dependency, it’s the only place you’ll need to modify. With just a little configuration, you’ve streamlined you delivery process and saved yourself from a huge amount of stress in the future. By the way, if you use a simple Servlet container (like Tomcat or Jetty) as your development application server, you could even put the skinny war configuration in a profile. Maven will produce “fat” WARs by default, at development time. At delivery time, just activate the profile and here’s your EAR product, bundling skinny WARs. You can find the source of this article in Maven/Eclipse format here. From http://blog.frankel.ch/dry-and-skinny-war
April 27, 2010
by Nicolas Fränkel
· 14,640 Views
article thumbnail
Categorise Projects in the Package Explorer to Reduce Clutter in Eclipse
if you’ve been hanging onto one eclipse workspace for the last couple of years, you’ll probably have dozens of projects cluttering up your workspace. if you’re an eclipse rcp developer, you may be sitting with around 50+ projects easily. the thing is that you’ll often only work with 1 or 2 at a time, not the whole lot. and sometimes you want a convenient way of only browsing projects belonging to a specific product/feature/layer/any-other-grouping-that-makes-sense. having all projects in a long list makes it difficult to manage and more difficult to browse. that’s why the package explorer and project explorer have a nice feature that reduces the clutter and allows you to organise your project into categories that make sense. so instead of the package explorer looking unwieldy and flat like this, it could look like this: how to categorise projects this feature works closely with another eclipse feature called working sets. a working set is just a grouping of resources (ie. files, folders and projects). each category is just a working set. to categorise projects, we’ll first create some working sets and then enable the feature in the package explorer. to create a working set do the following: open the package explorer (or project explorer) and in the view menu (triangle in the upper, right corner), click select working set… click new… in the select working set dialog. select resource working set type and click next. on the next page select all the projects you want to include in the working set and pick a descriptive name for your working set. repeat the process for any other working sets you want. click finish. here’s an example of what the working set dialog should look like: now to enable the grouping feature. open the package explorer’s view menu again and enable top level elements > working sets . if it’s the first time you do this, eclipse will prompt you to configure working sets – a way to ask you which working sets to display in the package explorer. select all the working sets you created and click ok. you should now see your working sets in the package explorer and if you expand it, all the projects you selected will be shown. here’s a quick video to give you an example of how this works and looks. in the example, there are 8 projects, 3 belonging to the ui and 3 to the model. the working sets will group them according to ui and model. there are also 2 projects that are scratchpad projects, so for now they won’t be categorised. notes: a project can belong to as many working sets as you want , so it can appear in a number of categories. you can choose which working sets display in the package explorer by choosing configure working sets … from the view menu and then selecting/deselecting the relevant working sets. nb! this menu item is not available if you’re not in the working set layout. to get back to the normal view, select top level elements > projects from the view menu. any project not assigned to a working set goes to a category called other projects . this isn’t really a working set, but a default category that eclipse assigns to group unassigned projects. you can reorder working sets by dragging and dropping them anywhere. new projects can quickly be assigned to working sets by either dragging and dropping them onto the working set or right-clicking on the project and selecting assign working sets . limitations: although working sets help you organise resources, any new resources won’t automatically be added to a working set, even if their parent already belongs to that working set . in our case, this means that any new project needs to be explicitly added to a working set, otherwise it will appear in the other projects category. normally you can do this on new project wizards, so watch out for these. some good reasons why you should categorise your projects now that you know how to group projects, you might be wondering why you should. well, apart from just looking a lot cleaner and less cluttered, it also means that you can act on a group of projects at a time. for example, you can right-click on a working set in package explorer and open, close or refresh all projects in that working set. the same applies to team commands (nice for selective updates). another reason is that you can now selectively search only those projects by telling eclipse to only search certain working sets. now you don’t have to pick up occurrences in test or scratchpad projects if you don’t want to. there are a host of other eclipse commands that act only on individual working sets (eg. build, problems, etc). and the last reason is that now it’s a lot easier to navigate the package explorer with the keyboard. another reason to start learning eclipse keyboard shortcuts and also impress your colleagues.
April 26, 2010
by Byron M
· 39,985 Views
article thumbnail
PubSub with Redis and Akka Actors
Redis (the version on the trunk) offers publish/subscribe based messaging. This is quite a big feature compared to the typical data structure oriented services that it had been offering so far. This also opens up lots of possibilities to use Redis as a messaging engine of a different kind. The sender and the receiver of the messages are absolutely decoupled from each other in the sense that senders do not send messages to specific receivers. Publishers publish messages on specific channels. Subscribers who subscribe to those channels get them and can take specific actions on them. As Salvatore notes in his weekly updates on Redis, this specific feature has evolved from lots of user requests who had been asking for a general notification mechanism to trap changes in the key space. Redis already offers BLPOP (Blocking list pop operation) for similar use cases. But still it's not sufficient to satisfy the needs of a general notification scheme. Salvatore explains it in more details in his blog post. I have been working on a Scala client, which I forked from Alejandro Crosa's repository. I implemented pubsub very recently and also have integrated it with Akka actors. The full implementation of the pubsub client in Scala is in my github repository. And if you like to play around with the Akka actor based implementation, have a look at the Akka repository. You define your publishers and subscribers as actors and exchange messages over channels. You can define your own callbacks as to what you would like to do when you receive a particular message. Let's have a look at a sample implementation at the client level .. I will assume that you want to implement your own pub/sub application on top of the Akka actor based pubsub substrate that uses the redis service underneath. Implementing the publisher interface is easy .. here is how you can bootstrap your own publishing service .. object Pub { println("starting publishing service ..") val p = new Publisher(new RedisClient("localhost", 6379)) p.start def publish(channel: String, message: String) = { p ! Publish(channel, message) } } The publish method just sends a Publish message to the Publisher. Publisher is an actor defined in Akka as follows: class Publisher(client: RedisClient) extends Actor { def receive = { case Publish(channel, message) => client.publish(channel, message) reply(true) } } The subscriber implementation is a bit more complex since you need to register your callback as to what you would like to do when you receive a specific type of message. This depends on your use case and it's your responsibility to provide a proper callback function downstream. Here is a sample implementation for the subscriber. We need two methods to subscribe and unsubscribe from channels. Remember in Redis the subscriber cannot publish - hence our Sub cannot do a Pub. object Sub { println("starting subscription service ..") val s = new Subscriber(new RedisClient("localhost", 6379)) s.start s ! Register(callback) def sub(channels: String*) = { s ! Subscribe(channels.toArray) } def unsub(channels: String*) = { s ! Unsubscribe(channels.toArray) } def callback(pubsub: PubSubMessage) = pubsub match { //.. } } I have not yet specified the implementation of the callback. How should it look like ? The callback will be invoked when the subscriber receives a specific type of message. According to Redis specification, the types of messages which a subscriber can receive are: a. subscribe b. unsubscribe c. message Refer to the Redis documentation for details of these message formats. In our case, we model them as case classes as part of the core Redis client implementation .. sealed trait PubSubMessage case class S(channel: String, noSubscribed: Int) extends PubSubMessage case class U(channel: String, noSubscribed: Int) extends PubSubMessage case class M(origChannel: String, message: String) extends PubSubMessage Our callback needs to take appropriate custom action on receipt of any of these types of messages. The following can be one such implementation .. It is customized for a specific application which treats various formats of messages and gives appropriate application dependent semantics .. def callback(pubsub: PubSubMessage) = pubsub match { case S(channel, no) => println("subscribed to " + channel + " and count = " + no) case U(channel, no) => println("unsubscribed from " + channel + " and count = " + no) case M(channel, msg) => msg match { // exit will unsubscribe from all channels and stop subscription service case "exit" => println("unsubscribe all ..") r.unsubscribe // message "+x" will subscribe to channel x case x if x startsWith "+" => val s: Seq[Char] = x s match { case Seq('+', rest @ _*) => r.subscribe(rest.toString){ m => } } // message "-x" will unsubscribe from channel x case x if x startsWith "-" => val s: Seq[Char] = x s match { case Seq('-', rest @ _*) => r.unsubscribe(rest.toString) } // other message receive case x => println("received message on channel " + channel + " as : " + x) } } Note in the above implementation we specialize some of the messages to give additional semantics. e.g. if I receive a message as "+t", I will interpret it as subscribing to the channel "t". Similarly "exit" will unsubscribe me from all channels. How to run this application ? I will assume that you have the Akka master with you. Also you need to have a version of Redis running that implements pubsub. You can start the subscription service using the above implementation and then use any other Redis client to publish messages. Here's a sample recipe for a run .. Prerequisite: Need Redis Server running (the version that supports pubsub) 1. Download redis from http://github.com/antirez/redis 2. build using "make" 3. Run server as ./redis-server For running this sample application :- Starting the Subscription service 1. Open up another shell similarly as the above and set AKKA_HOME 2. cd $AKKA_HOME 3. sbt console 4. scala> import sample.pubsub._ 5. scala> Pub.publish("a", "hello") // the first shell should get the message 6. scala> Pub.publish("c", "hi") // the first shell should NOT get this message Another publishing client using redis-cli Open up a redis-client from where you installed redis and issue a publish command ./redis-cli publish a "hi there" ## the first shell should get the message Have fun with the message formats 1. Go back to the first shell 2. Sub.unsub("a") // should unsubscribe the first shell from channel "a" 3. Study the callback function defined below. It supports many other message formats. 4. In the second shell window do the following: scala> Pub.publish("b", "+c") // will subscribe the first window to channel "c" scala> Pub.publish("b", "+d") // will subscribe the first window to channel "d" scala> Pub.publish("b", "-c") // will unsubscribe the first window from channel "c" scala> Pub.publish("b", "exit") // will unsubscribe the first window from all channels The full implementation of the above is there as a sample project in Akka master. And in case you are not using Akka, I also have a version of the above implemented using Scala actors in the scala-redis distribution. Have fun!
April 20, 2010
by Debasish Ghosh
· 15,622 Views
article thumbnail
Extract constants from strings and numbers with Eclipse refactorings
For readability’s sake, it’s almost always a good idea to replace magic numbers and string literals with constants. That’s all good, but it can take a bit of time to refactor these to constants, especially strings or parts of strings. For example, in the code below we want to refactor “shovel and spade” to a private static final String called TOOLS. To do that manually would take some time. It goes even slower if we only want to extract “spade” to a constant because we first have to convert the string to a concatenation. String tools = "shovel and spade"; ... String otherTools = "shovel and spade"; Luckily, Eclipse has a couple of ways to instantly convert literals to constants. Coupled with tools to speed up string selection and to pick out part of a string, you have the ability to create a constant in about 2 seconds flat. I’ll discuss all these features below. Extract a constant from a string/number There are 2 ways to extract a constant, the one uses a quick fix and the other a refactoring. I’ll show the quick fix method first and then the refactoring and discuss the (small) differences between the two. The example uses a string, but everything is true for numbers as well. Follow these steps to use the quick fix: First select the string. The fastest way is to place the cursor on the string and press Alt+Shift+Up (Select Enclosing Element; a nifty shortcut that I discuss in Select strings and methods with a single keystroke). After selecting the string, press Ctr+1 (Quick Fix) and then select Extract to constant. Eclipse will do the following: (a) Create a private final static variable of type String with a default name, (b) replace all occurrences of that string with the constant and (c) place the cursor on the constant’s declaration to give you a chance to change the name, type and visibility of the variable using placeholders that you can Tab through. Once you’re happy with the constant details, press Enter to go back to the line on which you initiated the quick fix. Here’s a short video with an example of using quick fix. We’ll extract a constant (called TOOLS) from a string literal (“shovel and spade”) that’s used in two places. Note: You can use Tab to move from one placeholder to another and pressing Enter will get you back to your original line. The other way to extract a constant is by using the Extract Constant refactoring. Again, select the string, then select Refactor > Extract Constant… (Alt+T, A) from the application menu. A dialog appears prompting you for the constant’s name, its visibility and whether to replace all occurrences of the string with the constant. After you’ve entered the details, press Enter and you’ll have your constant defined. Here’s a short video with an example using refactoring. We’ll use the same example as above. The differences between the two? Not much, the biggest difference being when you enter the details of the constant (ie. before the change is made or after). The refactoring dialog also provides an option to add the qualifying type name before the constant’s usage, but most of time this is redundant. I’d recommend using the quick fix, unless you’re more comfortable with dialogs. BTW, you can assign custom keyboard shortcuts to either command by mapping either Quick Assist – Extract Constant or the command Extract Constant. Pick out part of a string Sometimes you’ll want to break up a string into multiple parts and convert one of those parts into a constant. Eclipse can do this automatically. Select the part of the string you want to pick out (don’t worry about quotes), press Ctrl+1 and choose Pick out selected part of String. Eclipse will convert that part into a string with quotes, concatenate it to the rest of the string and select it. You can then use any of the Extract Constant tools above. Here’s an example of how to use this feature. Notice how the string’s already selected so we can use the Extract Constant quick fix immediately. Related Tips Select entire strings and methods in Eclipse with a single keystroke Convert string concatenations into StringBuilder or MessageFormat calls with Eclipse’s Quick Fix How to manage keyboard shortcuts in Eclipse and why you should Join/split if statements and rearrange expressions using Eclipse Quick Fix More tips on using quick fixes and making editing faster.
April 19, 2010
by Byron M
· 21,661 Views · 1 Like
article thumbnail
Running Hazelcast on a 100 Node Amazon EC2 Cluster
The purpose of this article is to give you the details of our 100 node cluster demo. This demo is recorded and you can watch the 5 minute screencast Hazelcast is an open source clustering and highly scalable data distribution platform for Java. JVMs that are running Hazelcast will dynamically cluster and allow you to easily share and partition your application data across the cluster. Hazelcast is a peer-to-peer solution (there is no master node, every node is a peer) so there is no single point of failure. Communication among cluster members is always TCP/IP with Java NIO beauty. The default configuration comes with 1 backup so if a node fails, no data will be lost (you can specify the backup count). It is as simple as using java.util.{Map, Queue, Set, List}. Just add the hazelcast.jar into your classpath and start coding. When you download the Hazelcast, you will find a test.sh under bin directory. The test.sh runs an application which randomly makes 40% get, 40% put and 20% remove on a distributed map. In this demo the same test application will be used to see how it performs on 100 node cluster. Amazon EC2 and S3 An easy to use and scalable cloud environment was needed for demo so we decided to use Amazon EC2 for server instances (nodes) and S3 service to store demo application zip and configuration files. With its newly announced Java SDK, it is very simple to start/stop server instances and upload files to S3 programatically. Hazelcast AMI & Launcher The challenge here is that we are running an application on 100 nodes and dealing with each and every server in the cluster is a huge task. We don't want to ssh into every server and manually start the application. This part is automated by creating a special server image (AMI). The AMI contains Java Runtime and a launcher application we developed, which will download the demo application from Amazon S3, unzip it, and run the hazelcast/bin/test.sh in it. The Launcher is actually so generic that it can run any application; it doesn't care/know what test.sh contains. Deployer Deployment of the demo application is also automated so that we don't need to login into AWS Management Console and manually start instances. Deployer instantiates any number of Amazon EC2 servers with any AMI and also uploads the demo application zip file to S3. So the idea here is that, the Deployer will store the application into S3 and launch 100 EC2 instances with our image. The Launcher on each instance will download the application from S3 and run it. Demo Details. The smallest EC2 instances (m1.small) are used to run the demo. These are the virtual instances with CPU about 1.0 GHz. Also keep in mind that EC2 platform suffers from considerable amount of network latency. That's why we increased the thread count to 250 in our application. The following steps performed during the demo Download hazelcast-1.8.3.zip from www.hazelcast.com. Unzip the file and move the monitoring war file into tomcat6/webapps directory. Edit the test.sh under the bin directory: Add -Xmx1G -Xms1G Add -Dhazelcast.initial.wait.seconds=100 to make the cluster evenly partition on start so that migration can be avoided for better performance. Add t250 as an argument to the application to set thread count to 250. Remember the latency issue. Run the Deployer from IDE. Check from EC2 Management Console if 100 servers started. Start tomcat. Copy the public DNS name of one of the servers to connect to from monitoring tool. Go to http://localhost:8080/hazelcast-monitor-1.8.3/ (Hazelcast Monitoring Tool). Paste the address and connect to the cluster. Enjoy! Results You should always look for programatic ways of launching applications on the cloud. With these tools we were able to deploy and run the demo application on 100 servers in minutes. The entire Hazelcast cluster was making over 400,000 operations per second on the smallest EC2 instances. In our next demo we will experiment Hazelcast on large data set and even bigger cluster. Watch the screencast
April 16, 2010
by Fuad Malikov
· 62,838 Views · 1 Like
article thumbnail
Share Eclipse Perspective Layouts Across Multiple Workspaces
once you’ve configured eclipse preferences to your heart’s content, you’ll often want to share those preferences across multiple workspaces. now normally you can go to file > export > general > preferences to save your preferences to a properties file which you can then import into the other workspace. this will share settings such as your customised keyboard shortcuts, formatting, repository settings, etc. but, for some reason, eclipse doesn’t save perspective/window layouts, such as which views are open and where they are placed in the perspective. so you’ll find yourself spending another half hour configuring the window to the way you like it. after the 3rd workspace you need to create, this becomes frustrating and just wastes time. fortunately there are ways to save and restore these settings automatically. the first is to save the perspective into the preferences and the other is to use eclipse’s copy settings feature when opening the other workspace. i prefer the first option, but i’ll mention the second option and when to use the one over the other. method 1: save the layout as a new perspective the first method is to save the perspective layout as another perspective, then export the preferences file as normal. the saved perspective’s settings will be included in the preferences file. when you’ve updated the layout, just resave and overwrite the perspective and export the preferences again. to save your perspective, select window > save perspective as… from the application menu. a dialog should popup (shown below), prompting you for a perspective name. enter a name that you’ll remember, eg. my java or debug jack . click ok once you’ve entered a new name. note : you can choose to overwrite one of the default perspectives, eg. java , without fear. however, i prefer to leave these intact, so always choose a new name, but you can choose whatever works for you. now you can go through the normal routine of exporting the preferences to a properties file via file > export > general > preferences . then import the same file in another workspace via file > import > general > preferences . all you now have to do is switch over to the perspective you saved and all your layout settings will be restored. if you overwrote one of the default perspectives, you may have to select window > reset perspective… to restore the saved settings. if you’ve chosen to create a new perspective, be sure to point your run/debug settings to the new perspective under window > preferences > run/debug > perspectives . for example, if you made a new perspective based on the debug perspective, then you’ll need to change references to the debug perspective to the my debug for launchers you use. luckily this is only required once as these settings are also saved when you export preferences (at least since eclipse 3.5). gotcha: i use fast views a lot , and for some reason the fast view dock’s position isn’t restored automatically. but manually restoring this is as easy as moving the dock, so it’s not that bad. toolbar settings aren’t saved either, but i haven’t tampered with these a lot anyway since i prefer using the keyboard and mouse gestures. method 2: use copy settings the other method of saving your window layout is to use the copy settings feature when switching to another workspace. to use this feature, first open the workspace that contains your customised layout. then select file > switch workspace > other… which will open a dialog prompting you for an existing/new workspace. select the workspace, then click the copy settings collapsible section. select the workbench layout checkbox and click ok. your workspace will open and should reflect the customised layout of the previous workspace. here’s what the dialog looks like: which method should i use? well, as i said before, i prefer the first method for a number of reasons. if some of these apply to you then you might want to use the first method as well. use this method if: you want to share layout settings across workspaces on different machines, eg. work and home. this method is a lot more portable because you only need one single properties file. you spend 90% of your time in 1 or 2 perspectives (eg. java & debug) then this method works well because you only have to manage those perspectives. you make a lot temporary changes to perspectives that you don’t necessarily want shared. for example, if you’ve opened a number of views that you rarely use, you don’t want to clutter your new workspace with these views. i find that i have my “base” perspective layout, around which things will change depending on the context and i don’t want these to clutter my “base” layout. you want to share preferences with a colleague/friend. use the copy settings method if: you want to quickly create another workspace with the saved layout without having to export any preferences. you have made a number of changes across many perspectives and you want to restore those settings. you’re feeling lazy. with this method, eclipse manages a lot more things, so it’s a bit easier to manage (in the short-term), but for the longer term, the first method is best. from http://eclipseone.wordpress.com
March 26, 2010
by Byron M
· 16,504 Views
article thumbnail
Aspect Oriented Programming For Eclipse Plug-ins
It seems to me that Aspect Oriented Programming never really took off when it was introduced. However, it's a useful way to intercept, or analyse, methods as they happen, in an independent way. Eclipse has a useful suite of AspectJ tools that you can download for your Eclipse installlation. Paired with the benefits of Eclipse's plug-in system, aspects are a nice way of intercepting your RCP application. The following instructions show how to get up and running with aspects in the Plug-in Development Environment really quickly. Once you have downloaded the Eclipse AspectJ tools, you will also want to include the Equinox Aspect jars in your plug-ins directory. The plug-ins you will need are org.eclipse.equinox.weaving.aspectj and org.eclipse.equinox.weaving.hook Create a new OSGi plug-in: Right click on the project and choose AspectJ Tools/Convert to AspectJ Project Create a new package within the plugin eg. com.dzone.aspects.aspectTest Make a new aspectj Aspect within the package e.g. MyAspect In your manifest.mf export the package created in the previous step Export-Package: com.dzone.aspects A you write your AspectJ code, you will be advising another plug-in (for example org.eclipse.jdt.junit) You'll need to do some extra setup in order to advise other plug-ins, by adding the following to your Aspect plug-in manifest.mf. Eclipse-SupplementBundle: org.eclipse.jdt.junit Note you can only supplement one bundle in an aspect. Therefore, if you want to crosscut another bundle, you’ll need to create a new AspectJ plug-in. It also helps to add the plugin that you are advising (org.eclipse.jdt.junit) to your aspect plugin's dependencies. If you don't do it you will get lint warnings from the AspectJ compiler In your plugins META-INF directory make a file called aop.xml, consisting of content similar to the following When executing use the following VM arguments in your Run Configuration -Dosgi.framework.extensions=org.eclipse.equinox.weaving.hook -Dorg.aspectj.osgi.verbose=true It's as simple as that. Have you any instructions to add to this?
March 23, 2010
by James Sugrue
· 10,881 Views
article thumbnail
Play! Framework Usability
Perhaps the most striking thing about about the Play! framework is that its biggest advantage over other Java web application development frameworks does not fit into a neat feature list, and is only apparent after you have used it to build something. That advantage is usability. Note that usability is separate from functionality. In what follows, I am not suggesting that you cannot do this in some other framework: I merely claim that it is easier and more pleasant in Play! I need to emphasise this because geeks often have a total blind spot for usability because they enjoying figuring out difficult things, and under-appreciate the value of things that Just Work. Written by web developers for web developers The first hint that something different is going on here is when you first hear that the Play! framework is 'written by web developers for web developers', an unconventional positioning that puts the web's principles and conventions first and Java's second. Specifically, this means that the Play! framework is more in line with the W3C's Architecture of the World Wide Web than it is with Java Enterprise Edition (Java EE) conventions. URLs for perfectionists For example, the Play! framework, like other modern web frameworks, provides first-class support for arbitrary 'clean' URLs, which has always been lacking from the Servlet API. It is no coincidence that at the time of writing, Struts URLs for perfectionists, a set of work-arounds for the Servlet API-based Struts 1.x web framework, remains the third-most popular out of 160 articles on www.lunatech-research.com despite being a 2005 article about a previous-generation Java web technology. In Servlet-based frameworks, the Servlet API does not provide useful URL-routing support; Servlet-based frameworks configure web.xml to forward all requests to a single controller Servlet, and then implement URL routing in the framework, with additional configuration. At this point, it does not matter whether the Servlet API was ever intended to solve the URL-routing problem and failed by not being powerful enough, or whether it was intended to be a lower-level API that you do not build web applications in directly. Either way, the result is the same: web frameworks add an additional layer on top of the Servlet API, itself a layer on top of HTTP. Play! combines the web framework, HTTP API and the HTTP server, which allows it to implement the same thing more directly with fewer layers and a single URL routing configuration. This configuration, like Groovy's and Cake PHP's, reflects the structure of an HTTP request - HTTP method, URL path, and then the mapping: # Play! 'routes' configuration file… # Method URL path Controller GET / Application.index GET /about Application.about POST /item Item.addItem GET /item/{id} Item.getItem GET /item/{id}.pdf Item.getItemPdf In this example, there is more than one controller. We also see the use of an id URL parameter in the last two URLs. HttpServletRequest Another example is Play!'s Http.Request class, which is a far simpler than the Servlet API's HttpServletRequest interface. In addition, Play! uses a class where Java EE 6 uses the Java EE convention of using an interface. This interface is also split between HttpServletRequest and the more generic ServletRequest interface. This separation may be useful if you want to use Servlets for things other than web applications, or if you want to allow for the unlikely possibility of the web changing protocol, but for most of us it is merely irrelevant complexity. In other words, the Servlet API is always used with a framework on top these days because it is sub-optimised for building web applications, which is what all of us actually use it for. Play! fixes that. Better usability is not just for normal people Another way of looking at the idea that Play! is by and for web developers is to consider how a web developer might approach software design differently to a Java EE developer. When you write software, what is the primary interface? If you are a web developer, the primary interface is a web-based user-interface constructed with HTML, CSS and (increasingly) JavaScript. A Java EE developer, on the other hand, may consider their primary interface to be a Java API, or perhaps a web services API, for use by other layers in the system. This difference is a big deal, because a Java interface is intended for use by other programmers, while a web user-interface interface is intended for use by non-programmers. In both cases, good design includes usability, but usability for normal people is not the same as usability for programmers. In a way, usability for everyone is a higher standard than usability for programmers, when it comes to software, because programmers can cope better with poor usability. This is a bit like the Good Grips kitchen utensils: although they were originally designed to have better usability for elderly people with arthritis, it turns out that making tools easier to hold is better for all users. The Play! framework is different because the usability that you want to achieve in your web application is present in the framework itself. For example, the web interface to things like the framework documentation and error messages shown in the browser is just more usable. Along similar lines, the server's console output avoids the pages full of irrelevant logging and pages of stack traces when there is an error, leaving more focused and more usable information for the web developer. $ play run phase ~ _ _ ~ _ __ | | __ _ _ _| | ~ | '_ \| |/ _' | || |_| ~ | __/|_|\____|\__ (_) ~ |_| |__/ ~ ~ play! 1.0, http://www.playframework.org ~ ~ Ctrl+C to stop ~ Listening for transport dt_socket at address: 8000 10:15:58,629 INFO ~ Starting /Users/peter/Documents/work/workspace/phase 10:16:00,007 WARN ~ You're running Play! in DEV mode 10:16:00,424 INFO ~ Listening for HTTP on port 9000 (Waiting a first request to start) ... 10:16:11,847 INFO ~ Connected to jdbc:hsqldb:mem:playembed 10:16:13,448 INFO ~ Application 'phase' is now started ! 10:16:14,825 INFO ~ starting DispatcherThread 10:16:48,168 ERROR ~ @61lagcl6i Internal Server Error (500) for request GET /application/startprocess?account=x Java exception (In /app/controllers/Application.java around line 41) IllegalArgumentException occured : Person not found for account x play.exceptions.JavaExecutionException: Person not found for account x at play.mvc.ActionInvoker.invoke(ActionInvoker.java:200) at Invocation.HTTP Request(Play!) Caused by: java.lang.IllegalArgumentException: Person not found for account x at controllers.Application.startProcess(Application.java:41) at play.utils.Java.invokeStatic(Java.java:129) at play.mvc.ActionInvoker.invoke(ActionInvoker.java:127) ... 1 more Try to imagine a JSF web application producing a stack trace this short. In fact, Play! goes further: instead of showing the stack trace, the web application shows the last line of code within the application that appears in the stack trace. After all, what you really want to know is where things first went wrong in your own code. This kind of usability does not happen by itself; the Play! framework goes to considerable effort to filter out duplicate and irrelevant information, and focus on what is essential. Quality is in the details In the Play! framework, much of the quality turns out to be in the details: they may be small things individually, rather than big important features, but they add up to result in a more comfortable and more productive development experience. The warm feeling you get when building something with Play! is the absence of the frustration that usually results from fighting the framework. We recommend that you go to http://www.playframework.org/, download the latest binary release, and spend half an hour on the tutorial. Peter Hilton is a senior software developer at Lunatech Research.
March 16, 2010
by $$anonymous$$
· 24,750 Views
article thumbnail
Generate Class Constructors in Eclipse Based on Fields or Superclass Constructors
You’ll often need to add a constructor to a class based on some/all of its fields or even based on constructors of its superclass. Take the following code: public class Contact { private String name, surname; private int age; public Contact(String name, String surname, int age) { this.name = name; this.surname = surname; this.age = age; } } That’s 5 lines of code (lines 5-9) just to have a constructor. You could write them all by hand, but writing a constructor that accepts and initialises each field takes a lot of time and becomes irritating after a while. And creating constructors from a superclass can take even longer because the superclass can define multiple constructors that you need to reimplement. That is why Eclipse has two features to help you generate these constructor instantly: Generate Constructor using Field and Generate Constructor from Superclass. Both features will generate a constructor in seconds, freeing you up to get to the exciting code. You’ll also see how to add/remove/reorder arguments of an existing constructor based on fields defined in the class. Generate a constructor from fields The fastest way to generate a constructor based on fields is to press Alt+Shift+S, O (alternatively select Source > Generate Constructor using Fields… from the application menu). This pops up a dialog where you can select the fields you want to include in the constructor arguments. Once you’ve selected the fields you want, just click Ok and you’re done. BTW, Alt+Shif+S is the shortcut to display a shortened Source menu, allowing Java source editing commands. The following video shows an example of how much time this feature can save you. We’ll create a constructor for the class Message. Notes: You can additionally call a superclass constructor with a subset of the fields by changing the dropdown Select super constructor to invoke at the top of the dialog. This creates a super(…) call with the relevant arguments and initialising code for the rest of the arguments on your subclass’s constructor. If you don’t want the JavaDoc for the constructor, disable the checkbox Generate constructor comments on the dialog. You can include/exclude the calls to super() using the checkbox Omit call to default constructor super(), on the dialog. You have to be positioned in a class to invoke this command. If you use frequently use this command, you can remap its keyboard shortcut by changing the key binding for the command Generate Getters and Setters. Generate constructor(s) from a superclass Sometimes you’ll want to reimplement some/all of a superclass’s constructors, especially as part of the contract. To generate constructor(s) from a superclass, just press Alt+Shift+S, C (or alternatively select Source > Generate Constructor from Superclass… from the application menu). A dialog pops up allowing you to select the constructor(s) you’d like to create. Once you click Ok, Eclipse generates the constructor, together with a super() call. Here’s an example of how to create a constructor in SecretMessage, that inherits from the class Message. Message has three constructors: a default one, one that accepts one String (content) and another that accepts three Strings (content, fromAddress and toAddress). SecretMessage should only expose the last two constructors. Note: You have to be positioned in a class to invoke this command. If you use this command frequently, you can remap its keyboard shortcut by changing the key binding for the command Generate constructors from superclass. Add, reorder and remove fields on existing constructors If you have an existing constructor and want to reorder its arguments or remove some of them, have a look at the Change Method Signature refactoring that does that in a jiffy. If you want to add a single field to an existing constructor, have a look at the next video that uses Eclipse’s Quick Fix (Ctrl+1) to do that easily. I’ll add a field createdDate to an existing constructor in Message by choosing Assign parameter to field from the Quick Fix menu while positioned on the field. From http://eclipseone.wordpress.com
March 9, 2010
by Byron M
· 31,036 Views · 1 Like
article thumbnail
Automatically Place a Semicolon at the End of Java Statements in Eclipse
we all know that java statements are terminated by a semicolon (;), but they’re a bit of a pain to add to the end of a line. one way would be to press end (to move to the end of the line) then press semicolon, but this is tedious. because this is something that you do often it’s worth learning how to do this faster. it’s a good thing eclipse can automatically put the semicolon at the end of the line, no matter where you are in the statement. it’s as easy as setting one preference and there’s a bonus preference for adding braces to the correct position as well. for something so small, it saves a lot of time. so in the example below, if you imagine that your cursor is placed after the word blue since you were editing the string. pressing semicolon will cause eclipse to place the semicolon after the closing bracket at the end. nice. system.out.println("the house is blue") how to set the semicolon preference the preference is disabled by default, so you have to enable it. go to window > preferences > java > typing . then enable semicolons under the section automatically insert at correct position . now when you press semicolon from anywhere in a statement, eclipse adds a semicolon to the end of the line and places the cursor right after the semicolon so you can start editing the next line. the preference should look like this: notes: sometimes you’d want to add a semicolon to a string literal instead of at the end of the line. eclipse caters for this by allowing you to press backspace after you pressed semicolon. pressing backspace will remove the semicolon from the end of the line, move your cursor to the original position in the string and add the semicolon to the string. if there’s already a semicolon at the end of the line, eclipse won’t try to add another to the end. it will just add the semicolon to wherever you placed it. eclipse is smart enough to know that for for loops you’d want to add the semicolon to the middle of the statement (eg. when editing the initialiser, condition and increment code). bonus tip: you can also add braces automatically at the correct position by selecting the braces option on the preference page. this comes in handy when your coding standards require braces to be on the same line as the control structure statement. for example, when adding a for or while loop, you can type { at any place in the first line and eclipse will insert it at the end of the line. from http://eclipseone.wordpress.com
March 2, 2010
by Byron M
· 15,233 Views · 13 Likes
article thumbnail
Top 10 Interesting NetBeans IDE Java Shortcuts I Never Knew Existed
I'm working on updating the NetBeans IDE Keyboard Shortcut Card (which you can always find under the "Help" menu in the IDE) and have learned about a lot of shortcuts I never knew about before. Here's a grab bag of things I have added to the shortcut card (some new, some old that hadn't been included before) that you might find interesting too. Type "fcom" (without the quotes, same as all the rest below) and then press Tab. You now have this, i.e., a brand new code fold: // // Type "bcom" and then press Tab to create the start of a new set of comments in your code: /**/ Type "runn" and press Tab and you'll have all of this: Runnable runnable = new Runnable() { public void run() { } }; If I have this: String something = ""; ...and then below that type "forst" and press Tab, I now have this: String something = ""; for (StringTokenizer stringTokenizer = new StringTokenizer(something); stringTokenizer.hasMoreTokens();) { String token = stringTokenizer.nextToken(); } Also, experiment with "forc", "fore", "fori", "forl", and "forv"! I always knew that "sout" turns into "System.out.println("");" but did you know that (again assuming you first have a string something like above) if you type "soutv" you end up with this: System.out.println("something = " + something); Thanks Tom Wheeler for this tip. Next, here are the new shortcuts that are new from NetBeans IDE 6.9 onwards: as - assert=true; su - super db - double sh - short na - native tr - transient vo - volatile I knew that "ifelse" would resolve to an if/else block. But did you know that if you don't need an 'else', you can simply type "iff", press Tab, and then end up with this: if (exp) { } From NetBeans IDE 6.9 onwards, the "sw" shortcut expands to the following: switch (var) { case val: break; default: throw new AssertionError(); } If you're using while loops, experiment with "whileit", "whilen", and "whilexp". Always remember these: "im" expands to "implements; "ex" to "extends". Other tips along these lines are more than welcome here on NetBeans Zone!
February 19, 2010
by Geertjan Wielenga
· 97,949 Views · 4 Likes
article thumbnail
Electric Cloud's New Tools Avoid Unnecessary Builds
electric cloud has recently developed several unique capabilities for its software production suite, and now the company has built these technologies into the newest versions of their electricaccelerator and electriccommander products, which were released this week. electricaccelerator 5.0 has added two major features. the "electrify" feature can now parallel process virtually any software production task, and the new subbuild feature avoids unnecessary builds. electriccommander 3.5 features a new, extensible interface for managing and automating a shop's existing tool infrastructure. electricaccelerator 5.0 electricaccelerator speeds up make, nmake, microsoft visual studio, and apache ant based builds (by 10-20x the company says) by parallelizing them and running them on a computer cluster. accelerator 5.0 is the full debut of electric cloud's patented technology to safely speed up development tasks through its parallel processing via public or private compute clouds. originally, accelerator's parallel processing applied only to software builds, but now it applies to other tools and development tasks in the build-test-deploy cycle including parallel testing and data modeling. electrify creates an all-purpose private compute cloud for parallel processing, but parallel processing can also be done on desktops or a dedicated server. another innovative addition to accelerator is the subbuilds feature. first previewed in electric cloud's free spark build tool , subbuilds allow unnecessary build avoidance. subbuilds are able to skip large swaths of the build tree by building only the relevant pieces to the current work. the result is fewer broken builds and the ability to compile and test quickly and frequently without affecting the rest of the team. the dependency graph below shows the agent component (util, xml, http libraries, and the agent application code) as solid. sparkbuild can recognize that only this component needs to be rebuilt. electricaccelerator 5.0 now supports build tools such as msbuild and scons along with homegrown systems. teams that standardize on scons, for example, can use less hardware and provide faster builds than individual mutli-core servers by applying the benefits of centralization. the virtualization capabilities of accelerator also allow easier support for multiple configurations. electriccommander 3.5 electriccommander is a web-based application for defining and executing distributed processes in the build-test-deploy cycle. in a development environment using many disparate tools, commander 3.5 can remove the need to learn multiple interfaces, and it manages those tools from a central, custom ui. electriccommander 3.5 can be configured to extract and display data from the defect tracker, relevant build results, and test results. this lets build managers track the status of fixes and be notified when qa resolves the issue. the commander ui's custom, dynamic screens can help developers create and execute a build or test request using the right parameters. commander 3.5 can give developers a custom interface based on their role in the production cycle. 3.5 also provides tools to create custom plug-ins for third-party integrations. electriccommander job plotter to try out some of electricaccelerator's capabilities, download electric cloud's free sparkbuild tool.
February 17, 2010
by Mitch Pronschinske
· 11,541 Views
article thumbnail
Four Methods to Automate Development Environment Setup
There are at least four methods that can be used in different combinations to make the process of setting up a complete development environment a lot less painful.
February 16, 2010
by Mitch Pronschinske
· 31,797 Views
article thumbnail
Checkout Multiple Projects Automatically Into Your Eclipse Workspace With Team Project Sets
When working in Eclipse, you’ll often end up with a number of projects in your workspace that constitute an application. You could have a multi-tiered system with a web, server and database project and other miscellaneous ones. Or if you’re an Eclipse RCP developer, you could end up with dozens of plugins each represented by a project. Although multiple projects give you modularity (which is good), they can make it difficult to manage the workspace (which is bad). Developers have to check out each project individually from different locations in the repository. Sometimes they even have to get projects from multiple repositories. This is a painstakingly long and error-prone task. But an easier way to manage multiple projects is with Eclipse’s Team Project Sets (TPS). Creating a workspace becomes as easy as importing an XML file and waiting for Eclipse to do its job. Yes, there are other more sophisticated tools out there that do this and more (eg. Maven and Buckminster) but team project sets are a good enough start if you haven’t got anything set up and may be good enough for the longer term as well, depending on how your team works. Create a Team Project Set to share with other developers It’s easy to create a team project set (TPS). The first thing is to start with a workspace that already has all the projects checked out. Then it’s as easy as choosing File > Export > Team > Team Project Set, selecting the projects you want to export and then entering a file name. Done. But it’s always better to see it in action. In the video, I export 3 projects that I’ve already checked out from Subversion into a TPS file. Notes: You can select which projects should go into the TPS. This way you can exclude irrelevant or personal projects you’ve got in your workspace. Eclipse adds the extension .psf if you don’t provide one. The exported file is an XML file, with the default extension of psf, so in the video the file would be music.psf. There is a project entry for each project you exported that includes the project’s name and its repository location, separated by commas. Once created, the file is easy to edit so go ahead and make your own changes if you want to. Here is an example of what it looks like: svn/repo/music-application/trunk,music-application"/> svn/repo/music-db/trunk,music-db"/> svn/repo/music-web/trunk,music-web"/> Import the Team Project Set to checkout multiple projects into your workspace Now for the fun part. To import a team project set (TPS), start with any workspace (normally an empty one) and choose File > Import > Team > Team Project Set. Choose the TPS file that someone else kindly exported for you and then wait for Eclipse to do its magic. Notes: If you have an existing project in your workspace whose name matches a project in the TPS, Eclipse will prompt you whether you want to overwrite the project. I always choose No To All, since overwriting the project will mean you lose any changes you made to it. But if you have the urge to start from scratch then you can choose Yes. The import also creates a link to the repository in SVN Repositories, so you don’t have to do that. If one already exists, it will not duplicate it but reuse the existing connection. The process may take a while depending on the number of projects in the TPS and the speed of your repo checkouts. You can choose to run the import in the background (as I did in the video), giving you the opportunity to use Eclipse while the import happens. Otherwise, grab some coffee and wait for it to finish the checkouts. Gotcha: You may find that Eclipse 3.4 and lower may actually create a repository connection per project if the repository didn’t exist beforehand, which is not ideal. To solve this, create an initial repository root that’s shared by the projects and then do the import of the TPS. This problem has been fixed in 3.5 Managing the team project set and working with branches I’d recommend checking in the team project set into your repository and versioning/tagging it along with the rest of your code base. With each release you may be adding/removing projects and consequently updating the TPS, so it’s important that the TPS matches what the repo looks like at that point. As projects are added/removed with each release, you have 3 possibilities: Recreate the TPS from an existing workspace: Same as the steps above, but it means that whoever does the export needs to maintain an up to date workspace to reflect the current project structure. Modify an existing TPS with the new/deleted project: This entails adding/removing an entry from the PSF file. Not a lot of maintenance, but someone needs to remember to do this. Automatically create/update the TPS: You could write a script that somehow updates the TPS to reflect the new repo structure. For example, if you’re developing an Eclipse RCP application, the PDE Build provides a map file that could be used as input to create the PSF file. If you want to checkout a branch other than trunk, just open the PSF file and do a Find/Replace of trunk with your branch name. You could also introduce an automated process as part of your build/release scripts to update the TPS with the correct branch and check it back in automatically, but that’s really optional. From http://eclipseone.wordpress.com
February 13, 2010
by Byron M
· 22,931 Views
article thumbnail
How to Manage Keyboard Shortcuts in Eclipse and Why You Should
when i use eclipse i try and use shortcuts all the time. they really make me work faster and give me time to focus on getting the code out rather than slowing down to invoke ide commands with the mouse. because people work differently and on different things, it’s important to manage keyboard shortcuts to suit the way you work. so it’s good that eclipse makes it really easy to change shortcuts and also to view shortcuts for the commands you use a lot. i’ll discuss how to change keyboard shortcuts, how to avoid conflicts with existing ones, why it’s a good thing to manage shortcuts and then end off with some examples of common shortcuts that you should add to you arsenal. how do you manage keyboard shortcuts the main preference page can be found under window > preferences > general > keys (or faster: press ctrl+3 , type keys and press enter ). from here you can see all commands and assign/change their associated keyboard shortcuts. in the video, i’ll show you how to reassign a key. we’ll use this to assign ctrl+tab to switch to the next editor. notes: you don’t have to copy a command to assign/reassign a shortcut. i just prefer to keep the old shortcut in case someone else wants to take over my keyboard and expects the shortcut to work. all commands registered with eclipse are listed on the keys preference page. browse through them or search to see if your favourite command is listed. if it doesn’t have a shortcut assigned, then assign one immediately. the when dropdown on the dialog shows you in which context the command applies (eg. only when editing java source). you can assign the same shortcut to two different commands, but if the context differs eclipse will only execute the one command. i suggest you don’t change the context. notice that eclipse shows you which keys conflict with the selected one if their in the same context. but all the keys are already taken no, they’re not. firstly, if a key you like is already taken then be creative. use combos like ctrl+alt, alt+shift or even alt+shift+ctrl (easier to press then you think). these aren’t used as often as ctrl or ctrl+shift. you can sort by binding to see which keys are already used. secondly, eclipse allows you to assign a sequence of keystrokes to a command. eg. alt+shift+x, j (that’s used to run the current class as a java application) is invoked by pressing alt+shift+x, releasing the keys then pressing j. if you forgot your sequence shortcuts, just press the first part (eg. alt+shift+x), wait a second then eclipse helps you out by listing all commands that have this keystroke as the first part of the sequence. the list appears in the lower right corner of the window. this works for any commands assigned a sequence of keystrokes. here’s an example of what you might see when you press the first sequence of keystrokes (notice the list in the lower, right corner). tip: for custom commands you want to assign, use a well-known first keystroke to group your commands. for example, i use alt+shift+b (b for byron) as my grouping prefix. this way there are fewer conflicts with existing shortcuts and eclipse can show me a quick list if i forgot which keys i used. so why bother managing keyboard shortcuts managing keyboard shortcuts in eclipse is important because: not all eclipse commands have assigned shortcuts. a command you frequently use could be assigned a shortcut. eg. an svn commit is registered as an eclipse command but doesn’t have a keyboard shortcut assigned. assigning one yourself will speed up checking in changes. sometime eclipse gets it wrong. a good example is ctrl+f6 for switching editors – ctrl+tab is a much more sensible option since the keys are close together and doable with one hand. going through the list of shortcuts may give you ideas for working faster or even show you a command you didn’t know eclipse could do. but don’t shortcuts take a long time to learn? no ways! i often hear people complain that it takes too long to learn the shortcuts. i assure you that the 5 minutes it takes to learn the shortcut saves you hours, even days, of work over the months and years that you’ll be working on eclipse. here are some tips to get into and improve your keyboard usage: start by learning the shortcuts for the things you do often. are you using the mouse a lot to launch applications or select code? well, there’s a shortcut to launch apps and one to select code faster. keyboard shortcuts are often indicated next to menu items. note them and try to use them instead of reaching for the mouse. learn to punish yourself when you reach for the mouse by undoing your action and forcing yourself to use the keyboard. this seems counterproductive (and harsh) at first, but it forces your brain to rewire itself so you’ll favour the shortcuts instead of the mouse the next time. there is an eclipse plugin called mousefeed that shows you a keyboard alternative to a mouse click you performed. you can also configure it to cancel mouse clicks where a keyboard alternative is available, forcing you to use the keyboard in those instances. i don’t use it personally but what i’ve seen looks good. it’s definitely sounds like a good idea if you want to change your mousey ways and it relates nicely to my previous point. also keep this in mind: one of the easiest, surefire ways to work faster is to reduce the number of times you move your hands between the keyboard and mouse. the key is doing as much as possible with either one. for the mouse there are things like mouse gestures (if you’re on windows, try strokeit ). for the keyboard there are keyboard shortcuts and eclipse has hundreds of them ready to make your life easier (also see the excellent autohotkey for other ways to boost your keyboard usage). examples of useful keyboard shortcuts there are way too many shortcuts to list and you’ll come across the more useful ones in other tips . here are some you should get acquainted with at first and try to use all the time. shortcut action ctrl+1 quick fix list (for resolving errors/warnings) and also refactoring ctrl+space display the autocomplete list to select a relevant method/template, etc. ctrl+3 open quick access which allows you to run commands and navigate views and dialogs by searching for them, similar to launchy on windows or quicksilver on mac. ctrl+shift+r open any resource in the workspace, eg. xml file, class file, etc. ctrl+shift+t open a java type, eg. a class or interface. f3 go to the declaration of the method/class/variable f11/ctrl+f11 debug/run the last launched application (see this tip for more information) ctrl+alt+h display all methods that call a method (call hierarchy) f2 show javadoc for the current element (shift+f2 shows external javadoc) alt+up/down, alt+shift+down, ctrl+d move a line up/down, copy a line, delete a line (see this tip for more information) ctrl+/ comment/uncomment the current line or selected lines. you can be anywhere in the line, not necessarily at the beginning. you can press ctrl+shift+l to get a list of registered keyboard shortcuts in the lower right corner. but for a complete list, i prefer to go to the preference dialog as i can see all commands that are registered, even if they don’t have shortcuts registered from http://eclipseone.wordpress.com
February 12, 2010
by Byron M
· 36,546 Views
article thumbnail
JavaFX, Sockets and Threading: Lessons Learned
When contemplating how machine-dependent applications might communicate with Java/JavaFX, JNI or the Java Native Interface, having been created for just such a task, would likely be the first mechanism that comes to mind. Although JNI works just fine thank you, a group of us ultimately decided against using it for a small project because, among others: Errors in your JNI implementation can corrupt the Java Virtual Machine in very strange ways, leading to difficult diagnosis. JNI can be time consuming and tedious, especially if there's a varied amount of interchange between the Native and Java platforms. For each OS/Platform supported, a separate JNI implementation would need to be created and maintained. Instead we opted for something a bit more mundane, namely sockets. The socket programming paradigm has been around a long time, is well understood and spans a multitude of hardware/software platforms. Rather than spending time defining JNI interfaces, just open up a socket between applications and send messages back and forth, defining your own message protocol. Following are some reflections on using sockets with JavaFX and Java. For the sake of simplicity, we'll skip the native stuff and focus on how sockets can be incorporated into a JavaFX application in a thread safe manner. Sockets and Threading Socket programming, especially in Java, lends itself to utilizing threads. Because a socket read() will block waiting for input, a common practice is to place the read loop in a background thread enabling you to continue processing while waiting for input at the same time. And if you're doing this work entirely in Java, you'll find that both ends of the socket connection -- the "server" side and the "client" side -- share a great deal of common code. Recognizing this, an abstract class called GenericSocket.java was created which is responsible for housing the common functionality shared by "server" and "client" sockets including the setup of a reader thread to handle socket reads asynchronously. For this simple example, two implementations of the abstract GenericSocket class, one called SocketServer.java, the other called SocketClient.java have been supplied. The primary difference between these two classes lies in the type of socket they use. SocketServer.java uses java.net.ServerSocket, while SocketClient.java uses java.net.Socket. The respective implementations contain the details required to set up and tear down these slightly different socket types. Dissecting the Java Socket Framework If you want to utilize the provided Java socket framework with JavaFX, you need to understand this very important fact: JavaFX is not thread safe and all JavaFX manipulation should be run on the JavaFX processing thread.1 If you allow a JavaFX application to interact with a thread other than the main processing thread, unpredictable errors will occur. Recall that the GenericSocket class created a reader thread to handle socket reads. In order to avoid non-main-thread-processing and its pitfalls with our socket classes, a few modifications must take place. [1] Stolen from JavaFX: Developing Rich Internet Applications - Thanks Jim Clarke Step 1: Identify Resources Off the Main Thread The first step to operating in a thread safe manner is to identify those resources in your Java code, residing off the main thread, that might need to be accessed by JavaFX. For our example, we define two abstract methods, the first, onMessage(), is called whenever a line of text is read from the socket. The GenericSocket.java code will make a call to this method upon encountering socket input. Let's take a look at the SocketReaderThread code inside GenericSocket, to get a feel for what's going on. class SocketReaderThread extends Thread { @Override public void run() { String line; waitForReady(); /* * Read from from input stream one line at a time */ try { if (input != null) { while ((line = input.readLine()) != null) { if (debugFlagIsSet(DEBUG_IO)) { System.out.println("recv> " + line); } /* * The onMessage() method has to be implemented by * a sublclass. If used in conjunction with JavaFX, * use Entry.deferAction() to force this method to run * on the main thread. */ onMessage(line); } } } catch (Exception e) { if (debugFlagIsSet(DEBUG_EXCEPTIONS)) { e.printStackTrace(); } } finally { notifyTerminate(); } } Because onMessage() is called off the main thread and inside SocketReaderThread, the comment states that some additional work, which we'll explain soon, must take place to assure main thread processing. Our second method, onClosedStatus(), is called whenever the status of the socket changes (either opened or closed for whatever reason). This abstract routine is called in different places within GenericSocket.java -- sometimes on the main thread, sometimes not. To assure thread safety, we'll employ the same technique as with onMessage(). Step 2: Create a Java Interface with your Identified Methods Once identified, these method signatures have to be declared inside a Java interface. For example, our socket framework includes a SocketListener.java interface file which looks like this: package genericsocket; public interface SocketListener { public void onMessage(String line); public void onClosedStatus(Boolean isClosed); } Step 3: Create Your Java Class, Implementing Your Defined Interface With our SocketListener interface defined, let's take a step-by-step look at how the SocketServer class is implemented inside SocketServer.java. One of the first requirements is to import a special Java class which will allow us to do main thread processing, achieved as follows: import com.sun.javafx.runtime.Entry; Next, comes the declaration of SocketServer. Notice that in addition to extending the abstract GenericSocket class it also must implement our SocketListener interface too: public class SocketServer extends GenericSocket implements SocketListener { Inside the SocketServer definition, a variable called fxListener of type SocketListener is declared: private SocketListener fxListener; The constructor for SocketServer must include a reference to fxListener. The other arguments are used to specify a port number and some debug flags. public SocketServer(SocketListener fxListener, int port, int debugFlags) { super(port, debugFlags); this.fxListener = fxListener; } Next, let's examine the implementation of the two methods which are declared in the SocketListener interface. The first, onMessage(), looks like this: /** * Called whenever a message is read from the socket. In * JavaFX, this method must be run on the main thread and * is accomplished by the Entry.deferAction() call. Failure to do so * *will* result in strange errors and exceptions. * @param line Line of text read from the socket. */ @Override public void onMessage(final String line) { Entry.deferAction(new Runnable() { @Override public void run() { fxListener.onMessage(line); } }); } As the comment points out, the Entry.deferAction() call enables fxListener.onMessage() to be executed on the main thread. It takes as an argument an instance of the Runnable class and, within its run() method, makes a call to fxListener.onMessage(). Another important point to notice is that onMessage()'s String argument must be declared as final. Along the same line, the onClosedStatus() method is implemented as follows: /** * Called whenever the open/closed status of the Socket * changes. In JavaFX, this method must be run on the main thread and * is accomplished by the Entry.deferAction() call. Failure to do so * will* result in strange errors and exceptions. * @param isClosed true if the socket is closed */ @Override public void onClosedStatus(final Boolean isClosed) { Entry.deferAction(new Runnable() { @Override public void run() { fxListener.onClosedStatus(isClosed); } }); } Another Runnable is scheduled via Entry.deferAction() to run fxlistener.onClosedStatus() on the main thread. Again, onClosedStatus()'s Boolean argument must also be defined as final. Accessing the Framework within JavaFX With this work behind us, now we can integrate the framework into JavaFX. But before elaborating on the details, lets show screenshots of two simple JavaFX applications, SocketServer and SocketClient which, when run together, can send and receive text messages to one another over a socket. These JavaFX programs were developed in NetBeans and utilize the recently announced NetBeans JavaFX Composer tool. You can click on the images to execute these programs via Java WebStart. Note: depending upon your platform, your system may ask for permission prior to allowing these applications to network. Source for the JavaFX applications and the socket framework in the form of NetBeans projects can be downloaded here. Step 4: Integrating into JavaFX To access the socket framework within JavaFX, you must implement the SocketListener class that was created for this project. To give you a feel for how this is done with our JavaFX SocketServer application, here are some code excerpts from the project's Main.fx file, in particular the definition of our ServerSocketListener class: public class ServerSocketListener extends SocketListener { public override function onMessage(line: String) { insert line into recvListView.items; } public override function onClosedStatus(isClosed : java.lang.Boolean) { socketClosed = isClosed; tryingToConnect = false; if (autoConnectCheckbox.selected) { connectButtonAction(); } } } Sparing all of the gory details, the onMessage() method will place the line of text read from the socket in to a JavaFX ListView control which is displayed in the program user interface. The onClosedStatus() method primarily updates the local socketClosed variable and attempts to reconnect the socket if the autoconnect option has been selected. To demonstrate how the socket is created, we examine the connectButtonAction() function: var socketServer : SocketServer; ... public function connectButtonAction (): Void { if (not tryingToConnect) { if (socketClosed) { socketServer = new SocketServer(ServerSocketListener{}, java.lang.Integer.parseInt(portTextbox.text), javafx.util.Bits.bitOr(GenericSocket.DEBUG_STATUS, GenericSocket.DEBUG_IO)); tryingToConnect = true; socketServer.connect(); } } } Whenever the user clicks on the "Connect" button, the connectButtonAction() function will be called. On invocation, if the socket isn't already open, it will create a new SocketServer instance. Recognize also that the SocketServer constructor includes an instance of the ServerSocketListener class which was defined above. To round this out, when the user clicks on the "Disconnect" button, the disconnectButtonAction() function is called. When invoked, it tears down the SocketServer instance. function disconnectButtonAction (): Void { tryingToConnect = false; socketServer.shutdown(); } Conclusion Admittedly, there's a fair amount to digest here. Hopefully, by carefully reviewing the steps and looking at the complete code listing, this can serve as a template if you wish to accomplish something similar in JavaFX. From http://blogs.sun.com/jtc/
February 11, 2010
by Jim Connors
· 22,078 Views
article thumbnail
Promiscuous Integration vs. Continuous Integration
The emergence of version control systems makes both promiscuous and continuous integration merging techniques more attractive. Which is better?
February 10, 2010
by Martin Fowler
· 50,150 Views · 2 Likes
article thumbnail
Reloading Java Classes: Classloaders in Web Development — Tomcat, GlassFish, OSGi, Tapestry 5
In this article we’ll review how dynamic classloaders are used in real servers, containers and frameworks to reload Java classes and applications. We’ll also touch on how to get faster reloads and redeploys by using them in optimal ways. RJC101: Objects, Classes and ClassLoaders RJC201: How do ClassLoader leaks happen? RJC301: Classloaders in Web Development — Tomcat, GlassFish, OSGi, Tapestry 5 and so on RJC401: HotSwap and JRebel — what do they really do? RJC501: The impact of the redeploy phase on the development process AKA:Turnaround Java EE (web) applications In order for a Java EE web application to run, it has to be packaged into an archive with a .WAR extension and deployed to a servlet container like Tomcat. This makes sense in production, as it gives you a simple way to assemble and deploy the application, but when developing that application you usually just want to edit the application’s files and see the changes in the browser. A Java EE enterprise application has to be packaged into an archive with an .EAR extension and deployed to an application container. It can contain multiple web applications and EJB modules, so it often takes a while to assemble and deploy it. Recently, 1100+ EE developers told us how much time it takes them, and we compiled the results into the Redeploy and Restart Report. Spoiler: Avg redeploy & restart time is 2.5 minutes – which is higher than we expected. In Reloading Java Classes 101, we examined how dynamic classloaders can be used to reload Java classes and applications. In this article we will take a look at how servers and frameworks use dynamic classloaders to speed up the development cycle. We’ll use Apache Tomcat as the primary example and comment when behavior differs in other containers (Tomcat is also directly relevant for JBoss and GlassFish as these containers embed Tomcat as the servlet container). Redeployment To make use of dynamic classloaders we must first create them. When deploying your application, the server will create one classloader for each application (and each application module in the case of an enterprise application). The classloaders form a hierarchy as illustrated: In Tomcat each .WAR application is managed by an instance of the StandardContext class that creates an instance of WebappClassLoader used to load the web application classes. When a user presses “reload” in the Tomcat Manager the following will happen: StandardContext.reload() method is called The previous WebappClassLoader instance is replaced with a new one All reference to servlets are dropped New servlets are created Servlet.init() is called on them Calling Servlet.init() recreates the “initialized” application state with the updated classes loaded using the new classloader instance. The main problem with this approach is that to recreate the “initialized” state we run the initialization from scratch, which usually includes loading and processing metadata/configuration, warming up caches, running all kinds of checks and so on. In a sufficiently large application this can take many minutes, but in a in small application this often takes just a few seconds and is fast enough to seem instant, as commonly demonstrated in the Glassfish v3 promotional demos. If your application is deployed as an .EAR archive, many servers allow you to also redeploy each application module separately, when it is updated. This saves you the time you would otherwise spend waiting for non-updated modules to reinitialize after the redeployment. Hot Deployment Web containers commonly have a special directory (e.g. “webapps” in Tomcat, “deploy” in JBoss) that is periodically scanned for new web applications or changes to the existing ones. When the scanner detects that a deployed .WAR is updated, the scanner causes a redeploy to happen (in Tomcat it calls the StandardContext.reload() method). Since this happens without any additional action on the user’s side it is commonly referred to “Hot Deployment”. Hot Deployment is supported by all wide-spread application servers under different names: autodeployment, rapid deployment, autopublishing, hot reload, and so on. In some containers, instead of moving the archive to a predefined directory you can configure the server to monitor the archive at a specific path. Often the redeployment can be triggered from the IDE (e.g. when the user saves a file) thus reloading the application without any additional user involvement. Although the application is reloaded transparently to the user, it still takes the same amount of time as when hitting the “Reload” button in the admin console, so code changes are not immediately visible in the browser, for example. Another problem with redeployment in general and hot deployment in particular is classloader leaks. As we reviewed in Reloading Java Classes 201, it is amazingly easy to leak a classloader and quickly run out of heap causing an OutOfMemoryError. As each deployment creates new classloaders, it is common to run out of memory in just a few redeploys on a large enough application (whether in development or in production). Exploded Deployment An additional feature supported by the majority of web containers is the so called “exploded deployment”, also known as “unpackaged” or “directory” deployment. Instead of deploying a .WAR archive, one can deploy a directory with exactly the same layout as the .WAR archive: Why bother? Well, packaging an archive is an expensive operation, so deploying the directory can save quite a bit of time during build. Moreover, it is often possible to set up the project directory with exactly the same layout as the .WAR archive. This means an added benefit of editing files in place, instead of copying them to the server. Unfortunately, as Java classes cannot be reloaded without a redeploy, changing a .java file still means waiting for the application to reinitialize. With some servers it makes sense to find out exactly what triggers the hot redeploy in the exploded directory. Sometimes the redeploy will be triggered only when the “web.xml” timestamp changes, or as in the case of GlassFish only when a special ”.reload” file timestamp changes. In most servers any change to deployment descriptors or compiled classes will cause a hot redeploy. If your server only supports deploying by copying to a special directory (e.g. Tomcat “webapps”, JBoss “deploy” directories) you can skip the copying by creating a symlink from that special directory to your project workspace. On Linux and Mac OS X you can use the common “ln -s” command to do that, whereas on Windows you should download the Sysinternals “junction” utility. If you use Maven, then it’s quite complicated to set up exploded development from your workspace. If you have a solo web application you can use the Maven Jetty plugin, which uses classes and resources directly from Maven source and target project directories. Unfortunately, the Maven Jetty plugin does not support deploying multiple web applications, EJB modules or EARs so in the latter case you’re stuck doing artifact builds. Session Persistence Since we’re on the topic of reloading classes, and redeploying involves reinitializing an application, it makes sense to talk about session state. An HTTP session usually holds information like login credentials and conversational state. Losing that session when developing a web application means spending time logging in and browsing to the changes page – something that most web containers have tried to solve by serializing all of the objects in the HttpSession map and then deserializing them in the new classloader. Essentially, they copy all of the session state. This requires that all session attributes implement Serializable (ensuring session attributes can be written to a database or a file for later use), which is not restricting in most cases. Session persistence has been present in most major containers for many years (e.g. Restart Persistence in Tomcat), but was notoriously absent in Glassfish before v3. OSGi There is a lot of misunderstanding surrounding what exactly OSGi does and doesn’t do. If we ignore the aspects irrelevant to the current issue, OSGi is basically a collection of modules each wrapped in its own classloader, which can be dropped and recreated at will. When it’s recreated, the modules are reinitialized exactly the same way a web application is. The difference between OSGi and a web container is that OSGi is something that is exposed to your application, that you use to split your application into arbitrarily small modules. Therefore, by design, these modules will likely be much smaller than the monolithic web applications we are used to building. And since each of these modules is smaller and we can “redeploy” them one-by-one, re-initialization takes less time. The time depends on how you design your application (and can still be significant). Tapestry 5, RIFE & Grails Recently, some web frameworks, such as Tapestry 5, RIFE and Grails, have taken a different approach, taking advantage of the fact that they already need to maintain application state. They’ll ensure that state will be serializable, or otherwise easily re-creatable, so that after dropping a classloader, there is no need to reinitialize anything. This means that application developers use frameworks’ components and the lifecycle of those components is handled by the framework. The framework will initialize (based on some configuration, either xml or annotation based), run and destroy the components. As the lifecycle of the components is managed by the framework, it is easy to recreate a component in a new classloader without user intervention and thus create the effect of reloading code. In the background, the old component is destroyed (classloader is dropped) and a new one created (in a new classloader where the classes are read in again) and the old state is either deserialized or created based on the configuration. This has the obvious advantage of being very quick, as components are small and the classloaders are granular. Therefore the code is reloaded instantly, giving a smooth experience in developing the application. However such an approach is not always possible as it requires the component to be completely managed by the framework. It also leads to incompatibilities between the different class versions causing, among others, ClassCastExceptions. We’ve Covered a Lot – and simplified along the way It’s worth mentioning that using classloaders for code reloading really isn’t as smooth as we have described here – this is an introductory article series. Especially with the more granular approaches (such as frameworks that have per component classloaders, manual classloader dropping and recreating, etc), when you start getting a mixture of older and newer classes all hell can break loose. You can hold all kinds of references to old objects and classes, which will conflict with the newly loaded ones (a common problem is getting a ClassCastException), so watch what you’re doing along the way. As a side note: Groovy is actually somewhat better at handling this, as all calls through the Meta-Object Protocol are not subject to such problems. This article addressed the following questions: How are dynamic classloaders used to reload Java classes and applications? How do Tomcat, GlassFish (incl v3), and other servers reload Java classes and applications? How does OSGi improve reload and redeploy times? How do frameworks (incl Tapestry 5, RIFE, Grails) reload Java classes and applications? Coming up next, we continue our explanation of classloaders and the redeploy process with an investigation into HotSwap and JRebel, two tools used to reduce time spent reloading and redeploying. Stay tuned! From http://www.zeroturnaround.com/blog/
January 23, 2010
by Dave Booth
· 26,251 Views
  • Previous
  • ...
  • 753
  • 754
  • 755
  • 756
  • 757
  • 758
  • 759
  • 760
  • 761
  • Next
  • 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
×