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 Languages Topics

article thumbnail
Approaches to XML - Part 4 - XMLBeans
If you remember from my previous blogs, I’m covering different approaches to parsing XML messages using the outrageously corny scenario of Pete’s Perfect Pizza, the pizza company with big ideas. In this story, you are an employee of Pete’s and have been asked to implement a system for sending orders from the front desk to the kitchen and you came up with the idea of using XML. You’ve just got your SAX Parser working, but Pete’s going global, opening kitchens around the world taking orders using the Internet. But, hang on a minute... didn’t I say this in my last blog? Déjà vu? Today’s blog is the alternative reality version of my JAXB blog as the scenario remains the same, but the solution changes. Instead of demonstrating JAXB, I’ll be investigating XMLBeans. So, Pete’s hired some consultants who’ve come up with a plan for extending your cosy XML message and they’ve specified it using a schema. They’ve also enhanced your message by adding in one of there own customer schemas. The result is that the following XSD files land in your inbox and you need to get busy... A wrapper around the customer and the pizza order This is a list of pizzas ordered by the customer The type of pizza on the menu type of base quantity of pizzas Plain and Simple Garlic Pizza... Ham and Musheroom with an egg thin base traditional Thick base The date is in the Common Era (minus sign in years is not permitted) The time zone although not included UTC is implied Generic Customer Definition The Customer's first name The Customer's surname The house number A line of an address You realise that with this level of complexity, you’ll be messing around with SAX for a long time, and you could also make a few mistakes. There must be a better way right? After-all XML has been around for some time, so there most be a few frameworks around that could be useful. After a bit more Googling you come across XMLBeans and realise that there are... XMLBeans uses a special compiler to convert an XML schema into a bunch of related Java classes that define the types required to access the XML elements, attributes and other content in a type-safe way. This blog isn’t a tutorial covering the ins and outs of XMLBeans, that can be found here, from Apache, except to say the the key idea for parsing, or unmarshalling, XML is that you compile your Java classes using XMLBeans and then use those classes in your application. In using any XML schema to Java class compiler, the neatest approach is to put all your schemas and the compiler in a separate JAR file. You can mix them in with your application’s source code, but that usually clouds the code base making maintenance more difficult. In creating a XMLBeans JAR file, you may come up with a POM file that looks something like this: 4.0.0 com.captaindebug xml-tips-xmlbeans jar 1.0-SNAPSHOT XML Beans for Pete's Perfect Pizza org.apache.xmlbeans xmlbeans 2.4.0 org.codehaus.mojo xmlbeans-maven-plugin xmlbeans true src/main/resources org.apache.maven.plugins maven-compiler-plugin 2.3.2 1.6 1.6 ...which is very straight forward. So, getting back to Pete’s Perfect Pizza, you’ve created your XMLBeans JAR file and all that’s left to do is to explore how it works, as demonstrated in the JUnit tests below: public class PizzaXmlBeansTest { private PizzaOrderDocument instance; @Test public void testLoadPizzaOrderXml() throws IOException, XmlException { String xml = loadResource("/pizza-order1.xml"); instance = PizzaOrderDocument.Factory.parse(xml); PizzaOrder order = instance.getPizzaOrder(); String orderId = order.getOrderID(); assertEquals("123w3454r5", orderId); // Check the customer details... CustomerType customerType = order.getCustomer(); NameType nameType = customerType.getName(); String firstName = nameType.getFirstName(); assertEquals("John", firstName); String lastName = nameType.getLastName(); assertEquals("Miggins", lastName); AddressType address = customerType.getAddress(); assertEquals(new BigInteger("15"), address.getHouseNumber()); assertEquals("Credability Street", address.getStreet()); assertEquals("Any Town", address.getTown()); assertEquals("Any Where", address.getArea()); assertEquals("AW12 3WS", address.getPostCode()); Pizzas pizzas = order.getPizzas(); PizzaType[] pizzasOrdered = pizzas.getPizzaArray(); assertEquals(3, pizzasOrdered.length); // Check the pizza order... for (PizzaType pizza : pizzasOrdered) { PizzaNameType.Enum pizzaName = pizza.getName(); if ((PizzaNameType.CAPRICCIOSA == pizzaName) || (PizzaNameType.MARINARA == pizzaName)) { assertEquals(BaseType.THICK, pizza.getBase()); assertEquals(new BigInteger("1"), pizza.getQuantity()); } else if (PizzaNameType.PROSCIUTTO_E_FUNGHI == pizzaName) { assertEquals(BaseType.THIN, pizza.getBase()); assertEquals(new BigInteger("2"), pizza.getQuantity()); } else { fail("Whoops, can't find pizza type"); } } } private String loadResource(String filename) throws IOException { InputStream is = getClass().getResourceAsStream(filename); if (is == null) { throw new IOException("Can't find the file: " + filename); } return toString(is); } private String toString(InputStream is) throws IOException { ByteArrayOutputStream bos = new ByteArrayOutputStream(); copyStreams(is, bos); return bos.toString(); } private void copyStreams(InputStream is, OutputStream os) throws IOException { byte[] buf = new byte[1024]; int c; while ((c = is.read(buf, 0, 1024)) != -1) { os.write(buf, 0, c); os.flush(); } } } The code above may look long and complex, but it really only comprises of three steps: firstly, turn the test file into a suitable type such as a String or InputStream (XMLBeans can handle several different input types). Then use the nested Factory class to process your XML source turning into a document object. Finally, use the returned document object to test that your results are what you'd expected them to be (this is by far the largest step). Once you’re happy with the largely boilerplate usage of XMLBeans, you add it into your Pete's Perfect Pizza kitchen XML parser code and distribute it around the world to Pete’s many pizza kitchens. One of the strong points of using a framework like XMLBeans is that if there’s ever a change to the schema, then all that’s required to incorporate those changes is to recompile, fixing up your client code accordingly. This may seem a bit of a headache, but it’s a much smaller headache than trying re-work a SAX parser. On the downside, XMLBeans has been criticised for being slow, but I’ve never had too many problems. It will theoretically use more memory that SAX - this may or may not be true - it does build sets of classes, but then again so do some SAX ContentHandler derived classes. Finally, it should be noted that there hasn’t been a release of XMLBeans since 2009, which may or may not be a good thing depending upon your viewpoint, though I should emphasized that this code certainly isn’t redundant as, to my certain knowledge, it is still widely used on a number of large scale projects. The source code is available from GitHub at: git://github.com/roghughe/captaindebug.git From http://www.captaindebug.com/2012/01/approaches-to-xml-part-4-xmlbeans.html
January 22, 2012
by Roger Hughes
· 9,588 Views
article thumbnail
Datatype Conversion in Java: XMLGregorianCalendar to java.util.Date / java.util.Date to XMLGregorianCalendar
package singz.test; import java.util.Date; import java.util.GregorianCalendar; import javax.xml.datatype.DatatypeConfigurationException; import javax.xml.datatype.DatatypeFactory; import javax.xml.datatype.XMLGregorianCalendar; /** * A utility class for converting objects between java.util.Date and * XMLGregorianCalendar types * */ public class XMLGregorianCalendarConversionUtil { // DatatypeFactory creates new javax.xml.datatype Objects that map XML // to/from Java Objects. private static DatatypeFactory df = null; static { try { df = DatatypeFactory.newInstance(); } catch(DatatypeConfigurationException e) { throw new IllegalStateException( "Error while trying to obtain a new instance of DatatypeFactory", e); } } // Converts a java.util.Date into an instance of XMLGregorianCalendar public static XMLGregorianCalendar asXMLGregorianCalendar(java.util.Date date) { if(date == null) { return null; } else { GregorianCalendar gc = new GregorianCalendar(); gc.setTimeInMillis(date.getTime()); return df.newXMLGregorianCalendar(gc); } } // Converts an XMLGregorianCalendar to an instance of java.util.Date public static java.util.Date asDate(XMLGregorianCalendar xmlGC) { if(xmlGC == null) { return null; } else { return xmlGC.toGregorianCalendar().getTime(); } } public static void main(String[] args) { Date currentDate = new Date(); // Current date // java.util.Date to XMLGregorianCalendar XMLGregorianCalendar xmlGC = XMLGregorianCalendarConversionUtil.asXMLGregorianCalendar( currentDate); System.out.println( "Current date in XMLGregorianCalendar format: " + xmlGC.toString()); // XMLGregorianCalendar to java.util.Date System.out.println( "Current date in java.util.Date format: " + XMLGregorianCalendarConversionUtil.asDate(xmlGC).toString()); } } Why do we need XMLGregorianCalendar? Java Architecture for XML Binding (JAXB) allows Java developers to map Java classes to XML representations. JAXB provides two main features: the ability to marshal Java objects into XML and the inverse, i.e. to unmarshal XML back into Java objects. In the default data type bindings i.e. mappings of XML Schema (XSD) data types to Java data types in JAXB, the following types in XML schema (mostly used in web services definition) – xsd:dateTime, xsd:time, xsd:date and so on map to javax.xml.datatype.XMLGregorianCalendar Java type. From http://singztechmusings.in/datatype-conversion-in-java-xmlgregoriancalendar-to-java-util-date-java-util-date-to-xmlgregoriancalendar/
January 21, 2012
by Singaram Subramanian
· 101,159 Views
article thumbnail
Java Garbage Collection Algorithm Design Choices And Metrics To Evaluate Garbage Collector Performance
Memory Management in the Java HotSpot Virtual Machine View more documents from white paper Serial vs Parallel With serial collection, only one thing happens at a time. For example, even when multiple CPUs are available, only one is utilized to perform the collection. When parallel collection is used, the task of garbage collection is split into parts and those subparts are executed simultaneously, on different CPUs. The simultaneous operation enables the collection to be done more quickly, at the expense of some additional complexity and potential fragmentation. Concurrent versus Stop-the-world When stop-the-world garbage collection is performed, execution of the application is completely suspended during the collection. Alternatively, one or more garbage collection tasks can be executed concurrently, that is, simultaneously, with the application. Typically, a concurrent garbage collector does most of its work concurrently, but may also occasionally have to do a few short stop-the-world pauses. Stop-the-world garbage collection is simpler than concurrent collection, since the heap is frozen and objects are not changing during the collection. Its disadvantage is that it may be undesirable for some applications to be paused. Correspondingly, the pause times are shorter when garbage collection is done concurrently, but the collector must take extra care, as it is operating over objects that might be updated at the same time by the application. This adds some overhead to concurrent collectors that affects performance and requires a larger heap size. Compacting versus Non-compacting versus Copying After a garbage collector has determined which objects in memory are live and which are garbage, it can compact the memory, moving all the live objects together and completely reclaiming the remaining memory. After compaction, it is easy and fast to allocate a new object at the first free location. A simple pointer can be utilized to keep track of the next location available for object allocation. In contrast with a compacting collector, a non-compacting collector releases the space utilized by garbage objects in-place, i.e., it does not move all live objects to create a large reclaimed region in the same way a compacting collector does. The benefit is faster completion of garbage collection, but the drawback is potential fragmentation. In general, it is more expensive to allocate from a heap with in-place deallocation than from a compacted heap. It may be necessary to search the heap for a contiguous area of memory sufficiently large to accommodate the new object. A third alternative is a copying collector, which copies (or evacuates) live objects to a different memory area. The benefit is that the source area can then be considered empty and available for fast and easy subsequent allocations, but the drawback is the additional time required for copying and the extra space that may be required. Performance Metrics Several metrics are utilized to evaluate garbage collector performance, including: Throughput—the percentage of total time not spent in garbage collection, considered over long periods of time. Garbage collection overhead—the inverse of throughput, that is, the percentage of total time spent in garbage collection. Pause time—the length of time during which application execution is stopped while garbage collection is occurring. Frequency of collection—how often collection occurs, relative to application execution. Footprint—a measure of size, such as heap size. Promptness—the time between when an object becomes garbage and when the memory becomes available. If you’d like to explore more on this and in general about Java’s garbage collection / memory management, have a look at these slides: Java Garbage Collection, Monitoring, and Tuning View more presentations from Carol McDonald Related articles Practical Garbage Collection – Part 1: Introduction (worldmodscode.wordpress.com) Reducing memory churn when processing large data set (stackoverflow.com) The Top Java Memory Problems – Part 2 (dynatrace.com) imabonehead: Performance Tuning the JVM for Running Apache Tomcat | TomcatExpert (tomcatexpert.com) When Does the Garbage Collector Run in JVM ? (javacircles.wordpress.com) Why Garbage Collection Paranoia is Still (sometimes) Justified (prog21.dadgum.com) Adventures in Java Garbage Collection Tuning (rapleaf.com) From http://singztechmusings.in/java-garbage-collection-algorithm-design-choices-and-metrics-to-evaluate-garbage-collector-performance/
January 19, 2012
by Singaram Subramanian
· 14,435 Views
article thumbnail
Make Your HTML5 Video Play on Mobile Devices
When I’m asked by web developers how they can get started with HTML5 Video, I ask them, “Why? What are you trying to solve?” Almost every time, I hear, “I just want my video to work on mobile devices.” Easy. I’ll show you how to get started. In most cases, the video content already exists in one format or another. A year and a half ago, I wrote about HTML5 video codecs and why I think H.264 is the clear leader. Nothing’s really changed. You still need to support a couple of codecs to be compatible with the full suite of modern desktop and mobile browsers, but as content creators, you get to decide how you want to encode your video content. Check out the IE Test Drive Video Format support page for some examples of how codecs work across different browsers. In reality, desktop browsers and web developers are happy to leave existing solutions in place to play existing video/audio content using plugins. That’s cool. Just supplement this with HTML5 Video and Audio tags if the browser is able to play your preferred codec natively. In my experience, the most popular mobile platforms—H.264, AAC, and MP3—are well supported using HTML5 Video and Audio Tags, which are already supported by what most people are already using. Ready to Go? Save Time, Development Cost, and Nerves. Start by learning about the Microsoft Media Platform (MMP), a frameworks are the glues together individual pieces of the Microsoft end-to-end media solution. The MMP: Player Framework (licensed for use under the Microsoft Public License Ms-PL) has recently added a preview of support for HTML5 (API Documentation) that lets you complement the Silverlight player framework with a HTML5 video experience and reach additional mobile platforms. Trust me, I have worked on a number of large-scale projects based on MMP (like the video platform behind the Rugby World Cup 2011). Two good commercial solutions that do all the work for you are JW Player™ (licensed for commercial use) and SublimeVideo® (Player as a Service). What If You Want to Roll Your Own Player? It’s surprisingly easy to roll your own video solution using default browser controls and codecs supported by the browser. The markup below shows what you need to play a video in HTML5 with a “Fall Back” to an unlisted video on YouTube. This WebMatrix is a lightweight IDE for building HTML5 mark-up. Use it—I find it handy. Demo Common Gotchas! 1. Video MIME types Set these on the server Azure Storage Explorer also allows you to do this on individual files. Update application/octet-stream to one of the following: .mp4 - “video/mp4″ .m4v - “video/m4v” .webm - “video/webm” .ogg - “application/ogg” .ogv - “video/ogg” Set these in the web.config 2. Fall-Back Fall-back content (like the YouTube example above) is only displayed by browsers that do not support the tag. If the browser supports the video tag but cannot play any of the media types you have requested, the fall-back code won’t fire. You’ll have to use JavaScript to detect this scenario using the canPlayType() method and provide fall-back content (shown below). Demo 3. Byte Range Requests (seeking) Content should be served from an HTTP 1.1-compatible web server to enable seek ahead to the end of the video. If your server is not HTTP 1.1-compatible (e.g. Azure Storage), you must encode the video with key index frames in the file and *not* at the end so that seek-ahead still works. The “H.264 YouTube HD” profile in Expression Encoder 4 Pro does this. NOTE: If the video file is gzipped, seeking won’t work. Since, with most codecs, the video/audio data is already compressed, gzip/deflate won't save you much bandwidth anyway. IIS also supports Bit Rate Throttling to save you bandwidth on the server side when delivering video content. Real-World Example I presented a session last week at Tech·Ed New Zealand, about a new video analysis system my buddies at NV Interactive, Gus and Zach, are creating for New Zealand Cricket. The solution uses video in wmv format and displays in a browser using Windows Media Plugin. This solution isn’t really supported cross platform, and it definitely doesn’t work on mobile devices. Gus and Zach are using H.264 and MediaElement.js to extend their video experience across a greater number of users and devices. Like the other commercial players, MediaElement.js uses the same HTML/CSS for all players. That means the HTML5 and Flash player experience looks the same for all users. Watch the video of the solution they’re working on: Where Does HTML5 Video Need to Go? There are currently a few key areas not addressed by the current W3C Video Standard (full screen support, live streaming, real-time communication, content protection, metadata, and accessibility). Recently, the W3C Web and TV Workshop covered these areas and offered some early thinking on how they may be adopted as web standards in the future. Live and adaptive streaming are the big topics for me. Currently, there are three proprietary solutions that support live and adaptive streaming we should pay attention to: Microsoft Smooth Streaming Apple HTTP Live Streaming Adobe HTTP Dynamic Streaming Dynamic Adaptive Streaming over HTTP (DASH) is currently in Draft International Standard. It looks likely that it will get W3C support if it is offered royalty free. DASH supports: Live, on-demand, and time-shifted content delivery and trick modes Splicing and ad insertion Byte-range requests Content descriptors for protection, accessibility, and rating What About Real-Time Communications? On HTML5Labs, you can find a Media Capture Audio Prototype that implements the audio portion of this W3C specification. HTML5 Labs is the site where Microsoft prototypes early and unstable specifications from web standards bodies such as W3C. Sharing these prototypes helps Microsoft have informed discussions with developer communities to provide better feedback on draft specifications based on this implementation experience. Their next prototype will support speech recognition and will implement the Microsoft proposal available on the W3C website. After that, the labs team will deliver another update to the Media Capture prototype that will add video capture capabilities. In Conclusion If you are hosting progressive download video and audio on the web, you should be looking to support HTML5 video and audio today to extend the reach of your content. More Resources 5 Things You Need to Know to Start Using and Today (my MIX conference presentation in Las Vegas) HTML5 Guide for Developers - video and audio Elements Simon Pieters - Everything you need to know about HTML5 video and audio Dive Into HTML5 - Video On The Web About the author Nigel Parker is an evangelist in the Developer and Platform Group at Microsoft New Zealand. He works with New Zealand software vendors helping them with the early adoption of web technologies. Nigel graduated from the University of Auckland with an honors degree in technology and philosophy. He has an entrepreneurial background and has numerous successful “start-ups” under his belt. He took some risks and broke some new ground during the first “.com” bubble and was one of the few that, despite losing money, didn’t lose heart for the unrealized potential of the tech industry. Source: http://msdn.microsoft.com/en-us/hh549238
January 18, 2012
by Nigel Parker
· 6,483 Views
article thumbnail
Shared Counter with Python’s Multiprocessing
One of the methods of exchanging data between processes with the multiprocessing module is directly shared memory via multiprocessing.Value. As any method that’s very general, it can sometimes be tricky to use. I’ve seen a variation of this question asked a couple of times on StackOverflow: I have some processes that do work, and I want them to increment some shared counter because [... some irrelevant reason ...] – how can this be done? The wrong way And surprisingly enough, some answers given to this question are wrong, since they use multiprocessing.Value incorrectly, as follows: import time from multiprocessing import Process, Value def func(val): for i in range(50): time.sleep(0.01) val.value += 1 if __name__ == '__main__': v = Value('i', 0) procs = [Process(target=func, args=(v,)) for i in range(10)] for p in procs: p.start() for p in procs: p.join() print v.value This code is a demonstration of the problem, distilling only the usage of the shared counter. A "pool" of 10 processes is created to run the func function. All processes share a Value and increment it 50 times. You would expect this code to eventually print 500, but in all likeness it won’t. Here’s some output taken from 10 runs of that code: > for i in {1..10}; do python sync_nolock_wrong.py; done 435 464 484 448 491 481 490 471 497 494 Why does this happen? I must admit that the documentation of multiprocessing.Value can be a bit confusing here, especially for beginners. It states that by default, a lock is created to synchronize access to the value, so one may be falsely led to believe that it would be OK to modify this value in any way imaginable from multiple processes. But it’s not. Explanation – the default locking done by Value This section is advanced and isn’t strictly required for the overall flow of the post. If you just want to understand how to synchronize the counter correctly, feel free to skip it. The locking done by multiprocessing.Value is very fine-grained. Value is a wrapper around a ctypes object, which has an underlying value attribute representing the actual object in memory. All Value does is ensure that only a single process or thread may read or write this value attribute simultaneously. This is important, since (for some types, on some architectures) writes and reads may not be atomic. I.e. to actually fill up the object’s memory, the CPU may need several instructions, and another process reading the same (shared) memory at the same time could see some intermediate, invalid state. The built-in lock of Value prevents this from happening. However, when we do this: val.value +=1 What Python actually performs is the following (disassembled bytecode with the dis module). I’ve annotated the locking done by Value in #<-- comments: 0 LOAD_FAST 0 (val) 3 DUP_TOP #<--- Value lock acquired 4 LOAD_ATTR 0 (value) #<--- Value lock released 7 LOAD_CONST 1 (1) 10 INPLACE_ADD 11 ROT_TWO #<--- Value lock acquired 12 STORE_ATTR 0 (value) #<--- Value lock released So it’s obvious that while process #1 is now at instruction 7 (LOAD_CONST), nothing prevents process #2 from also loading the (old) value attribute and be on instruction 7 too. Both processes will proceed incrementing their private copy and writing it back. The result: the actual value got incremented only once, not twice. The right way Fortunately, this problem is very easy to fix. A separate Lock is needed to guarantee the atomicity of modifications to the Value: import time from multiprocessing import Process, Value, Lock def func(val, lock): for i in range(50): time.sleep(0.01) with lock: val.value += 1 if __name__ == '__main__': v = Value('i', 0) lock = Lock() procs = [Process(target=func, args=(v, lock)) for i in range(10)] for p in procs: p.start() for p in procs: p.join() print v.value Now we get the expected result: > for i in {1..10}; do python sync_lock_right.py; done 500 500 500 500 500 500 500 500 500 500 A value and a lock may appear like too much baggage to carry around at all times. So, we can create a simple "synchronized shared counter" object to encapsulate this functionality: import time from multiprocessing import Process, Value, Lock class Counter(object): def __init__(self, initval=0): self.val = Value('i', initval) self.lock = Lock() def increment(self): with self.lock: self.val.value += 1 def value(self): with self.lock: return self.val.value def func(counter): for i in range(50): time.sleep(0.01) counter.increment() if __name__ == '__main__': counter = Counter(0) procs = [Process(target=func, args=(counter,)) for i in range(10)] for p in procs: p.start() for p in procs: p.join() print counter.value() Bonus: since we’ve now placed a more coarse-grained lock on the modification of the value, we may throw away Value with its fine-grained lock altogether, and just use multiprocessing.RawValue, that simply wraps a shared object without any locking. Source: http://eli.thegreenplace.net/2012/01/04/shared-counter-with-pythons-multiprocessing/
January 17, 2012
by Eli Bendersky
· 15,953 Views
article thumbnail
Python Hello World, for a web application
python -m SimpleHTTPServer is a very handy command that sets up a server listening on a port (by default 8080) having as document root the current directory. However it does not count for the purpose of this article: producing our first dynamic page with Python. We won't care a lot about the performance of various approaches or whether to adopt frameworks like Django: we are just getting started. Even when higher-level abstraction are introduced, we still have to know how the foundation of our house are made. Installation mod_python is an Apache module that bridges the Apache 2 httpd processes with the Python interpreter. You can install it on Ubuntu with a single command: sudo apt-get install libapache2-mod-python See the mod_python website for alternative ways of installation. In the words of its homepage, mod_python is a mature but not dead project: it requires very little maintenance due to its stability. It is of course built only for Apache, and exposes its API; in any case, it promises to be faster than CGI (who doesn't?) Apache configuration This configuration lines should made their way into your httpd.conf or in the other configuration files you have on your system: LoadModule python_module /usr/lib/apache2/modules/mod_python.so AddHandler mod_python .py PythonHandler hello PythonDebug On We loaded the .so file of the module: if you installed mod_python in a Linux distribution, this line should already be present (use the a2enmod command if it's not in the enabled/ directory). In Ubuntu, it's written in the /etc/apache2/mods-enabled/python.load file, where you can add the other lines. The rest of the configuration means that in the directory /var/www/python, we wwant to enable the processing of .py files by mod_python. The hello.py file will be targeted, unless you use a standard handler. PythonDebug On activates a nice stack trace visualization in the browser, in case of runtime errors. Without it, the production setting is to display a blank, generic 500 Server Error. Hello world Our Hello World it's easy to write: from mod_python import apache def handler(req): req.content_type = 'text/plain' req.write("Hello, World!") return apache.OK It's a bit strange that the Content-Type has to be specified on the request object, but there is no response object anyway: all interaction has to be performed on req. A bit less boilerplate? You can use a standard handler to simplify even more your .py files, by changing the configuration to this: PythonHandler mod_python.publisher Now the Hello World example becomes: from mod_python import apache def say(req): return "Hello, World!" and is displayed at http://localhost/python/hello.py/say. While the parameters are actually kept in the request object, you can specify them as required, named parameters: def say(req, name): return "Hello, " + name + "!" http://localhost/python/hello.py/say?name=Giorgio will display: Hello, Giorgio! Including other files import is the standard Python instruction for including other code into the current source file, usually with the form from module import entity. You can use it in your handlers, but you probably need to specify Python paths specific to each of them, to avoid that multiple application clash with each other: PythonPath "sys.path+['/var/python_code']" The string value of this directive should evaluate to a Python list containing all the folders to search for modules, just like sys.path originally does. To show you how it works, I can put this in /var/python_code/hello_lib.py: def say_to(name): return "Hello, " + name + "!" and micro-refactor my handler to: from mod_python import apache from hello_lib import say_to def say(req, name): return say_to(name) Conclusion Of course there's more to mod_python and to build real web applications: they have to manipulate cookies, the session API, and databases. Moreover, their configuration should access Apache internals, with directives for everything from importing automatically modules at the start of a request to setting up HTTP authentication. However, this article is about the HTTP-facing side of a web application. It's interesting to explore how the architecture on the server side works, so probably my next stop will be to try out a framework like Django to see which standard design choices it mades for us (and which may be questionable). In any case, we already have a Turing-complete entry point in our handlers, capable of linking to any Python source code. Resources The official mod_python documentation is long-winded but very good. The Style Guide for Python Code is a more general document that defines the coding standards for the whole Python world, while applying also to our web development scenario.
January 17, 2012
by Giorgio Sironi
· 37,718 Views
article thumbnail
Groovy DSL - A Simple Example
Domain Specific Languages (DSLs) have become a valuable part of the Groovy idiom. DSLs are used in native Groovy builders, Grails and GORM, and testing frameworks. To a developer, DSLs are consumable and understandable, which makes implementation more fluid compared to traditional programming. But how is a DSL implemented? How does it work behind the scenes? This article will demonstrate a simple DSL that can get a developer kickstarted on the basic concepts. What is a DSL DSL's are meant to target a particular type of problem. They are short expressive means of programming that fit well in a narrow context. For example with GORM, you can express hibernate mapping with a DSL rather than XML. static mapping = { table 'person' columns { name column:'name' } } Much of the theory for DSLs and the benefits they deliver are well documented. Refer to these sources as a starting point: Martin Fowler - DSL Writing Domain Specific Languages - Groovy Programming Groovy - Chapter 18 A Simple DSL Example in Groovy The following example offers a simplified view of implementing an internal DSL. Frameworks have much more advanced methods of creating a DSL. However this example does highlight closure delegation and meta object protocol concepts that are essential to understanding the inner workings of a DSL. Requirements Overview Imagine that a customer needs a memo generator. The memos needs to have a few simple fields, such as "to", "from", and "body". The memo can also have sections such as "Summary" or "Important." The summary fields are dynamic and can be anything on demand. In addition, the memo needs to be outputed in three formats: xml, html, and text. We elect to implement this as a DSL in Groovy. The DSL result looks like this: MemoDsl.make { to "Nirav Assar" from "Barack Obama" body "How are things? We are doing well. Take care" idea "The economy is key" request "Please vote for me" xml } The output from the code yields: Nirav Assar Barack Obama How are things? We are doing well. Take care The economy is key Please vote for me The last line in the DSL can also be changed to 'html' or 'text'. This affects the output format. Implementation A static method that accepts a closure is a hassle free way to implement a DSL. In the memo example, the class MemoDsl has a make method. It creates an instance and delegates all calls in the closure to the instance. This is the mechanism where the "to", and "from" sections end up executing methods inside the MemoDsl class. Once the to() method is called, we store the text in the instance for formatting later on. class MemoDsl { String toText String fromText String body def sections = [] /** * This method accepts a closure which is essentially the DSL. Delegate the * closure methods to * the DSL class so the calls can be processed */ def static make(closure) { MemoDsl memoDsl = new MemoDsl() // any method called in closure will be delegated to the memoDsl class closure.delegate = memoDsl closure() } /** * Store the parameter as a variable and use it later to output a memo */ def to(String toText) { this.toText = toText } def from(String fromText) { this.fromText = fromText } def body(String bodyText) { this.body = bodyText } } Dynamic Sections When the closure includes a method that is not present in the MemoDsl class, groovy identifies it as a missing method. With Groovy's meta object protocol, the methodMissing interface on the class is invoked. This is how we handle sections for the memo. In the client code above we have entries for idea and request. MemoDsl.make { to "Nirav Assar" from "Barack Obama" body "How are things? We are doing well. Take care" idea "The economy is key" request "Please vote for me" xml } The sections are processed with the following code in MemoDsl. It creates a section class and appends it to a list in the instance. /** * When a method is not recognized, assume it is a title for a new section. Create a simple * object that contains the method name and the parameter which is the body. */ def methodMissing(String methodName, args) { def section = new Section(title: methodName, body: args[0]) sections << section } Processing Various Outputs Finally the most interesting part of the DSL is how we process the various outputs. The final line in the closure specifies the output desired. When a closure contains a string such as "xml" with no parameters, groovy assumes this is a 'getter' method. Thus we need to implement 'getXml()' to catch the delegation execution: /** * 'get' methods get called from the dsl by convention. Due to groovy closure delegation, * we had to place MarkUpBuilder and StringWrite code in a static method as the delegate of the closure * did not have access to the system.out */ def getXml() { doXml(this) } /** * Use markupBuilder to create a customer xml output */ private static doXml(MemoDsl memoDsl) { def writer = new StringWriter() def xml = new MarkupBuilder(writer) xml.memo() { to(memoDsl.toText) from(memoDsl.fromText) body(memoDsl.body) // cycle through the stored section objects to create an xml tag for (s in memoDsl.sections) { "$s.title"(s.body) } } println writer } The code for html and text is quite similar. The only variation is how the output is formatted. Entire Code The code in its entirety is displayed next. The best approach I found was to design the DSL client code and the specified formats first, then tackle the implementation. I used TDD and JUnit to drive my implementation. Note that I did not go the extra mile to do asserts on the system output in the tests, although this could be easily enhanced to do so. The code is fully executable inside any IDE. Run the various tests to view the DSL output. package com.solutionsfit.dsl.memotemplate class MemolDslTest extends GroovyTestCase { void testDslUsage_outputXml() { MemoDsl.make { to "Nirav Assar" from "Barack Obama" body "How are things? We are doing well. Take care" idea "The economy is key" request "Please vote for me" xml } } void testDslUsage_outputHtml() { MemoDsl.make { to "Nirav Assar" from "Barack Obama" body "How are things? We are doing well. Take care" idea "The economy is key" request "Please vote for me" html } } void testDslUsage_outputText() { MemoDsl.make { to "Nirav Assar" from "Barack Obama" body "How are things? We are doing well. Take care" idea "The economy is key" request "Please vote for me" text } } } package com.solutionsfit.dsl.memotemplate import groovy.xml.MarkupBuilder /** * Processes a simple DSL to create various formats of a memo: xml, html, and text */ class MemoDsl { String toText String fromText String body def sections = [] /** * This method accepts a closure which is essentially the DSL. Delegate the closure methods to * the DSL class so the calls can be processed */ def static make(closure) { MemoDsl memoDsl = new MemoDsl() // any method called in closure will be delegated to the memoDsl class closure.delegate = memoDsl closure() } /** * Store the parameter as a variable and use it later to output a memo */ def to(String toText) { this.toText = toText } def from(String fromText) { this.fromText = fromText } def body(String bodyText) { this.body = bodyText } /** * When a method is not recognized, assume it is a title for a new section. Create a simple * object that contains the method name and the parameter which is the body. */ def methodMissing(String methodName, args) { def section = new Section(title: methodName, body: args[0]) sections << section } /** * 'get' methods get called from the dsl by convention. Due to groovy closure delegation, * we had to place MarkUpBuilder and StringWrite code in a static method as the delegate of the closure * did not have access to the system.out */ def getXml() { doXml(this) } def getHtml() { doHtml(this) } def getText() { doText(this) } /** * Use markupBuilder to create a customer xml output */ private static doXml(MemoDsl memoDsl) { def writer = new StringWriter() def xml = new MarkupBuilder(writer) xml.memo() { to(memoDsl.toText) from(memoDsl.fromText) body(memoDsl.body) // cycle through the stored section objects to create an xml tag for (s in memoDsl.sections) { "$s.title"(s.body) } } println writer } /** * Use markupBuilder to create an html xml output */ private static doHtml(MemoDsl memoDsl) { def writer = new StringWriter() def xml = new MarkupBuilder(writer) xml.html() { head { title("Memo") } body { h1("Memo") h3("To: ${memoDsl.toText}") h3("From: ${memoDsl.fromText}") p(memoDsl.body) // cycle through the stored section objects and create uppercase/bold section with body for (s in memoDsl.sections) { p { b(s.title.toUpperCase()) } p(s.body) } } } println writer } /** * Use markupBuilder to create an html xml output */ private static doText(MemoDsl memoDsl) { String template = "Memo\nTo: ${memoDsl.toText}\nFrom: ${memoDsl.fromText}\n${memoDsl.body}\n" def sectionStrings ="" for (s in memoDsl.sections) { sectionStrings += s.title.toUpperCase() + "\n" + s.body + "\n" } template += sectionStrings println template } }
January 17, 2012
by Nirav Assar
· 100,320 Views · 2 Likes
article thumbnail
Mocking of 'Open' as a Context Manager Made Simple In Python
Using open as a context manager is a great way to ensure your file handles are closed properly and is becoming common: with open('/some/path', 'w') as f: f.write('something') The issue is that even if you mock out the call to open it is the returned object that is used as a context manager (and has __enter__ and __exit__ called). Using MagicMock from the mock library, we can mock out context managers very simply. However, mocking open is fiddly enough that a helper function is useful. Here mock_open creates and configures a MagicMock that behaves as a file context manager. from mock import inPy3k, MagicMock if inPy3k: file_spec = ['_CHUNK_SIZE', '__enter__', '__eq__', '__exit__', '__format__', '__ge__', '__gt__', '__hash__', '__iter__', '__le__', '__lt__', '__ne__', '__next__', '__repr__', '__str__', '_checkClosed', '_checkReadable', '_checkSeekable', '_checkWritable', 'buffer', 'close', 'closed', 'detach', 'encoding', 'errors', 'fileno', 'flush', 'isatty', 'line_buffering', 'mode', 'name', 'newlines', 'peek', 'raw', 'read', 'read1', 'readable', 'readinto', 'readline', 'readlines', 'seek', 'seekable', 'tell', 'truncate', 'writable', 'write', 'writelines'] else: file_spec = file def mock_open(mock=None, data=None): if mock is None: mock = MagicMock(spec=file_spec) handle = MagicMock(spec=file_spec) handle.write.return_value = None if data is None: handle.__enter__.return_value = handle else: handle.__enter__.return_value = data mock.return_value = handle return mock >>> m = mock_open() >>> with patch('__main__.open', m, create=True): ... with open('foo', 'w') as h: ... h.write('some stuff') ... >>> m.assert_called_once_with('foo', 'w') >>> m.mock_calls [call('foo', 'w'), call().__enter__(), call().write('some stuff'), call().__exit__(None, None, None)] >>> handle = m() >>> handle.write.assert_called_once_with('some stuff') And for reading files, using a StringIO to represent the file handle: >>> from StringIO import StringIO >>> m = mock_open(data=StringIO('foo bar baz')) >>> with patch('__main__.open', m, create=True): ... with open('foo') as h: ... result = h.read() ... >>> m.assert_called_once_with('foo') >>> assert result == 'foo bar baz' Note that the StringIO will only be used for the data if open is used as a context manager. If you just configure and use mocks they will work whichever way open is used. This helper function will be built into mock 0.9. Source: http://www.voidspace.org.uk/python/weblog/arch_d7_2012_01_07.shtml
January 15, 2012
by Michael Foord
· 18,152 Views
article thumbnail
From Java to Node.js
I’ve been developing for quite a while and in quite a few languages. Somehow though, I’ve always seemed to fall back to Java when doing my own stuff – maybe partly from habit, partly because it has in my opinion the best open source selection out there, and party because I liked its mix of features and performance. Originally authored by Matan Amir Specifically though, in the web arena things have been moving fast and furious with new languages, approaches, and methods like RoR, Play!, and Lift (and many others!). While I “get it” regarding the benefits of these frameworks, I never felt the need to give them more than an initial deep dive to see how they work. I nod a few times at their similarities and move on back to plain REST-ful services in Java with Spring, maybe an ORM (i try to avoid them these days), and a JS-rich front-end. Recently, two factors made me deep dive into Node.js. First is my growing appreciation with the progress of the JavaScript front-end. What used to be little JavaScript snippets to validate a form “onSubmit” have evolved to a complete ecosystem of technologies, frameworks, and stacks. My personal favorite these days is Backbone.js and try to use it whenever I can. Second was the first hand feedback I got from a friend at Voxer about their success in using and deploying Node.js at real scale (they have a pretty big Node.js deployment). So I jumped in. In the short time I’ve been using it for some (real) projects, I can say that it’s my new favorite language of choice. First of all, the event-driven (and non-blocking) model is a perfect fit for server side development. While this has existed in the other languages and forms (Java Servlet 3.0, Event Machine, Twisted to name a few), I connected with the easy of use and natural maturity of it in JavaScript. We’re all used to using callbacks anyway from your typical run-of-the-mill AJAX work right? Second is the community and how large its gotten in the short time Node has been around. There are lots of useful open source libraries to use to solve your problems and the quality level is high. Third is that it was just so easy to pick up. I have to admit that my core JavaScript was decent before I started using Node, but in terms of the Node core library and feature set itself, it’s pretty lean and mean and provides a good starting point to build what you need in case you can’t find someone who already did (which you most likely can). So having said all that, I wanted to share what resources helped me get up to speed in Node.js coming from a Java background. Getting to know JavaScript There are lots of good resources out there on Node.js and i’ve listed them below. For me, the most critical piece was getting my JavaScript knowledge to the next level. Because you’ll be spending all your time writing your server code in JavaScript, it pays huge dividends to understand how to take full advantage of it. As a Java developer you’re probably trained to think in OO designs. With me, this was the part that I focused the most on. Fortunately (or unforunately), JavaScript is not a classic OO language. It can be if you shoehorn it, but i think that defeats the purpose. Here is my short list of JavaScript resources: JavaScript: The Good Parts - Definitely a requirement. Chapters 4 and 5 (functions, objects, and inheritance) are probably the most important part to understand well for those with an OO background. Learning Javascript with Object Graphs (part 2, and part 3) – howtonode.org has lots of good Node material, but this 3 part post is a good resource to top off your knowledge from the book. Simple “Class” Instantiation – Another good post I read recently. Worth digesting. Learning Node.js With a good JavaScript background, starting to use Node.js is pretty straightforward. The main part to understand is the asynchronous nature of the I/O and the need to produce and consume events to get stuff done. Here is a list of resources I used to get up to speed: DailyJS’s Node Tutorial - A multipart tutorial for Node on DailyJS’s blog. It’s a great resource and worth going through all the posts. Mixu’s Node Book - Not complete, but still worth it. I look forward to reading the future chapters. Node Beginner Book – A good starter read. How To Node – A blog dedicated to Node.js. Bookmark it. I felt that going through these was more than enough to give me the push I needed get started. Hopefully it does for you too (thanks to the authors for taking the time to share their knowledge!). Frameworks? Java is all about open source frameworks. That’s part of why it’s so popular. While Node.js is much newer, lots of people have already done quite a bit of heavy-lifting and have shared their code with the world. Below is what I think is a good mapping of popular Java frameworks to their Node.js equivalents (from what I know so far). Web MVC In Java land, most people are familiar with Web MVC frameworks like Spring MVC, Struts, Wicket, and JSF. More recently though, the trend towards client-side JS MVC frameworks like Ember.js (SproutCore) and Backbone.js reduces the required feature-set of some of these frameworks. Nonetheless, a good comparable Node.js web framework is Express. In a sense, it’s even more than a web framework because it also provides most of the “web server” functionality most Java developers are used to through Tomcat, Jetty, etc (more specifically, Express builds on top of Connect) It’s well thought out and provides the feature set needed to get things done. Application Lifecycle Framework (DI Framework) Spring is a popular framework in Java to provide a great deal of glue and abstraction functionality. It allows easy dependency injection, testing, object lifecycle management, transaction management, etc. It’s usually one of the first things I slap into a new project in Java. In Node.js… I haven’t really missed it. JavaScript allows much more flexible ways of decoupling dependencies and I personally haven’t felt the need to find a replacement for Spring. Maybe that’s a good thing? Object-Relational Mapping (ORMs) I have mixed feelings regarding ORMs in general, but it does make your life easier sometimes. There is no shortage of ORM librares for Node.js. Take your pick. Package Management Tools Maven is probably most popular build management tool for Java. While it is very flexible and powerful with a wide variety of plug-ins, it can get very cumbersome. Npm is the mainstream package manager for Node.js. It’s light, fast, and useful. Testing Framework Java has lots of these for sure, jUnit and company as standard. There are also mock libraries, stub libraries, db test libraries, etc. Node.js has quite a few as well. Pick your poison. I see that nodeunit is popular and is similar to jUnit. I’m personally testing Mocha. Testing tools are a more personal and subjective choice, but the good thing is that there definitely are good choices out there. Logging Java developers have quite a list of choices when choosing a logger library. Commons logging, log4j, logback, and slf4j (wrapper) are some of the more popular ones. Node.js also has a few. I’m currently using winston and have no complaints so far. It has the logging levels, multiple transports (appenders to log4j people), and does it all asynchronously as well. Hopefully this will help someone save some time when peeking into the world of Node. Good luck! Source: http://n0tw0rthy.wordpress.com/2012/01/08/from-java-to-node-js/
January 10, 2012
by Chris Smith
· 28,795 Views · 2 Likes
article thumbnail
Object-oriented Clojure
Clojure is a LISP dialect, and as such a functional language based on a large set of functions and a small set of data structures that they operate with. However, it is possible to implement classes and object in Clojure, with constructs well-supported in the language itself. I do not claim you should program in Clojure only with the techniques described in this article: they are just an attempt to bridge Java libraries with Clojure, and to introduce objects and interfaces where needed. Java interoperability Even from the Clojure REPL, you can easily instantiate Java classes as long as they are in the classpath (so use lein if they are in a library) (def ford (Car. arg1 arg2)) Since classes usually reside into packages, in real code you would use their fully qualified name: (def ford (com.dzone.example.Car. arg1 arg2)) You can also call methods: (.brake ford arg1 arg2) The first argument of the evaluation of a .methodName is always the object, while additional arguments are placed after it, in the same s-expression (a fancy name for a list that can be evaluated.) One of the first exercises in the book The Joy of Clojure is an instantiation of a java.awt.Frame object and a rendering done on it, all from the Clojure interactive interpreter. Doing exploratory testing classes and objects for Java development with the REPL is as faster as writing code into JUnit test. Define your own: interfaces defprotocol takes as the first argument an identifier, and a variable number of parameters. Each of this parameters is a method definition like you would do with fn, but without the fn keyword itself and a body to evaluate. The first argument of the methods should always be this, representing the current object (remember Python?). (defprotocol Position (description [this]) (translateX [this dx]) (translateY [this dy]) (doubleCoords [this]) (average [this another])) Define your own: classes Defining classes in Clojure is simple, at least when they implement immutable Value Objects. defrecord takes a class name, a list of parameters for the constructor, an optional protocol name and a variable number of arguments representing the methods. Again, the methods definition are similar to the ones made with fn, but this time with a body, an s-expression to evaluate. There is a catch: you can only implement methods defined in a protocol. (defrecord CartesianPoint [x y] Position (description [this] (str "(x=" x ", y=" y ")")) (translateX [this dx] (CartesianPoint. (+ x dx) y)) (translateY [this dy] (CartesianPoint. x (+ y dy))) (doubleCoords [this] (CartesianPoint. (* 2 x) (* 2 y))) (average [this another] (let [mean (fn [a b] (/ (+ a b) 2))] (CartesianPoint. (mean x (:x another)) (mean y (:y another)))))) The method access the (immutable) fields of the current object with their names, so this is not probably necessary if not for calling other methods on the object. Note that records are not strictly objects in the OO sense, since they do not encapsulate their fields: fields can be accessed anywhere with (:fieldname object). Here's how to work with CartesianPoint objects: (deftest test-point-x-field (is (= 1 (:x (CartesianPoint. 1 2))))) (deftest test-point-y-field (is (= 2 (:y (CartesianPoint. 1 2))))) (deftest test-point-to-string (is (= "(x=1, y=2)" (description (CartesianPoint. 1 2))))) (deftest test-point-translation-x (is (= (CartesianPoint. 11 2) (translateX (CartesianPoint. 1 2) 10)))) (deftest test-point-translation-y (is (= (CartesianPoint. 1 12) (translateY (CartesianPoint. 1 2) 10)))) (deftest test-point-doubling (is (= (CartesianPoint. 2 4) (doubleCoords (CartesianPoint. 1 2))))) (deftest test-points-average (is (= (CartesianPoint. 3 4) (average (CartesianPoint. 1 2) (CartesianPoint. 5 6)))))
January 10, 2012
by Giorgio Sironi
· 13,781 Views · 2 Likes
article thumbnail
Java Sequential IO Performance
Many applications record a series of events to file-based storage for later use. This can be anything from logging and auditing, through to keeping a transaction redo log in an event sourced design or its close relative CQRS. Java has a number of means by which a file can be sequentially written to, or read back again. This article explores some of these mechanisms to understand their performance characteristics. For the scope of this article I will be using pre-allocated files because I want to focus on performance. Constantly extending a file imposes a significant performance overhead and adds jitter to an application resulting in highly variable latency. "Why is a pre-allocated file better performance?", I hear you ask. Well, on disk a file is made up from a series of blocks/pages containing the data. Firstly, it is important that these blocks are contiguous to provide fast sequential access. Secondly, meta-data must be allocated to describe this file on disk and saved within the file-system. A typical large file will have a number of "indirect" blocks allocated to describe the chain of data-blocks containing the file contents that make up part of this meta-data. I'll leave it as an exercise for the reader, or maybe a later article, to explore the performance impact of not preallocating the data files. If you have used a database you may have noticed that it preallocates the files it will require. The Test I want to experiment with 2 file sizes. One that is sufficiently large to test sequential access, but can easily fit in the file-system cache, and another that is much larger so that the cache subsystem is forced to retire pages so that new ones can be loaded. For these two cases I'll use 400MB and 8GB respectively. I'll also loop over the files a number of times to show the pre and post warm-up characteristics. I'll test 4 means of writing and reading back files sequentially: RandomAccessFile using a vanilla byte[] of page size. Buffered FileInputStream and FileOutputStream. NIO FileChannel with ByteBuffer of page size. Memory mapping a file using NIO and direct MappedByteBuffer. The tests are run on a 2.0Ghz Sandybridge CPU with 8GB RAM, an Intel 230 SSD on Fedora Core 15 64-bit Linux with an ext4 file system, and Oracle JDK 1.6.0_30. The Code import java.io.*; import java.nio.ByteBuffer; import java.nio.MappedByteBuffer; import java.nio.channels.FileChannel; import static java.lang.Integer.MAX_VALUE; import static java.lang.System.out; import static java.nio.channels.FileChannel.MapMode.READ_ONLY; import static java.nio.channels.FileChannel.MapMode.READ_WRITE; public final class TestSequentialIoPerf { public static final int PAGE_SIZE = 1024 * 4; public static final long FILE_SIZE = PAGE_SIZE * 2000L * 1000L; public static final String FILE_NAME = "test.dat"; public static final byte[] BLANK_PAGE = new byte[PAGE_SIZE]; public static void main(final String[] arg) throws Exception { preallocateTestFile(FILE_NAME); for (final PerfTestCase testCase : testCases) { for (int i = 0; i < 5; i++) { System.gc(); long writeDurationMs = testCase.test(PerfTestCase.Type.WRITE, FILE_NAME); System.gc(); long readDurationMs = testCase.test(PerfTestCase.Type.READ, FILE_NAME); long bytesReadPerSec = (FILE_SIZE * 1000L) / readDurationMs; long bytesWrittenPerSec = (FILE_SIZE * 1000L) / writeDurationMs; out.format("%s\twrite=%,d\tread=%,d bytes/sec\n", testCase.getName(), bytesWrittenPerSec, bytesReadPerSec); } } deleteFile(FILE_NAME); } private static void preallocateTestFile(final String fileName) throws Exception { RandomAccessFile file = new RandomAccessFile(fileName, "rw"); for (long i = 0; i < FILE_SIZE; i += PAGE_SIZE) { file.write(BLANK_PAGE, 0, PAGE_SIZE); } file.close(); } private static void deleteFile(final String testFileName) throws Exception { File file = new File(testFileName); if (!file.delete()) { out.println("Failed to delete test file=" + testFileName); out.println("Windows does not allow mapped files to be deleted."); } } public abstract static class PerfTestCase { public enum Type { READ, WRITE } private final String name; private int checkSum; public PerfTestCase(final String name) { this.name = name; } public String getName() { return name; } public long test(final Type type, final String fileName) { long start = System.currentTimeMillis(); try { switch (type) { case WRITE: { checkSum = testWrite(fileName); break; } case READ: { final int checkSum = testRead(fileName); if (checkSum != this.checkSum) { final String msg = getName() + " expected=" + this.checkSum + " got=" + checkSum; throw new IllegalStateException(msg); } break; } } } catch (Exception ex) { ex.printStackTrace(); } return System.currentTimeMillis() - start; } public abstract int testWrite(final String fileName) throws Exception; public abstract int testRead(final String fileName) throws Exception; } private static PerfTestCase[] testCases = { new PerfTestCase("RandomAccessFile") { public int testWrite(final String fileName) throws Exception { RandomAccessFile file = new RandomAccessFile(fileName, "rw"); final byte[] buffer = new byte[PAGE_SIZE]; int pos = 0; int checkSum = 0; for (long i = 0; i < FILE_SIZE; i++) { byte b = (byte)i; checkSum += b; buffer[pos++] = b; if (PAGE_SIZE == pos) { file.write(buffer, 0, PAGE_SIZE); pos = 0; } } file.close(); return checkSum; } public int testRead(final String fileName) throws Exception { RandomAccessFile file = new RandomAccessFile(fileName, "r"); final byte[] buffer = new byte[PAGE_SIZE]; int checkSum = 0; int bytesRead; while (-1 != (bytesRead = file.read(buffer))) { for (int i = 0; i < bytesRead; i++) { checkSum += buffer[i]; } } file.close(); return checkSum; } }, new PerfTestCase("BufferedStreamFile") { public int testWrite(final String fileName) throws Exception { int checkSum = 0; OutputStream out = new BufferedOutputStream(new FileOutputStream(fileName)); for (long i = 0; i < FILE_SIZE; i++) { byte b = (byte)i; checkSum += b; out.write(b); } out.close(); return checkSum; } public int testRead(final String fileName) throws Exception { int checkSum = 0; InputStream in = new BufferedInputStream(new FileInputStream(fileName)); int b; while (-1 != (b = in.read())) { checkSum += (byte)b; } in.close(); return checkSum; } }, new PerfTestCase("BufferedChannelFile") { public int testWrite(final String fileName) throws Exception { FileChannel channel = new RandomAccessFile(fileName, "rw").getChannel(); ByteBuffer buffer = ByteBuffer.allocate(PAGE_SIZE); int checkSum = 0; for (long i = 0; i < FILE_SIZE; i++) { byte b = (byte)i; checkSum += b; buffer.put(b); if (!buffer.hasRemaining()) { channel.write(buffer); buffer.clear(); } } channel.close(); return checkSum; } public int testRead(final String fileName) throws Exception { FileChannel channel = new RandomAccessFile(fileName, "rw").getChannel(); ByteBuffer buffer = ByteBuffer.allocate(PAGE_SIZE); int checkSum = 0; while (-1 != (channel.read(buffer))) { buffer.flip(); while (buffer.hasRemaining()) { checkSum += buffer.get(); } buffer.clear(); } return checkSum; } }, new PerfTestCase("MemoryMappedFile") { public int testWrite(final String fileName) throws Exception { FileChannel channel = new RandomAccessFile(fileName, "rw").getChannel(); MappedByteBuffer buffer = channel.map(READ_WRITE, 0, Math.min(channel.size(), MAX_VALUE)); int checkSum = 0; for (long i = 0; i < FILE_SIZE; i++) { if (!buffer.hasRemaining()) { buffer = channel.map(READ_WRITE, i, Math.min(channel.size() - i , MAX_VALUE)); } byte b = (byte)i; checkSum += b; buffer.put(b); } channel.close(); return checkSum; } public int testRead(final String fileName) throws Exception { FileChannel channel = new RandomAccessFile(fileName, "rw").getChannel(); MappedByteBuffer buffer = channel.map(READ_ONLY, 0, Math.min(channel.size(), MAX_VALUE)); int checkSum = 0; for (long i = 0; i < FILE_SIZE; i++) { if (!buffer.hasRemaining()) { buffer = channel.map(READ_WRITE, i, Math.min(channel.size() - i , MAX_VALUE)); } checkSum += buffer.get(); } channel.close(); return checkSum; } }, }; } Results 400MB file =========== RandomAccessFile write=379,610,750 read=1,452,482,269 bytes/sec RandomAccessFile write=294,041,636 read=1,494,890,510 bytes/sec RandomAccessFile write=250,980,392 read=1,422,222,222 bytes/sec RandomAccessFile write=250,366,748 read=1,388,474,576 bytes/sec RandomAccessFile write=260,394,151 read=1,422,222,222 bytes/sec BufferedStreamFile write=98,178,331 read=286,433,566 bytes/sec BufferedStreamFile write=100,244,738 read=288,857,545 bytes/sec BufferedStreamFile write=82,948,562 read=154,100,827 bytes/sec BufferedStreamFile write=108,503,311 read=153,869,271 bytes/sec BufferedStreamFile write=113,055,478 read=152,608,047 bytes/sec BufferedChannelFile write=388,246,445 read=358,041,958 bytes/sec BufferedChannelFile write=390,467,111 read=375,091,575 bytes/sec BufferedChannelFile write=321,759,622 read=1,539,849,624 bytes/sec BufferedChannelFile write=318,259,518 read=1,539,849,624 bytes/sec BufferedChannelFile write=322,265,932 read=1,534,082,397 bytes/sec MemoryMappedFile write=300,955,180 read=305,899,925 bytes/sec MemoryMappedFile write=313,149,847 read=310,538,286 bytes/sec MemoryMappedFile write=326,374,501 read=303,857,566 bytes/sec MemoryMappedFile write=327,680,000 read=304,535,315 bytes/sec MemoryMappedFile write=326,895,450 read=303,632,320 bytes/sec 8GB File ============ RandomAccessFile write=167,402,321 read=251,922,012 bytes/sec RandomAccessFile write=193,934,802 read=257,052,307 bytes/sec RandomAccessFile write=192,948,159 read=248,460,768 bytes/sec RandomAccessFile write=191,814,180 read=245,225,408 bytes/sec RandomAccessFile write=190,635,762 read=275,315,073 bytes/sec BufferedStreamFile write=154,823,102 read=248,355,313 bytes/sec BufferedStreamFile write=152,083,913 read=253,418,301 bytes/sec BufferedStreamFile write=133,099,369 read=146,056,197 bytes/sec BufferedStreamFile write=131,065,708 read=146,217,827 bytes/sec BufferedStreamFile write=132,694,052 read=148,116,004 bytes/sec BufferedChannelFile write=406,147,744 read=304,693,892 bytes/sec BufferedChannelFile write=397,457,668 read=298,183,671 bytes/sec BufferedChannelFile write=364,672,364 read=414,281,379 bytes/sec BufferedChannelFile write=371,266,711 read=404,343,534 bytes/sec BufferedChannelFile write=373,705,579 read=406,934,578 bytes/sec MemoryMappedFile write=123,023,322 read=231,530,156 bytes/sec MemoryMappedFile write=121,961,023 read=230,403,600 bytes/sec MemoryMappedFile write=123,317,778 read=229,899,250 bytes/sec MemoryMappedFile write=121,472,738 read=231,739,745 bytes/sec MemoryMappedFile write=120,362,615 read=231,190,382 bytes/sec Analysis For years I was a big fan of using RandomAccessFile directly because of the control it gives and the predictable execution. I never found using buffered streams to be useful from a performance perspective and this still seems to be the case. In more recent testing I've found that using NIO FileChannel and ByteBuffer are the clear winners from a performance perspective. With Java 7 the flexibility of this programming approach has been improved for random access with SeekableByteChannel. I've seen these results vary greatly depending on platform. File system, OS, storage devices, and available memory all have a significant impact. In a few cases I've seen memory-mapped files perform significantly better than the others but this needs to be tested on your platform because your mileage may vary... A special note should be made for the use of memory-mapped large files when pushing for maximum throughput. I've often found the OS can become unresponsive due the the pressure put on the virtual memory sub-system. Conclusion There is a significant difference in performance for the different means of doing sequential file IO from Java. Not all methods are even remotely equal. For most IO I've found the use of ByteBuffers and Channels to be the best optimised parts of the IO libraries. If buffered streams are your IO libraries of choice, then it is worth branching out and and getting familiar with the sub-classes of Channel and Buffer. From http://mechanical-sympathy.blogspot.com/2011/12/java-sequential-io-performance.html
January 9, 2012
by Martin Thompson
· 19,110 Views · 2 Likes
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,170 Views
article thumbnail
Interactive 3D Dodecahedron in CSS3
Thursday's CSS3 bitmaps were clever and fun, but a little counter-HTML5-cultural: the whole point of SVG, Canvas, and so forth, is that vectors are better, because simpler, than bitmaps. Today's interactive geometric CSS3 shape is just the opposite: far more pixels than pre-rendering could possibly justify, emphatically composed of 2D surfaces, and fully animated in 3D. It's a folding/unfolding dodecahedron (not in FF/IE): On to the code: Because it's a simple shape, the div-organization is too plain to be interesting. The CSS is more satisfying -- with each side-pentagon transformed around x, y, and z axes, as dodecahedronity requires: #dodecahedron.closed #group5 { -webkit-transform: rotateZ(-324deg) rotateX(63deg); -moz-transform: rotateZ(-324deg) rotateX(63deg); transform: rotateZ(-324deg) rotateX(63deg); } and each pentagon defined with gratuitously pleasing transparency: .p2 { position: absolute; left: 0px; top: 0px; width: 0; height: 0; border-bottom: 59px solid #ff0000; border-left: 81px solid transparent; border-right: 81px solid transparent; } The JavaScript is what you might guess after a few seconds' interaction -- but is written efficiently and clearly enough to merit a look. Worth checking out, as an excellent, direct instantiation of several cool CSS3 elements.
January 6, 2012
by John Esposito
· 11,792 Views
article thumbnail
Simplifying the Data Access Layer with Spring and Java Generics
1. Overview This is the second of a series of articles about Persistence with Spring. The previous article discussed setting up the persistence layer with Spring 3.1 and Hibernate, without using templates. This article will focus on simplifying the Data Access Layer by using a single, generified DAO, which will result in elegant data access, with no unnecessary clutter. Yes, in Java. The Persistence with Spring series: Part 1 – The Persistence Layer with Spring 3.1 and Hibernate Part 3 – The Persistence Layer with Spring 3.1 and JPA Part 4 – The Persistence Layer with Spring Data JPA Part 5 – Transaction configuration with JPA and Spring 3.1 2. The DAO mess Most production codebases have some kind of DAO layer. Usually the implementation ranges from a raw class with no inheritance to some kind of generified class, but one thing is consistent – there is always more then one. Most likely, there are as many DAOs as there are entities in the system. Also, depending on the level of generics involved, the actual implementations can vary from heavily duplicated code to almost empty, with the bulk of the logic grouped in an abstract class. 2.1. A Generic DAO Instead of having multiple implementations – one for each entity in the system – a single parametrized DAO can be used in such a way that it still takes full advantage of the type safety provided by generics. Two implementations of this concept are presented next, one for a Hibernate centric persistence layer and the other focusing on JPA. These implementation are by no means complete – only some data access methods are included, but they can be easily be made more thorough. 2.2. The Abstract Hibernate DAO public abstract class AbstractHibernateDAO< T extends Serializable > { private Class< T > clazz; @Autowired SessionFactory sessionFactory; public void setClazz( Class< T > clazzToSet ){ this.clazz = clazzToSet; } public T findOne( Long id ){ return (T) this.getCurrentSession().get( this.clazz, id ); } public List< T > findAll(){ return this.getCurrentSession() .createQuery( "from " + this.clazz.getName() ).list(); } public void save( T entity ){ this.getCurrentSession().persist( entity ); } public void update( T entity ){ this.getCurrentSession().merge( entity ); } public void delete( T entity ){ this.getCurrentSession().delete( entity ); } public void deleteById( Long entityId ){ T entity = this.getById( entityId ); this.delete( entity ); } protected Session getCurrentSession(){ return this.sessionFactory.getCurrentSession(); } } The DAO uses the Hibernate API directly, without relying on any Spring templates (such as HibernateTemplate). Using of templates, as well as management of the SessionFactory which is autowired in the DAO were covered in the previous post of the series. 2.3. The Abstract JPA DAO public abstract class AbstractJpaDAO< T extends Serializable > { private Class< T > clazz; @PersistenceContext EntityManager entityManager; public void setClazz( Class< T > clazzToSet ){ this.clazz = clazzToSet; } public T findOne( Long id ){ return this.entityManager.find( this.clazz, id ); } public List< T > findAll(){ return this.entityManager.createQuery( "from " + this.clazz.getName() ) .getResultList(); } public void save( T entity ){ this.entityManager.persist( entity ); } public void update( T entity ){ this.entityManager.merge( entity ); } public void delete( T entity ){ this.entityManager.remove( entity ); } public void deleteById( Long entityId ){ T entity = this.getById( entityId ); this.delete( entity ); } } Similar to the Hibernate DAO implementation, the Java Persistence API is used here directly, again not relying on the now deprecated Spring JpaTemplate. 2.4. The Generic DAO Now, the actual implementation of the generic DAO is as simple as it can be – it contains no logic. Its only purpose is to be injected by the Spring container in a service layer (or in whatever other type of client of the Data Access Layer): @Repository @Scope( BeanDefinition.SCOPE_PROTOTYPE ) public class GenericJpaDAO< T extends Serializable > extends AbstractJpaDAO< T > implements IGenericDAO< T >{ // } @Repository @Scope( BeanDefinition.SCOPE_PROTOTYPE ) public class GenericHibernateDAO< T extends Serializable > extends AbstractHibernateDAO< T > implements IGenericDAO< T >{ // } First, note that the generic implementation is itself parametrized – allowing the client to choose the correct parameter in a case by case basis. This will mean that the clients gets all the benefits of type safety without needing to create multiple artifacts for each entity. Second, notice the prototype scope of these generic DAO implementation. Using this scope means that the Spring container will create a new instance of the DAO each time it is requested (including on autowiring). That will allow a service to use multiple DAOs with different parameters for different entities, as needed. The reason this scope is so important is due to the way Spring initializes beans in the container. Leaving the generic DAO without a scope would mean using the default singleton scope, which would lead to a single instance of the DAO living in the container. That would obviously be majorly restrictive for any kind of more complex scenario. 3. The Service There is now a single DAO to be injected by Spring; also, the Class needs to be specified: @Service class FooService implements IFooService{ IGenericDAO< Foo > dao; @Autowired public void setDao( IGenericDAO< Foo > daoToSet ){ this.dao = daoToSet; this.dao.setClazz( Foo.class ); } // ... } Spring autowires the new DAO insteince using setter injection so that the implementation can be customized with the Class object. After this point, the DAO is fully parametrized and ready to be used by the service. 4. Conclusion This article discussed the simplification of the Data Access Layer by providing a single, reusable implementation of a generic DAO. This implementation was presented in both a Hibernate and a JPA based environment. The result is a streamlined persistence layer, with no unnecessary clutter. For a step by step introduction about setting up the Spring context using Java based configuration and the basic Maven pom for the project, see this article. The next article of the Persistence with Spring series will focus on setting up the DAL layer with Spring 3.1 and JPA. In the meantime, you can check out the full implementation in the github project. If you read this far, you should follow me on twitter here.
January 5, 2012
by Eugen Paraschiv
· 25,041 Views · 1 Like
article thumbnail
CSS3 Optical Illusions
today i have prepared something interesting for you. this is a demonstration of several optical illusions in css3 (without using any images or javascript). enjoy the results. here are samples and downloadable package: live demo download in package ok, download the example files and let's start coding! step 1. html as usual, we start with the html. here is full html code of all 6 demos. index.html css3 optical illusions back to original tutorial on script tutorials 1 2 3 4 5 6 38 38 step 2. css here are the css styles. maybe you’ve noticed that in our html i have two css files: layout.css and illusions.css. the first file (layout.css) contain the styles of our test page. we will not publish these styles in this article, but if you wish – you can find these styles in our package. css/illusions.css span { display: none; } .contr { color: #000000; cursor: pointer; float: left; font-size: 16px; font-weight: bold; height: 30px; line-height: 30px; margin: 10px; text-align: center; text-decoration: none; width: 60px; -webkit-border-radius:10px; -moz-border-radius:10px; -ms-border-radius:10px; -o-border-radius:10px; border-radius:10px; background-color:#e3e3ff; background: -moz-linear-gradient(#ffffff, #eee); background: -ms-linear-gradient(#ffffff, #eee); background: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #ffffff), color-stop(100%, #eee)); background: -webkit-linear-gradient(#ffffff, #eee); background: -o-linear-gradient(#ffffff, #eee); filter: progid:dximagetransform.microsoft.gradient(startcolorstr='#ffffff', endcolorstr='#eee'); -ms-filter: "progid:dximagetransform.microsoft.gradient(startcolorstr='#ffffff', endcolorstr='#eee')"; background: linear-gradient(#ffffff, #eee); } .contr:hover{ background-color:#e3e3ff; box-shadow:0px 0px 4px rgba(0,0,0,0.5) inset, 0px 0px 0px 4px rgba(51,51,204,0.5); -moz-box-shadow:0px 0px 4px rgba(0,0,0,0.5) inset, 0px 0px 0px 4px rgba(51,51,204,0.5); -webkit-box-shadow:0px 0px 4px rgba(0,0,0,0.5) inset, 0px 0px 0px 4px rgba(51,51,204,0.5); } .demos { background-color: #b2b2b2; display: block; height: 640px; margin-top: 55px; overflow: hidden; position: relative; } .demos > div { display: none; } #page1:target ~ .demos #i1 { display: block; } #page2:target ~ .demos #i2 { display: block; } #page3:target ~ .demos #i3 { display: block; } #page4:target ~ .demos #i4 { display: block; } #page5:target ~ .demos #i5 { display: block; } #page6:target ~ .demos #i6 { display: block; } /* illusion 1 */ #i1 { width: 900px; } #i1 .row { background-color: #fff; border-bottom: 2px solid #888; height: 90px; -webkit-background-size: 140px 70px; -moz-background-size: 140px 70px; -ms-background-size: 140px 70px; -o-background-size: 140px 70px; background-size: 140px 70px; background-position: 0 50%; background-image: -webkit-linear-gradient(0deg, #000 50%, transparent 50%, transparent); background-image: -moz-linear-gradient(0deg, #000 50%, transparent 50%, transparent); background-image: -ms-linear-gradient(0deg, #000 50%, transparent 50%, transparent); background-image: -o-linear-gradient(0deg, #000 50%, transparent 50%, transparent); background-image: linear-gradient(0deg, #000 50%, transparent 50%, transparent); } #i1 .row:nth-child(3n+3) { background-position: 60px 50%; } #i1 .row:nth-child(2n+2) { background-position: 30px 50%; } /* illusion 2 */ #i2 { background-color: #98cb00; height: 640px; margin: 0 auto; overflow: hidden; padding: 0 150px; position: relative; width: 600px; } #i2 > div { float: left; height: 105px; padding-left: 90px; padding-top: 90px; position: relative; width: 105px; } #i2 div div { border: 1px outset #fff; height: 20px; position: absolute; width: 30px; -webkit-border-radius: 100px / 50px; -moz-border-radius: 100px / 50px; -ms-border-radius: 100px / 50px; -o-border-radius: 100px / 50px; border-radius: 100px / 50px; background: -webkit-linear-gradient(top, #580402, #a63b17, #580402, #a63b17, #580402); background: -moz-linear-gradient(top, #580402, #a63b17, #580402, #a63b17, #580402); background: -ms-linear-gradient(top, #580402, #a63b17, #580402, #a63b17, #580402); background: -o-linear-gradient(top, #580402, #a63b17, #580402, #a63b17, #580402); background: linear-gradient(top, #580402, #a63b17, #580402, #a63b17, #580402); } #i2 #o1 { -webkit-transform: rotate(-30deg) translatex(70px); -moz-transform: rotate(-30deg) translatex(70px); -ms-transform: rotate(-30deg) translatex(70px); -o-transform: rotate(-30deg) translatex(70px); transform: rotate(-30deg) translatex(70px); } #i2 #o2 { -webkit-transform: rotate(-60deg) translatex(70px); -moz-transform: rotate(-60deg) translatex(70px); -ms-transform: rotate(-60deg) translatex(70px); -o-transform: rotate(-60deg) translatex(70px); transform: rotate(-60deg) translatex(70px); } #i2 #o3 { -webkit-transform: rotate(-90deg) translatex(70px); -moz-transform: rotate(-90deg) translatex(70px); -ms-transform: rotate(-90deg) translatex(70px); -o-transform: rotate(-90deg) translatex(70px); transform: rotate(-90deg) translatex(70px); } #i2 #o4 { -webkit-transform: rotate(-120deg) translatex(70px); -moz-transform: rotate(-120deg) translatex(70px); -ms-transform: rotate(-120deg) translatex(70px); -o-transform: rotate(-120deg) translatex(70px); transform: rotate(-120deg) translatex(70px); } #i2 #o5 { -webkit-transform: rotate(-150deg) translatex(70px); -moz-transform: rotate(-150deg) translatex(70px); -ms-transform: rotate(-150deg) translatex(70px); -o-transform: rotate(-150deg) translatex(70px); transform: rotate(-150deg) translatex(70px); } #i2 #o6 { -webkit-transform: rotate(-180deg) translatex(70px); -moz-transform: rotate(-180deg) translatex(70px); -ms-transform: rotate(-180deg) translatex(70px); -o-transform: rotate(-180deg) translatex(70px); transform: rotate(-180deg) translatex(70px); } #i2 #o7 { -webkit-transform: rotate(-210deg) translatex(70px); -moz-transform: rotate(-210deg) translatex(70px); -ms-transform: rotate(-210deg) translatex(70px); -o-transform: rotate(-210deg) translatex(70px); transform: rotate(-210deg) translatex(70px); } #i2 #o8 { -webkit-transform: rotate(-240deg) translatex(70px); -moz-transform: rotate(-240deg) translatex(70px); -ms-transform: rotate(-240deg) translatex(70px); -o-transform: rotate(-240deg) translatex(70px); transform: rotate(-240deg) translatex(70px); } #i2 #o9 { -webkit-transform: rotate(-270deg) translatex(70px); -moz-transform: rotate(-270deg) translatex(70px); -ms-transform: rotate(-270deg) translatex(70px); -o-transform: rotate(-270deg) translatex(70px); transform: rotate(-270deg) translatex(70px); } #i2 #o10 { -webkit-transform: rotate(-300deg) translatex(70px); -moz-transform: rotate(-300deg) translatex(70px); -ms-transform: rotate(-300deg) translatex(70px); -o-transform: rotate(-300deg) translatex(70px); transform: rotate(-300deg) translatex(70px); } #i2 #o11 { -webkit-transform: rotate(-330deg) translatex(70px); -moz-transform: rotate(-330deg) translatex(70px); -ms-transform: rotate(-330deg) translatex(70px); -o-transform: rotate(-330deg) translatex(70px); transform: rotate(-330deg) translatex(70px); } #i2 #o12 { -webkit-transform: rotate(0deg) translatex(70px); -moz-transform: rotate(0deg) translatex(70px); -ms-transform: rotate(0deg) translatex(70px); -o-transform: rotate(0deg) translatex(70px); transform: rotate(0deg) translatex(70px); } /* illusion 3 */ #i3 { color: #000000; font-family: times new roman; font-size: 250px; padding-left: 300px; } #i3 .rev { text-align: right; -webkit-transform: rotate(-180deg); -moz-transform: rotate(-180deg); -ms-transform: rotate(-180deg); -o-transform: rotate(-180deg); transform: rotate(-180deg); } /* illusion 4 */ #i4 .row { background-color: #fff; border-bottom: 5px solid #fff; height: 50px; -webkit-background-size: 60px 50px; -moz-background-size: 60px 50px; -ms-background-size: 60px 50px; -o-background-size: 60px 50px; background-size: 60px 50px; background-position: 0 50%; background-image: -webkit-linear-gradient(0deg, #000 90%, transparent 10%, transparent); background-image: -moz-linear-gradient(0deg, #000 90%, transparent 10%, transparent); background-image: -ms-linear-gradient(0deg, #000 50%, transparent 50%, transparent); background-image: -o-linear-gradient(0deg, #000 50%, transparent 50%, transparent); background-image: linear-gradient(0deg, #000 50%, transparent 50%, transparent); } /* illusion 5 */ @-webkit-keyframes custom_effect { 0% {opacity: 0;} 33% {opacity: 1;} 100% {opacity: 1;} } @-moz-keyframes custom_effect { 0% {opacity: 0;} 33% {opacity: 1;} 100% {opacity: 1;} } #i5 { background-color: #b2b2b2; height: 600px; margin: 0 auto; overflow: hidden; position: relative; width: 600px; } #i5 > div { float: left; height: 200px; padding-left: 200px; padding-top: 200px; position: relative; width: 200px; } #i5 div div { height: 50px; position: absolute; width: 50px; -webkit-border-radius: 50px; -moz-border-radius: 50px; -ms-border-radius: 50px; -o-border-radius: 50px; border-radius: 50px; background-color: #b2b2b2; background-image: -webkit-radial-gradient(50% 50%, circle, #fd19fd, #b2b2b2 70%); background-image: -moz-radial-gradient(50% 50%, circle, #fd19fd, #b2b2b2 70%); background-image: -o-radial-gradient(50% 50%, circle, #fd19fd, #b2b2b2 70%); background-image: radial-gradient(50% 50%, circle, #fd19fd, #b2b2b2 70%); -moz-animation-name: custom_effect; -moz-animation-duration: 1.2s; -moz-animation-timing-function: linear; -moz-animation-iteration-count: infinite; -moz-animation-direction: normal; -moz-animation-delay: 0; -moz-animation-play-state: running; -moz-animation-fill-mode: forwards; -webkit-animation-name: custom_effect; -webkit-animation-duration: 1.2s; -webkit-animation-timing-function: linear; -webkit-animation-iteration-count: infinite; -webkit-animation-direction: normal; -webkit-animation-delay: 0; -webkit-animation-play-state: running; -webkit-animation-fill-mode: forwards; } #i5 #o1 { -moz-transform: rotate(30deg) translatex(150px); -moz-animation-delay: 0.1s; -webkit-transform: rotate(30deg) translatex(150px); -webkit-animation-delay: 0.1s; } #i5 #o2 { -moz-transform: rotate(60deg) translatex(150px); -moz-animation-delay: 0.2s; -webkit-transform: rotate(60deg) translatex(150px); -webkit-animation-delay: 0.2s; } #i5 #o3 { -moz-transform: rotate(90deg) translatex(150px); -moz-animation-delay: 0.3s; -webkit-transform: rotate(90deg) translatex(150px); -webkit-animation-delay: 0.3s; } #i5 #o4 { -moz-transform: rotate(120deg) translatex(150px); -moz-animation-delay: 0.4s; -webkit-transform: rotate(120deg) translatex(150px); -webkit-animation-delay: 0.4s; } #i5 #o5 { -moz-transform: rotate(150deg) translatex(150px); -moz-animation-delay: 0.5s; -webkit-transform: rotate(150deg) translatex(150px); -webkit-animation-delay: 0.5s; } #i5 #o6 { -moz-transform: rotate(180deg) translatex(150px); -moz-animation-delay: 0.6s; -webkit-transform: rotate(180deg) translatex(150px); -webkit-animation-delay: 0.6s; } #i5 #o7 { -moz-transform: rotate(210deg) translatex(150px); -moz-animation-delay: 0.7s; -webkit-transform: rotate(210deg) translatex(150px); -webkit-animation-delay: 0.7s; } #i5 #o8 { -moz-transform: rotate(240deg) translatex(150px); -moz-animation-delay: 0.8s; -webkit-transform: rotate(240deg) translatex(150px); -webkit-animation-delay: 0.8s; } #i5 #o9 { -moz-transform: rotate(270deg) translatex(150px); -moz-animation-delay: 0.9s; -webkit-transform: rotate(270deg) translatex(150px); -webkit-animation-delay: 0.9s; } #i5 #o10 { -moz-transform: rotate(300deg) translatex(150px); -moz-animation-delay: 1.0s; -webkit-transform: rotate(300deg) translatex(150px); -webkit-animation-delay: 1.0s; } #i5 #o11 { -moz-transform: rotate(330deg) translatex(150px); -moz-animation-delay: 1.1s; -webkit-transform: rotate(330deg) translatex(150px); -webkit-animation-delay: 1.1s; } #i5 #o12 { -moz-transform: rotate(0deg) translatex(150px); -moz-animation-delay: 1.2s; -webkit-transform: rotate(0deg) translatex(150px); -webkit-animation-delay: 1.2s; } /* illusion 5 */ #i6 { background-color: #3f023e; height: 640px; margin: 0 auto; overflow: hidden; padding-left: 120px; position: relative; width: 900px; } #i6 .yellow { background-color: #b9bd04; background-image: -webkit-radial-gradient(50% 50%, circle, #fff531 40%, #b9bd04 80%); background-image: -moz-radial-gradient(50% 50%, circle, #fff531 40%, #b9bd04 80%); background-image: -o-radial-gradient(50% 50%, circle, #fff531 40%, #b9bd04 80%); background-image: radial-gradient(50% 50%, circle, #fff531 40%, #b9bd04 80%); } #i6 .pink { background-color: #f101e8; background-image: -webkit-radial-gradient(50% 50%, circle, #0e0403 40%, #f101e8 80%); background-image: -moz-radial-gradient(50% 50%, circle, #0e0403 40%, #f101e8 80%); background-image: -o-radial-gradient(50% 50%, circle, #0e0403 40%, #f101e8 80%); background-image: radial-gradient(50% 50%, circle, #0e0403 40%, #f101e8 80%); } #i6 > div { float: left; height: 320px; position: relative; width: 320px; } #i6 .r1 { height: 320px; position: absolute; width: 320px; -webkit-border-radius: 320px; -moz-border-radius: 320px; -ms-border-radius: 320px; -o-border-radius: 320px; border-radius: 320px; } #i6 .r2 { height: 240px; left: 40px; position: absolute; top: 40px; width: 240px; -webkit-border-radius: 240px; -moz-border-radius: 240px; -ms-border-radius: 240px; -o-border-radius: 240px; border-radius: 240px; } #i6 .r3 { height: 160px; left: 40px; position: absolute; top: 40px; width: 160px; -webkit-border-radius: 160px; -moz-border-radius: 160px; -ms-border-radius: 160px; -o-border-radius: 160px; border-radius: 160px; } #i6 .r4 { height: 80px; left: 40px; position: absolute; top: 40px; width: 80px; -webkit-border-radius: 80px; -moz-border-radius: 80px; -ms-border-radius: 80px; -o-border-radius: 80px; border-radius: 80px; } this is very big pack of styles, but i hope that this is ok. i have used several different css3 techniques: and keyframe animation, and transform rotate, and sometimes – gradients. live demo download in package conclusion hope you enjoyed the new demo. don’t forget to give thanks and leave a comment good luck! source: http://www.script-tutorials.com/css3-optical-illusions/
January 5, 2012
by Andrei Prikaznov
· 8,260 Views
article thumbnail
Java: How to Save / Download a File Available at a Particular URL Location on the Internet?
package singz.test; import java.io.BufferedInputStream; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.net.MalformedURLException; import java.net.URL; import org.apache.commons.io.FileUtils; /* * @author Singaram Subramanian */ public class FileDownloadTest { public static void main(String[] args) { // Make sure that this directory exists String dirName = "C:\\FileDownload"; try { System.out.println("Downloading \'Maven, Eclipse and OSGi working together\' PDF document..."); saveFileFromUrlWithJavaIO( dirName + "\\maven_eclipse_and_osgi_working_together.pdf", "http://singztechmusings.files.wordpress.com/2011/09/maven_eclipse_and_osgi_working_together.pdf"); System.out.println("Downloaded \'Maven, Eclipse and OSGi working together\' PDF document."); System.out.println("Downloading \'InnoQ Web Services Standards Poster\' PDF document..."); saveFileFromUrlWithCommonsIO( dirName + "\\innoq_ws-standards_poster_2007-02.pdf", "http://singztechmusings.files.wordpress.com/2011/08/innoq_ws-standards_poster_2007-02.pdf"); System.out.println("Downloaded \'InnoQ Web Services Standards Poster\' PDF document."); } catch (MalformedURLException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } // Using Java IO public static void saveFileFromUrlWithJavaIO(String fileName, String fileUrl) throws MalformedURLException, IOException { BufferedInputStream in = null; FileOutputStream fout = null; try { in = new BufferedInputStream(new URL(fileUrl).openStream()); fout = new FileOutputStream(fileName); byte data[] = new byte[1024]; int count; while ((count = in.read(data, 0, 1024)) != -1) { fout.write(data, 0, count); } } finally { if (in != null) in.close(); if (fout != null) fout.close(); } } // Using Commons IO library // Available at http://commons.apache.org/io/download_io.cgi public static void saveFileFromUrlWithCommonsIO(String fileName, String fileUrl) throws MalformedURLException, IOException { FileUtils.copyURLToFile(new URL(fileUrl), new File(fileName)); } } From http://singztechmusings.wordpress.com/2011/12/20/java-how-to-save-download-a-file-available-at-a-particular-url-location-in-internet/
January 3, 2012
by Singaram Subramanian
· 148,507 Views
article thumbnail
Styling a JavaFX Control with CSS
Change the look and feel of any JavaFX control using CSS.
January 2, 2012
by Toni Epple
· 96,940 Views · 1 Like
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,421 Views · 4 Likes
article thumbnail
What are the differences between JAXB 1.0 and JAXB 2.0
What are the differences between JAXB 1.0 and JAXB 2.0? JAXB 1.0 only requires JDK 1.3 or later. JAXB 2.0 requires JDK 1.5 or later. JAXB 2.0 makes use of generics and thus provides compile time type safety checking thus reducing runtime errors. Validation is only available during marshalling in JAXB 1.0. Validation is also available during unmarshalling in JAXB 2.0. Termination occurs in JAXB 1.0 when a validation error occurs. In JAXB 2.0 custom ValidationEventHandlers can be used to deal with validation errors. JAXB 2.0 uses annotations and supports bi-directional mapping. JAXB 2.0 generates less code. JAXB 1.0 does not support key XML Schema components like anyAttribute, key, keyref, and unique. It also does not support attributes like complexType.abstract, element.abstract, element.substitutionGroup, xsi:type, complexType.block, complexType.final, element.block, element.final, schema.blockDefault, and schema.finalDefault. In version 2.0, support has been added for all of these schema constructs. References: http://javaboutique.internet.com/tutorials/jaxb/index3.html From http://dublintech.blogspot.com/2011/04/what-are-differences-between-jaxb-10.html
December 30, 2011
by Alex Staveley
· 15,343 Views
article thumbnail
XML Schema to Java - Generating XmlAdapters
In previous posts I have demonstrated how powerful JAXB's XmlAdapter can be when starting from domain objects. In this example I will demonstrate how to leverage an XmlAdapter when generating an object model from an XML schema. This post was inspired by an answer I gave to a question on Stack Overflow (feel free to up vote). XMLSchema (format.xsd) The following is the XML schema that will be used for this example. The interesting portion is a type called NumberCodeValueType. This type has a specified pattern requiring it be a seven digit number. This number can have leading zeros which would not be marshalled by JAXB's default conversion of numbers. NumberFormatter Since JAXB's default number to String algorithm will not match our schema requirements, we will need to write our own formatter. We are required to provide two static methods one that coverts our type to the desired XML format, and another that converts from the XML format. package blog.xmladapter.bindings; public class NumberFormatter { public static String printInt(Integer value) { String result = String.valueOf(value); for(int x=0, length = 7 - result.length(); x XJC Call The bindings file is referenced in the XJC call as: xjc -d out -p blog.xmladapter.bindings -b bindings.xml format.xsd Adapter1 This will cause an XmlAdapter to be created that leverages the formatter: package blog.xmladapter.bindings; import javax.xml.bind.annotation.adapters.XmlAdapter; public class Adapter1 extends XmlAdapter { public Integer unmarshal(String value) { return (blog.xmladapter.bindings.NumberFormatter.parseInt(value)); } public String marshal(Integer value) { return (blog.xmladapter.bindings.NumberFormatter.printInt(value)); } } Root The XmlAdapter will be referenced from the domain object using the @XmlJavaTypeAdapter annotation: package blog.xmladapter.bindings; import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlAccessorType; import javax.xml.bind.annotation.XmlElement; import javax.xml.bind.annotation.XmlRootElement; import javax.xml.bind.annotation.XmlType; import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; @XmlAccessorType(XmlAccessType.FIELD) @XmlType(name = "", propOrder = { "number" }) @XmlRootElement(name = "root") public class Root { @XmlElement(required = true, type = String.class) @XmlJavaTypeAdapter(Adapter1 .class) protected Integer number; public Integer getNumber() { return number; } public void setNumber(Integer value) { this.number = value; } } Demo Now if we run the following demo code: package blog.xmladapter.bindings; import javax.xml.bind.JAXBContext; import javax.xml.bind.Marshaller; public class Demo { public static void main(String[] args) throws Exception { JAXBContext jc = JAXBContext.newInstance(Root.class); Root root = new Root(); root.setNumber(4); Marshaller marshaller = jc.createMarshaller(); marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true); marshaller.marshal(root, System.out); } } Output We will get the desired output: 0000004 From http://blog.bdoughan.com/2011/08/xml-schema-to-java-generating.html
December 30, 2011
by Blaise Doughan
· 15,449 Views
  • Previous
  • ...
  • 439
  • 440
  • 441
  • 442
  • 443
  • 444
  • 445
  • 446
  • 447
  • 448
  • ...
  • 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
×