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

article thumbnail
Check Directory/dir/file Size In Linux
#check partition sizes df -h #check directory size du -s -h /var/log/ #check every directory and file sizes under a dir. du -s -h /var/log/* #check individual size size du -s -h /var/log/lastlog
December 9, 2008
by Snippets Manager
· 17,103 Views
article thumbnail
Configuring Logging in JBoss
Learn how to properly configure logs in JBoss.
November 19, 2008
by Meera Subbarao
· 223,230 Views
article thumbnail
Seven Forms of Business Process Management With JBoss jBPM
This article will explain Business Process Management (BPM) in terms of 7 distinct use cases for JBoss jBPM. By giving more insight in those use cases, you'll get a better understanding of the different forms of BPM and workflow and when a BPM engine like jBPM makes sense in your project. We'll also highlight the specific jPDL process language features related to those use cases. The term BPM is highly overloaded and used for many different things resulting in a lot of confusion. These use cases give concrete descriptions for the different interpretations of the term BPM. The individual nature of these use cases is important. BPM software vendors often take a mix of different aspects and concerns into account when developing their products. That often results into BPM products that are suitable only for a specific purpose in a specific environment. This is in my opinion the reason why there are so many different BPM products which only serve a small niche market. It also explains why new products and standards in this space keep appearing, don't get enough momentum and then get pushed aside by yet another new product or standard. When evaluating a BPM products, it should be done with specific use cases in mind. What is JBoss jBPM JBoss jBPM is a flexible and powerful BPM engine. In essence, BPM systems allow for execution flows to be specified graphically. As an example, here is a process diagram for a business trip: [img_assist|nid=5583|title=|desc=|link=none|align=undefined|width=623|height=487] A key capability of BPM systems is that processes steps can be wait states. For example in the business trip process above, nodes 'manager evaluation' and 'ticket purchase' are human tasks. When the execution of the process arrives in those nodes, the system executing the process should wait till the assigned user completes the task. From a software technical point of view that capability is a big deal. As the alternative is a bunch of methods that are linked by HTTP requests, Message Driven Beans (MDB), database triggers, task forms, etc. Even when using the most applicable architectural components available in Java today, it is still very easy to end up in a bunch of unmaintainable hooks and eyes. Using an overall business process makes it a lot easier to see and maintain the overall execution flow, even from a software technical perspective. JBoss jBPM does exactly that and it differentiates itself from other BPM projects in the following topics: Easily embeddable into a Java project. Traditional BPM Systems typically require a separate server to be installed which makes it hard to integrate into the Java software development cycle. One of the deployments that JBoss jBPM supports is just adding the jBPM library to the classpath. The jBPM tables can be hosted in any database next to the application's tables. Using JBoss jBPM really fits with the normal way of developing Java software. Support for multiple process languages. The view on what BPM actually is has not yet been stabilized. There are currently many different interpretations of what BPM is, resulting in big fragmentation in the market. In fact, the body of this article tries to identify 6 distinct concepts that all are associated to BPM. Very flexible transaction management. If your application just uses a JDBC connection in a standard Java environment, then jBPM can use that very JDBC connection to perform its work. If your application uses hibernate in a standard environment, then jBPM can use the same hibernate session factory. If your application runs in an enterprise environment, then jBPM can bind to the surrounding JTA transaction. Readable jPDL process language. For developers it is very convenient if the process language is compact and readable. Not all developers want to keep using the graphical editor. Most hard core programmers start to hand code the processes after a while. Then jBPM's jPDL process language is the most readable, compact and complete. Standards BPEL and BPMN Todays most known standards in the space of BPM are BPEL and BPMN. Those two standards have a completely different background. That is a clear indication of the diverse type of problems that is currently associated to BPM. BPEL is defined with an Enterprise Service Bus (ESB) in mind. It's all based on WSDL, which binds naturally to web services. The result of deploying a BPEL process is that a new service is being published. A BPEL process can hence be seen as a scripting language for services on the bus. A more elaborate conceptual explanation of BPEL can be found in Process Component Models: The Next Generation In Workflow ? So BPEL is an executable process language, which implies that a it is human to computer communication, just like a programming language. On the other hand, the first target of BPMN is modeling process diagrams by non-technical business analysts. It defines the shapes, types and meaning of the boxes and arrows. This type of modeling should be seen in the context of 'BPM as a discipline' (see below). By definition, non technical business analyst do not think in terms of web services or other technology aspects. BPMN processes are primarily intended for communication between humans. So far, so good. But now comes the hard and confusing reality: BPEL has been presented as a solution for 'BPM as a discipline' and BPMN 2.0 plans to add concrete executable semantics. These days, most IT people already realized that BPEL is not a convenient solution for 'BPM as a discipline'. On the other hand adding concrete executable semantics to a business analyst modeling notation means that non-technical analysts will be implicitly writing a piece of executable software. Would you put software into production written by a non-technical person ? Use Case 1 : BPM as a discipline BPM as a discipline refers to the analysis, documentation and improvement of the procedures that describe how people and systems work together in an organization. Realize that most BPM is done in this way, not even resulting into any form of software or IT support. MS Visio is one the most used tools to document business processes. Of course, once the business process is documented, it might make sense to develop software support for it. Suppose that a business analyst modeled and documented a 'business trip' process, then one usage might be to find optimizations in that process. And another usage might be the development of software support for business trips. Please be aware that an automatic translation between pure analysis models and executable process models are not feasible in general. Initially BPM products tried to make this translation automagically transparent. In the context of BPM as a discipline, we believe that a process model from a non technical business analyst can never be translated into an executable process model by just adding technical details to it. The next attempt was to acknowledge existence of an analysis model and an executable process model and then try to keep them in sync. Especially because of the big differences between BPMN and BPEL this approach got a lot of attention. But then the problem of maintaining the links between analysis and executable process model appears. Who is going to spend the time to link the analysis blocks to the executable blocks and then keep that mapping up to date. This is illustrated in the following picture: [img_assist|nid=5584|title=|desc=|link=none|align=undefined|width=539|height=295] For mainstream software development resulting from 'BPM as a discipline', we believe that the original analysis diagram should serve as input with the rest of the software requirements. Developers should then construct an executable process that looks as close as possible to the original analysis diagram. After that, the analysis diagram is discarded and replaced by the executable process diagram. That way, the developer is in full control of the software technical aspects, while the analyst will still recognize the diagram. jBPM's jPDL language is designed to facilitate this approach. First of all, it's based on free graph modeling. Secondly, it has so called actions, which can be seen as event listeners. These event listeners are pieces of Java code that are called when process execution produces the event, but they are hidden from the process diagram. This allows the developer to add programming logic without changing the diagram structure. Also super-states are often used in the context of creating better communication between business analyst and developer. Use Case 2 : Combining template based and ad hoc task management Orchestrating human tasks can be found in most process engines in one form or another. But what is often overlooked is that template based task orchestration only suits for a limited number of scenarios. First the process must be relatively stable. And secondly, enough executions of this process have to happen so that the gain that can be achieved with software support is worth the development effort. A lot of work being done in organizations does not meet those two requirements. For example, organizing a one-time team building event, a restyling of the office space or cleaning up after the sprinkler system went off unexpectedly. For that type of work, people in charge will invent the process on the spot and it will only be executed once. Human Interaction Management (HIM) focuses on this type of work. A story in HIM reflects a task that person creates for which an ad-hoc process will be created. People can get involved in different roles. There are big benefits of tracing such work with a task management system. First, people that get involved with such a task after a while will get instant visibility into the history of the whole story. And secondly, an audit trail is logged automatically. In jBPM 4, the task management component will support this ad hoc human tasks. The combination will be awsome. Human tasks in processes can be specified at a course grained level. When such a process task is created for a person, the assignee can involve other people by creating subtasks and assigning people in different roles to these tasks. Only when the owner decides that the overall task is finished, then the process will continue. Use case 3 : Transactional asynchronous architectures Gregor Hohpe's Entperprise Integration Patterns describes building blocks for asynchronous architectures. These patterns are based on the notion of Message Oriented Middleware (MOM) aka message brokers. MOM's are good at asynchronous transactional communication between two systems and JMS is the Java standard to work with it. Of course point-to-point communication can be set up easily with existing Java infrastructure like Message Driven Beans. But in many cases many of these point-to-point communications are related. For example, to process one order, a message might come from a client into the order processing system. As part of that transaction, a notification might be sent to the warehouse and stock planning team. Eventually after many more steps, a message might be sent back to the client as a confirmation of the order. If all these transactional communications are build linearly, it will be very hard to manage the overall state of order processing. BPEL also focuses on asynchronous architectures, but then in a (web) services environment, rather then a Java environment. In BPEL only (web) services can be invoked and XML based technologies like XPath are integrated. So for more complex calculations, a piece of programming logic needs to be included. To include programming logic in BPEL, it needs t be wrapped and exposed as a service. That can be quite cumbersome in certain situations. In contrast, jPDL is embedded in a Java environment. Such a central dispatching functionality is really suited to be implemented by a process language like jPDL. An incoming message can start a new jPDL process execution or provide a trigger for an existing execution. jPDL allows to include programming logic straight into the process transaction. Cause jPDL is based on a Java architecture, that results into much more flexibility and convenience. Using the central dispatching approach creates immediately more insight into the overall state of a process. In terms of our order processing example, it will be very easy to keep track of the state of each order. Further more, process engines like jPDL collect the history information. This is an extra feature that you get for free when using a process engine in this way. From the history information it is very easy to collect valuable statistical information like the average time in each step of the process. The difference with the use case 'BPM as a discipline' is that in this case, the goal is software technical in nature. The process is looked at from an implementation perspective. There doesn't have to be a relation to a business level analysis process. Use case 4 : Service orchestration Service orchestration is actually a variant of the previous use case 'transactional asynchronous architectures'. Interactions between services on an Enterprise Service Bus (ESB) are usually asynchronous. This time, the communication is not done through sending messages over a MOM, but instead by calling services over an ESB. BPEL is a process language specifically designed for this use case. Apart from a construct to invoke WSDL services, it has a whole infrastructure for supporting conversations. Conversations are so called long running processes. The clue here is that a BPEL process specifies a number of service operations that are being published when a BPEL process is deployed. A BPEL process can then contain receive activities, which mean that the process execution will wait until a service operation invocation is received. In jBPM we have implemented the BPEL process language as on of the languages that we support on top of our Process Virtual Machine. Use Case 5 : Visual programming With visual programming, we will target developers that do not yet have the full skillset to develop in Java. They can graphically specify the activities and draw transitions to indicate the control flow. Instead of typing Java code, just put blocks like 'perform hql query', 'generate pdf', 'send email', 'read file', 'parse xml', 'send msg to esb'. Instead of writing Java, they will be composing software programs by linking activity boxes in the diagram and filling in the configuration details. This will, of course, not have the same kind of flexibility as Java programming itself. Visual programming as we describe it here will not replace programming as we know it today. Today's programmers can be considered the power users and that kind will always be needed. But visual programming can lower the treshold to build applications for developers that have no or limited Java knowledge. The Process Virtual Machine (PVM) is the foundation of jBPM. In the PVM infrastructure it is really easy to add a new activity type. Think of it as a kind of command pattern, where the commands are configurable. So it will be very easy for us to develop new activity types. This way, we can expose the bulk part of the Java programming functionalities as activity types in the jPDL process language. In jPDL, these visual programs will be executable transactionally or without persisting the state of the execution. Use Case 6 : Thread Control Language This is a specific aspect of visual programming that also can be used by experienced developers. Coding multi-threaded Java programs is not easy. In fact, it is at least tedious and mostly pretty hard to code. Starting new threads, passing data into them, joining and making them stop properly can be a challenge. We'll develop a Thread Control Language which lets you specify a multithreaded Java concurrency by drawing forks, joins and method activities. A method activity invokes a methods on your Java object. And the concurrency control is handled by the forks and join in the process. These processes will be executed without any persistence. Use Case 7 : Easy creation of DSLs General purpose process languages are different from domain specific process languages. For example, think of a process language to specify approvals in an Enterprise Content Management (ECM) system. This gives a scoped functionality and a fixed environment. In such cases, a specific process language could be developed for this purpose. One of the advantages of such dedicated languages is that they can be made simple enough so that non technical business users can actually create fully executable processes. Another example of a domain specific process language is SEAM's Pageflow. It allows developers of a JSF based web site to specify the pages and navigations between the pages graphically. There is even an easier way. Instead of creating a full process language for a specific purpose, it is also possible to leverage jPDL's capabilities and just add new node types to it. That is already possible in jBPM 3 and will be peanuts in jBPM 4, even adding graphical support in the process designer for these new node types will be made simple. Conclusion The typical understanding of BPM is that non technical business people create diagrams that then automagically get executed on a BPM system. The first use case 'BPM as a discipline' describes that point of view. The value lies in the fact that non technical business people can communicate with the developers around a diagram. That diagram facilitates the communication between business analysts and developers. But even in that use case, the traditional understanding needs fine tuning. An analysis diagram at some point has to be converted into an executable process. At that moment, the responsibility over the process is transferred from the analyst to the developer. Many vendors have created the tools and illusion that this can be done automagically. But in practice, this black box approach creates more problems then it solves. The description of the 7 individual use cases shows distinct aspects of BPM. Knowing the difference between service orchestration and 'BPM as a discipline' will be key for organizations to select the most appropriate technology. All of the use cases have at least a technical side. That is understandable as all the use cases here target some form of software automation at some point. And other use cases target solely technical aspects. That is why the embeddability of jBPM is so important. Monolithic BPM engines have a high treshold to be incorporated into a typical software development project. jBPM has a big focus on delivering solutions for these distinct use cases to developers in a way that is easy for them to consume and integrate into their own software development project. Tom Baeyens is the founder and lead of JBoss jBPM, the leading open source BPM system. Tom mission is to bring the power of BPM technology into the hands of the developers. He's a frequent speaker at international conferences and maintains a blog at http://processdevelopments.blogspot.com
October 21, 2008
by Tom Baeyens
· 57,273 Views · 1 Like
article thumbnail
A Look Inside the JBoss Microcontainer, Part I -- Component Models
Looking at the current state of Java, we can see that POJOs (Plain Old Java Objects) rule the land yet again. Their dominance stretches from enterprise applications to middleware services. At JBoss we were known for our modular JMX-based kernel. The application server was nothing more than a bunch of flexible MBeans and a powerful MicroKernel in the middle. But, as you could feel the change is coming, we still wanted to be ahead of the pack. We could see different POJO based component models popping up all over the place (EJB3, JPA, Spring, Guice, … to name a few), yet nothing was out there that would bind them all, flattening out the differences on a single component model. Hence the Microcontainer project was born. The JBoss Microcontainer project is about many things. The Microcontainer's features range from reflection abstraction, a virtual file system, a simple state machine to transparent AOP integration, a new classloading layer, a deployment framework and an OSGi framework implementation. I'll try to address them all over a short series of articles that will be published here on DZone. This article will examine the Microcontainer's component models. Read the other parts in DZone's exclusive JBoss Microcontainer Series: Part 1 -- Component Models Part 2 –- Advanced Dependency Injection and IoC Part 3 -- the Virtual File System Part 4 -- ClassLoading Layer Part 5 - the Virtual Deployment Framework Part 6 - The Scanning Library What is a component model? What do we consider a component model? First of all, what do we consider being a component? One abstract way to express this would be that “components are reusable software programs that you can develop and assemble easily to create sophisticated applications.” To consider a bunch of components as an actual model, we also need to declare what kind of interactions we allow. JMX MBeans are one example of a component model. Their interactions include executing MBean operations, referencing attributes, setting attributes and declaring explicit dependencies between named MBeans. As mentioned, we had advanced JMX handling already with the MicroKernel. And as expected, the Microcontainer brought extensive POJO support. The default behavior and interactions in the Microcontainer are what you also normally get from any other IoC container and are similar to the functionality that MBeans provided: plain method invocations for operations, setters/getters for attributes and explicit dependencies. However, having only this functionality would mean we didn't get much further than just relieving the pain of declaring MBeans, hence it was only logical for us to do something more. I'll leave the discussion of these new IoC features for the next article in the series. There are many existing POJO component models out there, Guice and Spring being amongst the most popular. Effective integration with these frameworks was an important goal for us. Demo environment setup Before we begin, I'd like to first describe the various parts that constitute the demo. All the source code can be found at this location of our Subversion repository: • http://anonsvn.jboss.org/repos/jbossas/projects/demos/microcontainer/branches/DZone_1_0/ The project is fully mavenized, so it should be easy to adjust it to your IDE. I will first go over the sub-projects within the demo and describe their usage. At the end of my article series, I will provide a more detailed look at what certain sub-projects do. Below are the JBoss Microcontainer demos and sub-projects that are relevant for this article: • bootstrap (as the name suggests, it bootstraps the Microcontainer with demo code) • jmx (adds the JMX notion to demo's bootstrap) • models (source code of our components / services) The demo has only one variable you need to set - demos home - but even this one can be optional if you checked-out your project into the \projects\demos directory. Otherwise, you need to set the system property demos.home (e.g. -Ddemos.home=). You should now be able to run JMXMain as a main class. Make sure you include the models sub-project in the classpath, since some of the services require additional classes in the classpath, several more then what the jmx sub-project expects. Once the Microcontainer is booted it starts to scan the ${demos.home}/sandbox directory for any changes. Now all we need to do is provide a deployable unit and drop it in there. Models Let’s now turn our attention to the models sub-project. This is where the previously mentioned deployable unit should come from. You can see if everything is in place by building the models sub-project (mvn package) and dropping it into the sandbox. You should get a bunch of debug and info messages on the console log, showing how the Microcontainer got booted. Any error message indicates some problems. Let’s go over exactly what the models sub-project does, its integration code and try to redeploy it. If we look at the models src/main/resources/META-INF directory, we'll see plenty of -beans.xml resource files and one -service.xml. You’ll notice that each has a meaningful name that matches the source code package from models's src/main/java/org/jboss/demos/models directory. Let's dissect them one by one, starting with the ones that have no dependencies. org.jboss.demos.models.plain.PojoFactory This is a simple Micrcocontainer beans descriptor file. Anyone who crossed paths with some other IoC’s configuration file should be familiar with it. And, as I already mentioned, I'll follow up on more advanced usage in the next article. The next file shows what we have done to support Spring integration: Note that this file's namespace is different from the previous Microcontainer bean’s plain-beans.xml file. The urn:jboss:spring-beans:2.0 namespace points to our version of the Spring schema port, meaning you can describe your beans Spring style, but it's the Microcontainer that's going deploy then, not Spring's bean factory notion. public class Pojo extends AbstractPojo implements BeanNameAware { private String beanName; public void setBeanName(String name) { beanName = name; } public String getBeanName() { return beanName; } public void start() { if ("SpringPojo".equals(getBeanName()) == false) throw new IllegalArgumentException("Name doesn't match: " + getBeanName()); } } Although the SpringPojo bean has a dependency on Spring lib via implementing BeanNameAware interface, this dependency is only there to expose and mock some of the Spring's callback behavior (see SpringBeanAnnotationPlugin for more details). Since we introduced Spring integration, let's have a look at Guice integration. As Guice users know, Guice is all about type matching. Configuration of Guice beans is done via Modules which means that in order to generate beans, one must implement a Module. Two important parts to watch from this file are PojoModule and GuiceKernelRegistryEntryPlugin. The first one is where we configure our beans: public class PojoModule extends AbstractModule { private Controller controller; @Constructor public PojoModule(@Inject(bean = KernelConstants.KERNEL_CONTROLLER_NAME) Controller controller) { this.controller = controller; } protected void configure() { bind(Controller.class).toInstance(controller); bind(IPojo.class).to(Pojo.class).in(Scopes.SINGLETON); bind(IPojo.class).annotatedWith(FromMC.class).toProvider(GuiceIntegration.fromMicrocontainer(IPojo.class, "PlainPojo")); } } The second class provides integration with the Microcontainer: public class GuiceKernelRegistryEntryPlugin implements KernelRegistryPlugin { private Injector injector; public GuiceKernelRegistryEntryPlugin(Module... modules) { injector = Guice.createInjector(modules); } public void destroy() { injector = null; } public KernelRegistryEntry getEntry(Object name) { KernelRegistryEntry entry = null; try { if (name instanceof Class) { Class clazz = (Class)name; entry = new AbstractKernelRegistryEntry(name, injector.getInstance(clazz)); } else if (name instanceof Key) { Key key = (Key)name; entry = new AbstractKernelRegistryEntry(name, injector.getInstance(key)); } } catch (Exception ignored) { } return entry; } } Notice how we created an Injector from the Modules and then did a lookup on it for matching beans. In mbeans-service.xml we declare our legacy usage of MBeans: What’s interesting to note here is how we injected a POJO into an MBean. The preceding demonstrated our first interactions between different component models. In order to allow for MBean deployment via the Microcontainer, we had to write entirely new component model handling code. See the system-jmx-beans.xml for more details. The code from this file lives in the JBossAS source code: system-jmx sub-project. One note here, this is currently only possible with JBoss's JMX implementation, since the system-jmx code uses some implementation details. Now what if we wanted to expose our existing POJOs as MBeans, registering them into an Mbean server? @org.jboss.aop.microcontainer.aspects.jmx.JMX(exposedInterface=org.jboss.demos.models.mbeans.PojoMBean.class, registerDirectly=true) As you can see from looking at any of the beans in this file, in order to expose your POJOs as MBeans, it’s simply a matter of annotating them with an @JMX annotation. You can either expose the bean directly or its property: Here we see how you can use any of the injection lookup types by either looking up a plain POJO or getting a handle to an MBean from the MBean server. One of the injection options is to use type injection, which is also sometimes called autowiring: The FromGuice bean injects the Guice bean via type matching, where PlainPojo is injected with a common name injection. We then test if Guice binding works as expected: public class FromGuice { private IPojo plainPojo; private org.jboss.demos.models.guice.Pojo guicePojo; public FromGuice(IPojo plainPojo) { this.plainPojo = plainPojo; } public void setGuicePojo(org.jboss.demos.models.guice.Pojo guicePojo) { this.guicePojo = guicePojo; } public void start() { f (plainPojo != guicePojo.getMcPojo()) throw new IllegalArgumentException("Pojos are not the same: " + plainPojo + "!=" + guicePojo.getMcPojo()); } } This only leaves us with an alias component model. Even though the alias is quite a trivial feature, in order to implement it as a true dependency, it has to be introduced as a new component model inside the Microcontainer. The implementation details for this is part of the AbstractController source code: springPojo Here we’ve mapped the SpringPojo name to the springPojo alias. The beauty of having aliases as true component models is that it doesn't matter when the real bean gets deployed. This means that the alias will wait in a non-installed state until the real bean triggers it. Conclusion We've seen how we can deploy simple Microcontainer beans, legacy MBeans, Guice POJOs, Spring beans and aliases. And since all of this is controlled by the Microcontainer, we saw how easily we can mix and match the different component models. I can easily say, with the level of abstraction we put in our component model design, the sky is the limit on what we can handle. An example of this is the upcoming OSGi services, but that's another story, another article. Stayed tuned for my next article which will provide a detailed look at the Microcontainer's IoC functionality. About the Author Ales Justin was born in Ljubljana, Slovenia and graduated with a degree in mathematics from the University of Ljubljana. He fell in love with Java seven years ago and has spent most of his time developing information systems, ranging from customer service to energy management. He joined JBoss in 2006 to work full time on the Microcontainer project, currently serving as its lead. He also contributes to JBoss AS and is Seam and Spring integration specialist. He represent JBoss on 'JSR-291 Dynamic Component Support for Java SE' and 'OSGi' expert groups.
October 1, 2008
by Ales Justin
· 57,453 Views
article thumbnail
An Introduction to Aspect-Oriented programming with JBoss AOP
JBoss Application Server ships with support for aspect-oriented programming, so you can use AOP in your applications deployed in JBoss AS. JBoss AS 5, which is currently available as a community release, has AOP built into its core. However, JBoss AOP is also available as a standalone framework for use in your other applications. This article will take a simple example, and use JBoss AOP to add to its behaviour, while explaining some of the core functionality of JBoss AOP. We will look at encapsulating cross-cutting concerns into aspects, have a look at around advices vs the new lightweight advices in the upcoming JBoss AOP 2.0 release, and also look at using interface-introductions and mixins to add interfaces to your classes. Table of Contents Our Core Application Our Core Application The application we will look at is is a simple banking application. It has a BankAccount class: package bank; public class BankAccount { int accountNumber; int balance; public BankAccount(int accountNumber) { System.out.println("*** Bank Account constructor"); this.accountNumber = accountNumber; } public int getAccountNumber() { return accountNumber; } public int getBalance() { return balance; } public void debit(int amount) { System.out.println("*** BankAccount.debit()"); balance -= amount; } public void credit(int amount) { System.out.println("*** BankAccount.credit()"); balance += amount; } } In addition it has a main Bank class: package bank; import java.util.HashMap; import java.util.Map; public class Bank { static Map bankAccounts = new HashMap(); public static void transfer(BankAccount from, BankAccount to, int amount) { from.debit(amount); to.credit(amount); } public static void main(String[] args) { System.out.println("*** Creating account 1"); BankAccount acc1 = new BankAccount(1); acc1.credit(150); bankAccounts.put(acc1.getAccountNumber(), acc1); System.out.println("*** Creating account 2"); BankAccount acc2 = new BankAccount(2); acc2.credit(230); bankAccounts.put(acc2.getAccountNumber(), acc2); System.out.println("*** Balance acount 1: " + acc1.getBalance()); System.out.println("*** Balance acount 2: " + acc2.getBalance()); //Transfer some money System.out.println("*** Transfer 50 from account 1 to account 2"); transfer(acc1, acc2, 50); System.out.println("*** Balance acount 1: " + acc1.getBalance()); System.out.println("*** Balance acount 2: " + acc2.getBalance()); } } As you can see, we create two bank accounts with their account numbers, set the initial balances, and then transfer 50 from account1 to account 2. Running this simple example we get the following expected output: *** Creating account 1 *** Bank Account constructor *** BankAccount.credit() *** Creating account 2 *** Bank Account constructor *** BankAccount.credit() *** Balance acount 1: 150 *** Balance acount 2: 230 *** Transfer 50 from account 1 to account 2 *** BankAccount.debit() *** BankAccount.credit() *** Balance acount 1: 100 *** Balance acount 2: 280 The code for this example can be found in the listing1/ folder of . Logging as a Cross-Cutting Concern One of the main uses of AOP is to extract out cross-cutting concerns. Say we wanted to add some logging whenever an object is created, when its fields are set, and when its methods are called. The “obvious” way to do that in our example would be to go in and add logging statements to various points of our application. The problem with this approach is that there might be lots of places to edit, scattered around our system, so we would need to identify those places, make our changes, and recompile our application. To turn this behaviour off, we would need to remove our logging statements again and recompile our code again. So the “obvious” way both leads to bloat, and is difficult to turn on and off. Using AOP we can encapsulate this cross-cutting code in an aspect. The aspect itself is just a normal class, which can hold state, extend other classes, everything you can do in a normal Java class. package bank; import org.jboss.aop.joinpoint.ConstructorInvocation; import org.jboss.aop.joinpoint.FieldWriteInvocation; import org.jboss.aop.joinpoint.MethodInvocation; public class LoggingAspect { public Object log(ConstructorInvocation invocation) throws Throwable { try { System.out.println("C: Creating BankAccount using constructor " + invocation.getConstructor()); System.out.println("C: Account number: " + invocation.getArguments()[0]); return invocation.invokeNext(); } finally { System.out.println("C: Done"); } } public Object log(MethodInvocation invocation) throws Throwable { try { System.out.println("M: Calling method " + invocation.getMethod().getName()); System.out.println("M: Amount " + invocation.getArguments()[0]); return invocation.invokeNext(); } finally { System.out.println("M: Done"); } } public Object log(FieldWriteInvocation invocation) throws Throwable { BankAccount account = (BankAccount)invocation.getTargetObject(); System.out.println("F: setting field " + invocation.getField().getName() + " for BankAccount " + account.getAccountNumber()); System.out.println("F: Field old value " + account.getBalance()); System.out.println("F: New value will be " + invocation.getValue()); try { return invocation.invokeNext(); } finally { System.out.println("F: Field new value " + account.getBalance()); System.out.println("F: Done"); } } } The actual code implementing the cross-cutting concerns is encapsulated in methods called advice methods. For the type of advice methods that we are looking at now, around advice, the signature and format of the advice method is as shown here: public Object (org.jboss.aop.joinpoint.Invocation invocation) throws Throwable { //Do something before try { return invocation.invokeNext(); } finally { //Do something after } } The invocation parameter can be of type org.jboss.aop.joinpoint.Invocation, or one of its subclasses. Some of these are shown in the LoggingAspect, and which of the overloaded log methods gets called depends on what is being called once we apply our aspect. In the LoggingAspect we are able to handle calls to an object's constructor (the first log() method, starting on line 9), calls to an object's methods (the second log() method, starting on line 23) and calls to set a field (the third log() method, starting on line 37). These “events” are called joinpoints in AOP terminology. The invocation contains information about what field/method/constructor is being called. It also allows access to any arguments, and the object on which we are making the call. The around advice methods also contain a call to Invocation.invokeNext(), which propogates the call chain. If there are several advice methods applied to the target joinpoint, this call invokes the next advice in the chain. If this is the last advice in the chain, or as in our example, we are the only advice in the chain, the target joinpoint is called when we call Invocation.invokeNext(). To apply our aspects, we need some configuration to declare our aspects, and to select the joinpoints in our application where the advice methods should be applied. In JBoss AOP the easiest way to do this is with an xml configuration file, typically called jboss-aop.xml. First we declare our aspect: A binding has a pointcut to choose which methods we should apply the advice to. In this case we have a constructor expression that selects the constructor of the bank.BankAccount class that has an int parameter. Note that all class names used in pointcut expressions must be fully qualified. The word new is a special identifier within the pointcut language to pick out a constructor. Next, the around part of the binding says that we should apply the log advice from the bank.LoggingAspect to the joinpoints matched by its pointcut. In other words, when we call BankAccount's constructor, the first LoggingAspect.log() method, which takes a ConstructorInvocation, is invoked. The previous binding's pointcut only captures one joinpoint. The next one uses a wildcard in place of the method name, so we pick out all methods returning void that take an int parameter, regardless of their name. It looks a lot like the constructor expression in the previous binding, but also contains the return type of the methods we are interested in. This pointcut picks out BankAccount.debit() and BankAccount.credit(), and invokes the second LoggingAspect.log() method, which takes a MethodInvocation, when these methods are called. Finally, we have a binding capturing writes to the balance field of the BankAccount class. In this case we are using a wildcard in place of the type's name, and the third LoggingAspect.log method, which takes a FieldWriteInvocation, will be invoked when the field's value is set: In addition to wildcards, you can also capture whole inheritance hierarchies of classes, use typedefs for complex class expressions, all classes belonging to a package, and as we will see use annotations to capture a wide range of jonpoints. To run this application with aop enabled, you need to pass in a few extra parameters into the jvm when starting it up, as we can see in the example's build.xml The jboss.aop.path parameter contains the path to the jboss-aop.xml that declares our aspects and binds advice methods to joinpoints. The -javaagent switch points to the JBoss AOP library, which in turn turns on load-time weaving. When a class is first loaded, JBoss AOP will intercept that event and modify the bytecode of the class to add the hooks required to trigger the aspects for our selected joinpoints. In addition to weaving at load-time, you can weave the classes using our aopc post-processor. An example of this is shown in the example's build.xml. Running the example with load-time weaving yields the following output, now with quite a lot of extra information coming from our logging aspect: *** Creating account 1 C: Creating BankAccount using constructor public bank.BankAccount(int) C: Account number: 1 *** Bank Account constructor C: Done M: Calling method credit M: Amount 150 *** BankAccount.credit() F: setting field balance for BankAccount 1 F: Field old value 0 F: New value will be 150 F: Field new value 150 F: Done M: Done *** Creating account 2 C: Creating BankAccount using constructor public bank.BankAccount(int) C: Account number: 2 *** Bank Account constructor C: Done M: Calling method credit M: Amount 230 *** BankAccount.credit() F: setting field balance for BankAccount 2 F: Field old value 0 F: New value will be 230 F: Field new value 230 F: Done M: Done *** Balance acount 1: 150 *** Balance acount 2: 230 *** Transfer 50 from account 1 to account 2 M: Calling method debit M: Amount 50 *** BankAccount.debit() F: setting field balance for BankAccount 1 F: Field old value 150 F: New value will be 100 F: Field new value 100 F: Done M: Done M: Calling method credit M: Amount 50 *** BankAccount.credit() F: setting field balance for BankAccount 2 F: Field old value 230 F: New value will be 280 F: Field new value 280 F: Done M: Done *** Balance acount 1: 100 *** Balance acount 2: 280 The code for this example can be found in the listing2/ folder of . Externalising Security Checks Logging is the common example used for introductions to AOP, so let's try doing something more interesting. Say we want to make sure that only users with the correct permissions can call a method. We could annotate our methods from BankAccount as follows: package bank; public class BankAccount { int accountNumber; int balance; @Roles(roles= {"admin"}) public BankAccount(int accountNumber) { System.out.println("*** Bank Account constructor"); this.accountNumber = accountNumber; } ... @Roles(roles= {"admin"}) public void debit(int amount) { System.out.println("*** BankAccount.debit()"); balance -= amount; } @Roles(roles= {"admin", "user"}) public void credit(int amount) { System.out.println("*** BankAccount.credit()"); balance += amount; } } So only users with the role “admin” can create BankAccount instances and debit accounts, while users with the role “admin” or “user” can credit accounts. We have created a security.properties file to configure users and their roles: admin=password;admin,user guest=password;user There is a user called 'admin' whose password is 'password' who has the roles 'admin' and 'user', and a user called 'guest' whose password is 'password' who only has the role 'user'. We can then apply a SecurityAspect to the methods annotated with the @Roles annotation. Note that like everything else in the pointcut language the annotations need to be fully qualified. The “..” in place of the parameters in the pointcut expressions means we want this aspect to be applied to all constructors and methods annotated with @Roles regardless of the parameters it takes. The SecurityAspect then checks that the correct user is used: package bank; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.net.URISyntaxException; import java.net.URL; import java.util.Arrays; import java.util.Enumeration; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Properties; import org.jboss.aop.joinpoint.Invocation; public class SecurityAspect { Map usernamePassword = new HashMap(); Map> userRoles = new HashMap>(); public SecurityAspect() throws FileNotFoundException, IOException, URISyntaxException { //Initialise the usernamePassword and userRoles maps //with information from security.properties } public Object checkSecurity(Invocation invocation) throws Throwable { String username = LoginInfo.getUsername(); String password = usernamePassword.get(username); if (password == null) { throw new SecurityException("Unknown user"); } if (!password.equals(LoginInfo.getPassword())) { throw new SecurityException("Wrong password"); } Roles rolesAnnotaton = (Roles)invocation.resolveAnnotation(Roles.class); List hasRoles = userRoles.get(username); boolean hasRole = false; if (hasRoles != null) { for (String role : rolesAnnotaton.roles()) { if (hasRoles.contains(role)) { hasRole = true; break; } } } if (!hasRole) { throw new SecurityException("Wrong roles for user"); } return invocation.invokeNext(); } } The roles needed to invoke the target joinpoint are got from the invocation using this call: Roles rolesAnnotaton = (Roles)invocation.resolveAnnotation(Roles.class); This does the same as calling java.lang.reflect.Method.getAnnotation() or java.lang.reflect.Constructor.getAnnotation() for the called method or constructor, but also allows for annotation overrides as part of the aop configuration, which are beyond the scope of this article. Although the type of invocation used in this example is Invocation, the specific type created by JBoss AOP will be ConstructorInvocation or MethodInvocation depending on what we are calling. The referenced LoginInfo class is just a wrapper around some static fields containing the username and password. package bank; public class LoginInfo { private static String username; private static String password; public static void setUsernameAndPassword(String username, String password) { LoginInfo.username = username; LoginInfo.password = password; } public static String getUsername() { return username; } public static String getPassword() { return password; } } Now let us modify the Bank.main() method to populate the LoginInfo fields: public static void main(String[] args) { System.out.println("*** Log in as 'guest' - it does not have the correct roles to create an account"); LoginInfo.setUsernameAndPassword("guest", "password"); System.out.println("*** Attempting to create account 1"); try { BankAccount acc1 = new BankAccount(1); acc1.credit(150); bankAccounts.put(acc1.getAccountNumber(), acc1); } catch(SecurityException e) { System.out.println("!!! Expected SecurityException " + e.getMessage()); } System.out.println("*** Log in as 'admin' - the roles are fine for the rest now"); LoginInfo.setUsernameAndPassword("admin", "password"); System.out.println("*** Creating account 1"); BankAccount acc1 = new BankAccount(1); acc1.credit(150); bankAccounts.put(acc1.getAccountNumber(), acc1); System.out.println("*** Creating account 2"); BankAccount acc2 = new BankAccount(2); acc2.credit(230); bankAccounts.put(acc2.getAccountNumber(), acc2); System.out.println("*** Balance acount 1: " + acc1.getBalance()); System.out.println("*** Balance acount 2: " + acc2.getBalance()); //Transfer some money System.out.println("*** Transfer 50 from account 1 to account 2"); transfer(acc1, acc2, 50); System.out.println("*** Balance acount 1: " + acc1.getBalance()); System.out.println("*** Balance acount 2: " + acc2.getBalance()); } We first try to create a BankAccount with a user who does not have the required admin role, and then we do the rest, as before, with an user with the required roles. The output of running this application is: *** Log in as 'guest' - it does not have the correct roles to create an account *** Attempting to create account 1 !!! Expected SecurityException Wrong roles for user *** Log in as 'admin' - the roles are fine for the rest now *** Creating account 1 *** Bank Account constructor *** BankAccount.credit() *** Creating account 2 *** Bank Account constructor *** BankAccount.credit() *** Balance acount 1: 150 *** Balance acount 2: 230 *** Transfer 50 from account 1 to account 2 *** BankAccount.debit() *** BankAccount.credit() *** Balance acount 1: 100 *** Balance acount 2: 280 By using AOP to apply security, we have extracted the security checks into one place in our application, and used annotations to configure that. If we wanted to use a different mechanism of configuring the users we could leave the core application the same, write another aspect and easily change how we use security everywhere by modifying the jboss-aop.xml file. The code for this example can be found in the listing3/ folder of . Observer with Introductions and Mixins Say we want to be able to be notified somehow when BankAccount.balance is changed. An option would be to implement the Observer pattern, but we don't want to include all the Observable plumbing code in our BankAccount class. First of all let's add an annotation to the field we want to monitor. package bank; public class BankAccount { int accountNumber; @Observed int balance; ... } Next we can write an implementation of Observable: package bank; import java.util.ArrayList; import java.util.List; public class ObservableMixin implements Observable { List observers = new ArrayList(); public void addObserver(Observer listener) { observers.add(listener); } public void removeObserver(Observer listener) { observers.remove(listener); } public void notifyObservers(Object event) { for (Observer observer : observers) { observer.update(event); } } } This is a mixin class, which implements the Observable interface. It contains all the plumbing code needed for the Observable part of the pattern. It can be introduced into other POJOs using the following xml bank.Observable bank.ObservableMixin ... This does two things. It makes all classes that have a field annotated with @Observed implement the @Observable interface and implement those methods. Second, when anybody attempts to call the methods from the Observable interface, it delegates all the calls to an instance of the ObservableMixin. Next we have an aspect to trap when the annotated fields change their values bound using the following xml. ... The aspect is an around advice that captures the values before and after modifying the field. package bank; import java.lang.reflect.Field; import org.jboss.aop.joinpoint.FieldWriteInvocation; public class ObserverAspect { public Object fieldChanged(FieldWriteInvocation invocation) throws Throwable { Observable tgt = (Observable)invocation.getTargetObject(); Field fld = invocation.getField(); String fieldName = fld.getName(); fld.setAccessible(true); Object oldVal = invocation.getField().get(tgt); Object result = invocation.invokeNext(); Object newVal = invocation.getField().get(tgt); tgt.notifyObservers("Changed " + fieldName + " from " + oldVal + " to " + newVal); return result; } } Since the classes captured by the pointcut to select which classes should have the ObserverAspect applied are in the set of classes captured by the class expression to pick out classes that should have the Observable introduction and mixin, we can safely cast the target of the invocation to Observable. We then get the values before and after writing the field, and then use the Observable target object to notify the observers. As mentioned the call to Observable.notifyObservers() will end up inside BankAccount's ObservableMixin. Finally, let us modify the Bank.main() method to register an Observer with a BankAccount instance public static void main(String[] args) { System.out.println("*** Creating account 1"); BankAccount acc1 = new BankAccount(1); acc1.credit(150); bankAccounts.put(acc1.getAccountNumber(), acc1); System.out.println("*** Creating account 2"); BankAccount acc2 = new BankAccount(2); acc2.credit(230); bankAccounts.put(acc2.getAccountNumber(), acc2); System.out.println("Installing observer"); ((Observable)acc2).addObserver(new Observer(){ public void update(Object evt) { System.out.println("!!! Observer: " + evt); } }); System.out.println("*** Balance acount 1: " + acc1.getBalance()); System.out.println("*** Balance acount 2: " + acc2.getBalance()); //Transfer some money System.out.println("*** Transfer 50 from account 1 to account 2"); transfer(acc1, acc2, 50); System.out.println("*** Balance acount 1: " + acc1.getBalance()); System.out.println("*** Balance acount 2: " + acc2.getBalance()); } Although until woven the BankAccount class does not implement the Observable interface, the Java compiler does not perform any checks when casting to an interface (only to a superclass), so the cast from BankAccount to Observable will compile. (If the example is run without weaving you would get a ClassCastException since then BankAccount would not implement the Observable interface). When we run this example we can see the registered Observer gets triggered: *** Creating account 1 *** Bank Account constructor *** BankAccount.credit() *** Creating account 2 *** Bank Account constructor *** BankAccount.credit() Installing observer *** Balance acount 1: 150 *** Balance acount 2: 230 *** Transfer 50 from account 1 to account 2 *** BankAccount.debit() *** BankAccount.credit() !!! Observer: Changed balance from 230 to 280 *** Balance acount 1: 100 *** Balance acount 2: 280 The code for this example can be found in the listing5/ folder of . Conclusion We have taken a simple application, added extra behaviour to it using JBoss AOP, and explored a few of the features offered. Apart from adding a few annotations to help with our pointcut expressions (and there are even less intrusive, although more incovenient ways to achieve the similar effect), we have left the core application as is, and added extra cross-cutting behaviour such as logging and security by applying aspects, as well as using a combination of aspects, interface introductions and mixins to implement the Observer pattern. JBoss AOP can be downloaded from http://www.jboss.org/jbossaop/ and comes with a tutorial to get you started.
August 28, 2008
by Kabir Khan
· 85,124 Views · 2 Likes
article thumbnail
Compute Grids vs. Data Grids
in a nutshell, grid computing is a way to distribute your computations across multiple computers (nodes). however, even jms does that, but jms is not a grid computing product - it's a messaging protocol. to correctly classify grid computing products we have to split them into 2 categories: compute grids and data grids. compute grid compute grids allow you to take a computation, optionally split it into multiple parts, and execute them on different grid nodes in parallel. the obvious benefit here is that your computation will perform faster as it now can use resources from all grid nodes in parallel. one of the most common design patterns for parallel execution is mapreduce . however, compute grids are useful even if you don't need to split your computation - they help you improve overall scalability and fault-tolerance of your system by offloading your computations onto most available nodes. some of the "must have" compute grid features are: automatic deployment - allows for automatic deployment of classes and resources onto grid without any extra steps from user. this feature alone provides one of the largest productivity boosts in distributed systems. users usually are able to simply execute a task from one grid node and as task execution penetrates the grid, all classes and resources are also automatically deployed. topology resolution - allows to provision nodes based on any node characteristic or user-specific configuration. for example, you can decide to only include linux nodes for execution, or to only include a certain group of nodes within certain time window. you should also be able to choose all nodes with cpu loaded, say, under 50% that have more than 2gb of available heap memory. collision resolution - allows users to control which jobs get executed, which jobs get rejected, how many jobs can be executed in parallel, order of overall execution, etc. load balancing - allows to balance properly balance your system load within grid. usually range of load balancing policies varies within products. some of the most common ones are round robin, random, or adaptive. more advanced vendors also provide affinity load balancing where grid jobs always end up on the same node based on job's affinity key. this policy works well with data grids described below. fail-over - grid jobs should automatically fail-over onto other nodes in case of node crash or some other job failure. checkpoints - long running jobs should be able to periodically store their intermediate state. this is useful for fail-overs, when a failed job should be able to pick up its execution from the latest checkpoint, rather than start from scratch. grid events - a querying mechanism for all grid events is essential. any grid node should be able to query all events that happened on remote grid nodes during grid task execution. node metrics - a good compute grid solution should be able to provide dynamic grid metrics for all grid nodes. metrics should include vital node statistics, from cpu load to average job execution time. this is especially useful for load balancing, when the system or user need to pick the least loaded node for execution. pluggability - in order to blend into any environment a good compute grid should have well thought out pluggability points. for example, if running on top of jboss, a compute grid should totally reuse jboss communication and discovery protocols. data grid integration - it is important that compute grid are able to natively integrate with data grids as quite often businesses will need both, computational and data features working within same application. some compute grid vendors: - gridgain - professional open source - jppf - open source data grid data grids allow you to distribute your data across the grid. most of us are used to the term distributed cache rather than data grid (data grid does sound more savvy though). the main goal of data grid is to provide as much data as possible from memory on every grid node and to ensure data coherency. some of the important data grid features include: data replication - all data is fully replicated to all nodes in the grid. this strategy consumes the most resources, however it is the most effective solution for read-mostly scenarios, as data is available everywhere for immediate access. data invalidation - in this scenario, nodes load data on demand. whenever data changes on one of the nodes, then the same data on all other nodes is purged (invalidated). then this data will be loaded on-demand the next time it is accessed. distributed transactions - transactions are required to ensure data coherency. cache updates must work just like database updates - whenever an update failed, then the whole transaction must be rolled back. most data grid support various transaction policies, such as read committed, write committed, serializable, etc... data backups - useful for fail-over. some data grid products provide ability to assign backup nodes for the data. this way whenever a node crashes, the data is immediately available from another node. data affinity/partitioning - data affinity allows you to split/partition your whole data set into multiple subsets and assign every subset to a grid node. in the purest form, data is not replicated between nodes at all, every node is only responsible for it's own subset of data. however, various data grid products may provide different flavors of data affinity, such as replication only to back up nodes for example. data affinity is one of the more advanced features, and is not provided by every vendor. to my knowledge, according to product websites, out of commercial vendors oracle coherence and gemstone have it (there may be others). in professional open source space you can take a look at combination of gridgain with affinity load balancing and jbosscache . some data grid/cache vendors: - oracle coherence - commercial - gemstone - commercial - gigaspaces - commercial - jbosscache - professional open source - ehcache - open source
July 31, 2008
by Dmitriy Setrakyan
· 28,430 Views · 3 Likes
  • Previous
  • ...
  • 129
  • 130
  • 131
  • 132
  • 133
  • 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
×