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
The Best Kept Secret in the JDK: VisualVM
It's amazing the things that are right in front of you that you don't realise. VisualVM is probably the best example of this in the Java community.
May 28, 2009
by James Sugrue
· 226,848 Views · 7 Likes
article thumbnail
Why Java (and Other Languages) Don't Need Operator Overloading
If you knew that the language that you are reading supports it, you are just going to extend this mental path to operations that involve overridable operators.
April 13, 2009
by Cedric Beust
· 86,126 Views · 1 Like
article thumbnail
GraphML Viewer for the Web
GraphMLViewer is a freely available, Flash®-based, interactive viewer which displays diagrams, networks, and other graph-like structures in HTML web pages. It is optimized for diagrams created with the also freely available yEd graph editor and the yFiles Java diagramming library. Features of the GraphMLViewer include: Viewer application for diagrams in GraphML format: GraphMLViewer is created to display diagrams which are saved in GraphML format. GraphML is the XML-standard for saving graph-like diagrams. The viewer is optimized for diagrams which were created with the freely available yEd graph editor. Users can freely move and resize the displayed diagram A small, interactive overview of the diagram can be displayed. The current diagram can be printed. Descriptions which are added to graph elements in yEd can be displayed as tooltips. Users can navigate to URLs that can be added to graph elements in yEd via mouse click. Most of these features can be configured via parameters in the embedding HTML. This enables web authors to adapt the viewer to their requirements. The freely available yEd graph editor offers the option to export all needed files with a simple mouse click (export as "HTML Flash Viewer;" since version 3.2). GraphMLViewer makes use of the yFiles FLEX Actionscript library. This is a Flex® library that allows to integrate the viewing, editing, and animation of a wide range of diagrams, networks, and other graph-like structures into rich internet applications based on Adobe® Flex® or AIR™. For more information, please see the GraphMLViewer home page which provides more details on the features of the GraphMLViewer and explains howthe viewer can be embedded into web pages. About yWorks yWorks specializes in professional software solutions for the visualization of diagrams and graphs. Our yFiles product family offers high-quality diagramming for Java and .NET applications as well as for browser applications based on Adobe® Flex™ or AJAX technology. The extensive yFiles Java class library and the .NET class libraries yFiles.NET and yFiles WPF deliver state-of-the-art component technology which can easily be integrated into Java applications, servlets, and applets, and Windows Forms, ASP.NET, and Windows Presentation Foundation (WPF) applications, respectively. Our web products yFiles FLEX and yFiles AJAX are a perfect fit for web-based diagramming applications that use state-of-the art web technologies.
April 7, 2009
by Sebastian Mueller
· 29,584 Views
article thumbnail
JMS Message Exchange: Delphi to Open Message Queue
Delphi client library for the OpenMQ open source message broker Habari OpenMQ Client is a library for Delphi 6 to 2009 and Free Pascal which provides easy access to the Open Message Queue (OpenMQ) Message Broker. The library uses the Stomp message protocol and a plug-in architecture for communication libraries. It follows the specification of the JMS API for Message Oriented Middleware. Preview Release This release of Habari OpenMQ Client is a preview release. It requires the new version 4.4 of Open Message Queue which introduces Stomp support. Preview release tools and demo applications, 'Getting Started' guide and online API documentation are available now at http://www.mikejustin.com/ Habari client libraries are also available for Apache ActiveMQ, xmlBlaster and Amazon Simple Queue Service. About Open Message Queue (OpenMQ) Open message queue is an enterprise quality, production ready, scalable messaging server. It provides a complete Java Message Service (JMS) implementation for message oriented system integration. In addition, Open MQ provides the additional enterprise features that are necessary for enterprise deployments, large and small. It gets its roots from Java Message Queue and provides all the features, functions and capabilities of the currently available licensed product: Java System Message Queue.
March 31, 2009
by Michael Justin
· 2,128 Views
article thumbnail
Apache Camel: Integration Nirvana
Take any integration project and you have multiple applications talking over multiple transports on multiple platforms. As you can imagine, in large enterprise applications this can get complex very fast. Much of the complexity stems from two issues: 1. dealing with the specifics of applications and transports, and 2. coming up with good solutions to integration problems. Making your applications speak transports and APIs is relatively easy on its own. I'm sure everyone knows how to send JMS messages to their broker of choice; though it still requires in depth knowledge of the JMS specification, which many developers may not have. On top of that, what happens when you want to route that JMS message to another application? You then have to take care of mapping the JMS message to the application plus handle any new concepts related to the application. Add a dozen other applications into the mix and you've got quite a headache on your hands. Ignoring the mechanics of how to connect with multiple transports and APIs, we can focus on the high level design of how applications interact. Fortunately, most solutions to enterprise integration problems have been formalized already. Gregor Hohpe and Bobby Woolfe's book, Enterprise Integration Patterns: Designing, Building, and Deploying Messaging Solutions, boils down years of experience from enterprise architects into a set of sixty five Enterprise Integration Patterns (EIPs). This is great but we still have to hand code all parts of these patterns; these are not packaged solutions, only recommendations. Apache Camel was created with the intention of addressing these two issues. In this article I'll show you how it actually does this. What is Camel? Apache Camel is an open source Java framework that focuses on making integration easier and more accessible to developers. It does this by providing: • concrete implementations of all the widely used EIPs • connectivity to a great variety of transports and APIs • easy to use Domain Specific Language (DSL) to wire EIPs and transports together Figure 1 shows how these three items actually map to Camel concepts. To give you a good understanding of how Camel is organized, we will discuss Components, Endpoints, Processors, and the Domain Specific Language (DSL). There is of course a lot more going on here under the hood but we'll leave that for another discussion. Figure 1: High level view of Camel's architecture. Components are the extension point in Camel to add connectivity to other systems. The core of Camel is very small to keep dependencies low, promote embeddability, etc. and as a result contains only 12 essential components. There are over 60 components outside the core. To expose these systems to the rest of Camel, Components provide an Endpoint interface. By using URIs, you can send or receive messages on Endpoints in a uniform way. For instance, to receive messages from a JMS queue aQueue and send them to a file system directory "c:/tmp", you could use URIs like "jms:aQueue" and "file:c:\tmp". Processors are used to manipulate and mediate messages in between Endpoints. All of the EIPs are defined as Processors or sets of Processors. As of writing, Camel supports 41 patterns from the EIP book, 6 other integration patterns, and many other useful Processors. To wire Processors and Endpoints together, Camel defines a Java DSL. The term DSL is used a bit loosely here as it usually implies the involvement of a compiler or interpreter that can process keywords specific to a particular domain. In Camel, DSL means a fluent Java API that contains methods named like terms from the EIP book. Its best explained with an example from("jms:aQueue") .filter().xpath("/person[@name='Jon']") .to("file:c:\tmp"); Here we define a routing rule in a single Java statement that will consume messages from the "jms:aQueue" Endpoint, send them through a Message Filter Processor, which will then send on messages passing the XPath condition to the "file:c:\tmp" endpoint. Messages failing the condition will be dropped. You can also configure your routes in a XML-based Spring configuration file. This configuration file is a lot more verbose and less auto complete friendly than the Java DSL; many prefer it though because of its direct access to Spring concepts and no requirement for compilation after changes. Here is what the earlier example would look like in Spring: /person[@name='Jon'] These are the concepts that Camel was built upon. Since then many other interesting features have been added. Details of these are left up to the reader to investigate. To get you started, some of these include: • Pluggable data formats and type converters for easy message transformation between Artix Data Services, CSV, EDI, Flatpack, HL7, JAXB, JSON, XmlBeans, XStream, Zip, Camel-bindy, etc. • Pluggable languages to create expressions or predicates for use in the DSL. Some of these languages include: EL, JXPath, Mvel, OGNL, BeanShell, JavaScript, Groovy, Python, PHP, Ruby, SQL, XPath, XQuery, etc. • Support for the integration of beans and POJOs in various places in Camel. • Excellent support for testing distributed and asynchronous systems using a messaging approach • and much more... Example A motorcycle parts business, Rider Auto Parts, supplies parts to motorcycle manufacturers. Over the years they've changed the way they receive orders several times. Initially, orders were placed by uploading CSV files to an FTP server. The message format was later changed to XML. Currently they provide a web site to submit orders as XML messages over HTTP. All of these messages are converted to an internal POJO format before processing. Rider Auto Parts states to any new customers to use the web interface to place orders. However, because of existing agreements with customers, they must keep all the old message formats and interfaces up and running. Solution using EIPs Rider Auto Parts faces a pretty common problem; over years of operation businesses acquire software baggage in the form of transports/data formats that are popular at the time. Using patterns from the EIP book we can envision the solution as something like Figure 2. Figure 2: This shows the solution to Rider Auto Parts integration problem using notation from the Enterprise Integration Patterns book. So we have several patterns in use here. 1. There are two Message Endpoints; one for FTP connectivity and another for HTTP. 2. Messages from these endpoints are fed into the incomingOrderQueue Message Channel 3. The messages are consumed from the incomingOrderQueue and routed by a Content-Based Router to one of two Message Translators. As the EIP name implies, the routing destination depends on the content of the message. In this case we need to route based on whether the content is a CSV or XML file. 4. Both Message Translators convert the message content into a POJO, which is fed into the orderQueue Message Channel. The whole section that uses a Content-Based Router and several Message Translators is referred to as a Normalizer. This composite pattern has a unique graphic to depict it but was left out here in favor of its sub-patterns to make things clearer. Implementation using Camel As mentioned before, Camel has a small core set of components included by default. The rest of the components exist as separate modules. In applications that require many types of connectivity it is useful to figure out what Camel modules to include. Listing 1 shows the dependencies using Apache Maven for the Camel implementation of the Rider Auto Parts example. Of course, you don't need to use Apache Maven for dependencies - it is just the easiest way to rapidly add new dependencies to your applications. The list of dependencies includes support for core Camel, ActiveMQ, JAXB marshaling, CSV marshaling, and HTTP. To make the example easier to try out, I've opted to use the File endpoint instead of the FTP. If we were using the FTP endpoint we would need to add a dependency on the camel-ftp module as well. Listing 1: Maven dependencies for the Camel implementation org.apache.camel camel-core ${camel-version} org.apache.camel camel-spring ${camel-version} org.apache.activemq activemq-camel ${activemq-version} org.apache.camel camel-jaxb ${camel-version} org.apache.camel camel-csv ${camel-version} org.apache.camel camel-jetty ${camel-version} org.apache.activemq activemq-core ${activemq-version} org.apache.xbean xbean-spring ${xbean-spring-version} While it is perfectly legitimate to use Camel as a standalone Java application, it is often useful to embed it in a container. In this case, we will be loading Camel from Spring. The Spring beans XML file is shown in Listing 2. First we start an embedded Apache ActiveMQ broker and connect Camel to it. We also load up some helper beans that we will reference from the DSL. Finally, the camelContext element tells Camel to look for routes in the org.fusesource.camel package. Routes are Java classes that extend the RouteBuilder class in Camel. Listing 2: Spring XML file that configures an embedded ActiveMQ broker, several beans used in the Camel route, and initializes the Camel Context to search for routes in the org.fusesource.camel package. org.fusesource.camel The real meat of the Camel implementation lies in the OrderRouter class (shown in Listing 3). This class extends RouteBuilder, so it will be automatically picked up and loaded by Camel's runtime. Looking back at Figure 2, we need to receive orders from an FTP (substituted with File) and HTTP endpoint, formatted as shown in Listing 4. In the DSL we can specify these incoming endpoints with two from elements. Both from elements are connected to a to("jms:incomingOrderQueue") element, which will send the messages to a queue on the ActiveMQ broker. Listing 3: Route definitions for the example. The routing rules are specified using a fluent API, referred to as Camel's DSL. public class OrderRouter extends RouteBuilder { @Override public void configure() throws Exception { JaxbDataFormat jaxb = new JaxbDataFormat("org.fusesource.camel"); // Receive orders from two endpoints from("file:src/data?noop=true").to("jms:incomingOrderQueue"); from("jetty:http://localhost:8888/placeorder") .inOnly().to("jms:incomingOrderQueue") .transform().constant("OK"); // Do the normalization from("jms:incomingOrderQueue") .convertBodyTo(String.class) .choice() .when().method("orderHelper", "isXml") .unmarshal(jaxb) .to("jms:orderQueue") .when().method("orderHelper", "isCsv") .unmarshal().csv() .to("bean:normalizer") .to("jms:orderQueue"); } } In the case of the HTTP endpoint, there are a couple of extra things to mention. First off the HTTP client will be expecting a response from the application so we have to handle that. In Camel, we have full control over what the client gets back from the HTTP endpoint. Each response is determined by the last method in our current route definition (each Java statement is a route definition). In our case we use the transform method to set the response to the constant string "OK". Since we handle the response ourselves, we don’t want any response to come from the JMS incomingOrderQueue. To send to this queue in a fire-and-forget fashion we add the inOnly modifier. It is important to note at this point that when writing Camel DSL in a modern Java IDE, selection of the next processing step is easy because of auto complete. The auto complete feature basically gives you a list of processors (i.e. EIPs) to choose from at any point in your route. Since fluent APIs chain methods together, the only method you need to remember is the from; all other methods are shown via auto complete. Listing 4: Incoming message formats; XML on top, CSV below. "name", "amount" "brake pad", "2" The next section of DSL in Listing 3 specifies the Normalizer, complete with Content-Based Router and two Message Translators. First we specify that we want to consume messages from the incomingOrderQueue on the ActiveMQ broker. The content based routing of the messages is done with the choice and when methods. In our case, we want to send CSV messages to one Message Translator and XML messages to another. To check what type of message we have we will be using a simple Java bean shown in Listing 5. Of course, this is demonstration code only; for production cases you would want to add more thorough checking of content types. Listing 5: Java bean that contains helper methods to be used in the DSL. public class OrderHelper { public boolean isCsv(String body) { return !body.contains("> body) { List orderHeaders = body.get(0); List orderValues = body.get(1); return new Order(orderValues.get(0), Integer.parseInt(orderValues.get(1))); } } At this point, successfully normalized messages are sent to the orderQueue for processing by some other application at the Rider Auto Parts business. Conclusion In this article I've shown two common problems that an integration developer may face: dealing with the specifics of applications and transports, and coming up with good solutions to integration problems. The Apache Camel project provides a nice answer to both of these problems. As the example has shown, solving integration problems with Camel is straight forward and results in relatively concise code. In my opinion it is the closest thing to integration nirvana that we have today. Links Apache Camel – http://camel.apache.org FUSE Mediation Router (based on Apache Camel) – http://fusesource.com/products/enterprise-camel Enterprise Integration Patterns – http://www.enterpriseintegrationpatterns.com Jon’s Blog – http://janstey.blogspot.com Camel in Action book - http://www.manning.com/ibsen Article source code - http://repo.fusesource.com/maven2/org/fusesource/examples/rider-auto-example/1.0/rider-auto-example-1.0.zip Author Jonathan Anstey is a senior engineer working for Progress Software Corporation specializing in the enterprise integration space. Jon focuses mostly on Apache Camel and its Progress endorsed likeness, FUSE Mediation Router. He also works on the Apache ActiveMQ and Apache ServiceMix projects
March 23, 2009
by Jonathan Anstey
· 223,929 Views · 8 Likes
article thumbnail
How to Fix Memory Leaks in Java
Your pager hasn’t been sleeping well. It periodically wakes you up in the middle of the night to tell you that your server is firing off “OutOfMemoryError” messages. Worse still, your significant other forcibly relocated you to the couch and told you not to return until your pager stops buzzing. Sound familiar? If so, you may have a case of memory leak induced insomnia, but fortunately we’ve got a cure for what ails you. This tutorial will teach you everything you need to know to ease your suffering, including what memory leaks are, why they happen, and how to diagnose and fix ‘em. In this article we’ll focus on techniques that will enable you to address memory leaks with any commercial or free/open source memory profiler; we’re not here to recommend one tool over another. After all, the most important thing is that you fix the problem and get some rest, not the tool you use to get it done. Before You Start Ever heard the story about how Java has “automatic memory management”—you know, the one that someone in marketing upgraded to an epic tale about how you’ll never have to worry about memory leaks ever again? As is often the case, the truth is more complex than the marketing department made it out to be. While it’s true that Java’s garbage collector (GC) helps to eliminate the most common memory leak issues from applications, it is unfortunately still possible to experience memory leaks in Java. However, they happen a lot less often than they used to in the C or C++ days. Many people believe that black magic and complex tools are required to fix memory leaks. This undeserved reputation is caused by the lack of good explanations of what they are and what to do when you encounter them. But with the proper tools and knowledge to fix memory leaks, they aren’t nearly as intimidating. Methodology In this article we’ll cover everything from memory leak basics to analyzing heap dumps, so—whether you’re an experienced Java developer or encountering Java memory leaks for the first time—you’ll be better prepared to deal with memory leaks by the time you reach the conclusion. We won’t outline a series of steps, like “do ABC with commercial tool XYZ and don’t ask why,” as that approach doesn’t work and implies that remedies are more complex then they really are. Instead, we’ll give you the background information necessary to address memory leaks, with emphasis placed on particular steps you’ll need to execute. Similarly, we’ll assume that you can learn on your own how to use the memory profiler of your choice; what’s missing is an understanding of what the tool is trying to do and why, so that will be the focus of this article. Java will be used for all examples, so all information in this article directly applies to Java applications running standalone or as a part of J2EE/JEE/Tomcat-based application server. But remember, although our primary focus is on Java, most of the process of diagnosing and fixing memory leaks described herein applies to other languages with garbage collectors. So even if you’re using Ruby, C#, or Python, there should be something for you in this article. What Are Memory Leaks? Let’s start by describing how memory leaks happen in Java. Java implements automatic garbage collection (GC), and once you stop using an object you can depend on the garbage collector to collect it. While additional details of the collection process are important when tuning GC performance, for the sole purpose of fixing a memory leak we can safely ignore them. When is memory eligible for GC? Let’s take a look at an example: We don't have to do anything special to make an object eligible for GC—we just eliminate any references to it, and it "magically" disappears and stops using memory. That's why we say that Java performs "automatic" GC. Why "eligible" for GC? Because objects are not collected immediately. GC is not instantaneous and comes with some performance impacts. Consequently, Java doesn't immediately collect every object that is eligible for collection; it typically postpones collection until a more convenient time later on. The way to think about GC in Java is that it's a "lazy bachelor" that hates taking out the trash and typically postpones the process for some period of time. However, if the trash can begins to overflow, Java immediately takes it out. In other words, if memory becomes scarce, Java immediately runs GC to free memory. Since we don't need to do anything special in order to dispose of objects in Java, how do memory leaks happen in Java? Memory leaks occur when a program never stops using an object, thus keeping a permanent reference to it. Let's take a look at an example that helps illustrate this point. The following code will cause all available memory in the JVM to be exhausted: When no more memory is remaining, an OutOfMemoryError alert will be thrown and generate an exception like this: Exception in thread "main" java.lang.OutOfMemoryError: Java heap space at MemoryLeakDemo.main(MemoryLeakDemo.java:14) In the example above, we continue adding new elements to the list memoryLeakArea without ever removing them. In addition, we keep references to the memoryLeakArea, thereby preventing GC from collecting the list itself. So although there is GC available, it cannot help because we are still using memory. The more time passes the more memory we use, which in effect requires an infinite amount memory for this program to continue running. This is an example of unbounded memory leak—the longer the program runs, the more memory it takes. So even if the memory size is increased, the application will still run out of memory at a later date. Meat & Potatoes Fixing Memory Leaks As illustrated by the flowchart below, the process of fixing memory leaks is fairly simple: Memory leaks are misunderstood creatures. Just getting an OutOfMemoryError alert doesn’t necessary mean that you're suffering from a memory leak. So, before you dive into "fixing" the problem, you must first find out whether or not a memory leak actually exists. If a memory leak does in fact exist, the next step is to determine which objects are leaking and uncover the source of the memory leak. Then, you fix it. We'll skip past the initial steps and dive right into diagnosing whether or not the problem is a memory leak. Is My Program Leaking Memory? Not every OutOfMemoryError alert indicates that a program is suffering from a memory leak. Some programs simply need more memory to run. In other words, some OutOfMemoryError alerts are caused by the load, not by the passage of time, and as a result they indicate the need for more memory in a program rather than a memory leak. To distinguish between a memory leak and an application that simply needs more memory, we need to look at the "peak load" concept. When program has just started no users have yet used it, and as a result it typically needs much less memory then when thousands of users are interacting with it. Thus, measuring memory usage immediately after a program starts is not the best way to gauge how much memory it needs! To measure how much memory an application needs, memory size measurements should be taken at the time of peak load—when it is most heavily used. The graph below shows the memory usage in a healthy Java application that does not suffer from memory leaks, with the peak load occurring around 10 AM and application usage drastically decreasing at 5 PM. Naturally, the peak load on business applications often correlates with normal business hours. The application illustrated by the chart above reaches its peak load around 10 AM and needs around 900MB of memory to run. This is normal behavior for an application suffering from no memory leaks; the difference in memory requirements throughout the day is caused solely by the user load. Now, let's suppose that we have a memory leak in the application. The primary characteristic of memory leaks is that memory requirements increase as a function of time, not as a function of the load. Let's see how the application would look after running for a few days with a memory leak and the same peak user loads reached around 10 AM every day: Because peak loads on the system are similar every morning but memory usage is growing over a period of a few days, this picture indicates a strong possibility of memory leaks. If the program eventually started suffering from OutOfMemory exceptions, it would be a very strong indication that there’s a problem with memory leaks. The picture above shows a memory leak of about 100MB per day. Note that the key to this example is that the only thing changing is the amount of time the system is up—the system peak load doesn’t change over time. This is not the case for all businesses. For example, the peak load for a tax preparation service is seasonal, as there are likely more users on the system in April than July. There is one special case that should be noted here: a program that needs to be restarted periodically in order to prevent it from crashing with an OutOfMemoryError alert. Imagine that on the previous graph the max memory size was 1100MB. If the program started with about 900MB of memory used, it would take about 48 hours to crash because it leaks about 100MB of memory per day. Similarly, if the max memory size was set to 1000MB, the program would crash every 24 hours. However, if the program was regularly restarted more often than this interval, it would appear that all is fine. Regularly scheduled restarts may appear to help, but also might make “upward sloping memory use” (as shown in the previous graph) more difficult to notice because the graph is cut short before the pattern emerges. In a case like this, you’ll need to look more carefully at the memory usage, or try to increase the available memory so that it’s easier to see the pattern. Monitoring Memory in Java As you are already aware, you need to measure memory that is free and used inside of the JVM, not memory that the JVM process is using. In other words, the top/Task Manager/Activity Monitor will measure how much memory your Java process is using, but that’s not what you need. You need a tool that can look inside the JVM process and tell you how much memory is available for your program running inside the JVM. In addition, keep in mind that Java GC is not a constant process—it runs in intervals. The memory usage that you see in the JVM is usually higher then what your program needs at the moment, as GC hasn’t yet run. Remember, lazy bachelors usually have some trash in their apartments waiting to be taken out. So, what you need to investigate is not current memory usage, but rather the average usage over a long period of time. For example, if your program is currently using 100MB of memory and five seconds later it’s using 101MB, that’s not an indication of a memory leak because GC might free up memory when it eventually runs. But if your program’s memory usage increases over a long period of time under constant usage, you might have trouble on your hands. There are a couple of options for measuring the amount of memory a program uses. The simplest one, which does not require any tools and works even with production systems, is the Verbose GC log. Verbose GC Log The Verbose GC log is defined when the JVM process is started. There are a couple of switches that can be used: -verbose:gc — prints basic information about GC to the standard output -XX:+PrintGCTimeStamps — prints the times that GC executes -XX:+PrintGCDetails — prints statistics about different regions of memory in the JVM -Xloggc: — logs the results of GC in the given file The following is an example of the output generated for Tomcat running in the default configuration with all of the previous switches enabled: 1.854: [GC 1.854: [DefNew: 570K->62K(576K), 0.0012355 secs] 2623K->2175K(3980K), 0.0012922 secs] 1.871: [GC 1.871: [DefNew: 574K->55K(576K), 0.0009810 secs] 2687K->2229K(3980K), 0.0010752 secs] 1.881: [GC 1.881: [DefNew: 567K->30K(576K), 0.0007417 secs] 2741K->2257K(3980K), 0.0007947 secs] 1.890: [GC 1.890: [DefNew: 542K->64K(576K), 0.0012155 secs] 2769K->2295K(3980K), 0.0012808 secs] The most important set of numbers is located in the second column after the second -> (e.g., in the top line shown it is 2623K->2175K(3980K). These numbers indicate that as a result of GC, we are using around 2200K of memory at the end of each GC cycle. This trace is not an indication of a memory leak—it shows a short-term trend with less then a second between samples, and that’s why we must observe long-term trends. However, if the Verbose GC log showed that the program was using around 2200K of memory after running for two days, and after running for 10 days it was using 2GB of memory (even after GC had just run), we could then conclude that there’s a memory leak. All the information that needs to be collected in order to determine if a memory leak exists can be found in the results of the Verbose GC logs. The other memory monitoring tools we’ll cover in this article simply provide more information in a form that’s easier to interpret. Monitoring the Java Process The following approach works for any Java process, including standalone clients as well as application servers like JBoss and servlet containers like Tomcat. It is based on starting the Java process with JMX monitoring enabled and attaching with the JMX monitoring tools. We’ll use Tomcat in the following example. To start Tomcat or the Java process with JMX monitoring enabled, use the following options when starting JVM: -Dcom.sun.management.jmxremote — enables JMX monitoring -Dcom.sun.management.jmxremote.port= — controls the port for JMX monitoring Note that if you’re on a production system, you’ll most likely want to secure your JVM before running it with these parameters. For that, you can specify these additional options: com.sun.management.jmxremote.ssl com.sun.management.jmxremote.authenticate Once started, you can use JConsole or VisualVM to attach to the process. Note that later JDK 6 versions include VisualVM. This is an example of the JConsole monitoring Tomcat. As shown in the example below, click on the Memory tab to get memory information: Again, we're interested in the long-term trends of heap memory usage, not trends from just a few minutes of running. Finally, note that monitoring tools like Hyperic can typically show historical trends over longer periods of time than VisualVM or JConsole. In addition, tools like Hyperic allow for more fine-grained control over operations that are permitted by users. As a result, we recommend using monitoring tools for production systems use, while all the other tools discussed in this section are more appropriate for developers or "first aid" in the absence of the real monitoring tools. Speed Kills We now know how to find out whether or not a memory leak exists, and we can even determine the speed at which we're leaking memory (e.g., 100MB per day). But are we better off with a "slow" leak (e.g., 1MB per day) or a "fast" leak (e.g., 500MB/hour)? It depends. With a "slow" leak, it takes longer for the system to run out of memory. For example, if we have 256MB of free memory remaining at the peak load time, it can take quite a long time to run out of memory with a 1MB/day memory leak. On the other hand, a faster memory leak makes it easier to reproduce and fix the problem. One of the best ways to quickly determine whether there's a fast memory leak or you simply need more memory to run at the peak time is to allot more memory to the program and see what happens. If you increase the available heap in a Java program and the time between crashes increases, you are likely suffering from memory leak. Let's assume that we're lucky enough to have a fast memory leak—on the order of 100MB per hour—on our hands, and that the initial memory picture looks like this: In this example, we can expect to run out of memory after about five hours of running time. How To Find Leaked Objects in a Fast Memory Leak Somewhat surprisingly, it is much easier to debug large memory leaks than small memory leaks. The reason is that memory leaks present a sort of "needle in the haystack" type problem—you need to find the leaked objects amongst all the other objects in the program. Suppose that the program we're debugging just ran out of memory. If the program initially had 512MB of free memory and now has none, it is obvious that the leaked objects used about 512MB of memory. The figure below illustrates this example: In this situation, half of the objects in memory have been leaked! If we randomly select an object, there's a 50% chance that it has leaked. And as memory leaks usually consist of objects of a few classes, you can get a really good start on determining which objects are leaking memory by sorting memory usage based on aggregate memory use of all objects of the same class. What if the ratio is less favorable (e.g., 512MB heap size, initially used memory 480MB, and 32MB of leaked objects at the end)? If you have an easy to reproduce memory leak, you can increase the heap size because an unbounded memory leak will eventually fill any amount of memory allotted to the program. So, you can increase the heap to 1GB, reproduce the memory leak, and get 544MB of leaked objects in a 1GB of heap. If we had a way to look at the "complete picture" of memory, it would be fairly easy to pinpoint leaked objects. Fortunately, there's a way to do exactly this: heap dump the process. Dump me Gently A heap dump is a list of objects in the memory of JVM as well as the content of the memory occupied by those objects. It preserves the value of any attributes of the objects, including references to other objects. In other words, a heap dump gives you a complete picture of the memory. There are multiple tools that allow you to dump heap in a Java process: If you're using JDK 6, you can use tool called jmap on any platform. If you're using JDK 5, the situation is slightly more complex: If you're running UNIX (Linux, Solaris, OS X) with JDK 5 you can use jmap. If you're using JDK 5 update 14 or later, you can use the -XX:+HeapDumpOnCtrlBreak option when starting JVM, then use the CTRL+BREAK key combination on Windows (or CTRL + \ on UNIX) to dump the heap. If you're running Windows and using JDK 5 pre-update 14, you'll soon wish you weren't. Trying to reproduce the problem with a more recent JDK is probably the best bet here. Some tools like VisualVM and memory profilers allow you to initiate a heap dump from the GUI, but you don’t need any fancy tools here—jmap will do just fine. As it provides the most general case, we'll use jmap in the next example. Before you dump heap, be sure to keep the following issues in mind: Programs in the JVM should be paused for the duration of the heap dump, which might take anywhere from ten seconds to several minutes. Many enterprise applications—and users of those applications—don’t take kindly to pauses that long, which may cause various timeouts to expire. So don’t try this at home or in production (unless the application is already a goner)! Heap dumps are saved on disk, and the files might be fairly large. A good rule is to make sure that you have at least twice the size of the physical memory free on the disk before you initiate a memory dump. With those final words of caution out of the way, you should now be ready to run the following command: jmap -heap:live,format=b,file=FILENAME PID Note that the -F option, which will dump non-responsive programs, might be useful on UNIX systems, but is not available on Windows. Note also that JDK 6 includes the option +XX:+HeapDumpOnOutOfMemoryError that will dump heap whenever the OutOfMemoryError alert is encountered. This can be a useful option, but keep in mind that it has the potential to consume significant amounts of disk space. You now have a heap dump in the file FILENAME and are ready to analyze it. What's In "Leaked" Memory? With the heap dump complete, we can now take a look at the memory and find out what's really causing the memory leak. Suppose that objects are holding references to each other as illustrated by the picture below. For the sake of easy calculation, let's assume that each object is 100 bytes, so that all of them together occupy 600 bytes of memory. Now, suppose that the program holds reference to object A for a prolonged period of time. As a result, objects B, C, D, E, and F are all ineligible for garbage collection, and we have the following amount of memory leaking: 100 bytes for object A 500 bytes for objects B, C, D, E and F that are retained due to the retention of object A So, holding reference to object A causes a memory leak of 600 bytes. The shallow heap of object A is 100 bytes (object A itself), and the retained heap of object A is 600 bytes. Although objects A through F are all leaked, the real cause of the memory leak is the program holding reference to object A. So how can we fix the root cause of this leak? If we first identify that object F is leaked, we can follow the reference chain back through objects D, C and A to find the cause of the memory leak. However, there are some complications to this "follow the reference chain" process: Reference chains can be really long, so manually following them can be time consuming An object is sometimes retained by more then one object, and there can even be circles involved as shown in the picture below: If we start following inbound references from object F in this example, we have to choose between following object C or object D. In addition, there's the possibility of getting caught in a circle by repeatedly following the path between objects D, E and B. On this small diagram it's easy to see that the root cause is holding object A, but when you're dealing with a situation that involves hundreds of thousands of objects (as any self-respecting memory leak does) you quickly realize that manually following the reference chain be very complex and time consuming. This is where some shortcuts can come in handy: If we had a tool that allowed us to play a "what would happen if I remove this reference" type of guessing game, we could run experiments that help locate the cause. For example, we could see that if we removed reference from "Cause of Leak" to A in the diagram above, objects A through F would all be freed. Some tools (like Quest's JProbe) have this capability. If the memory leak is large and we have a tool that allows us to sort objects by retained heap, we'll get an even greater head start because the objects with the largest retained heap are usually the cause of large memory leaks. Now that we understand what memory leaks are and how they can be corrected, let's find out how to fix them by analyzing heap dumps. Tools for Dealing with Heap Dumps Strictly speaking, you don’t need any tools that are not already part of the JDK. JDK ships with a tool called jhat, which you can use to inspect the heap dump. The process of fixing memory leaks is the same with all tools, and it's our opinion that no single tool is "light years" ahead of the others when it comes to fixing memory leaks. Although jhat will get the job done, better tools often provide a few extra helpful features: Present a better summary of heap statistics. Sort objects by retained heap. In other words, some tools can tell you the memory usage of an object and all other objects that are referenced by it, as well as list the objects referenced by other objects. This makes it much faster to diagnose the cause of a memory leak. Function on machines that have less memory then the size of the heap dump. For example, they'll allow you to analyze a 16GB heap dump from your server on a machine with only 1GB of physical memory. There are several free tools that are useful for analyzing heap dumps in Java. One that's widely used and is even included with the later versions of the JVM 6 is VisualVM. VisualVM is nice tool that gives you just enough to resolve memory leaks, and it shows heap dumps and relations between objects in graphical form. Feature-wise, one step above VisualVM is the Eclipse Memory Analyzer Tool (MAT), a free tool that includes a lot of additional options. Although it's still in incubation phase as of publication of this article, MAT is free and we've found it to be extremely useful. Commercial products like JProfiler, YourKit, and JProbe are also excellent tools for debugging memory leaks. These applications include a few options that go above and beyond VisualVM and MAT, but they're certainly not necessary to successfully debug memory leaks. Unless you already have a license for one of these commercial tools, we recommend trying MAT first. Analyzing the Heap Dump for Fast Memory Leaks It's usually easy to find a fast memory leak. A lot of memory is leaked, and you simply need to find the big hog that leaked all that memory. Analyzing the heap dump is done in order to: Find objects that are "leaking" Find the root cause of the memory leak If you have a fast memory leak and are able to reproduce it in such a way as to make the leaked objects a significant portion of the final memory picture, then determining which objects are leaked is simple because they occupy a significant portion of the memory. To determine which objects are leaked, sort the classes by total memory usage of all instances of each class. The objects near the top of the list are usually the leaked objects. Then, you can follow the reference chain to them until you find the cause of the memory leak. A useful heuristic here is that if you sort all the objects by retained heap, you can find the objects that are likely the root cause of the memory leak. Again, an example: If we assume that each instance of object C is 100 bytes, then holding object A resulted in a memory leak of almost 1GB! In other words, the retained heap of object A in this example is about 1GB. So, if we were investigating this memory leak, it would be fairly obvious that we should start there. Remember, the Eclipse Memory Analyzer Tool (MAT) allows you to sort the heap dump by the retained heap usage of the objects, so it would have been easy to use MAT to determine the retained heap of object A. Slow and Small Memory Leaks It always helps if you can easily reproduce the problem, but what if the memory leak is really small and slow? What should you do if after a few days you can reproduce only a 10MB leak in a heap that contains 2GB of objects? In situations like this, looking for the cause of the problem can feel like finding a needle in the haystack. One solution in this case is the brute force approach—simply devote enough time looking at the objects to find the problem. While that will ultimately work, there's another way to address the problem if you have an idea of which operations are leaking memory. If you know or suspect which operations leak memory, you can find even relatively slow memory leaks. The secret here is to compare heap dumps, as this highlights objects that are present in one heap dump but not in another. For example, suppose that objects A, B, and C are present in the first heap dump, while objects A, B, C, D, and E are present in the second heap dump. In this case, objects D and E are the difference. Comparing heap dumps makes it easier to find memory leaks because it effectively reduces the size of the "haystack" containing your needle. Comparing heap dumps can easily reduce the size of the objects for which you need to examine heaps from 2GBs to a few KB. Many commercial profilers as well as Eclipse MAT can be used to compare heaps. Once you've selected a tool that can compare heaps, simply follow the process explained in the following diagram: In effect, what you’re doing is creating two snapshots, one before and one after executing the use case that you know is leaking memory. That way, you significantly reduce the number of objects that you need to investigate to find leaked objects. After you find the objects that leaked, you can find the cause of the memory leak as described in the previous section. Why perform garbage collection before taking a snapshot? Because some tools won’t automatically perform GC for you, and consequently the snapshots might include objects that are no longer reachable. Many modern tools will perform GC before taking the snapshot, but if you are unsure whether or not your tool performs full GC before taking a snapshot it is recommended that you do so yourself. That way you don’t have to worry about objects that are eligible for GC but have not yet been collected. Among the objects that are created during the use case, some are supposed to be there because they are the result of the use case execution (e.g., we created a new customer, and that customer object should be retained), while other objects are the memory leak. However, since the only objects present in the difference between the snapshots are the ones that were created during the use case, the size of the haystack you need to look through is significantly reduced. Practical Problems Why do memory leaks sometimes take a long time to fix if the process is this simple? In our opinion, the main reasons are: There isn’t a sufficient amount of easily available information about fixing Java memory leaks. We hope this article will help improve the situation. It can be difficult to reliably reproduce an issue, and a lot of time is typically required to reproduce an issue before you can really start addressing it. People lack the right tools for the job—in particular, memory profilers. With many free profilers available and reasonably low prices for commercial profilers, there’s no reason you shouldn’t have good tools in your toolbox. There are a few practical issues with the use of tools and techniques that might be perceived as road blocks the first time someone tries them. We’ll address some of these issues below. Fortunately, the practical issues most commonly encountered aren’t very difficult to solve. The most common problems are: You can’t load the snapshot because you don’t have enough memory in your development box. For example, this can easily happen if you have 64-bit servers with 8GB of memory allocated to the JVM. You might not have physical memory in your development box, or you might be using the 32-bit JVM on your development box, but the tool you’re using insists on loading most of the snapshot into memory. If you like the idea of having a really powerful development box, use this situation to your advantage and ask your boss for a new machine. Alternatively, try using a tool with less of an appetite for memory, like Eclipse MAT. You can’t increase your memory on the server to get a bigger set of leaked objects, yet you need a bigger set of leaked objects to speed up the process of finding the memory leak. This often happens with 32-bit JVMs. One option in this situation is to apply the techniques described above for finding slow memory leaks, although this approach requires a significant amount of time. Alternatively, you can try to reproduce problem on a 64-bit JVM, which will allow you to increase the memory. If the problem causing the memory leak is in your application, changing the JVM is extremely unlikely to “hide” the leak. The memory leak is not in objects of just one class—you’re leaking objects from thousands of classes, so it’s difficult to find leaked objects. Or, your graph of object relations is so complex that you can find the initially-leaked objects but can’t locate the cause. In either case, you’ve got quite a pickle on your hands. The only words of encouragement we can offer are that the situation will eventually improve, as the longer you track object references the better you’ll get at it. One other piece of advice: you should probably call your significant other and let him or her know that you won’t be home for dinner. You’re getting an OutOfMemoryError alert with a new, different format. For example, you might be looking at something like this: Exception in thread “pool-2-thread-1″ java.lang.OutOfMemoryError: GC overhead limit exceeded. This message can happen with some GC settings that limit the overhead of the GC. It often indicates a memory leak, although there are some corner cases in which problems with GC performance can cause it. The best way to distinguish the cause of this message (is it a GC misconfiguration or a memory leak?) is to examine the pattern of errors. If they happen with regularity (in other words, they’re a function of time the program is running), then it’s a memory leak. If they happen only occasionally under heavy loads and clear later (in other words, they’re not a function of running time), they might indicate a need to tweak the GC or increase available memory. 3rd party caching systems can be setup so that caches are allowed to expand and fill up the available memory the program doesn’t need. However, if the program no longer needs more memory, the cache automatically releases it. The point here is that in the absence of any OutOfMemoryError alerts, continually increasing memory usage does not necessary indicate a memory leak. Both “used memory grows as function of time” and “free memory eventually runs out” conditions are necessary in order to determine the presence of a memory leak. Finishing Up This article described the methodology and techniques necessary to fix memory leaks. These techniques are universal—they apply to any profiler, and some of them even apply to languages other than Java that use garbage collection. The information presented above should give you everything you need in order to use the tools of your choice to investigate and fix memory leaks. The proper usage of specific tools will be discussed in future articles, which will focus primarily on free tools and problems in Java. However, if there’s enough interest we might tackle other languages as well. If you’re interested in follow-up articles related to memory leak resolution in a different environment or language, please leave a comment or contact us at docs-at-openlogic.com. Additional Resources The following links provide additional information on the behavior of GC in Java as well as different tools that you may find useful. http://java.sun.com/j2se/1.5.0/docs/guide/management/agent.html http://java.sun.com/j2se/1.5.0/docs/guide/management/jconsole.html http://java.sun.com/j2se/reference/whitepapers/memorymanagement_whitepaper.pdf http://java.sun.com/developer/technicalArticles/Programming/GCPortal/ http://java.sun.com/docs/hotspot/gc5.0/gc_tuning_5.html http://www.eclipse.org/mat/ https://visualvm.dev.java.net/ http://www.ej-technologies.com/products/jprofiler/overview.html http://www.yourkit.com/ http://www.quest.com/jprobe/ http://java.sun.com/j2se/reference/whitepapers/memorymanagement_whitepaper.pdf http://java.sun.com/javase/6/docs/technotes/tools/share/jhat.html http://java.sun.com/j2se/1.5.0/docs/tooldocs/share/jmap.html http://java.sun.com/j2se/1.5.0/docs/tooldocs/share/jstat.html The above article originally appeared on Wazi, a clearinghouse for the timeliest thinking on open source software."
March 18, 2009
by Veljko Krunic
· 295,313 Views · 2 Likes
article thumbnail
Dynamic Java Programming With Rule Engine
Rules are statements that define business procedures and policies. Normally, every business application contains many embedded business rules that determine business process flow and execution. When we program these rules with static languages like Java, there is no problem at all. However, the problem is that some business rules change over time very frequently. It is very expensive to fix these changing parts since it requires new versions and software development cycles; develop, deploy on a test server, test, package, deploy on a production server etc. Here “Dynamic Programming” comes to our rescue. Our program doesn’t have to necessarily be written with a dynamic language. We can use this advantage in Java with Rule Engine mechanism. Rule Engines don’t serve only the dynamic programming. They evaluate rules and extract some inferences by using some algorithms like RETE. This inference mechanism is hardly possible with many “if-else” statements in normal program code. Rule Engines have generally 4 types of rules; Constraint Rule: We may need to define restriction or limits for some entities. “A customer sales order amount must be lower than 100 if the plant is over capacity ” Validation Rule: Some validation rules may change over time. “Production order can’t be accepted if current day is Sunday” Action Rule: Some actions may be triggered. “Send a notification e-mail if a purchase order is over $1000 to boss”. Computation Rule: Some formula may be executed. “Discount is 20% if customer is Mr. Anderson” We can use Rule Engines on the market but even we can write our own Rule Engine to benefit the dynamic programming in Java. By using Java compilers, classloaders, it is not so much hard. My favorite rule definition format is Java source code instead of some natural languages or XML. This can also reduce the overall development cost of your custom rule engine. By writing Java rule definitions, we can also use the IDE debugger features without learning a new syntax. If we develop our own Rule Engine, we may skip the inference engine part since we only want dynamic programming feature for now. Best place for plugging rule execution is database access layer. Rules should work invisibly behind the database objects. In some cases, some rules might be invoked from static program codes. The benefits that we have when using Rule Engine are: Dynamic programming with hotswapping feature that provides fix&run easiness. Minimal cost of business rule changes that occurs many times. Accumulation of business rules in one place that may result re-usability and code repetition prevention. Dynamic validations that may change over time. Constraints can be defines for default values, assertion checks etc. In any time rule may be turned off/on. Some of the features of Rule Engine may remind us database constraints and triggers. Using database may hinder portability and require DBA involvement. I think Rule Engine is better for business rule definitions. These database features may be used for other purposes. The critical question we should ask ourselves is which part of business rules should be taken into Rule Engine from the programs. The answer is “frequently changing” rules. Some changing parts can be defined within parameter tables (processing options) but we can’t define computation or many if-else statements in these tables. But we should prefer parameter table if it is enough for the problem. Links: http://java.sun.com/developer/technicalArticles/J2SE/JavaRule.html http://www.javaworld.com/javaworld/jw-04-2005/jw-0425-ruleengine.html http://www.javaworld.com/javaworld/jw-06-2006/jw-0612-dynamic.html http://www.amazon.com/Principles-Business-Addison-Wesley-Information-Technology/dp/0201788934/ref=sr_1_3?ie=UTF8&s=books&qid=1236927606&sr=1-3 http://www.amazon.com/Business-Rules-Applied-Building-Approach/dp/0471412937/ref=sr_1_1?ie=UTF8&s=books&qid=1236927606&sr=1-1
March 13, 2009
by Adam Brown
· 33,233 Views
article thumbnail
Event-based actors in Groovy
After publishing my earlier post on Thread-bound actors in Groovy I've received several requests to enhance GParallelizer with support for event-based actors. To briefly recap, actors allow for messaging-based concurrency model, built from independent active objects that exchange messages and have no mutable shared state. Actors naturally avoid issues like deadlocks, livelocks or starvation, so typical for shared memory. Event-based actors unlike the thread-bound actors described in the original post share a common pool of threads, from which they only borrow a thread to handle a single incoming message and then give it back to the pool so that the thread can serve other actors in turn. Actors become detached from the underlying threads and so a relatively small thread pool can serve potentially unlimited number of actors. Virtually unlimited scalability in number of actors is the main advantage of event-based actors over thread-bound ones, where each actor has its own exclusive background thread associated with it. Implementing the capability to dynamically attach and detach actors and threads is a bit of a challenge. However, in turned out that life is much easier if you can stand on the shoulders of giants - the java.util.concurrent package and Groovy in my case. To give you a taste of what is now possible with event-based actors in GParallelizer, I've prepared a couple of examples: import static org.gparallelizer.actors.pooledActors.PooledActors.* final def decryptor = actor { loop { react {String message-> reply message.reverse() } } }.start() actor { decryptor.send 'suonorhcnysa si yvoorG' react { println 'Decrypted message: ' + it } }.start() As you can see, you create new actors with the actor() method passing in the actor's body as a closure parameter. Inside the actor's body you can use loop() to iterate, react() to receive messages and reply() to send a message to the actor, which has sent you the currently processed message. With the start() method you schedule the actor to the underlying thread pool for processing. Here's the important piece: when the decryptor actor doesn't find a message in its message queue, the react() method gives up the thread and returns it back to the thread pool for other actors to pick up. Only after a new message arrives to the actor's message queue, the closure of the react() method gets scheduled for processing with the pool. Event-based actors internally simulate continuations - actor's work is split into sequentially run chunks, which get invoked once a message is available in the inbox. Each chunk for a single actor can be performed by different thread from the thread pool. Simple calculator Another example of an event-driven actor - a calculator that receives two numeric messages, sums them up and sends the result to the console actor. I deliberately decided to set the pool size to 1 to show that even a one-thread pool can handle multiple actors. import static org.gparallelizer.actors.pooledActors.PooledActors.* //not necessary, just showing that a single-threaded pool can still handle multiple actors getPool().initialize 1 final def console = actor { loop { react { println 'Result: ' + it } } }.start() final def calculator = actor { react {a -> react {b -> console.send(a + b) } } }.start() calculator.send 2 calculator.send 3 Notice that event-driven actors require special care regarding the react() method. Since event-driven actors need to split the code into independent chunks assignable to different threads sequentially and continuations are not natively supported on JVM, the chunks are created artificially behind the scenes with Runnable tasks and exceptions. As a result the react() and loop() methods never return normally and actors' code must be structured accordingly. Scala programmers would see where I took inspiration from by now, I believe. The react() method allows timeouts to be specified using the TimeCategory DSL: import static org.gparallelizer.actors.pooledActors.PooledActors.* def me = actor { friend.send('Hi') react(10.seconds) {message -> //continue conversation } } me.metaClass.onTimeout = {->friend.send('I see, busy as usual. Never mind.')} Notice the possibility to use Groovy meta-programming to define actor's lifecycle notification methods (e.g. onTimeout()) dynamically. Concurrent Merge Sort Example For comparison with the example given for thread-bound actors I'm including a more involved example performing a concurrent merge sort of a list of integers using actors. As you can see, we came pretty close to the Scala's model, although Scala's pattern matching for message handling is still something to long for. Closure createMessageHandler(def parentActor) { return { react {List message -> assert message != null switch (message.size()) { case 0..1: parentActor.send(message) break case 2: if (message[0] <= message[1]) parentActor.send(message) else parentActor.send(message[-1..0]) break default: def splitList = split(message) def child1 = actor(createMessageHandler(delegate)) def child2 = actor(createMessageHandler(delegate)) child1.start().send(splitList[0]) child2.start().send(splitList[1]) react {message1 -> react {message2 -> parentActor.send merge(message1, message2) } } } } } } def console = actor { react { println "Sorted array:\t${it}" } }.start() def sorter = actor(createMessageHandler(console)) sorter.start().send([1, 5, 2, 4, 3, 8, 6, 7, 3, 9, 5, 3]) This example shows the main advantage of event-driven actors - no matter how big array you want to sort and thus how many actors you create along the way, it can all be processed with one thread. There are certainly still some rough edges and missing pieces. Now I'd like to get some feedback to drive me further. Feel free to download GParallelizer and let me know what you think. All comments are appreciated.
March 5, 2009
by Vaclav Pech
· 16,350 Views
article thumbnail
Performance Monitoring Using Glassbox
The industry is recognizing the fact that performance testing & engineering should be part of the project execution road map starting from the requirements gathering phase. At many times during project executions, performance engineering related activities are executed based on customer need or slow response time of application after development phase gets completed. Glassbox can be leveraged (by developers/testers/business users) during and after the development cycle to monitor the response times of requests with-out being aware of underlying application structure and code details. Analysis generated by Glassbox gives direct pointers on where is the bottleneck which causes slow response time for that particular request/page/URL. About Glassbox Glassbox is an open source web application which aid in performance monitoring and troubleshooting of multiple web applications deployed in container. Troubleshooting It contains the built-in knowledge repository of common problems which are used to pinpoint the issues and suggestions on causes as Java code executes. Performance Monitoring It monitors the requests as Java code executes and provides details about response times. Glassbox web client (AJAX GUI) provides nice summary dashboard view which contains various attributes like (server-name, application name, operation/request-URL, average time, no. of executions, status (slow / OK) and analysis details). By default, an operation that takes more than 1 sec execution time is marked as SLOW status. Such SLA can be modified using Glassbox properties file. Analysis part describes the problem precisely and very clearly in plain English words, rather than displaying large code/exception trace. This definitely increases developer productivity by reducing developer’s time spent in log files and using IDE debuggers. Internals The two main components of Glassbox are Monitor and Agent. Monitor uses Aspect-Oriented Programming (AOP) to monitor the JVM activity. Agent diagnoses and presents the monitoring results and uses knowledge repository to cross reference the problem with suggestions/solutions. Glassbox agent supports viewing of the analysis results using JMX (eg. Java 5 JConsole) Consoles. Glassbox extensively uses the AOP approach internally to monitor the Java code. This gives the benefit of not making any changes to source code or build-process and hence can work with any legacy web application/jar file as well. Technologies Glassbox should work on any application server that supports Servlet 2.3 or later. The servers where Glassbox is tested and installation process is automated are Apache Tomcat, weblogic, websphere, Resin, Oracle OC4J, websphere, Resin, Jetty & GlassFish. Overhead Having Glassbox application running on same container would generate a performance overhead. Typically this would affect the response time and memory overhead. Hence it is recommended to start the Glassbox application only when it’s required for performance monitoring. Licensing Glassbox is an open source project, it is free to download and run. Glassbox uses the GNU Lesser General Public License to distribute software and documentation. Demo Application Development & Deployment to Tomcat To test the capabilities of Glassbox, a sample application is developed which has a TestServlet class. This servlet calls DelayGenerator class’s generateDelay() method. This method calls Thread class’s sleep() method which suspends the execution of servlet. A counter is being initialized in DelayGenerator class which determines the time interval till which servlet is needed to be suspended. TestServlet.java /** * File: TestServlet.java * @author Viral Thakkar */ package com.infosys.star.glassbox; import java.io.IOException; import java.io.PrintWriter; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class TestServlet extends HttpServlet { protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { DelayGenerator delayObj = new DelayGenerator(); int delay = delayObj.generateDelay(); response.setContentType("text/html"); PrintWriter out = response.getWriter(); out.println(""); out.println(" Hello World from Test Servlet : "+delay+" milliseconds "); out.println(""); out.flush(); } } DelayGenerator.java /** * File: DelayGenerator.java * @author Viral Thakkar */ package com.infosys.star.glassbox; public class DelayGenerator { private static int counter = 1; public int generateDelay() { try { Thread.sleep(counter * 100); counter++; } catch (InterruptedException e) { e.printStackTrace(); } return counter*100; } } Glassbox Installation & Integration to Apache Tomcat 6.0 Glassbox installation is very straightforward for non-clustered environment for the server where it’s automated. Simply drop the glassbox.war file at the appropriate folder inside server folder or perform the server specific steps/configuration to deploy the war file. Browse to server url with context root as glassbox – http://<>:/glassbox. Follow the instructions available on this page. According to specific server, this page would suggest the configuration changes for a server. Please refer to Glassbox User Guide document for details on how to install Glassbox for clustered application server environment. For Apache Tomcat 6.0- Add following command line arguments to Tomcat’s Java options: -Dglassbox.install.dir=C:\Tomcat6.0\lib\glassbox -Djava.rmi.server.useCodebaseOnly=true -javaagent:C:\Tomcat6.0\lib\aspectjweaver.jar Monitoring & Technical Analysis Glassbox web client (URL- http://<>:<>/glassbox ) shows the summary and detailed view of all the requests/operations that container/JVM has executed. Summary Section View Different attributes (columns) which gets displayed in this table are as below - Attribute / Column Name Comments Status This indicates whether operation/request is performing OK, SLOW or FAILING Analysis For SLOW/FAILING status, this value provides the small summary of the cause of the problem. Operation This is name of the operation/request of an application Server Name of the server where monitoring is being done. In a clustered environment, this allows to distinguish operations on different servers. Executions This value indicates how many times this operation has run since the application server was started or Glassbox’s statistics were last reset. Click the request in above summary table to view its detailed analysis in below detailed section. Detailed Section View The details area provides information relating to operations selected in the summary table. Different sub-sections which gets displayed in this view are as below - Sub-section Name Comments Executive Summary High level summary view of the selected operation gets displayed in a table format. This is neat view to senior stake holders who are not interested in technical details. Technical Summary This section contains more technical details in paragraph and table representation formats to provide insight into root cause of the problem if any, like which operation, query is slow and statistics of same. Details like stack trace, thread lock name are provided to find and fix the problem. “Common solutions” sub section shows pointers to resolve the identified problem/s. “Glassbox has ruled out other potential problems” sub section saves time to know what problems have already been ruled out. Executive Summary View Technical Summary -> Technical Details Views Above two snapshots are parts of the Technical Details section and provide minute details at code level with line number so as to pinpoint where the problem is. Here cause is identified at Class com.infosys.star.glassbox.DelayGenerator inside Method generateDelay at line number 12 where Thread.sleep is invoked. Perform Load Testing Using JMeter and Monitor Using Glassbox Apache JMeter is used to test performance both on static and dynamic resources (files, Servlets, Perl scripts, Java Objects, Data Bases and Queries, FTP Servers and more). It can be used to simulate a heavy load on a server, network or object to test its strength or to analyze overall performance under different load types. It can be used to make a graphical analysis of performance or to test server/script/object behavior under heavy concurrent load. Using JMeter, create a test plan that simulates 10 users requesting for 1 page 5 times. i.e. 10 x 1 x 5 = 50 HTTP requests. First step is to add a Thread Group element. The Thread Group tells JMeter the number of users to simulate, how often the users should send requests, and the how many requests they should send. Next step is to add HTTP Request element to added Thread Group. In parallel, have the Glassbox up and running to monitor response time statistics of the load generated by JMeter application. Below is the Executive summary view of above test in Glassbox web UI interface. Section “Monitoring & Technical Analysis” contains the details to understand the Glassbox generated analysis. Conclusion Glassbox is not the replacement for performance testing tool like load runner. Glassbox aids in the project to various stakeholders in finding, conveying and fixing the performance problems at all phases starting build (development) to post deployment. Glassbox application to be started/installed only during monitoring time so as to avoid the performance overhead for other applications due to CPU & memory footprint occupied by Glassbox application on the container. During load testing of the application, Glassbox turns out to be good option to figure out the root causes inside an application code. References Glassbox web site - http://www.glassbox.com/glassbox/Home.html Glassbox User Guide - http://nchc.dl.sourceforge.net/sourceforge/glassbox/Glassboxv2.0UserGuide.pdf Apache JMeter - http://jakarta.apache.org/jmeter/ Download & Support Glassbox Download Link - http://www.glassbox.com/glassbox/Downloads.html Glassbox forum Link - http://sourceforge.net/forum/forum.php?forum_id=575670 About Author Viral Thakkar is a Technical Architect with the Banking and Capital Markets vertical at Infosys. He has 9.5 years of technology consulting experience mainly on Java/JEE technologies and frameworks with large banks and financial institutions across the globe. He has been part of many small and large-scale initiatives related to application development, architecture creation and strategy definition. From http://viralpatel.net/blogs
March 5, 2009
by Viral Thakkar
· 20,694 Views
article thumbnail
Using Java, POST A Block Of XML To A Web Server
// This is a working example of POSTing a string (representing a block of XML) to a web server try { URL url = new URL( argUrl ); URLConnection con = url.openConnection(); // specify that we will send output and accept input con.setDoInput(true); con.setDoOutput(true); con.setConnectTimeout( 20000 ); // long timeout, but not infinite con.setReadTimeout( 20000 ); con.setUseCaches (false); con.setDefaultUseCaches (false); // tell the web server what we are sending con.setRequestProperty ( "Content-Type", "text/xml" ); OutputStreamWriter writer = new OutputStreamWriter( con.getOutputStream() ); writer.write( requestXml ); writer.flush(); writer.close(); // reading the response InputStreamReader reader = new InputStreamReader( con.getInputStream() ); StringBuilder buf = new StringBuilder(); char[] cbuf = new char[ 2048 ]; int num; while ( -1 != (num=reader.read( cbuf ))) { buf.append( cbuf, 0, num ); } String result = buf.toString(); System.err.println( "\nResponse from server after POST:\n" + result ); } catch( Throwable t ) { t.printStackTrace( System.out ); }
March 4, 2009
by Douglas Wyatt
· 22,649 Views
article thumbnail
Javascript Implementation Of Damerau-Levenshtein Distance
From Wikipedia: Damerau–Levenshtein distance is a "distance" (string metric) between two strings, i.e., finite sequence of symbols, given by counting the minimum number of operations needed to transform one string into the other, where an operation is defined as an insertion, deletion, or substitution of a single character, or a transposition of two characters. //based on: http://en.wikibooks.org/wiki/Algorithm_implementation/Strings/Levenshtein_distance //and: http://en.wikipedia.org/wiki/Damerau%E2%80%93Levenshtein_distance function levenshtein( a, b ) { var i; var j; var cost; var d = new Array(); if ( a.length == 0 ) { return b.length; } if ( b.length == 0 ) { return a.length; } for ( i = 0; i <= a.length; i++ ) { d[ i ] = new Array(); d[ i ][ 0 ] = i; } for ( j = 0; j <= b.length; j++ ) { d[ 0 ][ j ] = j; } for ( i = 1; i <= a.length; i++ ) { for ( j = 1; j <= b.length; j++ ) { if ( a.charAt( i - 1 ) == b.charAt( j - 1 ) ) { cost = 0; } else { cost = 1; } d[ i ][ j ] = Math.min( d[ i - 1 ][ j ] + 1, d[ i ][ j - 1 ] + 1, d[ i - 1 ][ j - 1 ] + cost ); if( i > 1 && j > 1 && a.charAt(i - 1) == b.charAt(j-2) && a.charAt(i-2) == b.charAt(j-1) ){ d[i][j] = Math.min( d[i][j], d[i - 2][j - 2] + cost ) } } } return d[ a.length ][ b.length ]; }
February 22, 2009
by kevin mcbob
· 2,986 Views
article thumbnail
Embedding OSGi in Tomcat
My last post embedded OSGi in an application server using Felix, Jetty, and PAX WEB. Here, I’m going to embed Equinox in Tomcat. I originally set out to embed Felix in Tomcat, but the dearth of tools and frameworks available for embedding Felix made using Equinox much easier. I use the word “much” pretty loosely, though, because there were still some hoops I had to jump through to get JSP compilation working. Of course, PAX WEB provided that capability when embedding Jetty in Felix. Unfortunately, no framework stepped forward that offered these capabilities in this embedding scenario. At least, I wasn’t able to find them. I want to keep this post strictly educational (like a tutorial), but I’m going to post a follow-up shortly that discusses these two scenarios. To give you something to chew on in the meantime, both scenarios presented a different set of challenges, and we have a long ways to go before many development teams will be able to leverage OSGi for building web applications. Like I said, I’ll explain why in a different post, but for now let’s move on with this example. Getting Started In the spirit of using the simplest tools possible, all you’ll need for this example is Tomcat, Ant, and Subversion. If you went through the previous example, you’ve already got Ant and Subversion installed. If you already have Tomcat, you should be set. But if not, download Tomcat 6, which is the version I used for this embedding exercise. Checkout HelloWorldEmbedJSP Next, you’ll need to checkout the project from my Google code repository. You can put the project anywhere when checking out, but you’ll have to make sure you know the path relative to each directory so that you can install the necessary bundles. I have the project sitting in a directory right alongside Tomcat. To checkout, open up a Terminal window or DOS prompt and do the following: svn checkout http://kcode.googlecode.com/svn/trunk/osgi/HelloWorldEmbedWebJSP Of course, if you have a Subversion client installed like TortoiseSVN, you can checkout from the directory browser. I don’t use these tools, though. Next step! Build the WebApp This step has nothing whatsoever to do with OSGi. But as a basis for comparision, I felt it would be interesting to package the sample as a web application. Since this is the exact same example I used when embedding Jetty in Felix, it does offer a nice basis for comparing how we can deploy this functionality in different ways. To build the web application, simply navigate to the web directory in the console and type the following: ant The build script spits out a web.war file in the bin directory. Simply take this web.war and copy it to the Tomcat webapps directory. If you haven’t started Tomcat yet, you should do so now. Just startup another DOS prompt or console window, navigate to the Tomcat bin directory, and execute the startup.bat or startup.sh. Once this is done, give it a second to explode the web application, and navigate to http://localhost:8080/web/hi. Like I said, if you went through the exercise on my previous post of embedding Jetty in Felix, you’ll see the same thing here deployed as a web application instead of a bundle. Onto OSGi. The Bridge The Bridge.war web application is the main reason I chose to use Equinox instead of Felix. It provides two very important functions that are critical when embedding OSGi in an application container. In fact, this is one of the items I’ll be speaking about in my next post - how difficult it is to use OSGi with the current generation of application servers. It’s virtually prohibitive. Anyway, here are the two necessary functions provided by the Bridge. Embeds and launches Equinox Tunnels servlet requests from Tomcat to Equinox Deploying the Bridge is easy because it’s a webapp. Just take the Bridge.war from the web/lib directory of the HelloWorldEmbedWebJSP project and drop it into the Tomcat webapps directory. Give Tomcat a second to explode the web application, and test it by accessing http://localhost:8080/bridge/sp_test. You should see a page that says the Servlet Delegate is registered. You’ve now got OSGi embedded within Tomcat with a bridge that will feed requests to Tomcat and pass them onto Equinox. Linux and Mac OS/X users take note. As you’ll recall in the previous examples, we install OSGi bundles from the OSGi console after starting OSGi. Well, since we embedded OSGi in Tomcat, where’s the console? The console is the same console window you used to start Tomcat. But because Tomcat redirects all output to a file, you may not see it. To enable the console, you’ll need to make some changes to the catalina.sh file in the Tomcat bin directory. Windows users shouldn’t have this problem, though I’m sure Windows users are dealing with many other types of problems. Anyway, once you’ve opened catalina.sh, comment out the following line so it looks like this. If you’ve got the same catalina.sh as I do that’s bundled with Tomcat 6, it’s line number 298. #>> "$CATALINA_BASE"/logs/catalina.out 2>&1 & Now, restart Tomcat and voila…in the console you used to start Tomcat, you should see the OSGi console. Type ss to see the list of installed bundles. Onward! Configuring the Environment Before we deploy the bundle, we need to configure the environment. If we weren’t using JSP, we’d be done. But because JSPs require compilation, and the JSPs will run within Equinox, they can’t use the JSP compiler included with Tomcat. We need to include our own JSP compiler, and we’ll use Jasper. I’ve included all the bundles needed in the same directory where you found Bridge.war. To install the bundles, jump over to the OSGi console, and do the following: osgi> install file:path to bundle/ javax.servlet.jsp_2.0.0.v200806031607.jar osgi> install file:path to bundle/ org.apache.commons.el_1.0.0.v200806031608.jar osgi> install file:path to bundle/ org.apache.commons.logging_1.0.4.v20080605-1930.jar osgi> install file:path to bundle/ org.apache.jasper_5.5.17.v200806031609.jar osgi> install file:path to bundle/ org.eclipse.equinox.jsp.jasper_1.0.100.v20080427-0830.jar osgi> install file:path to bundle/ org.eclipse.equinox.jsp.jasper.registry_1.0.0.v20080427-0830.jar Now, type ss to view the state of the bundles. If they aren’t active, you’ll need to start each one of them. Again, in the OSGi console, just type: osgi> start bundle id Dependening on the dependencies, multiple bundles may start. Just do an ss in between each start to see which ones haven’t been started yet. Wash, Rinse, Repeat! Build & Deploy the Bundle Unlike my previous example where I gave you a pre-configured environment that didn’t require you to build anything, we have to do the build and deploy of the bundle ourselves. Why did I do this? Only because Tomcat has a larger footprint than Felix and Jetty, and I didn’t want to put Tomcat in my Google code repository. Building is pretty easy though. We’ve already built and deployed the web application. Building the bundle is done the same way, except we’ll use a different Ant build script. For this step, you can either shut down Tomcat, or open up another DOS or terminal window. Navigate to the HelloWorldEmbedWebJSP/web directory, and type the following: ant -f buildjar.xml The JAR file overwrites the web.war in the bin directory and places a valid OSGi bundle named web.jar there for you. To install the bundle, make sure Tomcat is started, and type the following in the OSGi console: install file:relative path to web.jar/web.jar The bundle gets installed. Start it up using the OSGi start command. We can now access the OSGi enabled web application by navigating to http://localhost:8080/bridge/hi. Again, it’s the exact same functionality as the other web applications we’ve deployed, except using a different deployment topology. To shut down, just type close in the OSGi console. We’re done. If you had any problems, let me know via comments here or by contacting me. Next up…some general notes on OSGi and hopefully messing around with Distributed OSGi. Additional Notes A few additional notes about this exercise. Obviously it appeared a bit more difficult than embedding Jetty in Felix. But were it not for the PAX WEB framework, that exercise would have proven equally difficult. Also, the Bridge.war performs two very important functions for us. Felix has supporting documentation that shows how to embed Felix, but I found no framework that did it for me. The Bridge.war was available, so I used it. But were a bridge available for Felix, it would be easy to deploy that bridge and install web.jar with Felix embedded within Tomcat. From http://techdistrict.kirkk.com
February 17, 2009
by Kirk Knoernschild
· 60,953 Views · 1 Like
article thumbnail
Programming LDAP with Groovy
It all started with a task to do: Print all members of the group within Active Directory, including members of the nested groups. And a deadline: 15 minutes. Given the deadline, I had no chance to get it done in time. Having 15 minutes means you need to get it right from the first run. Googling for groovy ldap brought Gldapo. But after looking at it and seeing how much configuration has to be done, I searched for some alternatives. Groovy LDAP was beautifully simple and had no external dependencies. I downloaded the jar, dropped it into my GROOVY_HOME/lib directory and started to write the script: import org.apache.directory.groovyldap.LDAP ldap = LDAP.newInstance('ldap://ldap.mycompany.com:389/dc=mycompany,dc=com') After reading through the sample scripts, I already had the main part: ldap.eachEntry ('&(objectClass=person)(memberOf=cn=mygroup') { person -> println "${person.displayName} (${person.cn})" } I saved it as listGroup.groovy and ran it from the command line: groovy listGroup It worked out of the box, printing on the console all the members of the group: John Smith (smithj) Amanda McDonald (mcdonaa) Isabelle Dupre (duprei) Of course, the script was not printing members of the nested groups. In order to do that, I had to turn the snippet into the Groovy recurrent function and avoid hardcoding a group's name in favor of taking it as a command line parameter. Here is the entire script: import org.apache.directory.groovyldap.LDAP import org.apache.directory.groovyldap.SearchScope List getMembersOfAGroup(connection, groupName) { def members = [] def result = connection.searchUnique("cn=$groupName”); connection.eachEntry("memberOf=${result.dn}") { member -> if (member.objectclass.contains("group")) members.addAll(getMembersOfAGroup(connection, member.cn)) else members.add("${member.displayName} (${member.cn})") } return members } LDAP ldap = LDAP.newInstance("ldap://ldap.mycompany.com:389/dc=mycompany,dc=com") getMembersOfAGroup(ldap, args[0]).each { println it } If your directory contains circular group relations, the script has to be further adjusted. This detail has been omitted for simplicity reasons. Please note, that the examples in this article work only with Microsoft Active Directory, because they use vendor specific structure and schema elements. In other directory solutions for instance, group membership is often stored in group entries only, while in Active Directory it is stored in both group and member object. But the examples can easily be adjusted to fit another directory's solution, e.g. by modifying filter expressions. What is this LDAP thing you're talking about? LDAP 101: LDAP stands for Lightweight Directory Access Protocol. A directory is a storage organized as a tree of directory entries. The tree usually reflects political, geographical and/or organizational boundaries. Every directory entry consists of a set of attributes (name/value pairs). These attributes are defined in the LDAP schema. Each directory entry has a unique identifier named DN (Distinguished Name). For more information please read Apache Directory introductory article. Project background Groovy LDAP is a small library started by Stefan Zoerner from the Apache Directory project. Its goal was to create minimalistic LDAP API for Groovy, with metaphors understood by the LDAP community (e.g. members of the Apache Directory team). As such, the only two dependencies of Groovy LDAP are: Java SE (5 or later) Groovy 1.0 or later Under the hood, JNDI is used to perform LDAP queries, but fortunately Groovy LDAP hides it and lets you use a bunch of useful methods and objects, instead. It actually reminds me of the time when Netscape LDAP API was widely used. It defines a set of methods to perform basic LDAP operations: create, modify, delete, compare, search. Groovy LDAP is written in Java, not Groovy. The only Groovy dependency is a reference to a Closure class, which is used as a parameter in a couple of search methods. So with the exception of the method taking the closure, others can be also used in Java programs. How to get it The simplest way is to get the binaries from the Groovy LDAP download page. After downloading and expanding the zip file you need to look for groovy-ldap.jar in the dist directory. Drop it into your GROOVY_HOME/lib directory and you’re ready to write your first script. How to build it If you want to build the library on your own, you will need: Apache Ant 1.7.1 Ivy 1.4.1 or later After you download and install Ant, drop Ivy's jar (ivy-1.4.1.jar) into your ANT_HOME/lib directory. Now you can check out the source files from Apache Directory sandbox Subversion repository. Once the files are checked out, just type ant and wait until the distribution jar is built in the dist directory. Connecting to the directory The first thing you will want to do is to connect to the directory. Groovy LDAP offers here two types of connection: anonymous bind and simple bind. Anonymous bind happens when you connect to the directory without providing your credentials. Many directories allow anonymous bind if the client is only reading from the directory. In corporations anonymous bind is often disabled for security reasons. So, in order to connect you need to instantiate LDAP class using newInstance() method, with the following variants: public LDAP newInstance() public LDAP newInstance(url) A non-parameter method connects to the default address, which is localhost:389. It proves to be useful for various short proof-of-concept scripts. The second method takes the url of the directory as a second parameter. If anonymous bind is not allowed or not sufficient there is an equivalent method, taking additionally user credentials: public LDAP newInstance(url, user, password) Once the connection is established, you can perform any other actions. One tip is to always provide a baseDN as a part of the connection url e.g. ldap://ldap.mycompany.com:389/dc=mycompany,dc=com By doing so you define the default base, upon which searches will be performed, which in turn allows you to use convenient one parameter search methods, instead of specifying a search base and scope each time. Reading and searching directory entries You may want to start with checking if a specific directory entry exists: def found = ldap.exists('cn=smithj,dc=mycompany,dc=com') exists() method is searching the directory by DN (Distinguished Name) and returning a boolean result detailing whether an entry was found. As a companion there is read() method, that reads directory entry, specified by its DN: if (found) def entry = ldap.read('cn=smithj,dc=mycompany,dc=com') This method returns either a boolean value or a given entry, accordingly. But there might be cases when you do not want to search by DN, but by another attribute which is also unique. A good example of this is a userId attribute, which is usually unique within a company. def entry = ldap.searchUnique('userId=smithj') This method assumes uniqueness of an object. If more than one result is returned from the search, you will get an exception. When more results are expected, you can use search() method: and then iterate over a result set: results = ldap.search('(objectClass=user)') println 'Found: $results.size entries' results.each { entry -> println entry.dn } Searches can be also performed with more compact and more Groovy method eachEntry() taking a closure as the last parameter: ldap.eachEntry('(objectClass=user)') { entry -> println entry.dn } As you see, when you have the entry object, you can reference all its properties using native map syntax e.g. entry.dn. This is possible, because all result objects returned from Groovy LDAP search methods are Maps or Lists of Maps. But, how does Groovy LDAP know in which subtree you would like to perform your search? It doesn't, because you haven't specified anything else, but the basic query. So it assumed you want to search in baseDN (hopefully specified, when connecting to the directory). When you want to have more control over how the query is performed, there is a different version of search(), searchUnique() and eachEntry() methods that support it e.g. public List or Search class instance as parameters, but we'll leave them as for now. When you deal with LDAP directories as a part of your daily job, you may want to have a look at Apache Directory Studio, a full-fledged LDAP client tool, which allows you to connect, browse and modify any LDAP-compatible directory. It can also be used as diagnostic tool when your query in Groovy LDAP doesn't work as expected. Adding, modifying and deleting directory entries When you know how to search and read from the directory, it's time to do some modifications. Let's start from adding a new entry: def attributes = [ objectclass: ['top', 'person'], cn: 'smithc', displayName: 'John Smith' ] ldap.add('cn=smithc,dc=example,dc=com', attributes) add() method takes DN and a Map with attributes as parameters. You need to remember not to put DN in the attributes map, as it is not an attribute but rather the unique identifier of an entry. Removing a directory entry is even more straightforward: ldap.delete('cn=smithc,dc=example,dc=com') delete() method will throw an exception, if an object with the given DN does not exist. Modifying a directory entry is not very Groovyish for the time being. Adding single attributes is still relatively easy: def dn = 'cn=smithj,dc=mycompany,dc=com' def email = [ email: '[email protected]' ] ldap.modify(dn, 'ADD', email) Performing batch modifications could be more readable using Builder-like syntax.. The current way to do this is the following: def modifications = [ [ 'REPLACE', [email: '[email protected]'] ], [ 'ADD', [phone: '+48 99 999 99 99'] ] ] ldap.modify(dn, modifications) The same operation, using more expressive syntax, would potentially look like: ldap.modify ('cn=smithj,dc=mycompany,dc=com') { replace(email: '[email protected]') add(phone: '+48 99 999 99 99') } Summary As you can see, Groovy LDAP is a neat little library, delivering simple but convenient API to deal with LDAP directories, which makes it an ideal candidate to use in various administrator scripts and short programs. As a project it resides in Apache Directory sandbox, so when you have a chance, contribute and help Groovy LDAP to become an official subproject of the Apache Directory. Thanks I would like to thank Stefan Zoerner and Carolyn Harman for thorough review of the article. Resources Apache Directory Project Groovy LDAP Gldapo Apache Ant Apache Ivy Groovy
February 16, 2009
by Michal Szklanowski
· 52,992 Views · 5 Likes
article thumbnail
JBoss RichFaces with Spring
This article is going to show you how to build a RichFaces application with Spring.
February 16, 2009
by Max Katz
· 203,850 Views
article thumbnail
How to Create Modular Groovy Applications in 5 Steps!
let's create a modular groovy application! why?! modularity is an enabler of scaleability. as your groovy application increases in size, you increasingly need to manage code dependencies, structure your code in units that are larger than packages, and distribute pieces of your application to developers located in different locations and conflicting time zones. welcome to modularity. the netbeans platform already provides it (plus, osgi is coming to the netbeans platform ). beyond modularity, there are specific features that the netbeans platform provides that will remain unique, such as a shared filesystem for intermodular communication and the concept of "context" (i.e., netbeans lookup), which not only applications have (as with the jdk 6 serviceloader class), but netbeans platform objects such as windows themselves. welcome to loosely coupled modularity. now, let's get started. start up netbeans ide 6.5. go to this page and download the groovy console template and use the plugin manager (in the tools menu) to install it into the ide. now, in the new project dialog, you should see this new project template: click next, give your new application a name (such as "helloworld") and a location on disk, and then click finish. expand a few folders and you should now see this: briefly, the template gives you a groovy pojo, with this content: package org.my.app public class demopojo { def foo } the template also gives you a moduleinstall class, which handles the lifecycle of the module: package org.my.app import org.openide.modules.moduleinstall as mi public class installer extends mi { @override public void restored() { for(int i = 0; i < 10; i++) { demopojo dp = new demopojo() dp.setfoo(i) println("number: " + dp.getfoo()) } } } so, we have some standard groovy constructs here, simply to get you started in the ecosystem of the netbeans platform. the module also includes a properties file for internationalization purposes and a layer.xml file, for the module's contributions to the shared filesystem. run the application (i.e., without doing anything at all, no tweaking, no post processing, nothing at all, just run it). look in the output window of netbeans ide and you will see this: so, you can see that you only have the absolute minimum set of modules to start with. also you're using the groovy compiler (thanks to an additional target that's added to the demo module's build.xml file). that's how to get started with modular groovy applications. have fun with groovy on the netbeans platform!
February 14, 2009
by Geertjan Wielenga
· 21,882 Views
article thumbnail
Integrate OpenOffice with Java without Installing OpenOffice
Until a few days ago, I've always needed to work with the rather cumbersome Office Bean and UNO Runtime when integrating OpenOffice into a Java application. I also had to configure a whole bunch of things to force OpenOffice to play nicely with the Java integration. Two days ago, however, I found out about ODF Toolkit. It seems to be a relatively new project, independent since last year some time, though I could be wrong. What's especially interesting is the ODFDOM: ''ODFDOM is an OpenDocument (ODF) framework. It's purpose is to provide an easy common way to create, access and manipulate ODF files, without requiring detailed knowledge of the ODF specification. It is designed to provide the ODF developer community an easy lightwork programming API, portable to any object-oriented language.'' Here's a snippet of it in action: public static void main(String[] args) { try { OdfDocument odfDoc = OdfDocument.loadDocument(new File("/home/geertjan/test.ods")); OdfFileDom odfContent = odfDoc.getContentDom(); XPath xpath = odfDoc.getXPath(); DTMNodeList nodeList = (DTMNodeList) xpath.evaluate("//table:table-row/table:table-cell[1]", odfContent, XPathConstants.NODESET); for (int i = 0; i < nodeList.getLength(); i++) { Node cell = nodeList.item(i); if (!cell.getTextContent().isEmpty()) { System.out.println(cell.getTextContent()); } } } catch (Exception ex) { //Handle... } } Let's assume that the 'test.ods' file above has this content: From the above, the code listing would print the following: Cuthbert Algernon Wilbert And, as a second example, here's me reading the first paragraph of an OpenOffice Text document: public static void main(String[] args) { try { OdfDocument odfDoc = OdfDocument.loadDocument(new File("/home/geertjan/chapter2.odt")); OdfFileDom odfContent = odfDoc.getContentDom(); XPath xpath = odfDoc.getXPath(); OdfParagraphElement para = (OdfParagraphElement) xpath.evaluate("//text:p[1]", odfContent, XPathConstants.NODE); System.out.println(para.getFirstChild().getNodeValue()); } catch (Exception ex) { //Handle... } } On my classpath I have "odfdom.jar" and "xerces-2.8.0.jar". I don't necessarily have OpenOffice installed, which means I can very easily process a whole bunch of spreadsheets (or other OpenOffice output) without (a) installing OpenOffice and (b) faster than I would otherwise do, since OpenOffice doesn't need to be started up, via the Office Bean or otherwise. In fact, Aljoscha Rittner from Sepix, who told me about this project and who is using it in his commercial applications, reports that his processing has sped up to a fraction of the original, also because he doesn't need to handle the situation where OpenOffice would crash randomly in the middle of long running processes, such as during the night when there's no human interaction for restarting it.
February 7, 2009
by Geertjan Wielenga
· 50,519 Views
article thumbnail
An Overview of Servlet 3.0
JSR 315 (Servlet 3.0) is an update to the existing Servlet 2.5 specification. Servlet 3.0 is focussed on extensibility and web framework pluggability, aligning with the goals of Java EE 6. Ease of Development (EoD) will be supported using newer language features. A reference implementation is available in the GlassFish v3 nightly build. The public review contains: Pluggability EoD Async Support Security Enhancements Miscellaneous Changes In this article we will bring you up to speed with what's happening with the Servlet 3.0 specification and give more detail on what is included. Note: this article corresponds to the public review of the specification. As it is not yet final some things may change. The Expert Group Rajiv Mordani from Sun Microsystems is the specification lead with an expert group comprised of many of the most recognisable names in the Java community: Adobe Systems Inc. Apache Software Foundation BEA Systems Ericsson AB Google Inc. Hunter, Jason IBM Icesoft Technologies Inc NCsoft Corporation Oracle Pramati Technologies Prasanna, Dhanji R. SAP AG Ship, Howard M. Lewis Suleiman, Hani Sun Microsystems, Inc. Tmax Soft, Inc. Walker, Joe Wilkins, Gregory John Pluggability Due to the popularity of so many various web frameworks, Servlet 3.0 will make it easier to use and configure the developer's framework of choice. So if you want to add in Struts, or Spring Web Flow it will be easy to do so. Methods to add Servlets and Filters If a ServletContextListener is registered and wants to add a Servlet or Filter, then at the time of context initialization the event that is fired to the Listener can add Servlets and Filters to the context. The methods are addServlet and addFilter. For more details look for the javadocs at the JCP site at http://jcp.org/aboutJava/communityprocess/pr/jsr315/index.html. Web fragments Instead of having just one monolithic web.xml that is used by the developer to declare servlets, filters and other configuration for using the framework, the framework can now include a web-fragment.xml with all it's configuration. A web-fragment is almost identical to the web.xml and can contain all the configuration needed by the framework in the META-INF directory of the framework's jar file. The container will use the information to assembe the descriptor for the application and the application needn't have to use any of the boilerplate configuration in their app for the framework. There are rules that are defined int the specification for conflict resolution, overriding and disabling fragment scanning. Along with the annotations which also can be in libraries the feature is very compelling not only for the developers that use frameworks but also for framework authors to be self sufficient in defining the configuration needed. The great benefit to this is that library providers can supply their own web.xml fragment for use in your webapp. Ease of Development Several new annotations have been defined for ease of development in Servlet 3.0, allowing you to write a Servlet without requiring a descriptor. These annotations reside in the javax.servlet.annotation package. Thanks to the addition of annotations, it is now possible to have Servlet, Filter and ServletContextListener in a war file without a web.xml. It's important to point out that this makes the web.xml optional, rather than redundant. The web.xml may be user to override metadata specified via annotations. Following discussions in the expert group and the community, it was decided that method level annotations were not to be added, so you keep the doGet, doPost methods and need to extend HttpServlet to use them. Let's take a closer look at the annotations present in the Servlet 3.0 specification: Servlet Annotation In Servlet 3.0, servlet metadata can be specified using @WebServlet @WebServlet(name="mytest", urlPatterns={"/myurl"}, initParams={ @InitParam(name="n1", value="v1"), @InitParam(name="n2", value="v2") }) public class TestServlet extends javax.servlet.http.HttpServlet { .... } TestServlet extends HttpServlet, while the meta data provided corresponds with the web.xml as follows: Parameter Annotation Parameter web.xml Servlet name name= URL Pattern urlPatterns={ } Initialization parameters InitParams={ @InitParam{name=””, value=””} .. .. Servlet Filter Annotation ServletFilter meta data is specified using the @ServletFilter annotation public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException { .... } public void destroy() { .... } } Parameter Annotation Parameter web.xml URL Pattern urlPatterns={ } Initialization parameters InitParams={ @InitParam{name=””, value=””} .. .. Servlet Context Listener Annotation A ServletContextListener is simply marked with the @WebServletContextListener rather than needing to list it the web.xml file. @WebServletContextListener public class TestServletContextListener implements javax.servlet.ServletContextListener { .... public void contextInitialized(ServletContextEvent sce) { .... } public void contextDestroyed(ServletContextEvent sce) { .... } } Async Support The biggest change made in the specification is the addition of asynchronous processing. The main cases to cover were: Waiting for a resource to become available, such as JDBC or a call to a Web Service. Generating response asynchronously Using exisiting frameworks to generate responses after waiting the for asychronous operation to complete. While the early draft had suspend and resume, the latest specification has two variations of the startAsync() method on ServletRequest. One (startAsync() ) takes no parameters and initialises an AsyncContext with the original request and response. The ( startAsync() ) other takes a request and response as a parameter to initialise the AsyncContext with. Servlets (@WebServlet) and Filters (@ServletFilter) that support asynchronous processing need to be annotated with the supportAsync attribute set. It is illegal to call startAsync if you have a Servlet or Filter that doesn't support asynchronous processing anywhere in the request processing chain. The is also an AsyncListener that can be registered to get notification on timeout and completion of asynchronous processing of the request. This listener can be used to clean up resources if the wrapped request and response were used to create it's AsyncContext. You can forward requests back to the container using the AsyncContext.forward(path) and AsyncContext.forward() methods so frameworks like JSP can create a response. Security Enhancements HTTPServletRequest will be enhanced with methods allowing programmatic login and logout, while ServletRequest will be able to force a login.The logout method will allow an application to reset the authentication state of a request without requiring the authentication to be bound to a HTTPSession. Conclusion The draft is just beginning to be implemented within Glassfish v3. The specification will be a required piece of Java EE 6 and hence all the features described above will be available in all Java EE 6 compatible containers. The presence of the various features described above will make developing Java web appications much easier. Thanks to Rajiv Mordani for his input into this article, and to Shing Wai and Jan Luehe for the code snippets.
January 21, 2009
by James Sugrue
· 77,737 Views · 2 Likes
article thumbnail
Which Java Version Is Used To Run Our NetBeans Installation?
Ever wondered which Java version is used to run your NetBeans instance? I have a lot of JDK's installed and everytime I install a new one it ones to be the default JDK for my computer. To know which JDK is used for running NetBeans we go to Help | About and the dialog box shows which Java version is used: To explicitly tell NetBeans which JDK to use we can use the command-line argument --jdkhome when we start NetBeans. Or we can set the property netbeans_jdkhome in the file netbeans-install-dir/etc/netbeans.conf.
December 23, 2008
by Hubert Klein Ikkink
· 16,995 Views
article thumbnail
A Farewell to Heavyweight/Lightweight Conflicts
Problems resulting from the mixing of Swing and AWT components have been a constant source of confusion to Java newbies. This quote explains the reason for the difference very well: Most of the issues related to mixing AWT and Swing components are related to the mixing of so-called heavyweight and lightweight components. A heavyweight component is one that is associated with its own native screen resource (commonly known as a peer). A lightweight component is one that "borrows" the screen resource of an ancestor (which means it has no native resource of its own -- so it's "lighter"). From: Mixing Heavy and Light Components The lightweight approach, taken by Swing, is the preferred, since it consumes less resources. However, there are cases where one might need to mix the two in the same application, which can result in undesired side effects. A case in point, from the same article and where all the code used below is found, goes as follows. The menu on the right behaves correctly, while the menu on the left does not: The reason for the difference is that the badly displayed menu in the second screenshot is Swing and lightweight, while the other menu is AWT, and therefore heavyweight. The Button is an AWT component too, therefore being heavyweight. Unless one forces a lightweight component, via setDefaultLightWeightPopupEnabled(false), to behave like a heavyweight component, unwanted side effects such as the above will result. But all that is old news, of course. The new news is that already with the early access release of JDK 6 Update 12 one can, without needing to do anything at all, obtain the desired effect, which is as follows: This is exactly what one would want: the rendering of a lightweight component over a heavyweight component. Though the major features of the EA release are slated as "Windows 2008 Support" and "Java Plug-In now supports 64-bit browsers", it is this heavyweight/lightweight fix that I find the most useful (since I am neither a Windows- nor a 64-bit browser-user). If one looks through the list of issues fixed in the current JDK 6 Update 12 build, one notices that a lot of fixing has been done in the Swing & AWT packages. The final screenshot above was taken on JDK 6 Update 12, using the code from the article referenced at the start. I.e., without doing anything special at all, no fiddling with z-order or the like, the behavior was exactly as an end user would expect it to be. Hurray!
December 16, 2008
by Geertjan Wielenga
· 20,899 Views
article thumbnail
Real-World Scala: Managing Cross-Cutting Concerns using Mixin Composition and AOP
In a previous post I showed you how you could use mixin composition and self type annotations to enable Dependency Injection (DI). Mixin composition is an extremely powerful tool that you can utilize in many different ways to enable modular and reusable code. In this post I’ll try to show you how you can use it to solve the problem of crosscutting concerns using AOP/interceptor-style composition. Crosscutting concerns and AOP OOP has given us tools to reduce software complexity by introducing concepts like inheritance, abstraction, and polymorphism. However, developers face daily problems in software design that can’t be solved easily using OOP. One of these problems is how to handle cross-cutting concerns in the application. So what is a cross-cutting concern? A concern is a particular concept or area of interest. For example, in an ordering system the core concerns could be order processing and manufacturing, while the system concerns could be transaction handling and security management. A cross-cutting concern is a concern that affects several classes or modules, a concern that is not well localized and modularized. Symptoms of a cross-cutting concern are: Code tangling - when a module or code section is managing several concerns simultaneously Code scattering - when a concern is spread over many modules and is not well localized and modularized These symptoms affect software in various ways; for example, they make it harder to maintain and reuse software as well as harder to write and understand. Aspect-Oriented Programming (AOP) tries to solve these problems by introducing the concept of separation of concerns, in which concerns can be implemented in a modular and well-localized way. AOP solves this by adding an extra dimension to the design space, and introduces constructs that allow us to define the cross-cutting concerns, to lift them out into a new dimension and package them in a modular way. We are currently using two different types of interceptors (aspects if you like): Mixin composition stacks — a limited but sometimes very useful approach Generic interceptors/aspects using a pointcut pattern language Mixin composition stacks Mixin composition stacks is a core language feature of Scala and is similar to Rickard Oberg’s idea on using the so-called Abstract Schema pattern for type-safe AOP in plain Java. (This is a very contrived example that probably shows that don’t know a zip about dogs, but please bare with me.) First let’s define a couple of interfaces; Dog and DogMood modeled as a mixins (in this case without an implementation so similar to Java’s interface): trait Dog { def greet(me: Human) } trait DogMood extends Dog { def greet(me: Human) { println(me.sayHello) } } Now let’s define two different mixin “interceptors” that implement these interfaces. The first one defining an angry dog and the other one a hungry dog: trait AngryDog extends DogMood { abstract override def greet(me: Human) { println("Dog: Barks @ " + me) super.doStuff(me) } } trait HungryDog extends DogMood { abstract override def greet(me: Human) { super.doStuff(me) println("Dog: Bites " + me) } } As we can see in this example they both override the Mood.greet method. If we look more closely we can see that they follow the same pattern: Enter method (greet) Do something Invoke the same method on super (super.greet) Do something else The trick here is in the semantics of the call to super. Here Scala will invoke the next mixin in a stack of mixins, e.g. the same method in the “next” mixin that have been mixed in. Exactly what f.e. AspectJ does in its proceed(..) method and what Spring does in its interceptors. Now let’s fire up the Scala REPL and create a component based on the Dog interface. Scala’s mixin composition can take place when we instantiate an instance, e.g. it allows us to mix in functionality into specific instances that object creation time for specific object instances. scala> val dog = new Dog with AngryDog with HungryDog stuff2: Dog with AngryDog with HungryDog = $anon$1@1082d45 scala> dog.greet(new Human("Me")) Dog: Barks @ Me Me: Hello doggiedoggie Dog: Bites Me As you can see the call to Dog.greet is intercepted by the different moods that are added to the dog at instantiation time. Interceptors like this are as you can see not generically reusable since they are tied to a specific interface, however if well designed can be a pretty powerful technique. It has the advantage that everything is statically compiled and type-checked by the Scala compiler Generic pointcut-based aspects The main usage of generic aspects is for implementing infrastructure concerns such as logging, transaction demarcation, security, clustering, persistence etc. In order to create a framework for implementing generic aspects, the first thing we need to do is to define an invocation context, holding arguments, method to be invoked as well as the target instance. case class Invocation(val method: Method, val args: Array[AnyRef], val target: AnyRef) { def invoke: AnyRef = method.invoke(target, args:_*) override def toString: String = "Invocation [method: " + method.getName + ", args: " + args + ", target: " + target + "]" override def hashCode(): Int = { ... } override def equals(that: Any): Boolean = { ... } } The second thing that we need to do is to create a base Interceptor trait. This interface defines two different pointcut matching methods. The first one matches a precompiled AspectJ pointcut expression using the PointcutParser in AspectJ. This allows defining interceptors matches AspectJ compatible (method) pointcut expressions. The second matcher matches methods or classes that is annotated with a specific annotation. trait Interceptor { protected val parser = PointcutParser.getPointcutParserSupportingAllPrimitivesAndUsingContextClassloaderForResolution protected def matches(pointcut: PointcutExpression, invocation: Invocation): Boolean = { pointcut.matchesMethodExecution(invocation.method).alwaysMatches || invocation.target.getClass.getDeclaredMethods.exists(pointcut.matchesMethodExecution(_).alwaysMatches) || false } protected def matches(annotationClass: Class[T] forSome {type T < : Annotation}, invocation: Invocation): Boolean = { invocation.method.isAnnotationPresent(annotationClass) || invocation.target.getClass.isAnnotationPresent(annotationClass) || false } def invoke(invocation: Invocation): AnyRef } The last thing we need to do is to create a factory method allows us to wire in our interceptors, declarative, in a seamless fashion. This factory is using the plain old Java Dynamic Proxy API to create a proxy for our base components. object ManagedComponentFactory { def createComponent[T](intf: Class[T] forSome {type T}, proxy: ManagedComponentProxy): T = Proxy.newProxyInstance( proxy.target.getClass.getClassLoader, Array(intf), proxy).asInstanceOf[T] } class ManagedComponentProxy(val target: AnyRef) extends InvocationHandler { def invoke(proxy: AnyRef, m: Method, args: Array[AnyRef]): AnyRef = invoke(Invocation(m, args, target)) def invoke(invocation: Invocation): AnyRef = invocation.invoke } Just using this factory pass is won’t do any wiring for us, which is actually good since if we would use the dynamic proxy the old-fashioned way and we would have it to invoke each interceptor explicitly using reflection. But we can do better than that. Instead we will let the Scala compiler statically compiled in an interceptor stack with all our interceptors. This is best explained with an example. In this example we will define a couple of simple services called Foo and Bar along with their implementations. We will then implement two different infrastructure in interceptors; logging and transaction demarcation. Let’s first define the service. import javax.ejb.{TransactionAttribute, TransactionAttributeType} trait Foo { @TransactionAttribute(TransactionAttributeType.REQUIRED) def foo(msg: String) def bar(msg: String) } class FooImpl extends Foo { val bar: Bar = new BarImpl def foo(msg: String) = println("msg: " + msg) def bar(msg: String) = bar.bar(msg) } trait Bar { def bar(msg: String) } class BarImpl extends Bar { def bar(msg: String) = println("msg: " + msg) } Now let’s define a logging interceptor. Both of these interceptors are just mockups, since the actual implementation is not really of interest. The logging interceptor is defined using a standard AspectJ pointcut while the transaction interceptor is wired to a specific annotation. trait LoggingInterceptor extends Interceptor { val loggingPointcut = parser.parsePointcutExpression("execution(* *.foo(..))") abstract override def invoke(invocation: Invocation): AnyRef = if (matches(loggingPointcut , invocation)) { println("=====> Enter: " + invocation.method.getName + " @ " + invocation.target.getClass.getName) val result = super.invoke(invocation) println("=====> Exit: " + invocation.method.getName + " @ " + invocation.target.getClass.getName) result } else super.invoke(invocation) } trait TransactionInterceptor extends Interceptor { val matchingJtaAnnotation = classOf[javax.ejb.TransactionAttribute] abstract override def invoke(invocation: Invocation): AnyRef = if (matches(matchingJtaAnnotation, invocation)) { println("=====> TX begin") try { val result = super.doStuff println("=====> TX commit") result } catch { case e: Exception => println("=====> TX rollback ") } } else super.invoke(invocation) } Now let’s do the wiring. Here we are using dynamic proxy-based factory that we implemented because you can see, the actual wiring on the interceptor stack is done using Scala mixing composition and therefore has all its benefits, like compiler type checking and enforcement, the speed of statically compiled code, refactoring safety etc. var foo = ManagedComponentFactory.createComponent[Foo]( classOf[Foo], new ManagedComponentProxy(new FooImpl) with LoggingInterceptor with TransactionInterceptor) foo.foo("foo") foo.bar("bar") } This will produce the following output: =====> TX begin =====> Enter: foo @ FooImpl msg: foo =====> Exit: foo @ FooImpl =====> TX commit =====> TX begin =====> Enter: bar @ FooImpl msg: bar =====> Exit: bar @ FooImpl =====> TX commit So this wraps it up. I hope that you have learned a little bit about how powerful mixin composition in Scala is and how it can be used to write modular and reusable components with little effort. This is working fine for us, but there is definitely room for improvement. For example, runtime matcher in the interceptor is fast enough for the annotation matching (only a boolean check) but the AspectJ pointcut matcher is a bit slower since it has to do some more work. This might turn out be a problem or not, most infrastructure services (like persistence and security) performs quite a lot to work and in these cases the overhead over the interceptor of matching will not affect the overall performance much, but in other cases (such as logging or auditing) it might. We are so far only use the annotation matching, so it has not turned out to be a problem so far. However, if it turns out to be a performance bottleneck then we will most likely switch to using my old AspectWerkz AWProxy to get rid of all the Java reflection code and runtime matching. For those that are interested, here is the actual JTA transaction demarcation interceptor that we are using in production (implementing all the EJB transaction semantics). trait EjbTransactionInterceptor extends Interceptor with TransactionProtocol { val matchingJtaAnnotation = classOf[javax.ejb.TransactionAttribute] abstract override def invoke(invocation: Invocation): AnyRef = if (matches(matchingJtaAnnotation, invocation)) { val txType = getTransactionAttributeTypeFor(invocation.target.getClass, invocation.method) if (txType == TransactionAttributeType.REQUIRED) withTxRequired { super.invoke(invocation) } else if (txType == TransactionAttributeType.REQUIRES_NEW) withTxRequiresNew { super.invoke(invocation) } else if (txType == TransactionAttributeType.MANDATORY) withTxMandatory { super.invoke(invocation) } else if (txType == TransactionAttributeType.NEVER) withTxNever { super.invoke(invocation) } else if (txType == TransactionAttributeType.SUPPORTS) withTxSupports { super.invoke(invocation) } else if (txType == TransactionAttributeType.NOT_SUPPORTED) withTxNotSupported { super.invoke(invocation) } else super.invoke(invocation) } else super.invoke(invocation) } About this entry You’re currently reading “Real-World Scala: Managing Cross-Cutting Concerns using Mixin Composition and AOP,” an entry on Jonas Bonér Published: 12.09.08 / 5am Category: AOP, Scala
December 10, 2008
by Jonas Bonér
· 19,947 Views
  • Previous
  • ...
  • 458
  • 459
  • 460
  • 461
  • 462
  • 463
  • 464
  • 465
  • 466
  • 467
  • ...
  • 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
×