VMWare Screen Repaint issues
Posted in Bob Hedlund on April 12th, 2011 by adminadmin originally posted this on Eldorado Software.
I recently added an iMac with 8Gb Ram, and I use VMWare due to a need to run an oracle database and some of the Oracle utilities. To my horror, the repaint on the XP VM was marginal, and I often found myself doing double takes at the things I had written (more than the usual amount anyway).I tried mucking with the 3D Acceleration on the VM Settings, but that didn't have any effect.
What did the trick was modifying the settings on the Windows VM - in this case XP.
Under Control Panel / Display Settings / Settings Tab
click the Advanced Button
Goto the Troubleshoot Tab
Adjust the Hardware acceleration down one notch.
Restart your VM.
No more double takes due to missing pixels.
IBM’s Watson written mostly in Java
Posted in Eric Bruno on February 24th, 2011 by adminadmin originally posted this on Dr.Dobb's Journal | Eric Bruno Blog.
>In this blog on reddit, the developers of IBM's Watson mentioned that the code was mostly written in Java, with significant chunks written in C++ and Prolog, running on Linux. Here's an excerpt:
"Watson is powered by 10 racks of IBM Power 750 servers running Linux, and uses 15 terabytes of RAM, 2,880 processor cores and is capable of operating at 80 teraflops. Watson was written in mostly Java but also significant chunks of code are written C++ and Prolog, all components are deployed and integrated using UIMA."
While, in a way, this impressive feat is a testament to IBM's Power architecture and its ability to easily perform parallel tasks, I'm mostly sold on the RAM. 15 terabytes of RAM? That's a huge enabler! I predict that, based on the success of solid state disks and the common sense performance boost RAM gives you, we'll begin to see computers with battery-backed RAM disks in the future. And it's really nice to see Java is still at the center of ground-breaking achievements such as this, which is a good indicator of the future of computing. Take note, all of you out there proclaiming Java's decline!
Happy coding!
-EJB
Java SE 7 Preview Build
Posted in Eric Bruno on February 23rd, 2011 by adminadmin originally posted this on Dr.Dobb's Journal | Eric Bruno Blog.
>Oracle has made a developer preview release of Java SE 7 (formerly JDK 7) available for use. Not only is this the first time I've seen Oracle refer to JDK 7 as Java SE 7, they're asking for all Java developers to beat on it and report any bugs before it becomes finalized. The final release is planned for July, and with JavaFX 2.0 moving along as scheduled, I hope to see it bundled in there (at least optionally) as well.
Read more about Java SE 7 (including a link to download the pre-release) here: http://blogs.oracle.com/java/2011/02/java_se_7_developer_preview_release_now_available.html
Happy coding!
-EJB
Terracotta Extends Ehcache for Java
Posted in Eric Bruno on February 16th, 2011 by adminadmin originally posted this on Dr.Dobb's Journal | Eric Bruno Blog.
>Yesterday, Terracotta introduced Ehcache Search (see the press release), which is built upon their leading enterprise data cache product, Ehcache. Terracotta helps Java developers get the most in terms of scalability, performance, and latency for their data-intensive enterprise applications. Whether you're caching data from a database, a REST-based web service, or other system, Terracotta has solutions that, many times, simply plug-in with very little configuration, and just work.
With more and more customers caching larger amounts of data, Terracotta released BigMemory, which can store hundreds of gigabytes of data in memory, but outside of the Java heap to avoid Java garbage collection issues. In turn, Terracotta's customers have been caching more and more data and, in many cases, entire databases worth of data are stored in memory. This has begged the question, is it possible to perform basic queries against the cached data instead of the database itself, to further improve performance? With Ehcache Search, the answer is yes!
To implement this solution, Terracotta simply extended the Ehcache API and has included the feature in their latest version, v2.4. It's not a new product or additional plug-in that requires an additional purchase, but is instead available to existing Terracotta customers. The new API and other attributes of the cache now make it possible to perform search-like queries against the database data in memory, as opposed to hitting the actual database and its disk-backed storage each time.
If you're an existing Ehcache user, simply upgrade to version 2.4, which is released as open-source software, with commercial licensing and support available if you require. To get the most in terms of performance and scalability, Terracotta offers Enterprise Ehcache with BigMemory that allows for low-latency and high-scalability with extremely large caches, which can further be distributed across servers.
If you're not currently an Ehcache user, you can join the millions of Java developers who are by checking out Terracotta's open-source offerings at http://www.ehcache.org/.
Happy Coding!
-EJB
Creating Healthy Craftsmen
Posted in Jerry Andrews on January 18th, 2011 by adminThere’s been a healthy debate over on the software craftsmanship mailing list about what craftsmanship means in the context of software development. I’ve been a proponent of, among other things, some set of standards by which a practitioner’s capabilities can be measured. That’s been unpopular, as you might imagine.
George Dinwiddie (http://blog.gdinwiddie.com) has written a bit about what he believes. I respect and agree with most of his conclusions, but I do disagree with his attitude on measuring developer’s capabilities. I don’t want to pick on George, but his are the most recent articles I’ve read on this topic (http://blog.gdinwiddie.com/2011/01/15/software-craftsmanship/, http://blog.gdinwiddie.com/2011/01/17/trades-crafts-and-certification/), and they make the same mistakes I see everywhere when discussing performance tests. To wit:
G—- is a certified tradesman. G—- did horrible work. G—–’s work was certified acceptable by a third party, also certified. Therefore certification doesn’t guarantee excellent (or “craftsmanlike”) work.
Now here’s the fallacies in that argument:
- Certification, by itself, only guarantees that, at least at one point in time, the practitioner knew how to do excellent work (or at least, work up to the level of the certification standard). It doesn’t mean (s)he will always do it.
- One (or two, or ten) examples where certification doesn’t do what it was intended to do doesn’t mean that certification never works, or even that it seldom works.
- The certification in question when this sort of argument is made seldom, if ever, covers the issues of craftsmanship under discussion.
- A certified individual, like most people, may not do the same level of work every day. Even master craftsmen have bad days or weeks or even years. In trade work, unfortunately, you can’t always throw it out and fix it; there are schedules to meet.
So that particular argument is terminally flawed, and shouldn’t be made at all. To amplify a bit:
I’d be the last to contend that certification is the only ingredient of a healthy craftsmanship movement or in developing excellent programmers. It’s simply one tool–a way to measure oneself both for one’s own edification, and to help others gauge your breadth of knowledge. I think it’s a particularly important tool–a pillar, if you will, along with other pillars, such as the community of like-minded individuals against whom you measure yourself, and who can comment on your work.
I think it’s important to review what certification means. It usually means “at some point in time, this individual knew and could put into practice certain tools, rules, and practices which, by this certification, we have verified”. Usually the certification standard is generated by people who really know the subject, and are qualified to determine what parts of the subject are key to being effective. Certification doesn’t say anything about a practitioner’s willingness to apply what (s)he knows–that’s a different problem, solved in different ways (e.g. establishing and maintaining a reputation, publishing your work for review, etc.).
What I’d really like to see is some kind of actual data comparing the performance of programmers (or plumbers, or electricians) who are certified in some way to those who aren’t certified, on tasks related to the certification. I see a lot of opinions (mine included) bandied about without actual, real, verifiable data. One of the things that makes DeMarco and Lister (Peopleware) compelling reading is that they provide actual data. Real studies with results that aren’t anecdotal. They’re not just voicing “opinions developed over years of practice”–they (and we) should be conducting actual experiments to verify our theories.
Craftsmanship, in my mind, requires:
- an attitude that it’s worthwhile to create excellent work, to provide the necessary stimulus,
- access to people who can teach and/or materials from which a practitioner can learn what that means and how to accomplish it, to provide the necessary knowledge and experience,
- some standard ways to measure a practitioner’s progress from neophyte to mastery, to provide a mechanism for the practitioner to understand where (s)he is and where (s)he needs to go, and
- some mechanism for displaying the practitioner’s achievements, so that mastery carries real benefits in the working world, thereby incenting mastery in others, and helping people outside the craft or trade to select workers appropriate for their tasks.
Documentation in the wild
Posted in Jerry Andrews on January 12th, 2011 by adminI just started a new project. I has no documentation except the code.
In this particular project, this is generally a Good Thing–the code in question is clear, well written, and (ahem) completely without comments. I’m not having a lot of trouble understanding it, overall, because it really is very good code. But… I’ve spent 2 days trying to figure out how one important feature works.
http://thedailywtf.com/Articles/Documentation-Done-Right.aspx
‘Nuff said.
2011: Year of the iPad
Posted in Dave Rodenbaugh on January 5th, 2011 by adminadmin originally posted this on Lessons of Failure.
Happy New Year to everyone, first of all. And second, I hope you managed to get your hands on an iPad in the past 6 months because if you haven’t, you’re going to want one.
Why? Because 2011 is definitely going to be the Year of the iPad. Not by an inch, more like a mile. Let me explain why…
Now that I own an iPad, I finally get the hoopla over these devices. I wasn’t impressed when they came out and wasn’t really planning on getting one for the holidays. Thanks to a generous visit from Santa, who despite my best efforts to the contrary with acerbic blog posts considered me worthy of one under the tree, I now own one along with my wife. And I’m impressed. Very impressed.
iPad: The Must-Have Intermediate Computing Device
I’ll coin a new term for tablets: intermediate computing devices, although I’m hoping someone comes up with a better one in the future. To me, the tablet represents a new class of device that isn’t quite in the same class as netbooks and mobile PCs, although categorically they tend to be lumped together. These devices fill a gap where a PC is too cumbersome, but a smartphone isn’t powerful enough, or even large enough. The iPad is clearly king of the tablets right now. I say that, not as an Apple Fanboi, but as a solid convert to the notion this device does actually have a place in your house when you already own a desktop, laptop, media computer (e.g. AppleTV), and smartphone.
Each platform has tremendous utility within its own domain (smartphones are great for keeping in touch on the go, but lousy for typing blog posts, and the laptop is strong where the smartphone is weak, etc). It wasn’t until I actually owned the iPad that I suddenly found places where I really wanted more than my smartphone but much less than my laptop.
Let’s look at a specific example: my wife and I both love Rummy Tile. Getting the boxed game out after the kids are in bed is a bit of a hassle, and we can’t play on anything except a very flat and hard surface. Enter the iPad: each of us downloaded an iPad version and can play against each other sitting in bed via Bluetooth. Comfort and convenience, meet marital competition (For the record, my wife continues to beat me overall, even at the electronic version).
Not satisfied with that? How about this: I leave my email open on my laptop downstairs all the time. Doing so prevents my iPhone from getting email, so I find myself having to run down 2 levels at night to shut down Outlook so I can see email in the morning when I get up. Not with my iPad! I installed Team Viewer and can now remotely login to my laptop, shut it down, or do anything I need on the computer (like grab an attachment from an old email, which I frequently need as well).
Of course, don’t forget the real estate improvement over the smartphone genre: web browsing is a treat by comparison. My wife and I need to lookup things all the time, and the iPad is the perfect device for on-demand, quick-and-easy web surfing. No waiting for boot time of the laptop, no struggle to read the data displayed on the smartphone.
And…The Competition Sucks
After I got the iPad, I thought I’d check out the competition and see how the lay of the land was looking by comparison. It’s not good for the Android folks
right now:
- The Dell Streak requires a data plan from, yep, you guessed it, AT&T. It’s cheap if you get the two year data-only plan at $30/month, but as pricey as the iPad otherwise.
- The Google Android tablet has very mediocre reviews to date on Amazon. When the “best helpful review” for it says, “For the price it’s not bad…”, you know you’re in trouble.
- Two of the most promising contenders that generated huge buzz (Notion Ink and the Kno (aimed at college students)) just made the Wired Vaporware 2010 list. Oops.
- The Maylong $99 tablet sold at Walgreens got scathing reviews earlier this year, and continues to hold the distinction of “worst gadget ever“.
- Viewsonic’s G-tablet isn’t exactly burning up sales with comments like “With some sweat equity, you can get it to work…”, and “Next gen hardware, but software needs improvement”. At it’s current price, you can get a 3G iPad, and save on your Advil bills to offset the pain.
- And other low-end competitors are getting smacked around too, like the Augen NBA7800ATP.
- EDIT: For those wondering why I omitted the Samsung Galaxy, see the comments.
Out of the box, the iPad just works, which isn’t something you can say of most tablets mentioned above. At the current prices and capabilities, the Android tablets aren’t a clear win as a lower-end device. The experience is often so poor as to be unusable, and the higher end models are not significantly better than the iPad for nearly the same cash outlay. Never mind that engineers looking at the Android have discovered major issues with the compositing and view system which are primarily software-based, giving extremely poor responsiveness in the touch interface and the animation rates. Android has a ways to go here–either due to hubris or lack of experience.
And while Windows 7 mobile at least got that part right, they are still lagging heavily in this market and will likely remain so for the balance of the year. The market trends clearly favor Apple’s iPad as the hottest “mobile PC device” available, for 3 quarters running.
In short, no one else has a good handle on the market and user experience aside from Apple.
The Golden Last Frontier of Mobile App Development
Lastly, what about the developer community? Well, you can complain about the App Store all you want, but the Android Marketplace still isn’t a whole lot better than when I last wrote about it. Furthermore, the app selection for Android is still considerably worse than than for iPad.
But the real reason you want to get in on the action is that iPad apps aren’t cheap, and therefore command higher revenues from the App Store. The iPad versions of apps are often selling for several multiples (sometimes deserved, sometimes not) over their iPhone counterparts. Even though the average across all apps is only $1 higher for iPad apps, my experience looking at the top-selling apps is somewhat different. Here are a few examples that clearly show a difference if you get in the good graces of the world:
| App Name |
iPhone Price | iPad Price |
| Angry Birds: | $0.99 | $4.99 |
| Plants vs. Zombies | $2.99 | $9.99 |
| Fruit Ninja | $0.99 | $2.99 |
| Cut the Rope | $0.99 | $1.99 |
| UNO | $0.99 | $4.99 |
Some are the same in both (SlingPlayer, LogMeIn) but clearly the experience is vastly different.
In addition to the gaming possibilities of the device, the iPad opens up a whole new world for application development where the increased screen real estate makes a big difference (Netflix avoided the iPhone app for a long time and rightly so until the iPad came along…now it’s one of the top rated iPad apps in the store, and for good reason). And there are precious few decent iPad utility applications out there, making a rich market for those who have the know-how and willingness to surf the treacherous waters of Jobs & Co.
Unless a miracle happens, it looks like Apple has the tablet world by the tail for at least this year. In 2012, assuming the Mayan gods don’t come to punish all of us for bad John Cusack movies, the landscape may change dramatically but for now it’s Steve’s world and we’re just computing in it.
Drag-and-Drop Revisited
Posted in Justin Shacklette on December 14th, 2010 by adminadmin originally posted this on Saturnboy.
It’s time to revisit drag-and-drop in Flex 4. For a long time now, my previous Drag-and-Drop in Flex 4 post has been the most popular post on this blog. I get something like 1,200 pageview/month on that one post. This time around, I’ll try to expand on the thinking that goes on before I write the code to add drag-and-drop functionality to an app.
UX 101
It is impossible to develop an RIA without some basic understanding of interaction design. As they say in one of my favorite movies, "Many men have tried. They tried and failed? They tried and died." So a short UX primer on drag-and-drop goes like this…
Users are typically familiar with drag-and-drop for two basic actions: moving-stuff-around and putting-stuff-into. For example, we move windows around the desktop or move songs around in a playlist or move icons around in a folder. Also, we put stuff into the trash or put a picture into an album or put an attachment into an email. At a fundmental level, users have an understanding of these actions because they mimic the physical world. Performing these actions via a touch interface (rather than a mouse) is even better, but that’s a story for another day.
Given these two basic actions, I’m going to design a sample app that exercises them both. This is what I came up with:
Our sample app has three drag actions. In #1, you can drag to put items from the palette into the list. In #2a and #2b, you can drag items from the list into a target box (that preforms some action). In #3, you can drag items around inside the list to reorder them. I’ll break them down one by one.
#1 — Drag List Item to Another List
Dragging from one list and dropping on another is super easy in Flex 4. Here’s a snippet:
<s:List id="sourceList" dragEnabled="true"> <s:ArrayList source="['A','B','C','D']" /> </s:List> <s:List id="targetList" dropEnabled="true"> <s:ArrayList></s:ArrayList> </s:List>
We set dragEnable=true on the source list and dropEnable=true on the target list. For bi-directional drag-and-drop, just set both attributes true for both lists. In a feat of awesomeness, Flex 4 does everything else for you. You don’t need to listen for any events or write any handlers. And you even get some nice eye candy for free, because the target list glows when you drag an item over it.
Trick 1 — When the drop target is an empty list, you must given it an empty
dataProvider. In the above example, I just use an emptyArrayListpair of tags in MXML, but I could just as easily saydataProvider="{new ArrayList()}", or even do everything in Actionscript.
Trick 2 — The source list accepts a drop—if and only if—the item being dropped is compatible with the items in the target
dataProvider. For example, you can not drop aFooobject on a list ofBarobjects. Setting the target list to have an emptydataProvider(à la Trick 1), accepts anything.
#2 — Drag List Item to UIComponent Target
Again, to use a list as the drag source, we just set dragEnable=true. But this time the target is some non-List UIComponent, so we need to do what we always do to enable drop functionality on a component—namely, attach handlers to the dragEnter and dragDrop events. Here’s a snippet:
<s:List id="sourceList" dragEnabled="true"> <s:ArrayList source="['A','B','C','D']" /> </s:List> <s:Panel id="targetA" dragEnter="dragEnterHandler(event)" dragDrop="dragDropHandler(event)"> </s:Panel>
And here are the handlers:
private function dragEnterHandler(e:DragEvent):void { DragManager.acceptDragDrop(e.currentTarget as IUIComponent); } private function dragDropHandler(e:DragEvent):void { //do something with dropped item here }
As always, we accept the drop in the dragEnter handler via the static acceptDragDrop() method on the DragManager. And once the object is dropped, we can do whatever we want with it in the dragDrop handler.
#3 — Drag List Item to Reorder Items
Finally, we want to be able to reorder the items in a list. Again, the spark List does all the work for us. We just set both dragEnable=true and dropEnable=true on the list we want to reorder. We must also set the magical dragMoveEnabled=true, which has numerous ramifications. Here is the snippet:
<s:List id="reorderList" dragEnabled="true" dropEnabled="true" dragMoveEnabled="true"> <s:ArrayList source="['A','B','C','D']" /> </s:List>
The code is trivial, but what’s going on with dragMoveEnabled=true? Well, dragMoveEnable, which defaults to false, controls whether or not an object is moved (aka removed from the source and added to the target) or copied (aka added to the target leaving the source untouched). So to reorder the items in a list, we need the move behavior, thus we set dragMoveEnabled=true.
Trick 3 — If the source list is
dragMoveEnabled=trueand the target is a non-ListUIComponent, you will see some seemingly odd behavior. Every time to drop an object on your component, it will be deleted from the source list. This is because you are only seeing the first half of the move (the item is removed from the source), and not the second half (the item is added to the target) because the target is not aList.
Trick 4 — As an alternative to
dragMoveEnabled=true, you can make a call toDragManager.showFeedback(DragManager.MOVE)in thedragEnterhandler to control whether or not an object is moved or copied. Do NOT use bothshowFeedbackanddragMoveEnabledat the same time.
Eye candy
What’s a Flex app without eye candy? But with drag-and-drop, I’d say most of the eye candy is more of a UX necessity than anything else. It’s used to indicate potential drop targets, or highlight a target that is ready to receive a drop, etc.
Glow On Enter
With list to list drag-and-drop, we get a glow on the target list for free, which tells the user that the target list is ready to receive the drop. But when dragging to a non-List UIComponent, we need to add the glow ourselves:
private function dragEnterHandler(e:DragEvent):void { myGlow.alpha = 1; DragManager.acceptDragDrop(e.currentTarget as IUIComponent); } private function dragExitHandler(e:DragEvent):void { myGlow.alpha = 0; } private function dragDropHandler(e:DragEvent):void { myGlow.alpha = 0; //do something with dropped item here }
In the dragEnter handler, we turn the glow on, and we turn the glow off on either a dragExit or dragDrop event. And we need to add a simple GlowFilter to the target component:
<s:Panel id="targetA" dragEnter="dragEnterHandler(event)" dragDrop="dragDropHandler(event)"> <s:filters> <s:GlowFilter id="myGlow" blurX="16" blurY="16" color="#3399ff" alpha="0" /> </s:filters> </s:Panel>
No magic, just use MXML to add a GlowFilter to the target component, which in this snippet is a spark Panel component.
Custom Drag Proxy
Customizing the drag proxy (what an item looks like while dragging) is fun, but I covered that previously, so there’s no need to revisit it here. On the other hand, I haven’t discussed how to customizing an item dragged from a spark List yet. It is not only fun, but also quite a bit easier.
Flex 4 makes is super easy to create a custom drag proxy by simply adding a magic dragging state to the List‘s itemRenderer. For this snippet, imagine I have a trivial ItemRenderer that just shows a centered label with black text, but when it’s being dragged I want to turn the text red:
<?xml version="1.0" encoding="utf-8"?> <s:ItemRenderer ...> <s:states> <s:State name="normal" /> <s:State name="hovered" /> <s:State name="selected" /> <s:State name="dragging"/> </s:states> <s:Label left="0" right="0" top="0" bottom="0" text="{data.label}" textAlign="center" verticalAlign="middle" color="#000000" color.hovered="#0000ff" color.dragging="#ff0000" /> </s:ItemRenderer>
As you can see from the above code, customizing the drag indicator is a huge nothing. Just add the magic dragging state to the list of states, and use Flex 4′s inline state syntax to do whatever you want. In this snippet, we set color.dragging="#ff0000" to turn the text red when its being dragged. The sample app below does quite a few more things to customize the dragged item, so check out that code too.
Custom Drop Indicator
When a user drags an item over a target spark List, a line appears to show the user where the item will be inserted. This line is known as the drop indicator. To change things up, we will make a custom drop indicator that is a dashed line.
Trick 5 — Alas, Flex 4 does not have direct support for dashed strokes, so we need to fake it. The easy way to make a dashed line in Flex 4 is to use
BitmapFill. First, we create an image that is a tileable pattern of squares. Then, we make aRectand set its fill toBitmapFillandfillMode="repeat".
The dropIndicator component is found in the fx:Declarations block of the default spark ListSkin, so we must create a custom List skin with our custom dropIndicator component. Here’s a snippet from our custom skin’s fx:Declarations block:
<fx:Declarations> <fx:Component id="dropIndicator"> <s:Group minWidth="1" minHeight="1" maxWidth="1" maxHeight="1"> <s:Rect left="0" right="0" top="0" bottom="0"> <s:fill> <s:BitmapFill source="@Embed('dash.png')" fillMode="repeat" /> </s:fill> </s:Rect> </s:Group> </fx:Component> </fx:Declarations>
As described about, we have a Rect with a BitmapFill, and an image dash.png that is a tileable pattern of squares. But the real magic is in the Group wrapper, by setting all of minWidth, maxWidth, minHeight, maxHeight to 1px we ensure we get a one pixel line as our drop indicator independent of the layout applied to our List. This is because HorizontalLayout ignore min and max height, and VerticalLayout ignore min and max width. So if we take a 1px view of our pattern of squares, we see dashes.
Conclusion
Here’s the complete drag-and-drop sample (view source enabled):
Hopefully, I covered the full spectrum of drag-and-drop functionality that the average Flex app (or even above average) is ever likely to need. If you want more, check out the links below, or just leave me a comment.
Useful Links
- My first post on drag-and-drop in Flex 4 covered a lot of drag proxy stuff.
- Flex After Dark has a solid drag-and-drop tutorial that is definitely worth reading if you are implementing drag-and-drop functionality in your app.
- Evtim, aka The Godfather, as I like to call him, has a cool post on customizing both the drag indicator and the drop indicator of the spark
Listcomponent.
Files
Testing Private Methods in Java
Posted in Justin Shacklette on November 18th, 2010 by adminadmin originally posted this on Saturnboy.
I’ve been writing a lot of Java lately, and a lot of tests. We always write tests, right? Alas, no cool record-and-playback stuff like FlexMonkey or FoneMonkey, just plain old JUnit 4 tests with plently of Hamcrest goodness.
Suddenly, I realized that I really needed to test some private methods. So, a quick google for “testing private methods java” brings up a good article by Bill Venners. He lists all possible options to test private methods:
- Don’t test private methods
- Give the methods package access
- Use a nested test class
- Use reflection
Basically, the only real one is #4, use reflection. Bill didn’t give me the exact code I needed, so lots of googling later I realized that the world is filled with opinionated people (like me), and boy do they love to talk about #1. I just wanted some code, not a lecture, so I had to write my own code. Here is that code for anyone else that just wants to test private methods.
Imagine you have a class MyClass and it has a private method, myMethod(). Sorta like this:
public class MyClass { private String myMethod(String s) { return s; } }
Then you could use reflection to invoke the method like this:
MyClass myClass = new MyClass(); Method method = MyClass.class.getDeclaredMethod("myMethod", String.class); method.setAccessible(true); String output = (String) method.invoke(myClass, "some input");
The real magic is setAccessible(true) which allows the private method to be called outside the class. And shazam, I can now test all my private methods. I was really hoping JUnit 4 would provide some additional facilities specifically for testing private methods, but not luck.
A Better Example
Here’s a more complete example. Suppose we have a NovelWriter class that in a feat of API cleanliness only exposes the writeNovel() method. It happens to have a few private utility methods that we’d like to test:
public class NovelWriter { public String writeNovel() { //...the magic goes here... return null; } private String shout(String s) { return s.toUpperCase().replaceAll("\\.", "!"); } private List<Integer> countLetters(List<String> words) { List<Integer> out = new ArrayList<Integer>(); for (String word : words) { out.add( word.replaceAll("[^A-Za-z]+","").length() ); } return out; } }
I won’t get into all the details, but it seems easy to imagine a clean API that has private helper methods. Furthermore, it seems very logical to me to want to bring all methods, both public and private, so I can be sure they are being exercised to the fullest.
Our JUnit 4 + Hamcrest test class:
public class NovelWriterTest { public static NovelWriter novelWriter; @BeforeClass public static void beforeClass() { novelWriter = new NovelWriter(); } @Test public void privateShout() throws NoSuchMethodException, InvocationTargetException, IllegalAccessException { String input = "This is magic."; Method method = NovelWriter.class.getDeclaredMethod("shout", String.class); method.setAccessible(true); String output = (String) method.invoke(novelWriter, input); assertThat(output, notNullValue()); assertThat(output, is("THIS IS MAGIC!")); } @Test @SuppressWarnings("unchecked") public void privateCountLetters() throws NoSuchMethodException, InvocationTargetException, IllegalAccessException { List<String> input = Arrays.asList("Foo", "Foobar123", "Foo Bar Baz"); Method method = NovelWriter.class.getDeclaredMethod("countLetters", List.class); method.setAccessible(true); List<Integer> output = (List<Integer>) method.invoke(novelWriter, input); assertThat(output, notNullValue()); assertThat(output.size(), is(3)); assertThat(output, hasItems(3, 6, 9)); } }
The nice thing about using the Reflection API like this is that it really doesn’t get too messy. I’m not inspecting anything at runtime, because I know exactly the return type and the types of all the parameters. I’m just invoking the method with known inputs, followed by a simple cast on the output type. And as you can see in the second test above, privateCountLetters(), it’s not a problem to use generics because we’re not doing any inspection only invocation.
Happy testing.
Files
- novel.tgz – download the complete Eclipse project
