DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Refcards Trend Reports
Events Video Library
Refcards
Trend Reports

Events

View Events Video Library

The Latest Testing, Tools, and Frameworks Topics

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,485 Views
article thumbnail
EJB 3.0 and Spring 2.5
Why is it that developers from these two communities don't like to see eye to eye? I have been using both Spring from its inception, and EJB's from 2001. Just like everyone else did, I just dreaded the huge amount of XML we had to write for both of these; configuration files in Spring, and deployment descriptors in EJB 2.x. However, Java 5 came to our rescue and now annotations have mostly replaced XML files in both these. But, after having used these two latest versions Spring 2.5 and EJB 3.0, I think that they complement each other, rather than compete with each other. There are certain features which are powerful in Spring, and equal number of features powerful on the EJB side as well. Many developers fail to understand, that Spring is a popular non-standard framework created by Spring Source, while EJB 3.0 is a specification which is supported by major JEE vendors. There are a few developers with whom I have worked earlier, prefer to use standard specification, and they chose EJB2.x/ and are moving now to EJB 3.0. However, there isn't anything stopping you from using Spring along with EJB, is it? The complaint I have heard many times is: We can't use non-standard framework". The same developers who complain about Spring being non-standard use home grown frameworks, which was and will be forever so hard to even decipher. How can it be a specification when a couple of developers write several thousand lines of code? Also, a recent article published here at Javalobby by Adam Bien showed the trend moving towards EJB 3.0, right? Anyway, in this article we will see how by adding a few lines in your Spring configuration file, you can seamlessly use EJB 3.0 components within your Spring application. Back to our EJB 3.0 and Spring 2.5 article, we are going to see how easy and simple it is to access EJB 3.0 components in Spring by using its powerful dependency injection mechanism to inject an instance of our Customer session bean. This Customer session bean, in turn uses the Entity Manager for the CRUD operations on the Customer Entity. Here are the detailed steps: Step 1: Create a simple JPA Entity. The Java Persistence API (JPA) is defined as part of the Java EE 5 specification. Creating entities using JPA is as simple as creating a POJO with a few annotations as shown below: package com.ejb.domain; import java.io.Serializable; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.Id; import javax.persistence.Table; /** * * @author meerasubbarao */ @Entity @Table(name = "CUSTOMER", catalog = "", schema = "ADMIN") public class Customer implements Serializable { private static final long serialVersionUID = 1L; @Id @Column(name = "CUSTOMER_ID") private Long customerId; @Column(name = "FIRST_NAME") private String firstName; @Column(name = "LAST_NAME") private String lastName; @Column(name = "MIDDLE_NAME") private String middleName; @Column(name = "EMAIL_ID") private String emailId; public Customer() { } public Customer(Long customerId) { this.customerId = customerId; } public Long getCustomerId() { return customerId; } public void setCustomerId(Long customerId) { this.customerId = customerId; } public String getFirstName() { return firstName; } public void setFirstName(String firstName) { this.firstName = firstName; } public String getLastName() { return lastName; } public void setLastName(String lastName) { this.lastName = lastName; } public String getMiddleName() { return middleName; } public void setMiddleName(String middleName) { this.middleName = middleName; } public String getEmailId() { return emailId; } public void setEmailId(String emailId) { this.emailId = emailId; } } Step 2: Create a EJB 3.0 Session bean. This session beans uses the Entity Manager for the Create Read Update Delete (CRUD) operations for the Customer Entity we created in Step 1. The CRUD opertions are also published as web methods by adding a few basic annotations. The Interface: package com.ejb.service; import com.ejb.domain.Customer; import java.util.Collection; import javax.ejb.Remote; /** * * @author meerasubbarao */ @Remote public interface CustomerService { Customer create(Customer info); Customer update(Customer info); void remove(Long customerId); Collection findAll(); Customer[] findAllAsArray(); Customer findByPrimaryKey(Long customerId); } The Implementation Class: package com.ejb.service; import com.ejb.domain.Customer; import java.util.Collection; import javax.ejb.Stateless; import javax.jws.WebService; import javax.jws.soap.SOAPBinding; import javax.persistence.EntityManager; import javax.persistence.PersistenceContext; import javax.persistence.Query; import javax.jws.WebMethod; /** * * @author meerasubbarao */ @WebService(name = "CustomerService", serviceName = "CustomerService", targetNamespace = "urn:CustomerService") @SOAPBinding(style = SOAPBinding.Style.RPC) @Stateless(name = "CustomerService") public class CustomerServiceImpl implements CustomerService { @PersistenceContext private EntityManager manager; @WebMethod public Customer create(Customer info) { this.manager.persist(info); return info; } @WebMethod public Customer update(Customer info) { return this.manager.merge(info); } @WebMethod public void remove(Long customerId) { this.manager.remove(this.manager.getReference(Customer.class, customerId)); } public Collection findAll() { Query query = this.manager.createQuery("SELECT c FROM Customer c"); return query.getResultList(); } @WebMethod public Customer[] findAllAsArray() { Collection collection = findAll(); return (Customer[]) collection.toArray(new Customer[collection.size()]); } @WebMethod public Customer findByPrimaryKey(Long customerId) { return (Customer) this.manager.find(Customer.class, customerId); } } Step 3. Compile, Package and Deploy to an application server. There are no server specific annotations in either the Entity class or the Session bean. Package the entity class, the session bean interface, implemetation class along with the persistence.xml file in a JAR file. Since I am deploying this application to GlassFish, I am using the default persistence provider which is TopLink. Start your application server, and deploy this JAR to it. The contents of persistence.xml file is as shown below: oracle.toplink.essentials.PersistenceProvider spring-ejb Once your application is deployed, make sure you check the JNDI name of your session bean. In GlassFish, click on the JNDI Browsing toolbar button to view the JNDI names. Step 4: Test the Stateless Session beans. Since my session beans are published as web services, I can just easily test them using either the test page provided by GlassFish application server, or by using SoapUI and make sure that my Customer entity can be persisted using the CustomerService session bean. I am using the default test page provided by Glass Fish for web services: Step 5: Create a Spring Bean. Here, I define a simple CustomerManager interface, and an implementation class; just to show how things are wired using Spring. package com.spring.service; import com.ejb.domain.Customer; /** * * @author meerasubbarao */ public interface CustomerManager { public void addCustomer(Customer customer); public void removeCustomer(Long customerId); public Customer[] listCustomers(); } package com.spring.service; import com.ejb.domain.Customer; import com.ejb.service.CustomerService; /** * * @author meerasubbarao */ public class CustomerManagerImpl implements CustomerManager { CustomerService customerService; public void setCustomerService(CustomerService customerService) { this.customerService = customerService; } public void removeCustomer(Long customerId) { customerService.remove(customerId); } public Customer[] listCustomers() { return customerService.findAllAsArray(); } public void addCustomer(Customer customer) { customerService.create(customer); } } Step 6: Injecting the EJB 3.0 Session bean into our Spring Beans. As seen above, I am using setter injection to inject an instance of Customer Service and in turn invoke a method on the Stateless session bean. How do we inject an EJB into a Spring bean? It is quite simple as shown below in the Spring configuration file: The most important aspect here is the wiring of the EJB within the Spring configuration using the element in the jee schema. Next, we need to wire this with our Spring bean which is done as shown below: Step 7: Test How do we know that it works. Lets create a simple class and test. package com.spring.client; import com.ejb.domain.Customer; import com.spring.service.CustomerManager; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class SpringAndEJBMain { public static void main(String[] args) { ApplicationContext context = new ClassPathXmlApplicationContext("SpringXMLConfig.xml"); CustomerManager service = (CustomerManager) context.getBean("manageCustomer"); Customer customer = new Customer(); customer.setFirstName("Meera"); customer.setLastName("Subbarao"); customer.setMiddleName("B"); customer.setEmailId("[email protected]"); customer.setCustomerId(new Long(1)); service.addCustomer(customer); for (Customer cust : service.listCustomers()) { System.out.println(cust.getFirstName()); System.out.println(cust.getLastName()); System.out.println(cust.getMiddleName()); System.out.println(cust.getEmailId()); } service.removeCustomer(new Long(1)); } } And here is the sample output from my IDE: We can go back to our GlassFish web services test page, and test the findAll method. It should have two entities. In this article, we saw how quick and easy it was to create JPA entities, persist them using Entity Manager from within our session bean. We also saw how easy it was to publish web services by adding a few annotations to our session beans. Next, we saw how to create a simple Spring bean, inject our session bean, and finally call methods on this session bean from our Spring application. Spring isn't in my opinion a replacement for EJB 3.0, you can mix and match EJB 3.0 and Spring 2.5 components to get the best of both.
August 27, 2008
by Meera Subbarao
· 76,186 Views
article thumbnail
The Concept of Mocking
Explore the importance of mocking, including mock objects.
August 16, 2008
by Michael Minella
· 65,280 Views · 5 Likes
article thumbnail
Writing Unit Tests Using Groovy
Groovy can greatly decrease the level of work involved in creating unit tests for your Java code.
March 6, 2008
by Tomas Malmsten
· 57,242 Views
  • Previous
  • ...
  • 252
  • 253
  • 254
  • 255
  • 256
  • 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
×