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 Testing, Deployment, and Maintenance Topics

article thumbnail
Why You Shouldn't Use Quartz Scheduler
If you need to schedule jobs in Java, it is fairly common in the industry to use Quartz directly or via Spring integration, but you might want to think twice.
January 30, 2012
by Craig Flichel
· 303,480 Views · 5 Likes
article thumbnail
Low-level Infrastructure: Puppet, DNS and DHCP
Right. Let’s have a look at the massive technical implications of the Fix Puppet idea. As I mentioned in my earlier blogpost, in order to fix puppet in a sensible way, we’ll have to review all, and overhaul some of the underlying infrastructure that allows it all to run. The interlinks and dependencies between all the parts are a little tricky to visualise. So, here’s a picture. Anything in red needs attention, and the stuff in green *just works*. Things in blue are install stages, and these are what we’re working on making perfect. Right, so we’ve basically got a directed graph, representing the steps and stages that have to happen to a new machine before users can log in. The steps taken to build a machine, roughly look like this: Unbox. Plug in. Configure Netboot. Hand MAC Address to DHCP server and assign a hostname. Client PXEBoots. Client downloads a preseed file. Client installs itself. Client Reboots. Puppet runs on First Boot. Puppet completes. Client Reboots again. Users login That’s about it, really. The first 4 steps are a hell of a lot easier with the support and co-operation of the supplier. It’s nice to have systems preconfigured to PXE boot as the BIOS default, and even cooler if they can send the MAC addresses as labels on each physical machine. If we’re going to build out a new infrastructure, we’re going to need to review and reinstall the servers that provide this infrastructure, before we can build any workstations. I’m a massive massive fan of puppet, and believe that it should be used for the configuration of all servers and workstations. As such, I didn’t want to rebuild anything without using puppet, so the first step, had to be getting puppet working again. So, without further ado, let’s take a look at the Puppet portion of this, well, one of them. My predecessor saw fit that all nodes should be defined with puppet-dashboard, which is itself, a fine piece of software, but I think more for reporting than specification. Initially, at least, I rebuilt the puppet manifest from a known-good configuration. Namely the base configs I wrote for a blogpost about a year ago; base configs that I’m going to update soon. I’m a bit of an old fashioned puppet user. I like my nodes defined in nodes.pp, not some External Node Classifier service. Reason being, I like to be able to look in one place and find exactly what I want. It’s not a massive ballache to clone down the puppet git repo, make a change and push it back up. In fact, it’s better than having a web interface for your node classifications, because git provides you with an intrinsic log of what was changed, and it’s easy to revert to an old version, because everything’s stored in source control. You can also test what you’re about to do, because again, it’s just a source control repo. I’m a fan of having Jenkins run a few sanity checks on your puppet repo, but that’s a digression for another blogpost. I’m not going to go into great depth about how to install DHCP and DNS, and how to make it work with puppet, at least, not here. What I will say, though is that Puppet Module Tool is the most fantastically easy way to generate boilerplate modules for puppet. All you need to do is run puppet-module generate tomoconnor-dhcp and you get a full puppet module folder called tomoconnor-dhcp which contains all the structure according to the best practice guidelines. Excellent. As part of the review process, it became quite apparent that Bind9 has no sensible admin/management interface, or at least, there wasn’t one installed, and frankly, anything that has such horrific config files should be shot. Having had good experience and results using PowerDNS in the past, we decided that this would be a valid upgrade from BIND. PowerDNS relies on a SQL backend for storing the record data in. You can use either MySQL or PostgreSQL, or possibly some others. Since MySQL can be a bitch, and is, to all serious purposes, a toy database, Postgres seems like a better choice. 9.1 is stable, and there are deb package available for it. 9.1 also does hot-standby replication, which is a miracle, because Postgres replication used to be a massive pain in the testicles. There were, initially some mysterious problems with the TFTPd server being generally crappy, mostly regarding timeouts, which was because the storage of the TFTP data was on a painfully slow disk. Moving it from there to the NFS mount dramatically increased performance and stopped TFTP going crazy. In the TFTP'd config, there's a block for configuring the boot options of the preseed install. This is how PXE hands over the details of the preseed server, and the classes of preseed file to run (basically, which modules) label lucid_ws menu label ^2) Auto Install Ubuntu Lucid WorkStation text help Start hands off install of a workstation. endtext menu default kernel ubuntu-1004-installer/amd64/linux append tasks=standard pkgsel/language-pack-patterns= pkgsel/install-language-support=false vga=normal initrd=ubuntu-1004-installer/amd64/initrd.gz -- quiet auto debian-installer/country=GB debian-installer/language=en debian-installer/keymap=us debian-installer/locale=en_GB.UTF8 netcfg/choose_interface=eth0 netcfg/get_hostname=ubuntu netcfg/get_domain=installdomain.wibblesplat.com url=http://autoserver/d-i/lucid/preseed.cfg classes=wibblesplat;workstation DEBCONF_DEBUG=1 Initially, the Preseed files contained all sorts of crazy hacky shit in the d-i late-command setting. late-command is cool. It’s basically the last thing to run before the first reboot when you build a new debian/ubuntu system. You can tell it to do all sorts of stuff in there. You probably shouldn’t, though. Especially when what you’re doing in there is better done elsewhere. The previous Preseed file contained a whole bunch of “inject these source files into /etc/apt/sources.list”, which is utter bullshit, because you can do exactly the same thing with d-i local repositories, which does the same thing, only far far cleaner. That’s not to say that my refactored preseed files don’t use late-command at all. I’ve chosen to insert some lines into /etc/rc.local on the freshly built system that ensures a puppet run at first boot. On the preseed server, there’s a file called “firstboot.sh” which gets dropped into /usr/local/bin by way of a wget command in late-command. The next thing that happens in late-command is a line to remove “exit 0” from /etc/rc.local and replace it with a thing that calls “/usr/local/bin/firstboot.sh” When firstboot runs, it runs puppet, checks for sanity, and then removes itself from /etc/rc.local. The code to actually do that looks like this: d-i preseed/late_command string \ wget -q -O /target/root/firstboot.sh http://autoserver/d-i/bin/firstboot.sh && \ chmod +x /target/root/firstboot.sh && \ sed -i 's_exit 0_sh /root/firstboot.sh_' /target/etc/rc.local This relies on having something on http://autoserver that is basically just apache hosting some files for the preseeder to retrieve during installation. Cool huh? That ensures that the first thing that happens once the new machine has been built and rebooted, is a puppet run. Some stuff we do here relies on our hand-rolled deb packages, which are stored in our own, internal APT repo. We’ve also got an APT cache, created and maintained by apt-cacher-ng, which at least means that when you’re rebuilding systems frequently, that all the packages you would otherwise download from archive.ubuntu.com come straight over the LAN. The major problem initially with this was the speed, or lack of. It certainly wasn’t performing anywhere near speeds you’d expect from a 1GE LAN, and the reason was again, slow disks. Moving the apt-cache files to the NFS highspeed storage again helped performance. If we struggle in future, I’m going to look at a SSD cache for this, but I think that the performance of the SAS/SATA disks on massively parallel storage provided by our NFS servers will be adequate for the forseeable future. Next up, the Puppetmaster. Again, I was pretty keen on building this from scratch, but using puppet itself to configure it’s own master. Sounds pretty counter-intuitive, right? But the puppet client can bootstrap the master quite easily by using files as it’s source. The first step is to clone down the latest puppet manifests from git, so you either need to git export elsewhere, or install git-core. Your choice. Once you’ve got those, all you need to do is install puppet-client, and run: puppet apply /path/to/your/manifests/site.pp If you’ve written the manifests right, and you’ve got your master defined as a node, you should find that puppet will install puppetmaster, and so on, and then you get a ready and working puppetmaster that just configured itself. I used puppet-module tool to generate modules for the following services/items: “applications” - which actually contains a bunch of custom/proprietary application install rules, a declassified example is there’s a googlechrome.pp file that installs chrome from a PPA. Other modules: dhcp, kernel, ldap, network, nfs, nscd, ntp, nvidia, postgres, powerdns and ssmtp. As is the trend with puppet, and modern DevOps, a vast majority of the code in the entire manifest repository has been gleaned and researched from other puppet modules on github. Acknowledgement is in place where it’s due, and the working copies we’re using are frequently forked on github from the original. It’s great, this, actually. If you search on PuppetForge http://forge.puppetlabs.com/ the array of modules available is staggering. It makes bootstrapping a new manifest set remarkably quick and easy. The NFS module contains a bunch of requirements for mounting NFS shares, and the definitions for an NFS share to be mounted. All pretty simple stuff, but modularised for ease of use. I’m particularly proud of the postgres module which has a master class, and a slave class, which installs and configures the required files and packages to enable streaming hot-standby replication on Postgres9.1 I will release the declassified fork of this soon. I’m going to wrap this post up here. It’s a massively long one, and there’s still lots more left to write. Source: tomoconnor.eu/blogish/low-level-infrastructure-puppet-dns-and-dhcp/
January 29, 2012
by Tom O'connor
· 7,931 Views
article thumbnail
Unit testing when Value Objects get in the way
Tests developed during TDD can be classified into several levels, depending on the size of the object graph they need to work with. End-to-end tests span the whole application graph, while unit tests usually target a single public class at a time. In the middle we find functional tests, which exercise a group of objects. A recurring problem is that of nearby classes C creeping into unit tests of unrelated classes; this situation transform what would be a unit test of the original class O into a functional tests of O and C together (possibly with multiple C classes involved). Functional tests are handy for specifying behavior at an higher level of abstraction than that of a single object, and sometimes for checking the wiring of a component of the application. However, if they are introduced involuntarily in place of unit tests they are prone to raise maintenance problems, since they will need to change every time the C class is updated. Moreover, they will fail along with the unit test of C, pointing to a problem into either O or C, which are not able to localize immediately. Consider this test, where the original class is DocumentsDeclarationNodeCommand and the collaborating one is InMemoryDocumentCopy: @Test public void shouldSendTheListOfDocumentsAndWaitForAcknowledgement() throws ConnectionClosedException { UpstreamConnection upstream = mock(UpstreamConnection.class); DownstreamConnection downstream = mock(DownstreamConnection.class); InMemoryDocumentCopy first = new InMemoryDocumentCopy("1.txt", "hello"); InMemoryDocumentCopy second = new InMemoryDocumentCopy("2.txt", "hello2"); DocumentsDeclarationNodeCommand command = DocumentsDeclarationNodeCommand.fromDocumentCopies( Arrays.asList(first, second), 10001); command.execute(upstream, downstream); InOrder inOrder = inOrder(upstream, downstream); inOrder.verify(upstream).command("DOCUMENTS|PORT=10001"); inOrder.verify(upstream).command("1.txt|5"); inOrder.verify(upstream).command("2.txt|6"); inOrder.verify(upstream).endCommandSection(); inOrder.verify(downstream, times(1)).readResponse(); } The two expectations on command() make this test a functional one: a change in the textual serialization format of InMemoryDocumentCopy (such as "1.txt|sha1_hash|5") will break this checks, even if DocumentsDeclarationNodeCommand still works. Yet we cannot avoid to verify that the documents are really sent to the server by this object. Functional tests can be transformed again into unit tests by testing O with a Test Double instead of C (a Stub, or a Mock.) The only remaining dependency will be the one of the interface of C, which can be even extracted into an independent entity (a first-class interface in language that support them such as Java, C# and PHP.) Pure functions What happens when you can't easily inject a Test Double to maintain the tests at the unit level? This issues exists in functional languages where functions call a tree of other functions. A analogue approach to dependency injection is to inject the function as a parameter, but doesn't probably scale to the level of injection we perform on objects: every function signature would have to receive all the collaborating ones as additional parameters. There are even mocking frameworks for functional languages like Marick's one which are able to isolate a function from its collaborators. Uncle Bob uses the Derived Expectation pattern instead: testing "update-all" (let [ o1 (make-object ...) o2 (make-object ...) o3 (make-object ...) os [o1 o2 o3] us (update-all os) ] (is (= (nth us 0) (reposition (accelerate (accumulate-forces os o1) (is (= (nth us 1) (reposition (accelerate (accumulate-forces os o2) (is (= (nth us 2) (reposition (accelerate (accumulate-forces os o3) ) ) The update-all function calls internally reposition, accelerate and accumulate-forces (or it calls other functions which in turn call these three). Instead of specifying unreadable literal expectations in the tests like (1.096, 4.128), this approach let the test specify update-all link to the other functions without introducing magic numbers. It is therefore a unit test for update-all, while the same test containing numbers would be a functional test. Note that this approach is safe for functional languages because the collaborating functions have no state, being pure; you can call reposition and accelerate how many times you want, and their result won't change. This is not necessarily true for collaborators in object-oriented languages: in principle, a method can return a different value for each call. Tests with derived expectations As long as the composed methods do not change their result, this approach would build real unit tests, whose success does not depend on the correctness of classes other than the one under test. Apart from corner cases like the composed methods throwing exceptions, a change in the collaborator's behavior would change only the collaborator's test. Value Objects are the ideal collaborator to stub out with derived expectations: they are immutable, so their methods always return the same result. Their code is usually self-contained and simple, so it's difficult for a method to throw an exception or to break internally once the Value Object has been correctly built. Being simple, final classes they do not implement an explicit interface; and they are not commonly substituted by Test Doubles. Their behavior is mixed in with the objects using them. The test becomes: @Test public void shouldSendTheListOfDocumentsAndWaitForAcknowledgement() throws ConnectionClosedException { UpstreamConnection upstream = mock(UpstreamConnection.class); DownstreamConnection downstream = mock(DownstreamConnection.class); InMemoryDocumentCopy first = new InMemoryDocumentCopy("1.txt", "hello"); InMemoryDocumentCopy second = new InMemoryDocumentCopy("2.txt", "hello2"); DocumentsDeclarationNodeCommand command = DocumentsDeclarationNodeCommand.fromDocumentCopies( Arrays.asList(first, second), 10001); command.execute(upstream, downstream); InOrder inOrder = inOrder(upstream, downstream); inOrder.verify(upstream).command("DOCUMENTS|PORT=10001"); inOrder.verify(upstream).command(first.toString()); inOrder.verify(upstream).command(second.toString()); inOrder.verify(upstream).endCommandSection(); inOrder.verify(downstream, times(1)).readResponse(); } Conclusion We saw that Test Doubles like Mocks and Stubs are not the only way to achieve isolated tests, which fail only where the class under test fail and not when a collaborator changes its implementation. In the Example, DocumentsDeclarationNodeCommand is tested by involving the real collaborator, but setting up Derived Expectation from it instead of literal ones. The result is this test is only tied to the method signatures of the collaborator instead of to the real behavior (the output format of toString()). This technique doesn't need to be used often: its purpose is to isolate from an immutable object, without introducing a Test Double.
January 26, 2012
by Giorgio Sironi
· 12,815 Views
article thumbnail
Accessing Local Name-Based Virtual Hosts From the Android Emulator
To test mobile versions of websites, it is useful to be able to connect to a web server on your local machine from a web browser on an Android emulator without having to expose the web server to the Internet. You can’t use the normal loop-back IP address of 127.0.0.1 because that refers to the emulated Android device itself. Instead you have to use 10.0.2.2 to connect to the host machine. That’s fine if your local web server is serving a single site, but if you are using name-based virtual hosting to serve different sites depending on the host name of the request (with aliases for localhost defined in your machine’s hosts file), then you need to be making requests from the browser using the correct host name, not the IP address. The Android emulator does not use the host machine’s hosts file for name resolution so attempting to access http://myvirtualhost in the emulator’s browser will not work. This is because the emulated Android device has it’s own hosts file, so you have to update this to map the virtual host names to the local machine. The first step is to start the AVD with an increased partition size otherwise you may get an out of memory error when you try to save the modified hosts file: emulator -avd MyAVD -partition-size 128 You then have to remount the system partition so that it is writeable: adb remount Then copy the hosts file from the emulated device to the host machine: adb pull /etc/hosts Edit the hosts file so that it includes mappings for all relevant virtual host names: 127.0.0.1 localhost 10.0.2.2 myvirtualhost1 myvirtualhost2 Then copy the updated file back to the emulated device: adb push hosts /etc/hosts You should then be able to visit http://myvirtualhost1 in the emulator’s browser and see the correct site. From http://blog.uncommons.org/2012/01/12/accessing-local-name-based-virtual-hosts-from-the-android-emulator/
January 23, 2012
by Dan Dyer
· 15,379 Views
article thumbnail
Which Integration Framework Should You Use – Spring Integration, Mule ESB or Apache Camel?
Data exchanges between companies are increasing a lot. The number of applications that must be integrated is increasing, too. The interfaces use different technologies, protocols and data formats. Nevertheless, the integration of these applications must be modeled in a standardized way, realized efficiently and supported by automatic tests. Three integration frameworks are available in the JVM environment, which fulfil these requirements: Spring Integration, Mule ESB and Apache Camel. They implement the well-known Enteprise Integration Patterns (EIP, http://www.eaipatterns.com) and therefore offer a standardized, domain-specific language to integrate applications. These integration frameworks can be used in almost every integration project within the JVM environment – no matter which technologies, transport protocols or data formats are used. All integration projects can be realized in a consistent way without redundant boilerplate code. This article compares all three alternatives and discusses their pros and cons. If you want to know, when to use a more powerful Enterprise Service Bus (ESB) instead of one of these lightweight integration frameworks, then you should read this blog post: http://www.kai-waehner.de/blog/2011/06/02/when-to-use-apache-camel/ (it explains when to use Apache Camel, but the title could also be „When to use a lightweight integration framework“). Comparison Criteria Several criteria can be used to compare these three integration frameworks: Open source Basic concepts / architecture Testability Deployment Popularity Commercial support IDE-Support Errorhandling Monitoring Enterprise readiness Domain specific language (DSL) Number of components for interfaces, technologies and protocols Expandability Similarities All three frameworks have many similarities. Therefore, many of the above comparison criteria are even! All implement the EIPs and offer a consistent model and messaging architecture to integrate several technologies. No matter which technologies you have to use, you always do it the same way, i.e. same syntax, same API, same automatic tests. The only difference is the the configuration of each endpoint (e.g. JMS needs a queue name while JDBC needs a database connection url). IMO, this is the most significant feature. Each framework uses different names, but the idea is the same. For instance, „Camel routes“ are equivalent to „Mule flows“, „Camel components“ are called „adapters“ in Spring Integration. Besides, several other similarities exists, which differ from heavyweight ESBs. You just have to add some libraries to your classpath. Therefore, you can use each framework everywhere in the JVM environment. No matter if your project is a Java SE standalone application, or if you want to deploy it to a web container (e.g. Tomcat), JEE application server (e.g. Glassfish), OSGi container or even to the cloud. Just add the libraries, do some simple configuration, and you are done. Then you can start implementing your integration stuff (routing, transformation, and so on). All three frameworks are open source and offer familiar, public features such as source code, forums, mailing lists, issue tracking and voting for new features. Good communities write documentation, blogs and tutorials (IMO Apache Camel has the most noticeable community). Only the number of released books could be better for all three. Commercial support is available via different vendors: Spring Integration: SpringSource (http://www.springsource.com) Mule ESB: MuleSoft (http://www.mulesoft.org) Apache Camel: FuseSource (http://fusesource.com) and Talend (http://www.talend.com) IDE support is very good, even visual designers are available for all three alternatives to model integration problems (and let them generate the code). Each of the frameworks is enterprise ready, because all offer required features such as error handling, automatic testing, transactions, multithreading, scalability and monitoring. Differences If you know one of these frameworks, you can learn the others very easily due to their same concepts and many other similarities. Next, let’s discuss their differences to be able to decide when to use which one. The two most important differences are the number of supported technologies and the used DSL(s). Thus, I will concentrate especially on these two criteria in the following. I will use code snippets implementing the well-known EIP „Content-based Router“ in all examples. Judge for yourself, which one you prefer. Spring Integration Spring Integration is based on the well-known Spring project and extends the programming model with integration support. You can use Spring features such as dependency injection, transactions or security as you do in other Spring projects. Spring Integration is awesome, if you already have got a Spring project and need to add some integration stuff. It is almost no effort to learn Spring Integration if you know Spring itself. Nevertheless, Spring Integration only offers very rudimenary support for technologies – just „basic stuff“ such as File, FTP, JMS, TCP, HTTP or Web Services. Mule and Apache Camel offer many, many further components! Integrations are implemented by writing a lot of XML code (without a real DSL), as you can see in the following code snippet: You can also use Java code and annotations for some stuff, but in the end, you need a lot of XML. Honestly, I do not like too much XML declaration. It is fine for configuration (such as JMS connection factories), but not for complex integration logic. At least, it should be a DSL with better readability, but more complex Spring Integration examples are really tough to read. Besides, the visual designer for Eclipse (called integration graph) is ok, but not as good and intuitive as its competitors. Therefore, I would only use Spring Integration if I already have got an existing Spring project and must just add some integration logic requiring only „basic technologies“ such as File, FTP, JMS or JDBC. Mule ESB Mule ESB is – as the name suggests – a full ESB including several additional features instead of just an integration framework (you can compare it to Apache ServiceMix which is an ESB based on Apache Camel). Nevertheless, Mule can be use as lightweight integration framework, too – by just not adding and using any additional features besides the EIP integration stuff. As Spring Integration, Mule only offers a XML DSL. At least, it is much easier to read than Spring Integration, in my opinion. Mule Studio offers a very good and intuitive visual designer. Compare the following code snippet to the Spring integration code from above. It is more like a DSL than Spring Integration. This matters if the integration logic is more complex. The major advantage of Mule is some very interesting connectors to important proprietary interfaces such as SAP, Tibco Rendevous, Oracle Siebel CRM, Paypal or IBM’s CICS Transaction Gateway. If your integration project requires some of these connectors, then I would probably choose Mule! A disadvantage for some projects might be that Mule says no to OSGi: http://blogs.mulesoft.org/osgi-no-thanks/ Apache Camel Apache Camel is almost identical to Mule. It offers many, many components (even more than Mule) for almost every technology you could think of. If there is no component available, you can create your own component very easily starting with a Maven archetype! If you are a Spring guy: Camel has awesome Spring integration, too. As the other two, it offers a XML DSL: ${in.header.type} is ‘com.kw.DvdOrder’ ${in.header.type} is ‘com.kw.VideogameOrder’ Readability is better than Spring Integration and almost identical to Mule. Besides, a very good (but commercial) visual designer called Fuse IDE is available by FuseSource – generating XML DSL code. Nevertheless, it is a lot of XML, no matter if you use a visual designer or just your xml editor. Personally, I do not like this. Therefore, let’s show you another awesome feature: Apache Camel also offers DSLs for Java, Groovy and Scala. You do not have to write so much ugly XML. Personally, I prefer using one of these fluent DSLs instead XML for integration logic. I only do configuration stuff such as JMS connection factories or JDBC properties using XML. Here you can see the same example using a Java DSL code snippet: from(“file:incomingOrders “) .choice() .when(body().isInstanceOf(com.kw.DvdOrder.class)) .to(“file:incoming/dvdOrders”) .when(body().isInstanceOf(com.kw.VideogameOrder.class)) .to(“jms:videogameOrdersQueue “) .otherwise() .to(“mock:OtherOrders “); The fluent programming DSLs are very easy to read (even in more complex examples). Besides, these programming DSLs have better IDE support than XML (code completion, refactoring, etc.). Due to these awesome fluent DSLs, I would always use Apache Camel, if I do not need some of Mule’s excellent connectors to proprietary products. Due to its very good integration to Spring, I would even prefer Apache Camel to Spring Integration in most use cases. By the way: Talend offers a visual designer generating Java DSL code, but it generates a lot of boilerplate code and does not allow vice-versa editing (i.e. you cannot edit the generated code). This is a no-go criteria and has to be fixed soon (hopefully)! And the winner is… … all three integration frameworks, because they are all lightweight and easy to use – even for complex integration projects. It is awesome to integrate several different technologies by always using the same syntax and concepts – including very good testing support. My personal favorite is Apache Camel due to its awesome Java, Groovy and Scala DSLs, combined with many supported technologies. I would only use Mule if I need some of its unique connectors to proprietary products. I would only use Spring Integration in an existing Spring project and if I only need to integrate „basic technologies“ such as FTP or JMS. Nevertheless: No matter which of these lightweight integration frameworks you choose, you will have much fun realizing complex integration projects easily with low efforts. Remember: Often, a fat ESB has too much functionality, and therefore too much, unnecessary complexity and efforts. Use the right tool for the right job! Best regards, Kai Wähner (Twitter: @KaiWaehner) http://www.kai-waehner.de/blog/2012/01/10/spoilt-for-choice-which-integration-framework-to-use-spring-integration-mule-esb-or-apache-camel/
January 19, 2012
by Kai Wähner DZone Core CORE
· 110,861 Views · 9 Likes
article thumbnail
Use Clover to generate code coverage reports of your Integration/Automation Tests
clover is a great tool for generating code coverage reports from your unit tests. it can be executed as a plugin in eclipse, maven or ant. however, not everyone knows that it can also be used to collect coverage data of integration tests. this post explains how to collect coverage data with clover at runtime. this post assumes that you already know what are unit and integration tests. this post assumes that you know what clover is, and already used it either with eclipse, ant or maven. * let me assured you that even though the directions bellow seems complicated and clumsy at first, after doing them once or twice it is really easy to repeat them. motivation the default action of clover is to gather code coverage information during build time or compile time. therefore, this information includes just the coverage data created by unit tests. if you are developing web applications, you probably use more technologies to test your applications beside unit tests. these technologies may include httpunit/ htmlunit or automation technologies (like selenium). these technologies do not work at build time, they can only work during run time, where a web server is up and running and http calls are made. as a result, the code coverage made during build time is not reflecting the actual code coverage. we should be able to test the coverage while a server is running. the idea the idea is that we will first run clover regularly during build time. we will than take the clover artifacts, put them in our server and then run the integration tests. while running the integration tests, the clover database will be updated and we would be able to generate reports from it which will reflect both unit and integration tests. step 1 – preparation make sure that you have a web/application server (tomcat/jboss/weblogic…) with your web application already deployed. execute clover on your application as you would normally do (either by compiling the code on eclipse or by building with maven or ant, it doesn’t matter). the result of this action would be: clover db files. one of the outcome of executing the clover on your code are the db files. the db files hold all the information about your code and the coverage itself. the location of those files may change depending on the way you use clover and according to the way you configured clover in your environment. this is how the files looks like the .db file holds the information regarding your code (classes, methods and so on). all the other files hold all the coverage data. it is important that you will locate those files because we are going to use them in the next step. an instrumented code. another outcome of clover is that it instruments your code. a clover call is injected into each method so it would be reported in the coverage calculation. we will need this code. we will use this instrumented code in runtime to update the coverage data. if you use eclipse than the generated classes would be instrumented. if you use maven or ant than most chances are that a jar with all the instrumented code would be generated separately. search the instrument code jar. again, i can’t tell you exactly where it is located, but usually it generates a jar with a ‘clover’ postfix. example: if your jar name is my_app.jar, than the generated instrumented code jar will probably be something like my_app-clover.jar. so you will need to do some detective work here to find the instrumented classes/jar. if you are not sure whether the classes are instrumented or not, just decompile one of them with jad and search for the word clover inside of it. a code coverage report. this is a report with the unit test coverage. we don’t really need this, but it would be good so that we would be able to compare it with the report we will generate at the end. step 2 – updating the server the next steps are very important, please make sure you do them properly. replacing the existing application jar/classes with the instrumented jar/classes. take the instrumented jar/classes that were created by the clover and add it to your server’s classpath instead of the original jar/classes. the instrumented code will cause the clover db to be updated with the runtime data. adding clover jars and license. since we will use clover on runtime we will need also the clover jars in our server’s classpath. so add the clover own jars to your server’s classpath. if you are using clover with eclipse than these jars are located in the plugin folder of eclipse. if you are using maven than they will be loacted in your repository. * make sure you are using the same version of clover in your server as you used to generate the db files and instrumented code, otherwise it will not work and you will get error messages. also add the clover license file to the same location as the jars. adding the clover java argument. add the following java arg -dclover.initstring.basedir={ location of the db files that were created by the clover } . * notice – the path you have entered above is the path of the folder which contains the db files. example: -dclover.initstring.basedir=c:/workspace/mywebapp/target/clover. this java argument is used by the clover to locate the db files and update them. step 3 – restarting the server and running the tests now that hopefully all is set properly all that you need to do now is to restart your server and than running your integration tests. the tests should trigger the instrumented code which will call the clover api’s and will update the clover db. while running the tests: look at your log/console and search for error messages from clover. look at the folder which holds the clover db files. if everything is going as it should, new files will be created in this folder while running the tests. if not everything is going well the first time, don’t discourage, just go over each of the steps again. step 4 – generating an updated report if everything went well and new files were created in the db folder than that means you just need to generate a new report. if you are using clover with eclipse than you can simply push the reload button to reload the coverage data. if you are using maven or ant you can execute just the task which generates the report. another way is to use the clover htmlreporter to generate a report easily. now compare the new report to the old report. you should see that the new report coverage is much bigger than the old one since it contains also the integration tests coverage. * notice that not all the data is updated, even though the percentages are being updated, for some reason the calls counter does not. to summarize. as mentioned; yes, these instructions seems a bit complicated but after you succeed the first time, it is very easy to repeat it. in the company i work for we even made this whole process automatic and we are able to generate a full coverage report with unit and integrated tests combined. source: http://www.aviyehuda.com/2011/12/use-clover-to-generate-code-coverage-reports-of-your-integrationautomation-tests/
January 8, 2012
by Avi Yehuda
· 40,899 Views · 1 Like
article thumbnail
Test Doubles With Mockito
Introduction A common thing I come across is that teams using a mocking framework assume they are mocking. They are not aware that Mocks are just one of a number of 'Test Doubles' which Gerard Meszaros has categorised at xunitpatterns.com. It’s important to realise that each type of test double has a different role to play in testing. In the same way that you need to learn different patterns or refactoring’s, you need to understand the primitive roles of each type of test double. These can then be combined to achieve your testing needs. I'll cover a very brief history of how this classification came about, and how each of the types differs. I'll do this using some short, simple examples in Mockito. A Very Brief History For years people have been writing lightweight versions of system components to help with testing. In general it was called stubbing. In 2000' the article 'Endo-Testing: Unit Testing with Mock Objects' introduced the concept of a Mock Object. Since then Stubs, Mocks and a number of other types of test objects have been classified by Meszaros as Test Doubles. This terminology has been referenced by Martin Fowler in "Mocks Aren't Stubs" and is being adopted within the Microsoft community as shown in "Exploring The Continuum of Test Doubles" A link to each of these important papers are shown in the reference section. Categories of test doubles The diagram above shows the commonly used types of test double. The following URL gives a good cross reference to each of the patterns and their features as well as alternative terminology. http://xunitpatterns.com/Test%20Double.html Mockito Mockito is a test spy framework and it is very simple to learn. Notable with Mockito is that expectations of any mock objects are not defined before the test as they sometimes are in other mocking frameworks. This leads to a more natural style(IMHO) when beginning mocking. The following examples are here purely to give a simple demonstration of using Mockito to implement the different types of test doubles. There are a much larger number of specific examples of how to use Mockito on the website. http://docs.mockito.googlecode.com/hg/latest/org/mockito/Mockito.html Test Doubles with Mockito Below are some basic examples using Mockito to show the role of each test double as defined by Meszaros. I’ve included a link to the main definition for each so you can get more examples and a complete definition. Dummy Object http://xunitpatterns.com/Dummy%20Object.html This is the simplest of all of the test doubles. This is an object that has no implementation which is used purely to populate arguments of method calls which are irrelevant to your test. For example, the code below uses a lot of code to create the customer which is not important to the test. The test couldn't care less which customer is added, as long as the customer count comes back as one. public Customer createDummyCustomer() { County county = new County("Essex"); City city = new City("Romford", county); Address address = new Address("1234 Bank Street", city); Customer customer = new Customer("john", "dobie", address); return customer; } @Test public void addCustomerTest() { Customer dummy = createDummyCustomer(); AddressBook addressBook = new AddressBook(); addressBook.addCustomer(dummy); assertEquals(1, addressBook.getNumberOfCustomers()); } We actually don't care about the contents of customer object - but it is required. We can try a null value, but if the code is correct you would expect some kind of exception to be thrown. @Test(expected=Exception.class) public void addNullCustomerTest() { Customer dummy = null; AddressBook addressBook = new AddressBook(); addressBook.addCustomer(dummy); } To avoid this we can use a simple Mockito dummy to get the desired behaviour. @Test public void addCustomerWithDummyTest() { Customer dummy = mock(Customer.class); AddressBook addressBook = new AddressBook(); addressBook.addCustomer(dummy); Assert.assertEquals(1, addressBook.getNumberOfCustomers()); } It is this simple code which creates a dummy object to be passed into the call. Customer dummy = mock(Customer.class); Don't be fooled by the mock syntax - the role being played here is that of a dummy, not a mock. It's the role of the test double that sets it apart, not the syntax used to create one. This class works as a simple substitute for the customer class and makes the test very easy to read. Test stub http://xunitpatterns.com/Test%20Stub.html The role of the test stub is to return controlled values to the object being tested. These are described as indirect inputs to the test. Hopefully an example will clarify what this means. Take the following code public class SimplePricingService implements PricingService { PricingRepository repository; public SimplePricingService(PricingRepository pricingRepository) { this.repository = pricingRepository; } @Override public Price priceTrade(Trade trade) { return repository.getPriceForTrade(trade); } @Override public Price getTotalPriceForTrades(Collection trades) { Price totalPrice = new Price(); for (Trade trade : trades) { Price tradePrice = repository.getPriceForTrade(trade); totalPrice = totalPrice.add(tradePrice); } return totalPrice; } The SimplePricingService has one collaborating object which is the trade repository. The trade repository provides trade prices to the pricing service through the getPriceForTrade method. For us to test the business logic in the SimplePricingService, we need to control these indirect inputs i.e. inputs we never passed into the test. This is shown below. In the following example we stub the PricingRepository to return known values which can be used to test the business logic of the SimpleTradeService. @Test public void testGetHighestPricedTrade() throws Exception { Price price1 = new Price(10); Price price2 = new Price(15); Price price3 = new Price(25); PricingRepository pricingRepository = mock(PricingRepository.class); when(pricingRepository.getPriceForTrade(any(Trade.class))) .thenReturn(price1, price2, price3); PricingService service = new SimplePricingService(pricingRepository); Price highestPrice = service.getHighestPricedTrade(getTrades()); assertEquals(price3.getAmount(), highestPrice.getAmount()); } Saboteur Example There are 2 common variants of Test Stubs: Responder’s and Saboteur's. Responder's are used to test the happy path as in the previous example. A saboteur is used to test exceptional behaviour as below. @Test(expected=TradeNotFoundException.class) public void testInvalidTrade() throws Exception { Trade trade = new FixtureHelper().getTrade(); TradeRepository tradeRepository = mock(TradeRepository.class); when(tradeRepository.getTradeById(anyLong())) .thenThrow(new TradeNotFoundException()); TradingService tradingService = new SimpleTradingService(tradeRepository); tradingService.getTradeById(trade.getId()); } Mock Object http://xunitpatterns.com/Mock%20Object.html Mock objects are used to verify object behaviour during a test. By object behaviour I mean we check that the correct methods and paths are excercised on the object when the test is run. This is very different to the supporting role of a stub which is used to provide results to whatever you are testing. In a stub we use the pattern of defining a return value for a method. when(customer.getSurname()).thenReturn(surname); In a mock we check the behaviour of the object using the following form. verify(listMock).add(s); Here is a simple example where we want to test that a new trade is audited correctly. Here is the main code. public class SimpleTradingService implements TradingService{ TradeRepository tradeRepository; AuditService auditService; public SimpleTradingService(TradeRepository tradeRepository, AuditService auditService) { this.tradeRepository = tradeRepository; this.auditService = auditService; } public Long createTrade(Trade trade) throws CreateTradeException { Long id = tradeRepository.createTrade(trade); auditService.logNewTrade(trade); return id; } The test below creates a stub for the trade repository and mock for the AuditService We then call verify on the mocked AuditService to make sure that the TradeService calls it's logNewTrade method correctly @Mock TradeRepository tradeRepository; @Mock AuditService auditService; @Test public void testAuditLogEntryMadeForNewTrade() throws Exception { Trade trade = new Trade("Ref 1", "Description 1"); when(tradeRepository.createTrade(trade)).thenReturn(anyLong()); TradingService tradingService = new SimpleTradingService(tradeRepository, auditService); tradingService.createTrade(trade); verify(auditService).logNewTrade(trade); } The following line does the checking on the mocked AuditService. verify(auditService).logNewTrade(trade); This test allows us to show that the audit service behaves correctly when creating a trade. Test Spy http://xunitpatterns.com/Test%20Spy.html It's worth having a look at the above link for the strict definition of a Test Spy. However in Mockito I like to use it to allow you to wrap a real object and then verify or modify it's behaviour to support your testing. Here is an example were we check the standard behaviour of a List. Note that we can both verify that the add method is called and also assert that the item was added to the list. @Spy List listSpy = new ArrayList(); @Test public void testSpyReturnsRealValues() throws Exception { String s = "dobie"; listSpy.add(new String(s)); verify(listSpy).add(s); assertEquals(1, listSpy.size()); } Compare this with using a mock object where only the method call can be validated. Because we only mock the behaviour of the list, it does not record that the item has been added and returns the default value of zero when we call the size() method. @Mock List listMock = new ArrayList(); @Test public void testMockReturnsZero() throws Exception { String s = "dobie"; listMock.add(new String(s)); verify(listMock).add(s); assertEquals(0, listMock.size()); } Another useful feature of the testSpy is the ability to stub return calls. When this is done the object will behave as normal until the stubbed method is called. In this example we stub the get method to always throw a RuntimeException. The rest of the behaviour remains the same. @Test(expected=RuntimeException.class) public void testSpyReturnsStubbedValues() throws Exception { listSpy.add(new String("dobie")); assertEquals(1, listSpy.size()); when(listSpy.get(anyInt())).thenThrow(new RuntimeException()); listSpy.get(0); } In this example we again keep the core behaviour but change the size() method to return 1 initially and 5 for all subsequent calls. public void testSpyReturnsStubbedValues2() throws Exception { int size = 5; when(listSpy.size()).thenReturn(1, size); int mockedListSize = listSpy.size(); assertEquals(1, mockedListSize); mockedListSize = listSpy.size(); assertEquals(5, mockedListSize); mockedListSize = listSpy.size(); assertEquals(5, mockedListSize); } This is pretty Magic! Fake Object http://xunitpatterns.com/Fake%20Object.html Fake objects are usually hand crafted or light weight objects only used for testing and not suitable for production. A good example would be an in-memory database or fake service layer. They tend to provide much more functionality than standard test doubles and as such are probably not usually candidates for implementation using Mockito. That’s not to say that they couldn’t be constructed as such, just that its probably not worth implementing this way. References Test Double Patterns Endo-Testing: Unit Testing with Mock Objects Mock Roles, Not Objects Mocks Aren't Stubs http://msdn.microsoft.com/en-us/magazine/cc163358.aspx Original Article. The original article and others can be found here http://johndobie.blogspot.com/2011/11/test-doubles-with-mockito.html
January 7, 2012
by John Dobie
· 30,089 Views
article thumbnail
JMeter load testing against Apache Webserver: Errors and Resolutions
have been working on a fairly simple JMeter load script that I can run a series of 4 sequential pages against an Apache server, but the goal was to have the server support 2,000 concurrent requests for 5 minutes without error. Most of my issues in this exercise have been with JMeter and the client machine used to test the Apache server. To begin, I must state I was originally configuring Apache with a prefork MPM: StartServers 100 MinSpareServers 75 MaxSpareServers 100 ServerLimit 2000 MaxClients 2000 MaxRequestsPerChild 0 At approximately line 72 of Jmeter.bat, there are several entries the manage the JVM for running Jmeter. set HEAP=-Xms512m -Xmx512m set NEW=-XX:NewSize=128m -XX:MaxNewSize=128m set SURVIVOR=-XX:SurvivorRatio=8 -XX:TargetSurvivorRatio=50% set TENURING=-XX:MaxTenuringThreshold=2 set RMIGC=-Dsun.rmi.dgc.client.gcInterval=600000 -Dsun.rmi.dgc.server.gcInterval=600000 set PERM=-XX:PermSize=64m -XX:MaxPermSize=64m I decided to start with 1,000 concurrent requests for 5 minutes just to see how the test would fair. With the above settings I started getting OOM errors almost immediately so I decided to increase the HEAP and NEW memory to eliminate the issue and wanted to add more GC settings to increase the JVM’s ability to clean up: set HEAP=-Xms1024m -Xmx1024m -Xss128k set NEW=-XX:NewSize=256m -XX:MaxNewSize=256m set SURVIVOR=-XX:SurvivorRatio=14 -XX:TargetSurvivorRatio=50% set "TENURING=-XX:+UseConcMarkSweepGC -XX:+UseParNewGC -XX:+CMSParallelRemarkEnabled -XX:+UseCMSCompactAtFullCollection -XX:+DisableExplicitGC -XX:+UseCMSInitiatingOccupancyOnly -XX:CMSInitiatingOccupancyFraction=70 -XX:MaxTenuringThreshold=4" set "EVACUATION=-XX:+AggressiveOpts -XX:+UseFastAccessorMethods -XX:+UseCompressedStrings -XX:+OptimizeStringConcat" set RMIGC=-Dsun.rmi.dgc.client.gcInterval=600000 -Dsun.rmi.dgc.server.gcInterval=600000 set PERM=-XX:PermSize=64m -XX:MaxPermSize=64m This did resolve the JMeter OOM issues, but now started getting Apache errors. During the ramp-up phase, I started getting connection refused errors: Response code: Non HTTP response code: org.apache.http.conn.HttpHostConnectException Response message: Non HTTP response message: Connection to http://pasundtastgprt2:8001 refused I started looking at the Apache server and noticed that the number of httpd threads was at 1,000 and it appeared that JMeter was running out of memory because the requests where starting to back up. This is why we load test right! So I decided to run a worker MQM and recompiled Apache to support the new MPM ServerLimit 80 StartServers 25 MaxClients 2000 MinSpareThreads 75 MaxSpareThreads 125 ThreadsPerChild 5 MaxRequestsPerChild 0 I started testing this configuration and while monitoring the server running 1,000 concurrent requests and the server looked like Apache was handling 1,000 requests just fine. I was running a simple command to output the sockets and httpd processes on the server during the load test: while true do echo -----`date '+%r'` -----: netstat -ant | awk '{print $6}' | sort | uniq -c | sort -n echo httpd processes: [`ps aux | grep httpd | wc -l`] echo . sleep 30 done Then when I was monitoring the load test, I was concerned about seeing 82 httpd processes running which was the ServerLimit I had set. -----08:02:37 AM -----: 1 established) 1 Foreign 4 CLOSE_WAIT 17 LISTEN 32 FIN_WAIT2 41 ESTABLISHED 69 FIN_WAIT1 630 SYN_RECV 45386 TIME_WAIT [82] httpd processes . I now increased the load to my target of 2,000 concurrent requests and restarted the JMeter test and was able to get to around 1,800 concurrent request and started getting connection refused errors again. I suspected that my Servers where maxed out and was not able to create anymore threads for those servers where having: 80 server * 5 threads each server == 400 requests processed concurrently So I increased the number of threads to 25 80 server * 25 threads each server == 2,000 requests processed concurrently To end up with this worker setting: ServerLimit 80 StartServers 25 MaxClients 2000 MinSpareThreads 75 MaxSpareThreads 125 ThreadsPerChild 25 MaxRequestsPerChild 0 I was then able to turn the load up to 2,000 concurrent requests. -----08:53:27 AM -----: 1 established) 1 FIN_WAIT2 1 Foreign 4 CLOSE_WAIT 12 CLOSING 17 LISTEN 129 ESTABLISHED 621 FIN_WAIT1 1203 SYN_RECV 55556 TIME_WAIT [53] httpd processes At this point we are only using 53 Servers and 2,000 clients. The tests sustained zero errors for 5 minutes during the test. As a test I increased the ThreadsPerChild to 40 and run the load test against 3,000 concurrent requests. I was able to get to around 2,800 concurrent requests then I started getting connection refused errors: Error Count: 1 Response code: Non HTTP response code: org.apache.http.conn.HttpHostConnectException Response message: Non HTTP response message: Connection to http://pasundtastgprt2:8001 refused and I also started getting JMeter errors: Response code: Non HTTP response code: java.net.BindException Response message: Non HTTP response message: Address already in use: connect So in the furure I would like to see how much further I can push the server and I think I can get to 3,000 concurrent and most likely far more than that on my current installation. From http://www.baselogic.com/blog/development/adding-memory-jmeter/
January 5, 2012
by Mick Knutson
· 26,003 Views · 1 Like
article thumbnail
TDD for multithreaded applications
This article describes some practices for test-driving multithreaded and distributed applications written in Java. The example I worked on and we will use is a peer-to-peer application composed of many Nodes (clients) and of a few Supernodes (servers). The ultimate goal it to build an application composed of all these entities, but the first tests target a Supernode serving one or more Nodes. The walking skeleton TDD is mostly iterative, but needs a starting point. The simplest story we can think of is that of a Node connecting to a Supernode. Client and servers usually run in their own threads (in the case of the server, multiple ones), but initially the Node object can just be a POJO and run in the test's thread because we do not need to manage multiple Nodes yet. The Supernode object instead is a Thread (or a Runnable) and so we already face a simplified version of the synchronization problem: how to make sure the Supernode is ready to answer to connections once we have started its thread? The JUnit test is the following: @Test public void aNodeCanConnectToASupernode() throws Exception { Supernode supernode = new Supernode(8888); supernode.start(); supernode.ensureStartupIsFinished(); Node n = new Node(); n.connect("127.0.0.1", 8888); assertEquals(1, supernode.getNodes()); } supernode.start() runs the new thread, while the call to ensureStartupIsFinished() will have to block until the other thread is ready. Then, we create a Node object and tell it to connect; after it has finished this operation, we count how many nodes have connected to the Supernode. To satisfy this test, the Supernode can be a single-threaded server: public class Supernode extends Thread { private int port; private boolean startupCompleted; private int nodes = 0; public Supernode(int port) { this.port = port; this.startupCompleted = false; } public void run() { ServerSocket sock; try { sock = new ServerSocket(this.port); // ...networking setup... synchronized (this) { this.startupCompleted = true; notify(); } while (true) { // ...accepting new connections on sock and other stuff } } public int getNodes() { return nodes; } synchronized public void ensureStartupIsFinished() throws InterruptedException { while (!this.startupCompleted) { wait(); } } } What's in this first example? Thread objects are manageable as POJOs from a single JVM: as long as we write them with this API it will be simple to instantiate and terminate them, and to add primitives for synchronization. The startupCompleted field, which is an example of this synchronization behavior added to the production code. Adding production code just for end-to-end testing purposes is not uncommon. The test thread blocks inside ensureStartupIsFinished() until it is woken up via notification. Even then, startupCompleted must be true or it will wait more. This is Plain Old Java Synchronization: note the synchronized blocks around this.wait() and this.notify(). The problem with frameworks and containers is you have to hope they provide the synchronization facilities to test your code once it's inside them: have you ever tried to wait for Tomcat to start? There are some noticeable missing parts in this code: the threads for each node. The current test does not require them as only one Node is connecting for now. Thread.sleep() calls: at least for the happy paths I have covered until now, I never need to introduce them and considered them a smell. Configuration files: if we had to read configuration, the tests would take really long to write and would refer continuously to external resources. This is the case when testing with external tools which are not embeddable (Tomcat requiring configuration files while Jetty allowing configuration to be passed in Java test code). You can always add file-based configuration later, but for now it will slow us down. Evolution By adding one test at the time with a larger scope, we can try to evolve the code and add the difficult networking, multithreading part one bit at a time. After some iterations, the test becomes: public class FileSharingNetworkTest { Supernode supernode; @Before public void setUp() throws Exception { supernode = new Supernode(8888); supernode.start(); supernode.ensureStartupIsFinished(); } @After public void tearDown() throws Exception { supernode.ensureStop(); } @Test public void aNodeCanConnectToASupernode() throws Exception { Node n = newNode(Arrays.asList("1.txt", "2.txt")); n.ensureConnectionIsFinished(); assertEquals(1, supernode.getNodes()); assertEquals(2, supernode.getDocuments()); } @Test public void multipleNodesCanConnectToASupernodeSimultaneously() throws Exception { Node n1 = newNode(); Node n2 = newNode(); n1.ensureConnectionIsFinished(); n2.ensureConnectionIsFinished(); assertEquals(2, supernode.getNodes()); } private Node newNode() { Node n = new Node("127.0.0.1", 8888); n.start(); n.setDocumentList(Arrays.asList("1.txt", "2.txt")); return n; } private Node newNode(List documentList) { Node n = new Node("127.0.0.1", 8888); n.start(); n.setDocumentList(documentList); return n; } } The server-side code doesn't have multiple threads yet. What is the test case that will call for them? You have to find it and write it. This workflow will ensure that there is a test that targets this case. In my case, it was the first test requiring interaction between the two clients, where one had to see the documents listed by the other after both had connected. Even if you know where you will end up, you can test-drive the implementation: the advantage is that you understand better a standard design and ensure its test coverage. After a few more tests, I have reached a multithreaded server with a main thread and chidren for managing the connections; and Node objects implemented as independent threads. Conclusions When working with TDD at a system scale that includes asynchronous behavior, we should strive for a test suite that is: fast; even with multiple threads to wait for, a single end to end test should take less than a second to complete. Comprehensive; TDD makes us only write tested code instead of copying down snippets from the web. Robust: totally deterministic, as every run will either pass or fail, even when repeated dozens of times. There should be no sleeping calls for all the happy paths; there should be synchronization and stopping facilities built into the system. Featuring unit tests: along with the end to end tests we should write unit tests for the objects we need to extract (and that will be single threaded). It was easy for me to get caught up into covering more and more cases with a full scale test, but unit tests are better at pointing out where a bug resides. We also have to keep in mind how to design our objects and interfaces: not starting with N threads but with at most 1 more than the test's one (the server or a remote peer). Evolving them: adding a few lines of verbose Java networking code each time. My example has evolved to N client threads, a server main thread and N server children threads talking with each client. I will now have to evolve it to a network of supernodes, being this about a file sharing network; to introduce secure channels and certificates. The difficult part is to constantly refactor to support new stories without having to rework the whole system for a single one. Not only extracting methods (an automated operation), but also to extract interfaces and most importantly objects; targeting the longest and complex classes and chopping them down into basic responsibilities.
January 3, 2012
by Giorgio Sironi
· 14,964 Views
article thumbnail
JAXB, SAX, DOM Performance
This post investigates the performance of unmarshalling an XML document to Java objects using a number of different approaches. The XML document is very simple. It contains a collection of Person entities. person0 name0 person1 name1 ... There is a corresponding Person Java object for the Person entity in the XML ... @XmlAccessorType(XmlAccessType.FIELD) @XmlType(name = "", propOrder = { "id", "name" }) public class Person { private String id; private String name; public String getId() { return id; } public void setId(String id) { this.id = id; } public String getName() { return name; } public void setName(String value) { this.name = value; } } and a PersonList object to represent a collection of Persons. @XmlAccessorType(XmlAccessType.FIELD) @XmlRootElement(name = "persons") public class PersonList { @XmlElement(name="person") private List personList = new ArrayList(); public List getPersons() { return personList; } public void setPersons(List persons) { this.personList = persons; } } The approaches investigated were: Various flavours of JAXB SAX DOM In all cases, the objective was to get the entities in the XML document to the corresponding Java objects. The JAXB annotations on the Person and PersonList POJOS are used in the JAXB tests. The same classes can be used in SAX and DOM tests (the annotations will just be ignored). Initially the reference implementations for JAXB, SAX and DOM were used. The Woodstox STAX parsing was then used. This would have been called in some of the JAXB unmarshalling tests. The tests were carried out on my Dell Laptop, a Pentium Dual-Core CPU, 2.1 GHz running Windows 7. Test 1 - Using JAXB to unmarshall a Java File. @Test public void testUnMarshallUsingJAXB() throws Exception { JAXBContext jc = JAXBContext.newInstance(PersonList.class); Unmarshaller unmarshaller = jc.createUnmarshaller(); PersonList obj = (PersonList)unmarshaller.unmarshal(new File(filename)); } Test 1 illustrates how simple the progamming model for JAXB is. It is very easy to go from an XML file to Java objects. There is no need to get involved with the nitty gritty details of marshalling and parsing. Test 2 - Using JAXB to unmarshall a Streamsource Test 2 is similar Test 1, except this time a Streamsource object wraps around a File object. The Streamsource object gives a hint to the JAXB implementation to stream the file. @Test public void testUnMarshallUsingJAXBStreamSource() throws Exception { JAXBContext jc = JAXBContext.newInstance(PersonList.class); Unmarshaller unmarshaller = jc.createUnmarshaller(); StreamSource source = new StreamSource(new File(filename)); PersonList obj = (PersonList)unmarshaller.unmarshal(source); } Test 3 - Using JAXB to unmarshall a StAX XMLStreamReader Again similar to Test 1, except this time an XMLStreamReader instance wraps a FileReader instance which is unmarshalled by JAXB. @Test public void testUnMarshallingWithStAX() throws Exception { FileReader fr = new FileReader(filename); JAXBContext jc = JAXBContext.newInstance(PersonList.class); Unmarshaller unmarshaller = jc.createUnmarshaller(); XMLInputFactory xmlif = XMLInputFactory.newInstance(); XMLStreamReader xmler = xmlif.createXMLStreamReader(fr); PersonList obj = (PersonList)unmarshaller.unmarshal(xmler); } Test 4 - Just use DOM This test uses no JAXB and instead just uses the JAXP DOM approach. This means straight away more code is required than any JAXB approach. @Test public void testParsingWithDom() throws Exception { DocumentBuilderFactory domFactory = DocumentBuilderFactory.newInstance(); DocumentBuilder builder = domFactory.newDocumentBuilder(); Document doc = builder.parse(filename); List personsAsList = new ArrayList(); NodeList persons = doc.getElementsByTagName("person"); for (int i = 0; i persons = new ArrayList(); DefaultHandler handler = new DefaultHandler() { boolean bpersonId = false; boolean bpersonName = false; public void startElement(String uri, String localName,String qName, Attributes attributes) throws SAXException { if (qName.equalsIgnoreCase("id")) { bpersonId = true; Person person = new Person(); persons.add(person); } else if (qName.equalsIgnoreCase("name")) { bpersonName = true; } } public void endElement(String uri, String localName, String qName) throws SAXException { } public void characters(char ch[], int start, int length) throws SAXException { if (bpersonId) { String personID = new String(ch, start, length); bpersonId = false; Person person = persons.get(persons.size() - 1); person.setId(personID); } else if (bpersonName) { String name = new String(ch, start, length); bpersonName = false; Person person = persons.get(persons.size() - 1); person.setName(name); } } }; saxParser.parse(filename, handler); } The tests were run 5 times for 3 files which contain a collection of Person entities. The first first file contained 100 Person entities and was 5K in size. The second contained 10,000 entities and was 500K in size and the third contained 250,000 Person entities and was 15 Meg in size. In no cases was any XSD used, or any validations performed. The results are given in result tables where the times for the different runs are comma separated. TEST RESULTS The tests were first run using JDK 1.6.26, 32 bit and the reference implementation for SAX, DOM and JAXB shipped with JDK was used. Unmarshall Type 100 Persons time (ms) 10K Persons time (ms) 250K Persons time (ms) JAXB (Default) 48,13, 5,4,4 78, 52, 47,50,50 1522, 1457, 1353, 1308,1317 JAXB(Streamsource) 11, 6, 3,3,2 44, 44, 48,45,43 1191, 1364, 1144, 1142, 1136 JAXB (StAX) 18, 2,1,1,1 111, 136, 89,91,92 2693, 3058, 2495, 2472, 2481 DOM 16, 2, 2,2,2 89,50, 55,53,50 1992, 2198, 1845, 1776, 1773 SAX 4, 2, 1,1,1 29, 34, 23,26,26 704, 669, 605, 589,591 JDK 1.6.26 Test comments The first time unmarshalling happens is usually the longest. The memory usage for the JAXB and SAX is similar. It is about 2 Meg for the file with 10,000 persons and 36 - 38 Meg file with 250,000. DOM Memory usage is far higher. For the 10,000 persons file it is 6 Meg, for the 250,000 person file it is greater than 130 Meg. The performance times for pure SAX are better. Particularly, for very large files. The exact same tests were run again, using the same JDK (1.6.26) but this time the Woodstox implementation of StAX parsing was used. Unmarshall Type 100 Persons time (ms) 10K Persons time (ms) 250K Persons time (ms) JAXB (Default) 48,13, 5,4,4 78, 52, 47,50,50 1522, 1457, 1353, 1308,1317 JAXB(Streamsource) 11, 6, 3,3,2 44, 44, 48,45,43 1191, 1364, 1144, 1142, 1136 JAXB (StAX) 18, 2,1,1,1 111, 136, 89,91,92 2693, 3058, 2495, 2472, 2481 DOM 16, 2, 2,2,2 89,50, 55,53,50 1992, 2198, 1845, 1776, 1773 SAX 4, 2, 1,1,1 29, 34, 23,26,26 704, 669, 605, 589,591 JDK 1.6.26 + Woodstox test comments Again, the first time unmarshalling happens is usually proportionally longer. Again, memory usage for SAX and JAXB is very similar. Both are far better than DOM. The results are very similar to Test 1. The JAXB (StAX) approach time has improved considerably. This is due to the Woodstox implementation of StAX parsing being used. The performance times for pure SAX are still the best. Particularly for large files. The the exact same tests were run again, but this time I used JDK 1.7.02 and the Woodstox implementation of StAX parsing. Unmarshall Type 100 Persons time (ms) 10,000 Persons time (ms) 250,000 Persons time (ms) JAXB (Default) 165,5, 3, 3,5 611,23, 24, 46, 28 578, 539, 511, 511, 519 JAXB(Streamsource) 13,4, 3, 4, 3 43,24, 21, 26, 22 678, 520, 509, 504, 627 JAXB (StAX) 21,1,0, 0, 0 300,69, 20, 16, 16 637, 487, 422, 435, 458 DOM 22,2,2,2,2 420,25, 24, 23, 24 1304, 807, 867, 747, 1189 SAX 7,2,2,1,1 169,15, 15, 19, 14 366, 364, 363, 360, 358 JDK 7 + Woodstox test comments: The performance times for JDK 7 overall are much better. There are some anomolies - the first time the 100 persons and the 10,000 person file is parsed. The memory usage is slightly higher. For SAX and JAXB it is 2 - 4 Meg for the 10,000 persons file and 45 - 49 Meg for the 250,000 persons file. For DOM it is higher again. 5 - 7.5 Meg for the 10,000 person file and 136 - 143 Meg for the 250,000 persons file. Note: W.R.T. all tests No memory analysis was done for the 100 persons file. The memory usage was just too small and so it would have pointless information. The first time to initialise a JAXB context can take up to 0.5 seconds. This was not included in the test results as it only took this time the very first time. After that the JVM initialises context very quickly (consistly < 5ms). If you notice this behaviour with whatever JAXB implementation you are using, consider initialising at start up. These tests are a very simple XML file. In reality there would be more object types and more complex XML. However, these tests should still provide a guidance. Conclusions: The peformance times for pure SAX are slightly better than JAXB but only for very large files. Unless you are using very large files the performance differences are not worth worrying about. The progamming model advantages of JAXB win out over the complexitiy of the SAX programming model. Don't forget JAXB also provides random accses like DOM does. SAX does not provide this. Performance times look a lot better with Woodstox, if JAXB / StAX is being used. Performance times with 64 bit JDK 7 look a lot better. Memory usuage looks slightly higher. From http://dublintech.blogspot.com/2011/12/jaxb-sax-dom-performance.html
December 31, 2011
by Alex Staveley
· 47,410 Views · 4 Likes
article thumbnail
How to deploy a neo4j instance in Amazon EC2 in 10 minutes
Neo4j is a high-performance, NOSQL graph database with all the features of a mature and robust database. In this post I will explain how to deploy a neo4j instance in Amazon EC2 web service. For this tutorial to take you no more than 10 minutes you should be able to execute properly some bash commands like mv, tar, ssh and scp (secure copy). I also assume that you have an account in Amazon Web Services and you are familiar to the process of launching instances. If not, I strongly recommend you to follow this starting guide and complete it till you manage to connect to your instance with ssh. Start downloading the latest stable version of neo4j. Which you can find here. The “Community Edition” fits well for development purposes. Do not forget to select the Unix version of the server. This will download a tar.gz file which you will copy to your EC2 instance later. While you download the neo4j server open the AWS Management Console and launch a Basic 32-bit Amazon Linux AMI. If you want to launch an Ubuntu AMI please notice that it doesn’t ship with Java, which is required for running neo4j. If you are not familiar with key pairs, pem files or security groups I insist you to follow the EC2 starting guide I mentioned above. You can either create a new security group or use the default, but you will need to configure a new security rule for the neo4j server port. After launching the instance, create a TCP rule on port 7474 with source 0.0.0.0/0. Here you are opening port 7474 for anyone. If you are planning to use the neo4j REST API and remotely call it from another server, for example a Rails application hosted in Heroku, for security reasons, you may want to change the source field to the address of your Heroku server. Do not forget to open port 22 (SSH), this is typically the first rule normal people create after launching an instance. You are almost done! You should now install neo4j in your instance. Open a terminal in your localhost and navigate to the path where you downloaded neo4j. Copy the file to your Amazon instance by using the scp command: scp -i your_pem_file.pem neo4j-community-1.6.M01-unix.tar.gz ec2-user@YOUR_PUBLIC_INSTANCE_DNS:/home/ec2-user Please notice that you will need to change the path to your pem file, typically placed in ~/.ssh, the filename of the neo4j server you just downloaded and the plublic DNS of your instance. Now connect to your instance with SSH: ssh -i your_pem_file.pem ec2-user@YOUR_PUBLIC_INSTANCE_DNS Untar the neo4j server: tar xvfz neo4j-community-1.6.M01-unix.tar.gz.tar.gz Move it to /usr/local and rename the folder to neo4j: sudo mv neo4j-community-1.6.M01 /usr/local/neo4j Almost done!!! You should now open neo4j-server.properties under the conf directory and add the following line: org.neo4j.server.webserver.address=0.0.0.0 This lines allows anyone to connect remotely to your neo4j database server. Now run the start script. From the neo4j server folder. sudo ./bin/neo4j start Finally, open a browser and access the webadmin interface of your neo4j database by typing http://YOUR_PUBLIC_INSTANCE_DNS:7474. You should see the Neo4j Monitoring and Management Tool, pretty cool! If not, ask me You can now try using the REST API and the curl bash command to insert nodes and relationships. I hope this post helped you, good luck! Follow me on Twitter @negarnil Source: http://www.cloudtmp.com/java/how-to-deploy-a-neo4j-instance-in-amazon-ec2-in-10-minutes/
December 27, 2011
by Nicolas Garnil
· 27,397 Views · 1 Like
article thumbnail
Maven + JavaScript Unit Test: Running in a Continuous Integration Environment
So you're still interested in unit testing JavaScript (good). This post is an extension of my much more indepth first posting on how to unit test JavaScript using JS Test Driver. Please check it out here. Recap Last Posting In the last posting we successfully unit tested JavaScript using Maven and JsTest Driver. This allowes us to test JavaScript when on an environment that has a modern browser installed and can be run. Problem with typical CI environments So what happens when the test are passing on your local box, but you go to check in your code and the Continuous Integration (CI) server pukes on the new tests becasue there is no "screen" to run chrome or firefox? As of this posting, none of the top-tier browsers have a "headless" or an in-memory only browser window. There are alternatives to running JavaScript in a browser, such as rhino.js, env.js or HtmlUnit, however, these are just ports of browsers and the JavaScript and DOM representation are not 100% accurate which can lead to problems with your code when rendered in a client's browser. Approach What we need to do is to run JSTestDriver's browser in a Virtual X Framebuffer (Xvfb) which is possible on nearly all Linux based systems. The example below uses a Solaris version of Linux, however, Debian and RedHat linux distrubutions come with the simplified bash script to easily run an appliation in a virtual framebuffer. This solution was derived from one posted solution on the JS Test Driver wiki. The given example is also a full working example that is in use at my current client. Here is the quick list of what we will accomplish. Note, several of these steps are discussed in depth in the previous post and are not covered in depth here. Create a profile to run Js Unit-Tests Copy JsTestDriver library to a known location for Maven to use Copy JavaScript main and test files to known locations Use ANT to start JsTestDriver and pipe the screen into xvfb Here is a sample profile to use. You will need to adjust the properties at the top of the profile to match your system. ci-jstests /opt/swf/bin/firefox 1.3.2 /opt/X11R6/xvfb-run org.apache.maven.plugins maven-dependency-plugin 2.1 copy generate-resources copy com.google.jstestdriver jstestdriver ${js-test-driver.version} jar true jsTestDriver.jar ${project.build.directory}/jstestdriver false true maven-resources-plugin 2.4.3 copy-main-files generate-test-resources copy-resources ${project.build.directory}/test-classes/main-js src/main/webapp/scripts false copy-test-files generate-test-resources copy-resources ${project.build.directory}/test-classes/test-js src/test/webapp/scripts false org.apache.maven.plugins maven-antrun-plugin 1.6 test run Possible problems Although I cannot predict or fix all problems, I can share the one major problem I ran into with Solaris and the script used to fix that. In Solaris (and could happen to other distros) the xvfb-run script was not available and several of the other libraries did not exist. I first had to download the latest X libraries and place them in their appropriate locations on the CI server. Next, I had to re-engineer the xvfb-run script. Here is a copy of my script (NOTE: This is the solution for my server and this may not work for you) I created a script that contains: /usr/openwin/bin/Xvfb :1 screen 0 1280x1024x8 pixdepths 8 24 fbdir /tmp/.X11-vbf & From http://www.ensor.cc/2011/08/maven-javascript-unit-test-running-in.html
December 23, 2011
by Mike Ensor
· 12,237 Views
article thumbnail
Approval Tests: An Alternative View on Test Automation
Approval Tests or simply Approvals is a framework created by Llewellyn Falco and Dan Gilkerson, providing support for .NET, Java, PHP and Ruby. It is not yet another unit testing framework like NUnit or MbUnit etc.; instead these frameworks are used to run approval tests. Broadly speaking, software is nothing more than virtual box there we put in some inputs and expect some outputs. The outputs could be produce in a zillion ways. Those ways differ by implementation. Unit tests are too much focused on implementation. That's why unit tests might fail even if you have working code. Approvals, by contrast, are focused on output. How does it work? Let's take a look at a very simple case. Say, I have a class ShoppingCart. I can add some products inside the shopping cart, and confirm my purchase. I expect that the total price is calculated for me. [TestFixture] [UseReporter(typeof(DiffReporter))] public class ShoppingCartTests { [Test] public void should_calculate_the_total_price_for_shopping_cart() { // do var shoppingCart = new ShoppingCart(); shoppingCart.Add(new Product { Id = "iPad", Price = 500 }); shoppingCart.Add(new Product { Id = "Mouse", Price = 20 }); shoppingCart.Confirm(); // verify Approvals.Approve(shoppingCart); } } What happens if I run this test? If I'm running it the first time, it fails. No matter whether it works or doesn't. The framework simply doesn't know that yet. To understand how correct that code is, use your human power of recognition. In that case, you'll see that it will open the TortoiseDiff application and show the actual and expected outputs. Here, I can tell: "Ok, I have 2 products in my cart..one iPod and one Mouse, iPods costs 500 smth and mouse is 20 smth.. and the total price is 520 - looks good! I approve that result!". Technically, the approving is just copying actual output to expected. As soon as the test passes, the actual file output is deleted and the approved file resides near the test code file, so you just check it in source control. But let's say the shopping cart is modified and something goes wrong. There would be a failure. In the case of unit tests, that would be multiple failures of different cases and it might be not so easy to understand exactly what's wrong. For an approval test, on the other hand, it would be just one failure. And the cooles thing is that can see exactly where the deviation is. Where does it work? It is not only the simple objects that you can approve. You can even approve different sources: objects, enumerables, files, HTML, XML etc. On a more high level: WpfForm, WinForm, ASP.NET Page. For instance, code for ASP.NET: [Test] public void should_have_approved_layout() { ApprovalTests.Asp.Approvals.ApproveUrl("http://localhost:62642/customer/"); } Or for a WPF form: [Test] public void should_have_approved_layout() { ApprovalTests.Wpf.Approvals.Approve(new Form()); } With WPF and Win forms, it's able to serialize them into images, so the actual and expected results are actually images, so it is easy to track the differences (TortoiseDiff can do that). When should you use it? It works best when you deal with 2 things: UI and legacy code. Testing UI is always difficult. But what you typically need to do is: make sure that UI is not changed, and if it has changed, know where exactly the change happened. Approval testing solves that nicely. It takes only one line of code to test ASP.NET page, for instance. Legacy is another story: you have no tests there at all, but you have to change code to implement a new feature, or refactor. The interesting thing about legacy codeis - It works! It works for years, no matter how it is written (remember, virtual box). And this is a very great advantage of that code. With approvals, with only one test you can get all possible outputs (HTML, XLM, JSON, SQL or whatever output it could be) and approve, because you know - it works! After you have complete such a test and approved the result, you are really much safer with a refactoring, since now you "locked down" all existing behavior. Approvals are not something you need to run all the time, like units or integration tests. Approval testing is more like handy tool. You create approval tests, you do your job and at the end of the day it might happen - the tool is no longer needed, so you can just throw the tool away. Want to hear more? Just go and listen to this Herding Code podcast episode, or visit the project web site or join me at 17 December on XP Days Ukraine conference in Kiev, where I'm going to have a speech dedicated to Approvals. Source: http://www.beletsky.net/2011/12/approval-tests-alternative-view-on-test.html
December 22, 2011
by Alexander Beletsky
· 10,542 Views · 1 Like
article thumbnail
Enabling JMX in Hibernate, Ehcache, Quartz, DBPC and Spring
A collection of short how-to's for enabling JMX in several popular Java technologies. Continuing our journey with JMX (see: ...JMX for human beings) we will learn how to enable JMX support (typically statistics and monitoring capabilities) in some popular frameworks. Most of this information can be found on project's home pages, but I decided to collect it with few the addition of some useful tips. Hibernate (with Spring support) Exposing Hibernate statistics with JMX is pretty simple, however some nasty workarounds are requires when JPA API is used to obtain underlying SessionFactory class JmxLocalContainerEntityManagerFactoryBean() extends LocalContainerEntityManagerFactoryBean { override def createNativeEntityManagerFactory() = { val managerFactory = super.createNativeEntityManagerFactory() registerStatisticsMBean(managerFactory) managerFactory } def registerStatisticsMBean(managerFactory: EntityManagerFactory) { managerFactory match { case impl: EntityManagerFactoryImpl => val mBean = new StatisticsService(); mBean.setStatisticsEnabled(true) mBean.setSessionFactory(impl.getSessionFactory); val name = new ObjectName("org.hibernate:type=Statistics,application=spring-pitfalls") ManagementFactory.getPlatformMBeanServer.registerMBean(mBean, name); case _ => } } } Note that I have created a subclass of Springs built-in LocalContainerEntityManagerFactoryBean. By overriding createNativeEntityManagerFactory() method I can access EntityManagerFactory and by trying to downcast it to org.hibernate.ejb.EntityManagerFactoryImpl we were able to register Hibernate Mbean. One more thing has left. Obviously we have to use our custom subclass instead of org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean. Also, in order to collect the actual statistics instead of just seeing zeroes all the way down we must set the hibernate.generate_statistics flag. @Bean def entityManagerFactoryBean() = { val entityManagerFactoryBean = new JmxLocalContainerEntityManagerFactoryBean() entityManagerFactoryBean.setDataSource(dataSource()) entityManagerFactoryBean.setJpaVendorAdapter(jpaVendorAdapter()) entityManagerFactoryBean.setPackagesToScan("com.blogspot.nurkiewicz") entityManagerFactoryBean.setJpaPropertyMap( Map( "hibernate.hbm2ddl.auto" -> "create", "hibernate.format_sql" -> "true", "hibernate.ejb.naming_strategy" -> classOf[ImprovedNamingStrategy].getName, "hibernate.generate_statistics" -> true.toString ).asJava ) entityManagerFactoryBean } Here is a sample of what can we expect to see in JvisualVM (don't forget to install all plugins!): In addition we get a nice Hibernate logging: HQL: select generatedAlias0 from Book as generatedAlias0, time: 10ms, rows: 20 EhCache Monitoring caches is very important, especially in application where you expect values to generally be present there. I tend to query the database as often as needed to avoid unnecessary method arguments or local caching. Everything to make code as simple as possible. However this approach only works when caching on the database layer works correctly. Similar to Hibernate, enabling JMX monitoring in EhCache is a two-step process. First you need to expose provided MBean in MBeanServer: @Bean(initMethod = "init", destroyMethod = "dispose") def managementService = new ManagementService(ehCacheManager(), platformMBeanServer(), true, true, true, true, true) @Bean def platformMBeanServer() = ManagementFactory.getPlatformMBeanServer def ehCacheManager() = ehCacheManagerFactoryBean.getObject @Bean def ehCacheManagerFactoryBean = { val ehCacheManagerFactoryBean = new EhCacheManagerFactoryBean ehCacheManagerFactoryBean.setShared(true) ehCacheManagerFactoryBean.setCacheManagerName("spring-pitfalls") ehCacheManagerFactoryBean } Note that I explicitly set CacheManager name. This is not required but this name is used as part of the Mbean name and a default one contains hashCode value, which is not very pleasant. The final touch is to enable statistics on a cache basis: Now we can happily monitor various caching characteristics of every cache separately: As we can see the percentage of cache misses increases. Never a good thing. If we don't enable cache statistics, enabling JMX is still a good idea since we get a lot of management operations for free, including flushing and clearing caches (useful during debugging and testing). Quartz scheduler In my humble opinion Quartz scheduler is very underestimated library, but I will write an article about it on its own. This time we will only learn how to monitor it via JMX. Fortunately it's as simple as adding: org.quartz.scheduler.jmx.export=true To quartz.properties file. The JMX support in Quartz could have been slightly broader, but still one can query e.g. which jobs are currently running. By the way the new major version of Quartz (2.x) brings very nice DSL-like support for scheduling: val job = newJob(classOf[MyJob]) val trigger = newTrigger(). withSchedule( repeatSecondlyForever() ). startAt( futureDate(30, SECOND) ) scheduler.scheduleJob(job.build(), trigger.build()) Apache Commons DBCP Apache Commons DBCP is the most reasonable JDBC pooling library I came across. There is also c3p0, but it doesn't seem like it's actively developed any more. Tomcat JDBC Connection Pool looked promising, but since it's bundled in Tomcat, your JDBC drivers can no longer be packaged in WAR. The only problem with DBCP is that it does not support JMX. At all (see this two and a half year old issue). Fortunately this can be easily worked around. Besides we will learn how to use Spring built-in JMX support. Looks like the standard BasicDataSource has all what we need, all we have to do is to expose existing metrics via JMX. With Spring it is dead-simple – just subclass BasicDataSource and add @ManagedAttribute annotation over desired attributes: @ManagedResource class ManagedBasicDataSource extends BasicDataSource { @ManagedAttribute override def getNumActive = super.getNumActive @ManagedAttribute override def getNumIdle = super.getNumIdle @ManagedAttribute def getNumOpen = getNumActive + getNumIdle @ManagedAttribute override def getMaxActive: Int= super.getMaxActive @ManagedAttribute override def setMaxActive(maxActive: Int) { super.setMaxActive(maxActive) } @ManagedAttribute override def getMaxIdle = super.getMaxIdle @ManagedAttribute override def setMaxIdle(maxIdle: Int) { super.setMaxIdle(maxIdle) } @ManagedAttribute override def getMinIdle = super.getMinIdle @ManagedAttribute override def setMinIdle(minIdle: Int) { super.setMinIdle(minIdle) } @ManagedAttribute override def getMaxWait = super.getMaxWait @ManagedAttribute override def setMaxWait(maxWait: Long) { super.setMaxWait(maxWait) } @ManagedAttribute override def getUrl = super.getUrl @ManagedAttribute override def getUsername = super.getUsername } Here are few data source metrics going crazy during load-test: JMX support in the Spring framework itself is pretty simple. As you have seen above exposing arbitrary attribute or operation is just a matter of adding an annotation. You only have to remember about enabling JMX support using either XML or Java (also see: SPR-8943 : Annotation equivalent to with @Configuration): or: @Bean def annotationMBeanExporter() = new AnnotationMBeanExporter() This article wasn't particularly exciting. However, the knowledge of JMX metrics will enable us to write simple yet fancy dashboards in no time. Stay tuned! From http://nurkiewicz.blogspot.com/2011/12/enabling-jmx-in-hibernate-ehcache-qurtz.html
December 22, 2011
by Tomasz Nurkiewicz
· 12,621 Views
article thumbnail
Diminishing Returns in software development and maintenance
Everyone knows from reading The Mythical Man Month that as you add more people to a software development project you will see diminishing marginal returns. When you add a person to a team, there’s a short-term hit as the rest of the team slows down to bring the new team member up to speed and adjusts to working with another person, making sure that they fit in and can contribute. There’s also a long-term cost. More people means more people who need to talk to each other (n x n-1 / 2), which means more opportunities for misunderstandings and mistakes and misdirections and missed handoffs, more chances for disagreements and conflicts, more bottleneck points. As you continue to add people, the team needs to spend more time getting each new person up to speed and more time keeping everyone on the team in synch. Adding more people means that the team speeds up less and less, while people costs and communications costs and overhead costs keep going up. At some point negative returns set in – if you add more people, the team’s performance will decline and you will get less work done, not more. Diminishing Returns from any One Practice But adding too many people to a project isn’t the only case of diminishing returns in software development. If you work on a big enough project, or if you work in maintenance for long enough, you will run into problems of diminishing returns everywhere that you look. Pushing too hard in one direction, depending too much on any tool or practice, will eventually yield diminishing returns. This applies to: - Manual functional and acceptance testing - Test automation - Any single testing technique - Code reviews - Static analysis bug finding tools - Penetration tests and other security reviews Aiming for 100% code coverage on unit tests is a good example. Building a good automated regression safety net is important – as you wire in tests for key areas of the system, programmers get more confidence and can make more changes faster. How many tests are enough? In Continuous Delivery, Jez Humble and David Farley set 80% coverage as a target for each of automated unit testing, functional testing and acceptance testing. You could get by with lower coverage in many areas, higher coverage in core areas. You need enough tests to catch common and important mistakes. But beyond this point, more tests get more difficult to write, and find fewer problems. Unit testing can only find so many problems in the first place. In Code Complete, Steve McConnell explains that unit testing can only find between 15% and 50% (on average 30%) of the defects in your code. Rather than writing more unit tests, people’s time would be better spent on other approaches like exploratory system testing and code reviews or stress testing or fuzzing to find different kinds of errors. Too much of anything is bad, but too much whiskey is enough. Mark Twain, as quoted in Code Complete Refactoring is important for maintaining and improving the structure and readability of code over time. It is intended to be a supporting practice – to help make changes and fixes simpler and clearer and safer. When refactoring becomes an end in itself or turns into Obsessive Refactoring Disorder, it not only adds unnecessary costs as programmers waste time over trivial details and style issues, it can also add unnecessary risks and create conflict in a team. Make sure that refactoring is done in a disciplined way, and focus refactoring on those areas that need it the most: on code that is frequently changed, routines that are too big, too hard to read, too complex and error-prone. Putting most of your attention refactoring (or if necessary rewriting) this code will get you the highest returns. Less and Less over Time Diminishing returns also set in over time. The longer that you spend working the same way and with the same tools, the less benefits you will see. Even core practices that you’ve grown to depend on don’t pay back over time, and at some point may cost more than they are worth. It’s time again for New Year’s resolutions – time to sign up at a gym and start lifting weights. If you stick with the same routine for a couple of months, you will start to see good results. But after a while your body will get used to the work – if you keep doing the same things the same way your performance will plateau and you will stop seeing gains. You will get bored and stop going to the gym, which will leave more room for people like me. If you do keep going, trying to push harder for returns, you will overtrain and injure yourself. The same thing happens to software teams following the same practices, using the same tools. Some of this is due to inertia. Teams, organizations reach an equilibrium point and they want to stay there. Because it is comfortable, and it works – or at least they understand it. And because the better the team is working, the harder it is to get better – all the low-hanging fruit has been picked. People keep doing what worked for them in the past. They stop looking beyond their established routines, stop looking for new ideas. Competence and control lead to complacency and acceptance. Instead of trying to be as good as possible, they settle for being good enough. This is the point of inspect-and-adapt in Scrum and other time boxed methods – asking the team to regularly re-evaluate what they are doing and how they are doing it, what’s going well and what isn’t, what they should do more of or less of, challenging the status quo and finding new ways to move forward. But even the act of assessing and improving is subject to diminishing returns. If you are building software in 2-week time boxes, and you’ve been doing this for 3, 4 or 5 years, then how much meaningful feedback should you really expect from so many superficial reviews? After a while the team finds themselves going over the same issues and problems and coming up with the same results. Reviews become an unnecessary and empty ritual, another waste of time. The same thing happens with tools. When you first start using a static analysis bug checking tool for example, there’s a good chance that you will find some interesting problems that you didn’t know were in the code – maybe even more problems than you can deal with. But once you triage this and fix up the code and use the tool for a while, the tool will find fewer and fewer problems until it gets to the point where you are paying for insurance – it isn’t finding problems any more, but it might someday. In "Has secure software development reached its limits?” William Jackson argues that SDLCs – all of them – eventually reach a point of diminishing returns from a quality and security standpoint, and that Microsoft and Oracle and other big shops are already seeing diminishing returns from their SDLCs. Their software won’t get any better – all they can do is to keep spending time and money to stay where they are. The same thing happens with Agile methods like Scrum or XP – at some point you’ve squeezed everything that you can from this way or working, and the team’s performance will plateau. What can you do about diminishing returns? First, understand and expect returns to diminish over time. Watch for the signs, and factor this into your expectations – that even if you maintain discipline and keep spending on tools, you will get less and less return for your time and money. Watch for the team’s velocity to plateau or decline. Expect this to happen and be prepared to make changes, even force fundamental changes on the team. If the tools that you are using aren’t giving returns any more, then find new ones, or stop using them and see what happens. Keep reviewing how the team is working, but do these reviews differently: review less often, make the reviews more focused on specific problems, involve different people from inside and outside of the team. Use problems or mistakes as an opportunity to shake things up and challenge the status quo. Dig deep using Root Cause Analysis and challenge the team’s way of thinking and working, look for something better. Don’t settle for simple answers or incremental improvements. Remember the 80/20 rule. Most of your problems will happen in the same small number of areas, from a small number of common causes. And most of your gains will come from a few initiatives. Change the team’s driving focus and key metrics, set new bars. Use Lean methods and Lean Thinking to identify and eliminate bottlenecks, delays and inefficiencies. Look at the controls and tests and checks that you have added over time, question whether you still need them, or find steps and checks that can be combined or automated or simplified. Focus on reducing cycle time and eliminating waste until you have squeezed out what you can. Then change your focus to quality and eliminating bugs, or to simplifying the release and deployment pipeline, or some other new focus that will push the team to improve in a meaningful way. And keep doing this and pushing until you see the team slowing down and results declining. Then start again, and push the team to improve again along another dimension. Keep watching, keep changing, keep moving ahead. Source: http://swreflections.blogspot.com/2011/11/diminishing-returns-in-software.html
December 14, 2011
by Jim Bird
· 13,403 Views
article thumbnail
10 Goals Related to DevOps
Looking for a "DevOps Manifesto" to help guide your own organizational transiton? Well, there's no 'manifesto' out there like we have for Agile and SOA, but I think if you look around, you'll find that this commuity does have some well-defined, agreed-upon goals. In Kris Buytaert's presentation: "Devops, the future is here, it's just not evenly distributed yet" he gives a great 10 point summary of organizational goals from Edward Deming that coincide with what the DevOps movment is looking to achieve in IT organizations: Adopt the new philosophy. We are in a new economic age. Western management must awaken to the challenge, and must learn their responsibilities, and take on leadership for a change. Cease dependence on inspection to achieve quality. Eliminate the need for massive inspection by building quality into the product in the first place. Constantly improve your system of production and service, to improve quality and productivity, and thus constantly decrease costs. Institute training on the job. Institute leadership. The aim of supervision should be to help people and machines and gadgets to a better job. Drive out fear, so that everyone may work effectively for the company. Break down barriers between departments. People in research, design, sales, and production must work as a team in order to forsee problems of production and usage that may be encountered with the product or service. Eliminate slogans, exhortation, and targets for the work force; asking for zero defects and new levels of productivity. Such exhortations only create adversarial relationships, since the bulk of the causes of low quality and low productivity belong to the system and thus lie beyond the power of the work force. *Eliminate management by objective. Eliminate management by numbers and numerical goals. Instead substitute with leadership. *Remove barriers that rob the hourly worker of his/her right to pride of workmanship. The responsibility of supervisors must be changed from sheer numbers to quality. *Remove barriers that rob people in management and in engineering of their right to pride of workmanship. Institute a vigorous program of education and self-improvement. Put everybody in the company to work to accomplish the transformation. The transformation is everybody's job. On a more technical level, Kris says you need the following things to get to a point where your team can deploy at a moment's notice, quickly and safely: Version Control Continuous Integration Built Pipelines Bug Tracking Integrated Testing Automated Deployment Here are all of the slides from his presentation: Devops, the future is here, it's just not evenly distributed yet. View more presentations from Kris Buytaert
December 9, 2011
by Mitch Pronschinske
· 31,227 Views · 1 Like
article thumbnail
Zero Downtime – What is it and why is it important?
For most large web applications, uptime is of foremost importants. Any outage can be seen by customers as a frustration, or opportunity to move to a competitor. What's more for a site that also includes e-commerce, it can mean real lost sales. Zero Downtime describes a site without service interruption. To achieve such lofty goals, redundancy becomes a critical requirement at every level of your infrastructure. If you're using cloud hosting, are you redundant to alternate availability zones and regions? Are you using geographically distributed load balancing? Do you have multiple clustered databases on the backend, and multiple webservers load balanced. All of these requirements will increase uptime, but may not bring you close to zero downtime. For that you'll need thorough testing. The solution is to pull the trigger on sections of your infrastructure, and prove that it fails over quickly without noticeable outage. The ultimate test is the outage itself. Sean Hull on Quora: What is zero downtime and why is it important? Source: http://www.iheavy.com/2011/06/23/zero-downtime-what-is-it-and-why-is-it-important/
November 23, 2011
by Sean Hull
· 26,149 Views
article thumbnail
What Is CDI, How Does It Relate to @EJB And Spring?
A brief overview of dependency injection in Java EE, the difference between @Resource/@EJB and @Inject, and how does that all relate to Spring – mostly in the form of links. Context Dependency Injection (CDI, JSR 299) is a part of Java EE 6 Web Profile and itself builds on Dependency Injection for Java (JSR 330), which introduces @Inject, @Named etc. While JSR 330 is for DI only and is implemented e.g. by Guice and Spring, CDI adds various EE stuff such as @RequestScoped, interceptors/decorators, producers, eventing and a base for integration with JSF, EJBs etc. Java EE components such as EJBs have been redefined to build on top of CDI (=> @Stateless is now a CDI managed bean with additional services). A key part of CDI aside of its DI capabilities is its awarness of bean contexts and the management of bean lifecycle and dependencies within those contexts (such as @RequestScoped or @ConversationScoped). CDI is extensible – you can define new context scopes, drop-in interceptors and decorators, make other beans (e.g. from Spring) available for CDI,… . Resources to check: Contexts and Dependency Injection in Java EE 6 by Adam Bien – a very good explanation of the basics of CDI and how it differs from DI in Java EE 5 (hint: context awarness) Slideshow with a good overview of CDI and all it offers About CDI extensibility and SPIs (e.g. Seam 3 is basically a set of portable CDI extensions) Guice and Spring do not implement CDI (3/2011) – and Spring perhaps isn’t motivated to do so (it supports JSR 330, CDI would be too much work) DZone CDI Refcard may be handy CDI 1.0 vs. Spring 3.1 feature comparsion: bean definition & dependency injection: “in the area that I compared in this article [= DI], there is only little critical difference in the two technologies” (though Spring more fine-tunable) Java EE 6 (CDI / EJB 3.1) XOR Spring Core Reloaded: New projects should preferably start with pure Java EE including CDI and add Spring utilities such as JDBC/JMS when needed Oracle: CDI in the Java EE 6 Ecosystem – 62 pages slideshow, the stuff is explained more than in the previously mentioned slideshow Note: CDI 1.1 (JSR 346, Java EE 7) should have a standard way of bootstrapping it in non-EE environment (i.e. SE) From http://theholyjava.wordpress.com/2011/11/09/what-is-cdi-how-does-it-relate-to-ejb-and-spring/
November 12, 2011
by Jakub Holý
· 14,768 Views · 1 Like
article thumbnail
Dependency Injection for Dummies
Dependency injection is a very simple concept: if you have an object that interacts with other objects the responsibility of finding a reference to those objects at run time is moved outside of the object itself. What does it mean for an object to "interact" with other objects? Generally it means invoking methods or reading properties from those objects. So if we have a class A that invokes method Calculate on class B, we can say that A interacts with B. In the following example we show class A interacting with class B. We can equally say that A depends on class B to fulfill a responsibility. In this case, it not only invokes its method Calculate but it also creates a new instance of that class. class A { private B _b; public A { _b = new B(); } public int SomeMethod() { return (_b.Calculate() * 2); } } In the following example, on the other side, the responsibility of getting a reference to an implementation of a class of type B is moved outside of A: class A { private _b = B; public A(B b) { _b = b; } public int SomeMethod() { return _(b.Calculate * 2); } } In this case we say that a dependency (B) has been injected into A, via the constructor. Of course, you can also inject dependencies via a property (or even a regular method), like in the following example: class A { private _b = B; public B B { get { return _b; } set { _b = value; } } public int SomeMethod() { if (_b != null) return _b.RetrieveValue() * 2;} else // HANDLE THIS ERROR CASE return -1; } } So this is all there is about dependency injection. Everything else just builds on this core concept. Like for example Inversion Of Control (IoC) tools which helps you wiring together your objects at run time, injecting all dependencies as needed. So what exactly is Inversion of Control and how does it relate to Dependency Injection (DI)? I like to associate IoC to the Hollywood Principle: "Don't call us, we'll call you". IoC is a design principle where reusable generic code controls the execution of problem-specific code: it is a characteristic of many frameworks, where the application is built extending or customizing a common skeleton; you put your own classes at specific points and the framework will call you when needed. You can use an IoC container as a framework to perform Dependency Injection on your behalf: you tell the container which are the concrete implementation classes for your dependencies and the container will make sure that your constructors or setters will be called with the right objects. Therefore, IoC containers are just a convenience to simplify how dependency injection is handled. But even if you don't use one you could still manually perform dependency injection. (If you want to have a look at how an IoC container works you can jump to my mini tutorial on Ninject). Why is the concept of dependency injection important? Because by applying it, you simplify your design (separating the responsibility of using an object from the responsibility of using the object) and your code becomes much easier to test, since you can mock out the dependencies substituting them with fake (stub) objects. But that is the subject for another post.
November 8, 2011
by Stefano Ricciardi
· 11,082 Views · 28 Likes
article thumbnail
Just in Time Compiler (JIT) in Hotspot
What is JIT Compiler? The Just In Time Compiler (JIT) concept and more generally adaptive optimization is well known concept in many languages besides Java (.Net, Lua, JRuby). In order to explain what is JIT Compiler I want to start with a definition of compiler concept. According to wikipedia compiler is "a computer program that transforms the source language into another computer language (the target language)". We are all familiar with static java compiler (javac) that compiles human readable .java files to a byte code that can be interpreted by JVM - .class files. Then what does JIT compile? The answer will given a moment later after explanation of what is "Just in Time". According to most researches, 80% of execution time is spent in executing 20% of code. That would be great if there was a way to determine those 20% of code and to optimize them. That's exactly what JIT does - during runtime it gathers statistics, finds the "hot" code compiles it from JVM interpreted bytecode (that is stored in .class files) to a native code that is executed directly by Operating System and heavily optimizes it. Smallest compilation unit is single method. Compilation and statistics gathering is done in parallel to program execution by special threads. During statistics gathering the compiler makes hypotheses about code function and as the time passes tries to prove or to disprove them. If the hypothesis is dis-proven the code is deoptimized and recompiled again. The name "Hotspot" of Sun (Oracle) JVM is chosen because of the ability of this Virtual Machine to find "hot" spots in code. What optimizations does JIT? Let's look closely at more optimizations done by JIT. Inline methods - instead of calling method on an instance of the object it copies the method to caller code. The hot methods should be located as close to the caller as possible to prevent any overhead. Eliminate locks if monitor is not reachable from other threads Replace interface with direct method calls for method implemented only once to eliminate calling of virtual functions overhead Join adjacent synchronized blocks on the same object Eliminate dead code Drop memory write for non-volatile variables Remove prechecking NullPointerException and IndexOutOfBoundsException Et cetera When the Java VM invokes a Java method, it uses an invoker method as specified in the method block of the loaded class object. The Java VM has several invoker methods, for example, a different invoker is used if the method is synchronized or if it is a native method. The JIT compiler uses its own invoker. Sun production releases check the method access bit for value ACC_MACHINE_COMPILED to notify the interpreter that the code for this method has already been compiled and stored in the loaded class. JIT compiler compiles the method block into native code for this method and stores that in the code block for that method. Once the code has been compiled the ACC_MACHINE_COMPILED bit, which is used on the Sun platform, is set. How do we know what JIT is doing in our program and how can it be controlled? First of all to disable JIT Djava.compiler=NONE parameter can be used. There are 2 types of JIT compilers in Hotspot - one is used for client program and one for server (-server option in VM parameters). Program, running on server enjoys usually from more resources than program running on client and to server program top throughput is usually more important. Hence JIT in server is more resource consuming and gathering statistics takes more time to make the statistics more accurate. For client program gathering statics for a method lasts 1500 method calls, for server 15000. These default values can be changed by -XX:CompileThreshold=XXX VM parameter. In order to find out whether default value is good for you try enabling "XX:+PrintCompilation" and "-XX:-CITime" parameters that print JIT statistics and time CPU spent by JIT. Benchmarks Most of the benchmarks show that JITed code runs 10 to 20 times faster than interpreted code. There are many benchmarks done. Below given result graphs of two of them: Its worth to mention that programs that run in JIT mode, but are still in "learning mode" run much slower than non JITed programs. Drawbacks of JIT JIT Increases level of unpredictability and complexity in Java program. It adds another layer that developers don't really understand. Example of possible bugs - 'happens before relations" in concurrency. JIT can easily reorder code if the change is safe for a program running in single thread. To solve this problem developers make hints to JIT using "synchronized" word or explicit locking. Increases non heap memory footprint - JITed code is stored in "Code Cache" generation. Advanced JIT JIT and garbage collection. For GC to occur program must reach safe points. For this purpose JIT injects yieldpoints at regular intervals in native code. In addition to scanning of stack to find root references, registers must be scanned as they may hold objects created by JIT Comments are appresiated. The article can be found also at: artiomg.blogspot.com/2011/10/just-in-time-compiler-jit-in-hotspot.html
October 29, 2011
by Artiom Gourevitch
· 39,217 Views · 1 Like
  • Previous
  • ...
  • 582
  • 583
  • 584
  • 585
  • 586
  • 587
  • 588
  • 589
  • 590
  • 591
  • ...
  • 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
×