This content was uploaded by our users and we assume good faith they have the permission to share this book. If you own the copyright to this book and it is wrongfully on our website, we offer a simple DMCA procedure to remove your content from our site. Start by pressing the button below!
All rights reserved. No part of this book may be reproduced, stored in a retrieval system, or transmitted in any form or by any means, without the prior written permission of the publisher, except in the case of brief quotations embedded in critical articles or reviews. Every effort has been made in the preparation of this book to ensure the accuracy of the information presented. However, the information contained in this book is sold without warranty, either express or implied. Neither the authors, nor Packt Publishing, and its dealers and distributors will be held liable for any damages caused or alleged to be caused directly or indirectly by this book. Packt Publishing has endeavored to provide trademark information about all of the companies and products mentioned in this book by the appropriate use of capitals. However, Packt Publishing cannot guarantee the accuracy of this information.
First published: November 2009
Production Reference: 1061109
Published by Packt Publishing Ltd. 32 Lincoln Road Olton Birmingham, B27 6PA, UK. ISBN 978-1-847196-94-1 www.packtpub.com
About the Authors Vamsavardhana Reddy Chillakuru, a.k.a. Vamsi, is an Advisory Software
Engineer who has been working with IBM India Private Limited since 1996, and is part of the IBM worldwide Level 3 support team for Apache Geronimo and IBM WebSphere Application Server Community Edition (WASCE). He is proficient in Java and Java EE technologies, having more than 13 years experience in the IT Industry. His interests include application security in general, and cryptographic security in particular. He has presented sessions Apache conferences on various Apache Geronimo topics, ranging from security to server administration. He has authored many articles within IBM on developerWorks, and has also co-authored an IBM Redbook on Migration from WASCE to WebSphere Application Server (WAS). Considered as a security expert in the Geronimo community, he is actively involved in adding new security features to Geronimo. Associated with the Apache Geronimo project since July 2005, he is a committer on Apache Geronimo and Apache Tuscany projects, and is a member of the Apache Geronimo PMC. He is involved in the standards development for Service Component Architecture (SCA) and is a member of the OASIS (Organization for the Advancement of Structured Information Standards) SCA-Assembly, SCA-Java, and SCA-Policy Technical Committees, and the SCA-J Java EE Subcommittee. He received his B.Stat. (Hons.) and M.Stat. degrees from the Indian Statistical Institute, Kolkata, India in 1994 and 1996 respectively. I thank my wife Sushma and my son Susanth for their support throughout this book project. I thank my manager Sriram Mahalingam and director Kalpana Margabandhu at IBM India Private Limited for facilitating my authorship of this book. I thank my co-author Manu for his cooperation and the grace with which he handled the project. I thank the Apache Geronimo community for their support in my proficiency development with Geronimo. Finally, I am grateful to Packt Publishing for giving me this opportunity to author this book and thank Kshipra Singh, Rashmi Phadnis, Rajashree Hamine, Darshana Shinde, and Mayuri Kokate at Packt Publishing for their valuable support time and again.
Manu T. George is a Staff Software Engineer at IBM India Software Labs in Bangalore, India. He has eight years of experience in the IT field, most of it in Java and J2EE technologies. He is a committer on the Apache Geronimo and Apache OpenEJB projects, and has been a part of the IBM WebSphere Application Server Community Edition Level 3 Support Team for the past three years. He has been with IBM for around five years. Prior to that, he was an employee of Cognizant Technology Solutions India Ltd., and has worked on many services engagements there. His interests include Application Servers, especially in relation to Scalability, Transaction processing, EIS connectivity, and The Java Virtual Machine. He has also authored articles in IBM developer works, and has co-authored an IBM Redbook on Migration to WebSphere Application Server. He received his Bachelor of Technology in Applied Electronics from the College of Engineering Thiruvananthapuram in 2001. I am very grateful to my employer IBM, manager Sriram Mahalingam, and Director Kalpana Margabandhu for supporting me in writing this book and to Packt Publishing for giving me this opportunity. I would like to thank all the Packt staff that worked with us on this book. I would also like to thank my family, and especially my wife Nitya for the support that she provided and for her patience with me when I was authoring this book. I would like to thank both the Apache Geronimo and Apache OpenEJB communities for the support and help they gave me in understanding their respective projects. I would also like to mention my deep gratitude to David Blevins of Apache OpenEJB whose guidance and help both technical and non technical, was instrumental in helping me learn and understand the internals of OpenEJB as well as EJB technology. Finally, I would like to thank Vamsi, my co-author, for giving me the opportunity to work with him on this book.
About the Reviewer Sujit Pal started programming some 20 years ago, and has never looked back
since. He currently works at Healthline Networks, Inc., a search vertically focused on health, as part of its Research and Development team. Apart from his work, his favorite pastime is to explore new software technologies, techniques, and languages, and he writes about his experiments at sujitpal.blogspot.com.
Table of Contents Preface Chapter 1: Getting Started with Geronimo
1 7
Motivation behind the Geronimo project Constituent projects Apache Geronimo architecture Downloading and running Apache Geronimo Geronimo Administration Console
7 8 11 12 14
Building Geronimo Contributing to Geronimo Java EE 5 development tools Java EE 5 samples Summary
18 20 20 20 21
Information portlet Java System Info portlet Server Logs portlet Web Server portlet JMS Server portlet Repository portlet JMS Resources portlet Database Pools portlet Deploy New portlet Plan Creator portlet Plugins portlet Applications portlets Users and Groups portlet DB Info portlet DB Manager portlet
Chapter 2: Geronimo Architecture
Inversion of Control and dependency injection GBeans Configurations
15 15 15 16 16 16 16 16 16 17 17 17 17 18 18
23
24 28 30
Table of Contents
Dependencies High-level architecture Class loader architecture Modifying default class loading behavior Important modules Server directory structure Deployment architecture Deployer Repository Configuration builder Module builder Module builder extension Naming builder Hot deployment Deployment watcher Plugins Plugin catalog and plugin repository Custom server assemblies Extensible Administration Console Summary
Chapter 3: Database Connectivity
Database pool scopes Creating a server-wide database pool Using the Administration Console Wizard Installing unlisted drivers
Using the Deploy New portlet Using the command-line deployer Using GShell Creating an application-scoped database pool Creating a client-scoped pool Editing an existing pool Importing a pool from another application server Creating an XA pool Using a database pool in an application Accessing a server-scoped database pool Accessing an application-scoped database pool from the same application Accessing an application-scoped database pool from a different application Summary [ ii ]
Message broker configuration GBean configuration Using the Administration Console JMS resource scopes Creating JMS resources Creating Server-wide JMS resources Using the Administration Console Wizard Using the Deploy New portlet Using the command-line deployer Using GShell
Creating application-scoped JMS resources Creating application client-scoped JMS resources Using JMS resources in an application Connecting to a different provider Summary
Chapter 5: Java EE Application Deployment Deployment of applications Deployment descriptors Deployment plans The deploy tool Deployment from the Administration Console Deployment through GShell Web modules Servlet Filter Listener Web deployment descriptor Annotations Resource annotation EJB annotation
75
75 76 78 78 78 79
79 86 86 86
86 89 90 94 94
95
96 96 97 98 100 100 100 100 101 102 105 106
106 107
Web deployment plan
108
Sample web application EJB applications Annotations EJB deployment plan Sample EJB application
112 112 113 116 118
Tomcat specific configuration Jetty specific configuration
110 111
Deploy the JMS resources Deploy the EJB sample Deploy the Web application
Setting transaction timeout Transaction isolation levels Transactions in web applications
145 145 146
Summary
148
Chapter 6: Security
Overview of security standards Java Authentication and Authorization Service (JAAS) Java Authorization Contract for Containers (JACC) The Common Secure Interoperability Version 2 (CSIv2) protocol Securing the server directory Securing the Administration Console, JMX server, and deployer Securing the embedded Derby database Updating database pools Cryptographic security Keystores Keystores portlet Creating a new keystore Viewing the contents of a keystore Adding a private key Adding a trusted certificate Deleting a private key or trusted certificate Changing a keystore password
[ iv ]
149
149 150 150 150 150 151 152 153 154 154 155
156 156 157 158 159 159
Table of Contents Unlocking keystore for availability Unlocking a keystore for editing Locking a keystore for editing or availability View private key details Changing a Private Key password Generating CSR for a Private Key Importing the CA Reply for a Private Key
Preparing a keystore for use with SSL Certificate Authority portlet Protecting passwords HTTPS connectors Tomcat HTTPS connectors Jetty HTTPS connectors
159 160 160 161 161 161 162
162 164 164 164
165 166
JAAS login modules Login modules for authentication
Principal wrapping Application security Configuring web application security
180 180 180
Configuring EJB application security
185
Run-as and default subjects
192
Using the Security Realms portlet Security realm deployment plan
Running the sample web application
Defining security roles in the deployment descriptor Declaring method permissions in the deployment descriptor Using annotations to define roles and permissions Mapping principals to roles in the EJB deployment plan Running the EJB sample application Configuring entity bean security Credential store Configuring an application to use a credential store Configuring run-as and default subjects Running a sample EJB application with run-as Configuring message-driven bean security []
174 179
185 185 186 188 189 190 191 192 193 194 195 196
Table of Contents
Configuring EAR application security Application-scoped security realms Single sign-on (SSO) Replacing the default security realm Summary
Chapter 7: CORBA
CORBA concepts ORB Naming service Security services Support in Geronimo Exposing EJBs through CORBA Creating a Target Security Service (TSS) SSL Authentication mechanism Identity Tokens
196 196 196 197 197
199
199 199 199 200 200 200 200
202 203 204
Configuring EJB to use TSS Sample application exposing EJBs through CORBA Deploying and running the sample EJB application Referencing EJBs through CORBA Creating a Client Security Service (CSS)
205 205 209 209 209
Configuring the EJB reference to use CSS Sample web application accessing CORBA EJBs
Developing a plugin Creating a plugin project Installing a plugin Available plugins Pluggable Administration Console Architecture Developing an Administration Console extension Plugins portlet Custom server assemblies and server profiles Summary Administration Console Server portlets
231 232 236 237 237 238 238 243 245 247 249 251
Information portlet Java System Info portlet Server Logs portlet Shutdown portlet Web Server portlet Thread Pools portlet Apache HTTP portlet JMS Server portlet Monitoring portlet
Web Server administration HTTP connectors HTTPS connectors AJP connectors Web Server Logs JMS server administration JMS listeners Monitoring the server Adding a Server Adding a Graph Creating a new view GShell Starting and exiting GShell Getting help Supported commands Summary
Eclipse and the web tools framework Download and installation GEP download and installation Developing an application in GEP Deploying and running or debugging the application in Geronimo Summary WADI Updating deployment descriptor and deployment plan Load balancing with Apache web server Installing the Apache web server Web app in Geronimo served through Apache web server Apache HTTP portlet Accessing the sample app through Apache web server Running multiple server instances from a single installation Clustered Helloworld-cluster application Updating workers.properties Farming Cluster member configuration
Server startup errors BindException IllegalArgumentException due to a wrong instance name InvalidConfigurationException Deployment errors MissingDependencyException XmlException—Invalid deployment descriptor DuplicateDeploymentException Runtime errors LoginException—No LoginModules configured
[]
367 367 368 369 369 369 370 371 372 372
Preface Apache Geronimo is an open source application server that is suitable for use on everything from development environments to enterprise-level deployments. Geronimo brings together the best-of-breed open source technologies to deliver full Java EE 5 compliance. Distributed under the ASL2.0 license, one of the most liberal open source licenses, Geronimo becomes an application server of choice for enterprises and solution vendors. This book provides the reader with a comprehensive reference to the Apache Geronimo Application Server from the Apache Server Foundation. The authors have provided a reference for the average Apache Geronimo user that provides the user with the steps required to configure anything and everything in Apache Geronimo. This book covers everything from where to download the server software to how to customize it using custom GBeans. After reading this book, the user will be familiar with most of the features of Apache Geronimo v2.1. This book provides samples that are relevant to each task being performed. The book provides an in-depth coverage of the Apache Geronimo internals, in order for the user to be able to write custom services on Geronimo. There is also coverage of the Geronimo plugin architecture and how to extend the server functionality through plugins. The authors have made the different configuration items available as self contained chapters that can be referred to independently of the other chapters, so that readers can go straight to whatever part of Geronimo they want to configure.
Preface
What this book covers
Chapter 1: Introduction - This chapter introduces the reader to the Apache Geronimo Application Server, lists the features that it provides, and the steps that the user has to follow in order to download, install, and start the server. Chapter 2: Architecture - This chapter gives a high-level overview of the Geronimo architecture. It introduces the reader to the concepts of GBeans, Geronimo Plugins, and the different subsystems of Geronimo. Chapter 3: Database connectivity - This chapter talks about Geronimo's database connectivity features. It lists the databases supported, and explains how to create database pools and establish connectivity with all of the supported databases using Geronimo. Chapter 4: JMS - This chapter details the messaging features that Geronimo provides, and guides the user through using the bundled JMS provider, ActiveMQ, to create and use JMS resources. Chapter 5: Java EE Application deployment - This chapter details the installation of different types of Java EE applications and modules and application clients. It guides users through writing deployment plans for these different Java EE artifacts. This chapter also covers the transaction support provided by Geronimo. Chapter 6: Security - This chapter takes the user through configuring security in order to secure the server environment and the applications running in Geronimo. Chapter 7: CORBA - This chapter covers configuring the EJBs running in Geronimo so that they are available through CORBA, and also covers configuring remote EJB references to invoke remote EJBs through CORBA. Chapter 8: JNDI - This chapter describes the different JNDI environments in Geronimo, gives the steps necessary to bind custom resources to JNDI by using GBeans, and shows us how the global JNDI environment can be leveraged for user's applications. Chapter 9: Plugins - This chapter educates the user in creating and deploying Geronimo plugins, creating custom server assemblies, and extending Administration Console through plugins. Chapter 10: Administration - This chapter walks the user through the common administration tasks, such as managing server components, application management, monitoring, working with keystores, and GShell.
[]
Preface
Chapter 11: Eclipse Plugin - This chapter introduces the Geronimo Eclipse Plugin (GEP) and explains how to obtain and install it. It takes the user through the various features of the GEP and shows how to develop a sample application by using the Geronimo Eclipse Plugin. Chapter 12: Clustering - This chapter covers how to configure horizontal and vertical clustering using Geronimo, demonstrates web application clustering using WADI, and explains how to configure load balancing by using the Apache Web Server and mod_jk plugin. Chapter 13: Logging - This chapter covers all of the configurations required for setting up logging for both the server and user applications. It covers logging frameworks such as log4j JUL, and so on, and the SLF4j wrapper that comes with Geronimo. Chapter 14: Geronimo Internals – This chapter introduces the user to the internals of Geronimo and the low-level services such as kernel, server info, configuration manager, and so on. It takes the user through developing and deploying new services through GBeans. Appendix-A: Deployment plans – This appendix covers elements common to all Geronimo deployment plans. Appendix-B: Troubleshooting – This appendix covers troubleshooting server startup, application deployment, application startup, and runtime problems.
What you need for this book
The reader must be familiar with Java EE 5 concepts and application development.
Who this book is for
This book is intended for Java EE developers and server administrators who would like to use Geronimo for developing and deploying fully-fledged Java EE 5 applications, and Independent Solution Vendors who want to freely distribute Geronimo with their solutions.
[]
Preface
Conventions
In this book, you will find a number of styles of text that distinguish between different kinds of information. Here are some examples of these styles, and an explanation of their meaning. Code words in text are shown as follows: "In the given sample code, you see that there is a new class called the Assembler." A block of code is set as follows: Nitya
When we wish to draw your attention to a particular part of a code block, the relevant lines or items are set in bold: console.dbpool DerbyTestPool
Any command-line input or output is written as follows: java –cp di-sample-1.0.jar packtsamples.Assembler packtsamples. di.ServiceTaxCalculator
New terms and important words are shown in bold. Words that you see on the screen, in menus or dialog boxes for example, appear in the text like this: "Deployment can also be done by using the Deploy New portlet in the Administration Console". Warnings or important notes appear in a box like this.
Tips and tricks appear like this.
[]
Preface
Reader feedback
Feedback from our readers is always welcome. Let us know what you think about this book—what you liked or may have disliked. Reader feedback is important for us to develop titles that you really get the most out of. To send us general feedback, simply send an email to [email protected], and mention the book title in the subject of your message. If there is a book that you need and would like to see us publish, please send us a note in the SUGGEST A TITLE form on www.packtpub.com, or send an email to [email protected]. If there is a topic that you have expertise in and you are interested in either writing or contributing to a book on, see our author guide at www.packtpub.com/authors.
Customer support
Now that you are the proud owner of a Packt book, we have a number of things to help you to get the most from your purchase. Downloading the example code for the book Visit http://www.packtpub.com/files/code/6941_Code.zip to directly download the example code. The downloadable files contain instructions on how to use them.
Errata
Although we have taken every care to ensure the accuracy of our content, mistakes do happen. If you find a mistake in one of our books—maybe a mistake in the text or the code—we would be grateful if you would report this to us. By doing so, you can save other readers from frustration, and help us to improve subsequent versions of this book. If you find any errata, please report them by visiting http://www.packtpub.com/support, selecting your book, clicking on the let us know link, and entering the details of your errata. Once your errata are verified, your submission will be accepted and the errata added to any list of existing errata. Any existing errata can be viewed by selecting your title from http://www.packtpub.com/support.
[]
Preface
Piracy
Piracy of copyright material on the Internet is an ongoing problem across all media. At Packt, we take the protection of our copyright and licenses very seriously. If you come across any illegal copies of our works, in any form, on the Internet, please provide us with the location address or web site name immediately so that we can pursue a remedy. Please contact us at [email protected] with a link to the suspected pirated material. We appreciate your help in protecting our authors, and our ability to bring you valuable content.
Questions
You can contact us at [email protected] if you are having a problem with any aspect of the book, and we will do our best to address it.
[]
Getting Started with Geronimo Apache Geronimo is a free, open source Java EE application server from the Apache Software Foundation (ASF). The latest released version, 2.1.4, is Java EE 5 certified. In this chapter, we will quickly take you through: •
The motivation behind the Geronimo project
•
Geronimo architecture
•
The constituent projects that it integrates
•
Downloading and running Geronimo
•
Building Geronimo from source code
•
Contributing to the Geronimo project
This should get you started with using the Geronimo application server right away, and give you a glimpse of what Geronimo has to offer.
Motivation behind the Geronimo project
Apache Geronimo started as an application server. The first release of Apache Geronimo, that is, version 1.0 was J2EE 1.4 certified. The latest version is backward compatible to the J2EE 1.4, 1.3, and 1.2 specifications. The rationale behind Apache Software Foundation creating this project was: •
There was no open source J2EE server based on BSD license available in the market at the time Apache Geronimo was proposed. With BSD license, anyone could modify the source code and also include it in their derivative offerings without making the derivative open source.
Getting Started with Geronimo
•
There were many projects in the Apache Software Foundation that implemented parts of the J2EE specification. The rationale was to create a full application server that used these best-of-breed open source components internally and filled in the gaps that were missing.
•
There was still more room for innovation in the J2EE application server space.
Thus Apache Geronimo was born.
Constituent projects
As the aim was to integrate many existing Apache projects into Apache Geronimo, the server had a very modular architecture with a lightweight and compact kernel into which other services could be plugged in order to provide additional functionality. Other containers that implemented parts of the J2EE specifications could then be added on top of this, and they would be able to use the services that were available. The various components and services could be stopped when they were not required, to save on system resources. In newer versions, this was improved upon and you could install or uninstall plugins at runtime to add or remove functionality. The latest version even has the ability to generate customserver assemblies from the Administration Console of the server. Apache Geronimo leverages a lot of popular open source projects to provide Java EE 5 compliance. Some of the projects used are: •
Apache Tomcat Apache Tomcat is an open source JavaServer Pages (JSP) and Java Servlet container from the Apache Software Foundation. It is fast, lightweight, and very popular, and is used widely in the industry. It is considered as a benchmark for Servlet and JSP containers. Apache Tomcat is used by Apache Geronimo as its web container. It is thereby used to host the web applications that you deploy in Apache Geronimo. Apache Tomcat is hosted at http://tomcat.apache.org.
•
Apache OpenEJB Enterprise JavaBeans (EJB) technology provides the server-side component architecture for Java Platform. EJB technology enables the rapid and simplified development of distributed, transactional, secure, and portable applications based on Java technology.
[]
Chapter 1
Apache OpenEJB is a free, open source EJB container. It is both embeddable and lightweight. The current version, OpenEJB 3.x, supports EJB 3.0 and is also backward compatible with previous EJB versions. It also has a few experimental EJB 3.1 features. Apache OpenEJB is used by Apache Geronimo as its EJB container. Therefore, all EJB applications that you deploy in Apache Geronimo will in turn be deployed into Apache OpenEJB by the deployment subsystem. Apache OpenEJB is a complete rewrite of OpenEJB 2.1, which was included in Apache Geronimo 1.x. Thus, it is more robust and has a higher order of performance than its predecessor. Apache OpenEJB can be made to work with different JPA providers. However, it provides Container Managed Persistence (CMP) of EJB 2.1 support, through a wrapper over OpenJPA. Apache OpenEJB is hosted at http://openejb.apache.org. •
Apache Axis 1.x Apache Axis is an open source web services engine from the Apache Software Foundation. This version of Apache Axis is used to provide support for JAX-RPC web services. Apache Axis is hosted at http://ws.apache.org/axis.
•
Apache Axis2 Apache Axis2 is a rewrite of the Apache Axis web services engine. Apache Axis2 is used to provide support for JAX-WS, SOAP 1.2, SAAJ, and all the other specifications of web services, which are required for Java EE 5 compliance. Apache Axis2 is hosted at http://ws.apache.org/axis2/.
•
Apache CXF Apache CXF is an open source services framework. It is also available as the web services container in Geronimo. It can be used as an alternative to Apache Axis2. Apache CXF is hosted at http://cxf.apache.org.
•
Jetty from Mortbay Jetty is a fast and lightweight open source web server and Servlet container. It is easily embeddable and, like Tomcat, is widely used. Jetty can also be used as the web container in Apache Geronimo, as an alternative to Tomcat. This project is hosted at http://www.mortbay.org/jetty and is distributed under the Apache License, Version 2.0.
•
Apache ActiveMQ Apache ActiveMQ is a popular and powerful open source message broker. It is fast, lightweight, embeddable, and supports many cross language clients and protocols. It supports the JMS specification. It is used as a message broker in Apache Geronimo. Apache Geronimo 2.1.4 uses ActiveMQ 4.1.2. Apache ActiveMQ is hosted at http://activemq.apache.org.
[]
Getting Started with Geronimo
•
•
•
•
•
•
Apache XBean Apache XBean is a plugin-based server framework. It provides functionality to discover, download, and install server plugins from a remote repository. It also supports Inversion of Control (IoC), lifecycle and class loader management, JMX, and Spring Integration. Apache XBean is a subproject of the Apache Geronimo project, and is hosted at http://geronimo.apache.org/xbean/. Apache Derby Apache Derby is a free, open source, lightweight, and embeddable RDBMS, implemented entirely in Java. Derby is integrated in Apache Geronimo as the default database, and the Administration Console has built-in portlets for basic Apache Derby administration tasks. Apache Derby is a part of the Apache DB project, and is hosted at http://db.apache.org/derby. Apache Scout Apache Scout is an open source implementation of the Java API for XML Registries (JAXR). It provides a registry where web services can be registered by their providers, and users can look for the services they need in the registry. Apache Scout is hosted at http://ws.apache.org/scout/. Apache OpenJPA Apache OpenJPA is an open source Java Persistence API (JPA) container that can either be used as a standalone POJO persistence layer or integrated into any EJB 3.0 container. OpenJPA was donated by BEA to the Apache Software Foundation, and is based on BEA's Kodo JPA Engine. It is used as the default JPA provider for Apache Geronimo and Apache OpenEJB. The version used in Apache Geronimo 2.1.4 is OpenJPA 1.2. Apache OpenJPA is hosted at http://openjpa.apache.org/. Apache log4j & SLF4J Apache log4j is the logging framework that is used for logging in Apache Geronimo, and SLF4J is the logging adapter that is used so that the source is not tied down to any logging framework. Apache log4j is hosted at http:// logging.apache.org/, and SLF4J is hosted at http://www.slf4j.org/ Apache Commons The Commons is an Apache project focused on all aspects of reusable Java components. Some of the components are: ° BeanUtils: Easy-to-use wrappers around the Java reflection and introspection APIs ° FileUpload: A file upload capability for servlets and web applications ° IO: Collection of I/O utilities, and so on Apache Commons is hosted at http://commons.apache.org. [ 10 ]
Chapter 1
•
Apache GShell Apache GShell is a framework for building rich command-line applications. GShell is used as a bootstrap launcher for Apache Geronimo. It provides a number of built-in commands, and many optional ones. GShell is extensible, and the version in Apache Geronimo has been extended with many Apache Geronimo specific commands. Apache GShell is a subproject of the Apache Geronimo project, and is hosted at http://cwiki.apache.org/GSHELL.
•
Apache Yoko Apache Yoko is a robust and high-performance CORBA server written in Java that can run on any Java Virtual Machine (JVM). It provides the ORB and CORBA naming service that is used by Apache Geronimo. It is also used by Geronimo to expose EJBs as CORBA services. Apache Yoko is a subproject of the Apache Geronimo project, and is hosted at http://cwiki.apache.org/YOKO/.
•
TranQL TranQL is an open source framework for building persistence engines. The TranQL project is hosted at the Codehaus. It's also a framework for building J2CA connectors. TranQL provides J2CA connector implementations that wrap drivers for several popular relational databases. The TranQL project is hosted at http://tranql.codehaus.org.
These open source projects are plugged into the Geronimo system via wrapper GBeans or as dependant libraries. You can configure Geronimo servers that contain all or a subset of these projects. Apache Geronimo also provides you with more choice when choosing the parts that will make up your application server than any other application server. For example, you can have a server with Apache Tomcat as the web container and Axis2 as the web services container, or you can have a server with Jetty and CXF. So one key differentiator at the time Apache Geronimo was released was that it was not monolithic like many other Java EE application servers. However, most application server vendors are now re-architecting their servers to also be modular and lightweight.
Apache Geronimo architecture
Apache Geronimo consists of an IoC kernel that provides dependency management, configuration management, lifecycle management, and repository services. The plumbing required by Java EE containers, namely, support for deployment, transactions, remoting, naming, work management, and security, is implemented on top of the kernel. On top of this are plugged in the various containers, such as Apache OpenEJB, Apache ActiveMQ, and so on, which provide parts of the Java EE functionality and together make Geronimo a Java EE application server. [ 11 ]
Getting Started with Geronimo
GBeans are the basic building blocks of Geronimo. A GBean provides lifecycle callbacks and acts as a thin wrapper around the various containers and modules that are plugged into Geronimo. The kernel then manages these containers and modules via the GBeans that wrap them. A group of GBeans that wraps a particular module is called a configuration. Interestingly, a configuration itself is a GBean, thereby leading to the statement, "Everything in Geronimo is a GBean!!" The Geronimo architecture is modular and extensible. The extensibility is achieved via plugins. Geronimo provides the ability for new functionality to be added as plugins. Plugins are actually configurations or groups of configurations, along with metadata about their dependencies. Plugins can be installed in Geronimo via the Administration Console or via the command-line tools. Geronimo has the ability to download and install plugins from a remote repository. One such remote repository is available at http://geronimoplugins.com/. Thus, the Geronimo kernel also provides plugin installation and management services. Each of the containers in Geronimo is actually installed as a plugin. This method of extending the features of Geronimo via plugins initially gave rise to a minimal version of the server called little Geronimo (Little-G) that consisted of the Geronimo kernel, the required plumbing, and the web container. Later, even more flexibility was provided and you could export servers containing only the components you needed, from the Administration Console. This provided a large amount of flexibility in the configurations. A set of predefined server profiles were also provided out of the box, for users to export.
Downloading and running Apache Geronimo
Apache Geronimo can be downloaded from the project's web site at http://geronimo.apache.org. The Downloads section has the latest version as well as previous releases. The server is available for download in .zip and tar.gz formats. Download the ZIP file and then extract it to a directory on your drive. Let us refer to this directory as . Open a command window and change directory to /bin. Set either the JAVA_HOME or the JRE_HOME environment variable to a directory where Sun Java 1.5 is installed, and type start-server, in Windows, or ./start-server, in Linux. This will start the Geronimo server in the same command window. The following screenshot shows the command-line console output from Geronimo server startup:
[ 12 ]
Chapter 1
The console displays the port numbers on which the various services are running, a list of Started Application Modules, and the context-root for the running web applications. You can use startup to start Geronimo in a new window. If you want to start GShell (a Java-based shell for Geronimo), then you need to use gsh. Invoking the GShell results in a new shell prompt in the format user@hostname:/>, for example, administrator@foo:/>. GShell supports a large number of commands to perform a variety of operations in Geronimo. You can start or stop the server, install or uninstall applications, and even export a new server from the current installation. To get a list of commands that are supported by GShell, type help at the prompt. [ 13 ]
Getting Started with Geronimo
To start the server from GShell, type geronimo/start-server at the GShell prompt. To stop the server, open another GShell prompt and enter geronimo/stop-server. You will be prompted to enter the username and password. Enter system for the Username and manager for the Password. If you encounter any port conflicts during startup, you will need to either shut down the other services that are using those ports or you will need to configure the Geronimo installation to use other ports. The steps for doing this are given in Appendix-B, Troubleshooting.
Geronimo Administration Console
Geronimo has a powerful web-based Administration Console, consisting of portlets developed using Apache Pluto that can be used for various administrative tasks. The Administration Console provides a convenient and user friendly way to administer many aspects of the server. Once the Geronimo server has been started, the Administration Console can be accessed by using the URL http://localhost:8080/console. The default Username is system and the default Password is manager. The following figure shows the layout of the Administration Console.
[ 14 ]
Chapter 1
The portlets are grouped into various portlet groups, such as, Server, Services, Applications, Security, and so on, according to the functions addressed by the portlets. The portlets can be broadly divided into the following two categories: •
Portlets to monitor the server: Information portlet, Java System Info portlet, Monitoring portlet, Repository portlet, and DB Info portlet are some of the portlets that help monitor the server status.
•
Portlets to perform administrative operations: Web Server portlet, JMS Server portlet, Database Pools portlet, portlets under Applications group, and DB Manager portlet are some of the portlets that help in administering some aspect of the server.
In this section, we will briefly introduce some of the commonly-used portlets. See Chapter 10, Administration for more details on Administration Console.
Information portlet
The Information portlet is launched by clicking on the Information link under the Server portlet group in Console Navigation pane. This portlet displays information on the version number of the Geronimo server, the server Start Time, the server Up Time, the Name of the operating system, the JVM in which the server is running, and the current Server Memory Usage.
Java System Info portlet
The Java System Info portlet is launched by clicking on the Java System Info link under the Server portlet group in Console Navigation. This portlet displays the system properties set in the JVM in which the server is running. For display purposes, the system properties are grouped into Java, Virtual Machine, Operating System, Sun, User, and Etc groups.
Server Logs portlet
The Server Logs portlet is launched by clicking on the Server Logs link under the Server portlet group in Console Navigation. This portlet enables you to browse the server log messages, web access log messages, and Derby database log messages. The portlet provides the ability to filter the log messages based on various criteria, such as displaying log messages containing specified text, generated within a specific date range, and so on. The portlet also features a Log Manager, which allows the server log settings to be temporarily altered.
[ 15 ]
Getting Started with Geronimo
Web Server portlet
The Web Server portlet is launched by clicking on the Web Server link under the Server portlet group in Console Navigation. This portlet enables you to add new HTTP, HTTPS, and AJP ports or listeners to the web container, and perform Start, Stop, Restart, Edit, and Delete operations on existing listeners. In order to add a new HTTP port to the web container, click on Tomcat BIO HTTP Connector. On the next page, enter a uniqueName for the connector, change the default port number to a port number of your choice, and click on Save.
JMS Server portlet
The JMS Server portlet is launched by clicking on the JMS Server link under the Server portlet group in Console Navigation. This portlet enables you to add new JMS listeners and perform Start, Stop, Edit, and Delete operations on existing JMS listeners.
Repository portlet
The Repository portlet is launched by clicking on the Repository link under the Services portlet group in Console Navigation. This portlet displays a list of JAR files and configurations deployed on the server. The portlet also provides the ability to install a new archive into the server's repository.
JMS Resources portlet
The JMS Resources portlet is launched by clicking on the JMS Resources link under the Services portlet group in Console Navigation. This portlet enables you to create new JMS resources such as Connection Factory, Queue, and Topic.
Database Pools portlet
The Database Pools portlet is launched by clicking on the Database Pools link under the Services portlet group in Console Navigation. This portlet enables you to Create a new database pool: Using the Geronimo database pool wizard and to perform Edit and Delete operations on existing database pools. You can also Run SQL commands against an existing data source.
Deploy New portlet
The Deploy New portlet is launched by clicking on the Deploy New link under the Applications portlet group in Console Navigation. This portlet enables you to deploy a new application or a new service into the server. An archive or a Geronimo specific deployment plan, or both can be used to deploy new applications and services. [ 16 ]
Chapter 1
Plan Creator portlet
The Plan Creator portlet is launched by clicking on the Plan Creator link under the Applications portlet group in Console Navigation. This portlet enables creating a Geronimo specific deployment plan required to deploy an archive in a sequence of steps, and deploying the archive using the generated deployment plan.
Plugins portlet
The Plugins portlet is launched by clicking on the Plugins link under Applications portlet group in Console Navigation. This portlet provides the ability to install plugins onto a Geronimo server, export existing configurations as Geronimo plugins, and create a custom server assembly from configurations and plugins running in the server.
Applications portlets
The Applications portlets lets you view the running status of the applications, perform operations like Stop, Start, Restart, and Uninstall applications. There are multiple portlets for this purpose, each of which displays a selected group of configurations running on the server. The portlets that fall into this category are: •
Web App WARs portlet: Shows the web applications deployed on the server
•
System Modules portlet: Shows the services (such as ActiveMQ, Axis, and so on) deployed on the server
•
Application EARs portlet: Shows the enterprise applications deployed on the server
•
EJB JARs portlet: Shows the EJB applications deployed on the server
•
J2EE Connectors portlet: Shows the database pool and JMS resource configurations deployed on the server
•
App Clients portlet: Shows the enterprise application clients installed on the server
Users and Groups portlet
The Users and Groups portlet is launched by clicking on the Users and Groups link in the Security portlet group under Console Navigation. This portlet enables you to add new users, add new groups, change an existing user password, edit an existing group to change the user membership of the group, delete an existing user, and delete an existing group. Note that users belonging to the admin group have access to the Administration Console.
[ 17 ]
Getting Started with Geronimo
DB Info portlet
The DB Info portlet is launched by clicking on the DB Info link in the Embedded DB portlet group under Console Navigation. This portlet displays information on the embedded Derby database server.
DB Manager portlet
The DB Manager portlet is launched by clicking on the DB Manager link in the Embedded DB portlet group under Console Navigation. This portlet enables an administrator to create new databases, delete an existing database, run SQL commands against an existing database, view database tables, and browse the contents of database tables.
Building Geronimo
You can download the source code of Geronimo and build the server from it. The Geronimo source code is maintained in a Subversion repository. The URL is https://svn.apache.org/repos/asf/geronimo/server. There are different tags for the different releases. For example https://svn.apache.org/repos/ asf/geronimo/server/tags/2.1.4 corresponds to the 2.1.4 release. The branches are for making bug fixes to previous releases if required. The trunk is the latest codebase, where most of the new development is happening. You can check out and build any of these. We will now go through the procedure to download and check out the source code of version 2.1.4. Go to the location on your disk where you want to check out the code and type the following command: svn checkout https://svn.apache.org/repos/asf/geronimo/server/ tags/2.1.4 server
You need to install the Subversion client before you can actually checkout the code. The client is available at http://subversion.tigris.org/
Once the process has completed you will notice that a directory called server that contains the source is created. You will now need to download and install Apache Maven 2, which is required in order to build the server from the source code. You can download Maven 2 from http://maven.apache.org/download.html.
[ 18 ]
Chapter 1
You need to use Sun JDK 1.5.x and Apache Maven 2.0.9, to build Geronimo version 2.1.4 server from source code.
Once you finish installing Maven 2, you need to change your directory to the directory into which you checked out the source, and then run mvn install. The build process will take 30 to 40 minutes and you will need to be connected to the Internet during the build. Once the build is successful (all the tests need to pass for the build to succeed), you can find the various server distributions in the assemblies directory. In case there is a build failure, due to test failures you can run the builds with the -Dmaven.test.skip=true, -Dmaven.itest.skip=true
flags, so that test failures are ignored. The assemblies directory contains the following subdirectories: •
geronimo-boilerplate-minimal
Provides boilerplate files for all of the Geronimo server assemblies •
geronimo-framework
A Geronimo server framework assembly •
geronimo-jetty6-javaee5
Java EE 5 certified Geronimo version with Jetty as the web container and CXF as the web services engine, and all the bells and whistles •
geronimo-jetty6-minimal
Minimal version of Geronimo with just the web container (Jetty) and the Geronimo framework •
geronimo-tomcat6-javaee5
Java EE 5 certified Geronimo version with Tomcat as the web container and Axis2 as the web services engine and all the bells and whistles •
geronimo-tomcat6-minimal
Minimal version of Geronimo with just the web container (Tomcat) and the Geronimo framework
[ 19 ]
Getting Started with Geronimo
Contributing to Geronimo
Apache Geronimo is developed and distributed under the Apache License, Version 2.0, which is a derivative of the BSD License. This means that any individual or commercial entity can distribute Apache Geronimo for free. The big difference from GPL licensed software is that derivative works that are distributed need not be open source. This makes Geronimo attractive to corporations and software houses. Some corporations actually pay their employees to work full time on Geronimo. However, a lot of people contribute to Geronimo as a hobby or as a way to learn how to write scalable software. Anyone can contribute new features, raise defects, contribute documentation, or contribute bug fixes to Geronimo. This is encouraged, as a more vibrant community will help to make a better product. The procedure to follow is to open an issue in the Geronimo issue tracker (JIRA) and attach a patch file. You can generate the patch file by invoking the svn diff subcommand. Once you attach a patch file, one of the committers (people who can make changes to the source code in the Geronimo subversion repository) will review your patch and if he or she feels it is valid, will commit it to the source tree in subversion repository.
Java EE 5 development tools
Eclipse from the Eclipse Foundation is a popular open source IDE written in Java that supports a variety of languages, including Java. Support for Java EE 5 is provided by a set of Eclipse plugins called the Web Tools Platform or WTP. WTP provides extension points for application server vendors to extend WTP to integrate with their servers and provide deployment and debug functionality during server-side Java EE development. Apache Geronimo provides a WTP server adapter or an Eclipse plugin that runs on top of WTP and provides Java EE developers with features to develop, deploy, and debug Java EE applications on Apache Geronimo. The Geronimo Eclipse Plugin (GEP) can be downloaded from the subprojects site at http://geronimo.apache.org/development-tools.html. The source code for the Geronimo Eclipse Plugin is available from https://svn.apache.org/repos/asf/ geronimo/devtools/eclipse-plugin/.
Java EE 5 samples
Apache Geronimo provides a set of sample Java EE 5 applications that exercise almost all aspects of the Java EE 5 specification. These samples range from the most trivial web applications such as the Inventory sample to reasonably complex enterprise applications like the Day Trader. The samples for different versions of Apache Geronimo can be obtained from the URL http://cwiki.apache.org/GMOxSAMPLES/. [ 20 ]
Chapter 1
The Day Trader sample is actually checked into the subversion tree for Apache Geronimo. Users can download it from the Subversion repository and build it. The Subversion (SVN) URL is https://svn.apache.org/repos/asf/ geronimo/daytrader/. The other samples are also available in SVN at https://svn.apache.org/repos/
asf/geronimo/samples/.
Summary
In this chapter, we have provided an overview of Geronimo, various component projects in Geronimo, and we have briefly discussed the architecture of Geronimo. We have discussed how to download and run Geronimo, and given an introduction to the Administration Console. We have also provided instructions on how to build Geronimo from source code that has been checked out from the Geronimo Subversion repository.
[ 21 ]
Geronimo Architecture This chapter expands on what we discussed in the first chapter about the Apache Geronimo architecture. We will first see the concept of Inversion of Control (IoC) and dependency injection, which are two of the core concepts around which the current architecture is developed. We will then give a high-level overview of the internal architecture of Apache Geronimo and go through each component that makes up the architecture. Therefore, we will be covering GBeans, configurations, the kernel interface, repository, attribute store, dependencies, class loaders, deployment, plugins, and the concept of custom server assemblies. We will be covering these topics in detail so that you are able to understand the big picture. It will also help you if you want to contribute to Apache Geronimo or develop new services to run on Apache Geronimo. We will also list the different modules by their configuration IDs and map them to their functionality. In this chapter, you will learn about: •
How Inversion of Control and dependency injection work
•
GBeans—the building blocks of Geronimo
•
Configuration—a collection of GBeans deployed together
•
High-level architecture of Geronimo
•
Class loader architecture
•
Geronimo server directory structure
•
Deployment architecture
•
Plugins
Geronimo Architecture
Inversion of Control and dependency injection
Inversion of Control (IoC) is a design pattern used in software engineering that facilitates the creation of loosely-coupled systems. In an IoC system, the flow of control is inverted, that is, the program is called by the framework—unlike in normal linear systems where the program calls the libraries. This allows us to circumvent the tight coupling that arises from the control being with the calling program. Dependency injection is a specific case of IoC where the framework provides an assembler or a configurator that provides the user program with the objects that it needs through injection. The user program declares dependencies on other services (provided by the framework or other user programs), and the assembler injects the dependencies into the user program wherever they are needed. It is important that you clearly understand the concept of dependency injection before we proceed further into the Geronimo architecture, as that is the core concept behind the functioning of the Geronimo kernel and how services are loosely coupled in it. To help you understand the concept more clearly, we will provide a simple example. Consider the following two classes: package packtsamples; public class RentCalculator{ private float rentRate; private TaxCalculator tCalc; public RentCalculator(float rate, float taxRate){ rentRate = rate; tCalc = new ServiceTaxCalculator(taxRate); } public void calculateRent(int noOfDays){ float totalRent = noOfDays * rentRate; float tax = tCalc.calculateTax(totalRent); totalRent = totalRent + tax; System.out.println("Rent is:"+totalRent); } } package packtsamples; public class ServiceTaxCalculator implements TaxCalculator{ private float taxRate; public ServiceTaxCalculator(float rate){ taxRate = rate; } public float calculateTax(float amount){ [ 24 ]
Chapter 2 return (amount * taxRate/100); } } package packtsamples; public interface TaxCalculator{ public float calculateTax(float amount); } package packtsamples; public class Main { /** * @param args. args[0] = taxRate, args[1] = rentRate, args[2] = noOfDays */ public static void main(String[] args) { RentCalculator rc = new RentCalculator(Float.parseFloat(args[1]), Float.parseFloat(args[0])); rc.calculateRent(Integer.parseInt(args[2])); } }
The RentCalculator class calculates the room rent including tax, given the rent rate, and the number of days. The TaxCalculator class calculates the tax on a particular amount, given the tax rate. As you can see from the code snippet given, the RentCalculator class is dependent on the TaxCalculator interface for calculating the tax. In the given sample, the ServiceTaxCalculator class is instantiated inside the RentCalculator class. This makes the two classes tightly coupled, so that we cannot use the RentCalculator with another TaxCalculator implementation. This problem can be solved through dependency injection. If we apply this concept to the previous classes, then the architecture will be slightly different. This is shown in the following code block: package packtsamples.di; public class RentCalculator{ private float rentRate; private TaxCalculator tCalc; public RentCalculator(float rate, TaxCalculator tCalc){ rentRate = rate; this.tCalc = tCalc; } public void calculateRent(int noOfDays){ float totalRent = noOfDays * rentRate; float tax = tCalc.calculateTax(totalRent); totalRent = totalRent + tax; System.out.println("Rent is:" +totalRent); } [ 25 ]
Geronimo Architecture } package packtsamples.di; public class ServiceTaxCalculator implements TaxCalculator{ private float taxRate; public ServiceTaxCalculator(float rate){ taxRate = rate; } public float calculateTax(float amount){ return (amount * taxRate/100); } } package packtsamples.di; public interface TaxCalculator{ public float calculateTax(float amount); }
Notice the difference here from the previous implementation. The RentCalculator class has a TaxCalculator argument in its constructor. The RentCalculator then uses this TaxCalculator instance to calculate tax by calling the calculateTax method. You can pass in any implementation, and its calculateTax method will be called. In the following section, we will see how to write the class that will assemble this sample into a working program. package packtsamples.di; import java.lang.reflect.InvocationTargetException; public class Assembler { private TaxCalculator createTaxCalculator(String className, float taxRate){ TaxCalculator tc = null; try { Class cls = Class.forName(className); tc = (TaxCalculator)cls.getConstructors()[0] .newInstance(taxRate); } catch (ClassNotFoundException e) { e.printStackTrace(); } catch (IllegalArgumentException e) { e.printStackTrace(); } catch (SecurityException e) { e.printStackTrace(); } catch (InstantiationException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (InvocationTargetException e) { e.printStackTrace(); } [ 26 ]
In the given sample code, you can see that there is a new class called the Assembler. The Assembler, in its main method, invokes the implementation class of TaxCalculator that we want RentCalculator to use. The Assembler then instantiates an instance of RentCalculator, injects the TaxCalculator instance of the type we specify into it, and calls the calculateRent method. Thus the two classes are not tightly coupled and the program control lies with the assembler, unlike in the previous case. Thus there is Inversion of Control happening here, as the framework (Assembler in this case) is controlling the execution of the program. This is a very trivial sample. We can write an assembler class that is more generic and is not even coupled to the interface as in the previous case. This is an example of dependency injection. An injection of this type is called constructor injection, where the assembler injects values through the constructor. You can also have other types of dependency injection, namely setter injection and field injection. In the former, the values are injected into the object by invoking the setter methods that are provided by the class, and in the latter, the values are injected into fields through reflection or some other method. The Apache Geronimo kernel uses both setter injection and constructor injection for resolving dependencies between the different modules or configurations that are deployed in it. The code for these examples is provided under di-sample in the samples. To build the sample, use the following command: mvn clean install [ 27 ]
Geronimo Architecture
To run the sample without dependency injection, use the following command: java –cp di-sample-1.0.jar packtsamples.Main
To run the sample with dependency injection, use the following command: java –cp di-sample-1.0.jar packtsamples.Assembler packtsamples. di.ServiceTaxCalculator
GBeans
A GBean is the basic unit in Apache Geronimo. It is a wrapper that is used to wrap or implement different services that are deployed in the kernel. GBeans are similar to MBeans from JMX. A GBean has attributes that store its state and references to other GBeans, and can also register dependencies on other GBeans. GBeans also have lifecycle callback methods and metadata. The Geronimo architects decided to invent the concept of GBeans instead of using MBeans in order to keep the Geronimo architecture independent from JMX. This ensured that they did not need to push in all of the functionality required for the IoC container (that forms Geronimo kernel) into the JMX implementation. Even though GBeans are built on top of MBeans, they can be moved to some other framework as well. A user who is writing a GBean has to follow certain conventions. A sample GBean is shown below: import org.apache.geronimo.gbean.GBeanInfo; import org.apache.geronimo.gbean.GBeanInfoBuilder; import org.apache.geronimo.gbean.GBeanLifecycle; public class TestGBean implements GBeanLifecycle{ private String name; public TestGBean(String name){ this.name = name; } public void doFail() { System.out.println("Failed............."); } public void doStart() throws Exception { System.out.println("Started............"+name); } public void doStop() throws Exception { System.out.println("Stopped............"+name); } public static final GBeanInfo GBEAN_INFO; static { GBeanInfoBuilder infoBuilder = GBeanInfoBuilder .createStatic(TestGBean .class, "TestGBean"); [ 28 ]
You will notice certain characteristics that this GBean has from the previous section. We will list these characteristics as follows: •
All GBeans should have a static getGBeanInfo method, which returns a GBeanInfo object that describes the attributes and references of GBean as
well as the interfaces it can implement. •
All GBeans will have a static block where a GBeanInfoBuilder object is created and linked to that GBean. All of the metadata that is associated with this GBean is then added to the GBeanInfoBuilder object. The metadata includes descriptions of the attributes, references, interfaces, and constructors of GBean.
We can add GBeans to configurations either programmatically, using methods exposed through the configuration manager and kernel, or by making an entry in the plan for the GBean, as follows: Nitya
We need to specify the attribute values in the plan, and the kernel will inject those values into the GBean at runtime. There are three attributes for which we need not specify values. These are called the magic attributes, and the kernel will automatically inject these values when the GBeans are being started. These attributes are abstractName, kernel, and classLoader. As there is no way to specify the values of these attributes in the deployment plan (an XML file in which we provide Geronimo specific information while deploying a configuration), we need not specify them there. However, we should declare these attributes in the GBeanInfo and in the constructor. If the abstractName attribute is declared, then the Geronimo kernel will inject the abstractName of the GBean into it. If it is the kernel attribute, then a reference to the kernel that loaded this GBean is injected. If we declare classLoader, then the class loader for that configuration is injected. More on how to do this will be discussed in Chapter 14, Geronimo Internals.
[ 29 ]
Geronimo Architecture
Configurations
A group of GBeans that provide a certain service is called a configuration. A configuration has a name, can declare dependencies on other configurations, and is the basic deployable unit in Apache Geronimo. The GBeans that you write can only be deployed in Geronimo as part of a configuration. When you deploy a new service or an enterprise application in Apache Geronimo, the configuration details that you provide by means of a deployment plan are parsed and a configuration is created. Internally, a configuration is another GBean that actually groups a number of GBeans within it. A configuration contains the following persistable attributes: •
•
•
Its configurationData The configurationData represents all of the information that is stored in this configuration. Among the information that it contains is the classpath of this configuration (a list of URLs to locations where the classes representing this configuration are located), its configurationId (a unique ID for identifying this configuration to the kernel), the namespace of this configuration, and a byte array representing the state of all of the GBeans in this configuration. The list of its parents This is the list of parent configurations for this configuration. A configuration can have multiple parents, and each parent can in turn have multiple parents, and so on. A reference to a ManageableAttributeStore A manageable GBean attribute is one that can be changed at runtime by an administrator in order to change the behavior of the service that is wrapped by the GBean. For example, if we have a simple HttpServer service that is managed by a GBean, then one possible manageable attribute is the port on which the server will be listening. The ManageableAttributeStore is a repository where the manageable attributes are stored so that they are more easily accessible to the end user when compared to serialized configurations. Changes to the manageable attributes of the GBeans are made to the store and is persisted in the config.xml file present in the / var/config directory. There is also a config-substitutions.properties file for values of variables in the config.xml file. Each configuration is given a unique name. The name of a configuration as it is specified in the deployment plan of that module is, as follows: org.apache.geronimo.configs openejb 2.1.4 car [ 30 ]
Chapter 2
The name of the configuration is in the format // / •
groupId: The groupId identifies a group of related modules. If no group ID is specified for a module or an application, then its groupId is taken as default. If
no group ID is specified for a dependency entry, then it is taken as a wildcard and instances of groupId are not used in the search. •
artifactId: The artifactId identifies the artifact within the group. It should be unique within the group. If the artifactId is not specified, then it will be defaulted to the name of the module file.
•
version: The version is the version of that artifact. It can take the form 1.x.x. If it is not specified, then the version is taken as the timestamp at the time of deploying the configuration
•
type: This represents the type of the artifact. It can be car for system services and jar, ear, war, and so on for other modules.
Dependencies
A module or configuration can have dependencies on other modules. You can specify the dependencies on other modules through the dependency tag, as shown below: org.apache.geronimo.configs j2ee-server 2.1.4 car org.apache.geronimo.framework geronimo-kernel 2.1.4 jar
[ 31 ]
Geronimo Architecture
Most commonly, users will need to give dependencies on other configurations, services, or libraries. There is a difference in the way in which these dependencies are handled by the Geronimo kernel. In the case of a dependency on a configuration, all of the services of that configuration as well as the classes, are available to the current configuration. A configuration, specified as a dependency becomes a parent of the current configuration. Its class loader becomes the parent of the current configuration's class loader. If the dependency is on a jar type artifact, which is not a configuration, the classes of that jar type artifact are added to the classpath of the current configuration.
High-level architecture
Apache Geronimo consists of a lightweight kernel that provides services such as Lifecycle Management, Dependency Management, Repository, and Configuration Management to the other services that are deployed on it. As we saw earlier in the chapter, the basic manageable unit in Apache Geronimo is the GBean. GBean is a manageable wrapper object with attributes, references, and lifecycle callback methods. It also has a static GBEAN_INFO attribute, which is, a description used by the kernel to instantiate, manage, and modify the GBean state. The following diagram shows the Apache Geronimo kernel and all of the services that it provides, as well as the other services that are layered on top of the basic kernel services: Java EE Container System
Security
Work Management
Deployments Dependency Management
Lifecycle Management
Kernel Repository
Configuration Management Naming
Transactions
Remoting
[ 32 ]
Chapter 2
This architecture is the key for Geronimo's extensibility. It adds new services or plugins as services deployed on the server, which are in the form of GBeans whose state, dependencies, and lifecycle are managed by the kernel. A GBean may have a reference to another GBean, and the kernel makes sure that the GBean has access to a properly initialized and started instance of that GBean. The Configuration Manager is a component in the Apache Geronimo kernel that takes care of starting the configurations in the requisite order and also of providing the plumbing required to connect related and dependent configurations together so that they can consume the services of other configurations. The Apache Geronimo kernel also provides the Repository and configuration store that contains configurations of the existing modules as well as the required libraries. Any new module that you add will also be added to the Repository. If it is a configuration archive, then it will be added to the configuration store as well. By the Geronimo kernel, we mean the core of Geronimo that provides the services shown in the previous diagram. We will also be referring to the org.apache.geronimo.kernel.Kernel interface. This is the core interface whose implementations will actually manage GBeans. Whenever we refer to the Kernel implementation, we mean implementations of this interface. We will be referring to both of these, and you should keep in mind the subtle difference between them.
We will now see each of the services that the kernel provides, in detail: •
Repository The repository is the place where Apache Geronimo stores the majority of the artifacts that it contains. The repository consists of two types of artifacts: °
Libraries: The libraries are utilized by Apache Geronimo as well as the applications that are deployed on it. The libraries are usually JAR files that contain a number of classes. The libraries may be standalone or be included in a configuration. An example of a commonly-used library is log4j for logging. The log4j library will be present in the repository in the directory /repository/log4j/log4j/1.2.14/log4j1.2.14.jar.
[ 33 ]
Geronimo Architecture
°
Configurations: These are the configurations that are deployed in Apache Geronimo. A configuration represents a set of services that can be loaded and brought online by the Geronimo kernel. Once you deploy a module, the configuration information is serialized to the disk in a subdirectory of /repository, along with the libraries that provide the functionality of that module. The serialized configuration information generally consists of the information in the deployment plan as well as the values for different GBean attributes, and queries for different GBean references. It is stored in the META-INF directory directly inside the root directory of the configuration. The path of the root directory of the configuration will consist of the group ID of the configuration, with dots replaced by slashes. A configuration will always have a directory name ending with .car. For example, the openEJB configuration will be present in the repository in the /repository/org/apache/ geronimo/configs/openejb/2.1.4/openejb-2.1.4.car
•
•
directory as its artifactId is org.apache.geronimo. configs/openejb/2.1.4/car. Configuration Management The kernel manages all of these tasks, from creating new configurations to linking them to their parents and children, serializing them to disk, reading them back, as well as managing the attributes of the GBeans. There is a configuration manager GBean which manages these tasks. An additional task that the kernel performs is to make MBean wrappers for the GBeans so that they can be managed remotely over JMX. Lifecycle Management This is another service that is provided by the kernel. This actually includes providing lifecycle management to all of the services that are deployed in Apache Geronimo. The Kernel implementation provides Lifecycle Management through GBeans. The Kernel implementation is actually aware of GBeans only, and it can Start, Stop, Load, and Unload GBeans. GBeans that implement the org.apache.geronimo.gbean.GBeanLifecycle interface will provide implementations of callback methods that will be called by the Kernel after starting (doStart), before stopping (doStop), and in case of failure (doFail). The kernel internally has a LifecycleMonitor that will be sent notifications whenever a GBean is loaded, starting, running, stopping, stopped, failed, or unloaded. The notifications are sent by a LifecycleBroadcaster. The LifecycleMonitor will have a number of instances of LifecycleListener that are registered with it, and they are configured to perform tasks corresponding to the state notifications that they receive. [ 34 ]
Chapter 2
•
Dependency Management Finally, the Apache Geronimo Kernel provides Dependency Management— that is, the management of dependencies for the services deployed in the server. The dependencies for a configuration or module are specified in the deployment plan for that module. So the kernel provides the plumbing that will link a configuration together with all of its dependencies. Dependency Management also includes making sure that all of the services that a configuration depends on are started before the configuration is started. Again at the Kernel implementation level the dependencies are between GBeans, and the Kernel manages starting all of the dependencies of a GBean before it is started, as well as making them available to the GBean at runtime.
Class loader architecture
This section covers the class loader architecture for Apache Geronimo. The following image shows the class loader hierarchy for an application that is deployed in Apache Geronimo: BootStrap Extensions System org.apache.geronimo.framework/j2ee-system//car SystemDatabase
EAR WAR
The BootStrap class loader of the JVM is followed by the Extensions class loader and then the System class loader. The j2ee-system class loader is the primary class loader of Apache Geronimo. After the j2ee-system class loader, there are multiple other layers of class loaders before reaching the application class loaders. Applications have an application class loader, which loads any required application-level libraries and EJB modules. However, the web application packaged in the EAR will have its own class loader. The Administration Console has a ClassLoader Viewer portlet that can be used to view the class loader hierarchy as well as the classes loaded by each class loader.
[ 35 ]
Geronimo Architecture
Modifying default class loading behavior
In certain situations, we will need to follow a class loading strategy that is different from the default one that is provided by Apache Geronimo. A common situation where we need this functionality is when a parent configuration uses a library that is also used by the child and the library used by the parent is a different version, which is incompatible with the child's version of the library. In this case, if we follow the default class loading behavior, then we will always get the classes loaded by the parent configuration and will never be able to reference the classes in the library present in the child configuration. Apache Geronimo provides you with the ability to modify the default class loading behavior at the configuration level to handle such scenarios. This is done by providing certain elements in the deployment plan which, if present, will change the class loading behavior. These elements and the changes in class loading behavior that they represent, are explained as follows: •
hidden-classes: This tag is used to hide classes that are loaded in parent
class loaders, so that the child class loader loads its own copy. Similarly, we can use this tag to specify the resources that should be loaded from the configuration class loader. For example, consider the case where you have a module that needs to load its copy of log4j. The server also has its own copy used for logging that is loaded in the parent class loader. We can add the hidden-classes element in the deployment plan for that module so that it loads its own copy of log4j, and the server loaded version of log4j is hidden from it.
•
non-overridable-classes: This element specifies the list of classes that can be loaded only from the parent configurations of this configuration. In other words, the classes specified in this element cannot be loaded by the current configuration's class loader. The non-overridable-classes element is for preventing applications from loading their own copies of classes that should always be loaded from the parent class loaders, such as the Java EE API classes.
•
private-classes: The classes that are defined by this tag will not be visible to class loaders that are the children of the current class loader. These classes will be loaded either from the current class loader or from its parents. The same class loading behavior can be achieved by using the hidden-classes tag in all of the child class loaders.
[ 36 ]
Chapter 2
•
inverse-classloading: If this element is specified, then the standard class loading strategy will be reversed for this module. This in effect means that a class is first looked up from the current class loader and then from its parent. Thus, the class loader hierarchy is inverted.
•
suppress-default-environment: This will suppress the environment
that is created by the builder for this module or configuration. This is a rarely-used element and can have nasty side effects if it is used carelessly.
Important modules
In this section, we will list the important configurations in Apache Geronimo. We will group them according to the Apache or other open source projects that they wrap. Configurations that do not wrap any other open source project will be listed under the Geronimo section. Apache ActiveMQ org.apache.geronimo.configs/activemq-broker/2.1.4/car org.apache.geronimo.configs/axis/2.1.4/car Apache Axis org.apache.geronimo.configs/axis-deployer/2.1.4/car Apache Axis2
org.apache.geronimo.configs/axis2-ejb-deployer/2.1.4/ car org.apache.geronimo.configs/cxf/2.1.4/car org.apache.geronimo.configs/cxf-deployer/2.1.4/car org.apache.geronimo.configs/cxf-ejb/2.1.4/car
Apache Derby
org.apache.geronimo.configs/cxf-ejb-deployer/2.1.4/ car org.apache.geronimo.configs/derby/2.1.4/car
Apache Geronimo org.apache.geronimo.configs/client/2.1.4/car org.apache.geronimo.configs/client-deployer/2.1.4/car org.apache.geronimo.configs/client-security/2.1.4/car org.apache.geronimo.configs/client-transaction/2.1.4/ car org.apache.geronimo.configs/clustering/2.1.4/car org.apache.geronimo.configs/connector-deployer/2.1.4/ car
[ 37 ]
Geronimo Architecture
org.apache.geronimo.configs/farming/2.1.4/car org.apache.geronimo.configs/hot-deployer/2.1.4/car org.apache.geronimo.configs/j2ee-deployer/2.1.4/car org.apache.geronimo.configs/j2ee-server/2.1.4/car org.apache.geronimo.configs/javamail/2.1.4/car org.apache.geronimo.configs/persistence-jpa10deployer/2.1.4/car org.apache.geronimo.configs/sharedlib/2.1.4/car org.apache.geronimo.configs/transaction/2.1.4/car org.apache.geronimo.configs/webservices-common/2.1.4/ car org.apache.geronimo.framework/client-system/2.1.4/car org.apache.geronimo.framework/geronimo-gbeandeployer/2.1.4/car org.apache.geronimo.framework/j2ee-security/2.1.4/car org.apache.geronimo.framework/j2ee-system/2.1.4/car org.apache.geronimo.framework/jee-specs/2.1.4/car org.apache.geronimo.framework/jmx-security/2.1.4/car org.apache.geronimo.framework/jsr88-cli/2.1.4/car org.apache.geronimo.framework/jsr88deploymentfactory/2.1.4/car org.apache.geronimo.framework/offline-deployer/2.1.4/ car org.apache.geronimo.framework/online-deployer/2.1.4/ car org.apache.geronimo.framework/plugin/2.1.4/car org.apache.geronimo.framework/rmi-naming/2.1.4/car org.apache.geronimo.framework/server-securityconfig/2.1.4/car org.apache.geronimo.framework/shutdown/2.1.4/car org.apache.geronimo.framework/transformeragent/2.1.4/car org.apache.geronimo.framework/upgrade-cli/2.1.4/car Apache Yoko
org.apache.geronimo.configs/j2ee-corba-yoko/2.1.4/car org.apache.geronimo.configs/client-corba-yoko/2.1.4/ car
org.apache.geronimo.configs/jaxws-ejb-deployer/2.1.4/ car org.apache.geronimo.configs/jsr88-earconfigurer/2.1.4/car org.apache.geronimo.configs/jsr88-jarconfigurer/2.1.4/car org.apache.geronimo.configs/jsr88-rarconfigurer/2.1.4/car org.apache.geronimo.configs/jsr88-warconfigurer/2.1.4/car org.apache.geronimo.configs/myfaces/2.1.4/car
Apache OpenEJB
org.apache.geronimo.configs/myfaces-deployer/2.1.4/ car org.apache.geronimo.configs/openejb/2.1.4/car
Apache OpenJPA
org.apache.geronimo.configs/openejb-corbadeployer/2.1.4/car org.apache.geronimo.configs/openejb-deployer/2.1.4/ car org.apache.geronimo.configs/openjpa/2.1.4/car
Spring
org.apache.geronimo.configs/spring/2.1.4/car
Apache Tomcat6
org.apache.geronimo.configs/tomcat6/2.1.4/car
JSR 88
org.apache.geronimo.configs/tomcat6-clusteringbuilder-wadi/2.1.4/car org.apache.geronimo.configs/tomcat6-clusteringwadi/2.1.4/car org.apache.geronimo.configs/tomcat6-deployer/2.1.4/ car org.apache.geronimo.configs/tomcat6-no-ha/2.1.4/car Apache WADI
org.apache.geronimo.framework/gshell-framework/2.1.4/ car org.apache.geronimo.framework/gshell-geronimo/2.1.4/ car org.apache.geronimo.framework/xmlbeans/2.1.4/car
If you check the configurations, then you will see that most of the components that make up Geronimo have a deployer configuration and a main configuration. The deployer configuration contains the GBeans that will deploy modules onto that component. For example, the openejb-deployer contains GBeans that implement the functionality to deploy an EJB module onto Apache Geronimo. For accomplishing this, the EJB JAR file and its corresponding deployment plan are parsed by the deployer and then converted into a format that can be understood by the OpenEJB subsystem. This is then deployed on the OpenEJB container. The main configuration will usually contain the GBeans that configure the container and also manage its lifecycle.
Server directory structure
It is important for a user or an administrator to understand the directory structure of a Geronimo server installation. The directory structure of a v2.1.4 server is shown in the following screenshot:
Please note that the directory that we will be referring to as is the geronimo-tomcat6-javaee5-2.1.4 directory shown in the screenshot.
[ 40 ]
Chapter 2
The following are some important directories that you should be familiar with: • • • • •
• • • •
The bin directory contains the command scripts and the JAR files required to start the server, stop the server, invoke the deployer, and start the GShell. The etc directory contains the configuration files for GShell. The lib directory contains the JAR files required to start the basic Geronimo framework. The schema directory contains Geronimo schemas. The var/config directory contains Geronimo configurations files. A Geronimo administrator or user can find most of the configuration information about the server here. The var/derby directory contains the database files for the embedded Derby database server. The var/log directory contains logging configuration and logfiles. The var/security directory contains user credential and grouping files. The var/security/keystores directory contains the cryptographic keystore files used for server SSL configuration.
The following are some important configuration files under the Geronimo directory structure: •
config.xml: This file is located under the /var/config
•
config-substitutions.properties: This file is located under the /var/config directory. The property values specified in this file are used in expressions in config.xml. The property values in
directory. This file preserves the information regarding GBean attributes and references that were overridden from the default values used at deployment time.
this file can be overridden by using a system property or environment variable with a property name that is prefixed with org.apache.geronimo. config.substitution.
•
artifact_aliases.properties: This file is located under the /var/config directory. This file is used to substitute
one module or configuration ID for another module or configuration ID. The entries in this file are of the form oldArtifactId=newArtifactId, for example default/mylib//jar=default/mylib/2.0/jar. Note that the version number in the old artifact ID may be omitted, but the version number in the new artifact ID must be specified. •
client_artifact_aliases.properties: This file is located under the /var/config directory. This file is used for artifact
aliasing with application clients.
[ 41 ]
Geronimo Architecture
•
•
•
•
•
server-log4j.properties: This file is located under the / var/log directory. This file contains the logging configuration for the server.
More details about this configuration can be found in Chapter 13, Logging. deployer-log4j.properties: This file is located under the /var/log directory. This file contains the logging configuration for the deployer. More details about this configuration can be found in Chapter 13, Logging. client-log4j.properties: This file is located under the /var/log directory. This file contains the logging configuration for application clients. More details about this configuration can be found in Chapter 13, Logging. users.properties: This file is located under the /var/ security directory. This file contains the authentication credentials for the server. See Chapter 6, Security, for more details. groups.properties: This file is located under the /var/ security directory. This file contains the grouping information for the users defined in users.properties. See Chapter 6, Security, for more details.
Among the directories that contain sensitive information, such as user passwords, are var/security, var/derby, and var/config. These directories should be protected using operating system provided directory and file security.
Deployment architecture
In this section, we discuss some of the important aspects of deployment of artifacts on a Geronimo server.
Deployer
The deployer aggregates all instances of the ConfigurationBuilder available on the server and invokes the appropriate ConfigurationBuilder to deploy an archive, or a Geronimo-specific deployment plan XML file, or both. The deployer can be used through the web-based Administration Console, command-line deploy tool, hot-deployer, or GShell. Note that Administration Console, command line deploy tool, and GShell provide the option to specify an archive and a plan, whereas hot-deployer requires that the plan be packaged inside the archive. Installed modules, applications, and services configurations can be uninstalled using the command-line deploy tool or GShell, and specifying the configuration ID. Configurations can also be uninstalled by clicking on the uninstall link in the Administration Console from the appropriate Applications portlets page. See Chapter 10, Administration, for more details on portlets in the Administration Console. [ 42 ]
Chapter 2
Repository
Geronimo uses the Maven 2 type artifact repositories for library files, resources, and deployed configurations. The root of this repository is the directory /repository. This repository contains all of the server runtime configurations. An artifact with ID /// is located under the directory /repository// / with the filename -.. For example, the log4j JAR file that has an artifact ID of log4j/log4j/1.2.14/jar is located in the /repository/log4j/log4j/1.2.14 directory under the filename log4j-1.2.14.jar. When the groupId contains a dot (period), it results in a subdirectory rather than a directory with a dot in the directory name. For example, the RAR file corresponding to org.tranql/tranql-connector-ra/1.4/rar is located under the /repository/org/tranql/tranql-connectorra/1.4 directory rather than /repository/org.tranql/tranqlconnector-ra/1.4.
Configuration builder
A configuration builder creates a runtime configuration containing a class loader definition and GBeans that represent the function to be provided by deploying an application archive or a service plan in Geronimo. The archive or plan is translated into a set of GBeans. The definition of the GBeans is already available on the server or provided in the archive that is being deployed. The configuration builders deployed in the server are aggregated by the Deployer to provide a single interface for deploying all kinds of supported archives and/or plans. EARConfigBuilder and ServiceConfigBuilder are two configuration builders that are included in a Geronimo server by default. A configuration builder implements the org.apache.geronimo.deployment. ConfigurationBuilder interface shown in the following listing: public interface ConfigurationBuilder { static final String CONFIG_BUILDER = "ConfigBuilder"; Object getDeploymentPlan(File planFile, JarFile module, ModuleIDBuilder idBuilder) throws DeploymentException; Artifact getConfigurationID(Object plan, JarFile module, ModuleIDBuilder idBuilder) throws IOException, DeploymentException; DeploymentContext buildConfiguration( boolean inPlaceDeployment, //Boolean specifying whether to deploy in place Artifact configId,// the configuration id Object plan, // the deployment plan JarFile module, // the archive to deploy [ 43 ]
Geronimo Architecture Collection configurationStores, // the list of config stores ArtifactResolver artifactResolver, ConfigurationStore targetConfigurationStore // target store ) throws IOException, DeploymentException; }
During the deployment, the getDeploymentPlan() method of each ConfigurationBuilder is invoked with the archive and/or plan files received for deployment. The configuration builder examines the provided archive and plan files, and returns the plan if that configuration builder can handle the deployment. The first configuration builder to return a non-null plan is chosen as the candidate to deploy the archive and/or plan. The candidate configuration builder's getConfigurationID() method determines the ID of the configuration under which the deployment will happen. Note that any fields in the configuration ID that are not determined by the configuration builder will be set to the default values by the deployer. The configuration ID will determine the directory under the repository into which the configuration will be deployed. The configuration builder's buildConfiguration() performs the moving of unpacked configuration directories to the repository and creates the necessary GBeans to complete the deployment. Configuration builders use instances of ModuleBuilder and NamingBuilder to handle the individual modules in the deployment process. Any new ConfigurationBuilder GBeans that are started in the server at runtime get dynamically added to the deployer and are immediately available for use.
Module builder
Geronimo's EARConfigBuilder uses instances of ModuleBuilder to process individual web, EJB, connector, and application client modules in the deployment process. A ModuleBuilder processes the configuration and creates GBeans corresponding to a module that ModuleBuilder is capable of processing. Some instances of the ModuleBuilder that are available in Geronimo are given as follows: •
EjbModuleBuilder
•
TomcatModuleBuilder
•
JettyModuleBuilder
•
ConnectorModuleBuilder
•
AppClientModuleBuilder
A ModuleBuilder GBean implements the interface org.apache.geronimo.j2ee. deployment.ModuleBuilder. The interface definition is as follows: public interface ModuleBuilder { Module createModule(File plan, JarFile moduleFile, Naming naming, ModuleIDBuilder idBuilder) [ 44 ]
The createModule() method processes the individual Java EE module—that is, either a part of an EAR or being deployed as a standalone module, creates the artifacts that need to be installed, and also creates additional dependencies that need to be added to the configuration. The installModule() method handles the copying of artifacts to the repository. The initContext() method handles the initialization of the application context. The addGBeans() method handles the adding of any GBeans to the module's configuration.
Module builder extension
A ModuleBuilderExtension to a ModuleBuilder provides additional processing on the module over and above those provided by the ModuleBuilder. A ModuleBuilderExtension implements the interface org.apache.geronimo.j2ee. deployment.ModuleBuilderExtension. This interface definition is given in the following listing: public interface ModuleBuilderExtension { void createModule(Module module, Object plan, JarFile moduleFile, String targetPath, URL specDDUrl, Environment environment, Object moduleContextInfo, AbstractName earName, Naming naming, ModuleIDBuilder idBuilder) throws DeploymentException; [ 45 ]
Each ModuleBuilder can be configured with zero or more instances of ModuleBuilderExtension. During each of the method invocations in ModuleBuilder, once the processing by the ModuleBuilder is completed, the method invokes the corresponding method on each of the configured instances of ModuleBuilderExtension so that the extension completes additional processing. For example, MyFacesModuleBuilderExtension for TomcatModuleBuilder takes care of processing MyFaces configuration files and adding necessary additional dependencies and GBeans to the configuration.
Naming builder
Instances of ModuleBuilder and ModuleBuilderExtension use instances of NamingBuilder to process the Geronimo naming of related XML elements, for example, EJB references, GBean references, and so on, in the deployment plans. Some instances of the NamingBuilder are: •
EjbRefBuilder
•
ResourceRefBuilder
•
CorbaRefBuilder
•
TSSLinkBuilder
•
EnvironmentEntryBuilder
•
GBeanRefBuilder
The instances of NamingBuilder to be used by instances of ModuleBuilder and ModuleBuilderExtension are configured in a NamingBuilderCollectionGBean.
Hot deployment
Geronimo provides hot deployment by means of DirectoryHotDeployer, whereby the files copied to the /deploy directory are automatically deployed to the Geronimo server. [ 46 ]
Chapter 2
Deployment watcher
A DeploymentWatcher enables the receipt of notifications about configurations being deployed to and removed from the server. A DeploymentWatcher implements the interface org.apache.geronimo.kernel.DeploymentWatcher. The interface definition is given in the following listing: public interface DeploymentWatcher { void deployed(Artifact id); void undeployed(Artifact id); }
For example, the DirectoryHotDeployer, which is a DeploymentWatcher, handles the removal of files from the hot-deploy directory when the configuration being removed is originally deployed using the hot deployer.
Plugins
A Geronimo plugin is a predeployed configuration that contains a class loader description, GBeans, and other resources. An example is the Quartz plugin that, upon installation, provides sophisticated scheduling functionality to applications being deployed on Apache Geronimo. A plugin defines prerequisite configurations as well as dependencies that must be downloaded. As it is already processed by the deployer, a plugin JAR is directly extracted into the server's repository without going through a deployment step where the configuration is created. A plugin installation differs from a normal deployment in the way that any non-prerequisite dependencies for the plugin will be downloaded during installation. The prerequisite configurations must have already been deployed in the server for the plugin to be installed. Note that in case of a regular deployment, all of the dependencies must already exist in the repository. Plugins can be installed by using the command-line deploy tool, the Administration Console, or the GShell.
Plugin catalog and plugin repository
A Plugin archive file contains a metadata file geronimo-plugin.xml under the META-INF directory. This geronimo-plugin.xml file contains descriptive information about the plugin, such as the plugin category, URL for a site that contains more information on the plugin, content to be added to config.xml for customization of GBeans, property values to be added to config-substitutions.properties, artifact aliases to be added to artifact-aliases.properties, a description of the content to be unpacked to the server directory, and so on. The information from multiple plugins is collected into a plugin catalog called geronimo-plugins.xml. A maven repository containing plugins and a plugin catalog is referred to as a plugin repository. [ 47 ]
Geronimo Architecture
Custom server assemblies
Starting from v2.1, a Geronimo server is completely assembled out of plugins. This architecture provides the ability to assemble a server containing only selected configurations according to a user's interest, and the necessary dependencies. This provides the users with the ability to start with a full Java EE server, deploy the user's applications, and then extract a server with the minimum footprint required to run the user's applications. Assembling a server in this manner can be done using the Plugins portlet in the Administration Console or by using the assemble-server GShell command. Note that the org.apache.geronimo.assemblies/geronimoboilerplate-minimal/2.1.4/jar configuration must be included in order to have a working server. Another way to create a custom server assembly is to use the car-maven plugin and build the server using Maven to include geronimoboilerplate-minimal, along with your plugin(s) that need to be part of the server. See Chapter 9, Geronimo Plugins, for more details on creating custom server assemblies.
Extensible Administration Console
The flexible server assemblies require that the Administration Console is also flexible, in order to provide the administration functionality for the newly added components as plugins to be made available from a single place. New functions can be added to the Administration Console by installing Administration Console Extensions. This provides the plugin developers with the capability to package administration components along with the functional components of their plugin. See Chapter 9, Geronimo Plugins, for details on creating Administration Console Extensions.
Summary
We conclude this chapter after having gone through a fairly detailed overview of the architecture of Apache Geronimo, as well as the base pattern behind the Geronimo kernel—that is, dependency injection. We have covered GBeans, configurations, dependencies, and the repository. We then had a look at the high-level architecture of Apache Geronimo. We covered the functionality that the Apache Geronimo kernel exposes and had a look at the class loader hierarchy in Apache Geronimo. We listed the important system-level modules and explained the difference between normal and deployer modules. Finally, we discussed the deployment architecture and plugins. This brings us to the end of the chapter on the Apache Geronimo architecture. The authors hope that you now have a fairly detailed understanding of the Kernel and that you will be able to understand the Apache Geronimo source code better with this in mind. In the next chapter, you will learn about configuring database connectivity and using the Apache Derby database embedded in Apache Geronimo. [ 48 ]
Database Connectivity Apache Geronimo is used for hosting Java EE enterprise applications. All enterprise applications operate on data and in most of them, all or a part of this data is stored in a relational database. Therefore, it is important for an application server to provide an infrastructure for applications to simplify and optimize relational database access. Java applications use the Java Database Connectivity (JDBC) API for SQL-based database access. This is an API that is independent of the underlying database. The database vendors provide JDBC drivers for their respective RDBMSes. The Java EE application server provides a mechanism for optimizing and simplifying database access through connection pools. The server creates a pool of connections so that the applications can reuse the connections in the pool. As a result, the applications are spared from creating and closing connections, and the connection reuse actually speeds up the process as it is more efficient than creating connections whenever required. Another advantage is that it ensures that the application code will not contain any RDBMS vendor-specific code, thereby making it possible to swap the RDBMS used without changing any code. Apache Geronimo provides these features with the help of the TranQL framework. The TranQL framework wraps JDBC drivers in J2CA connectors, and so in Apache Geronimo, JDBC connectivity is also exposed through J2CA just like it is for JMS. This enables both database and JMS invocations to be part of a single transaction. Geronimo supports JDBC connection pools with local transaction support, and also ones with XA transaction support. All you have to do is configure the resource adapter with the JDBC properties that you would use to establish a JDBC connection directly, and the resource adapter will create the database pool. Creating a database connection upon each request is costly in terms of resource usage, and it holds on to resources unnecessarily. With a database pool, the created connections are placed in a pool and reused so that new connections need not be made unless the connections in the pool are all in use. This also reduces the waiting time of the application to obtain a connection to the database.
Database Connectivity
There are generic TranQL connectors in Geronimo that can support any relational database and there are also database-specific resource adapters. All of the XA connectors are database-specific and so XA support is provided only for a limited number of databases. The TranQL RAR files contain the connection pooling logic that is used by Geronimo. In this chapter, you will learn: •
The scope of database pools
•
Creating a server-wide database pool
•
Creating an application-scoped database pool
•
Creating a client-scoped database pool
•
Editing an existing database pool
•
Importing a database pool from another application server
•
Using a database pool in an application
Database pool scopes
In Apache Geronimo, you can deploy database pools with three different scopes. The different scopes and their significance are explained as follows: •
Server-wide: If your database pool is server-wide, it will be visible throughout the entire server instance. Any application or service that is deployed on the server can then look up and use the connections in that pool. You can also use the @Resource annotation in your application code to get the database pool injected instead of using lookups.
•
Application-scoped: An application-scoped database pool is visible only inside an enterprise application. It is not visible to other enterprise applications or services that are deployed on the same application server that are separate from this enterprise application. All of the different Java EE modules that are packaged inside the enterprise application in whose scope the pool is created will have access to that pool. So if an EAR file has both web and EJB modules, then they will be able to access and use a database pool declared in the EAR file's scope. Note that an application-scoped database pool can still be accessed by another application if it declares a dependency on the application that declares the pool.
•
Client-scoped: A client-scoped database pool is visible only in the scope of the application client which declares it. This scope is used when application clients want to access relational databases. Application clients run inside a client container—that is, separate from the application server—and so they cannot access database pools that are declared on the server side. [ 50 ]
Chapter 3
Application-scoped database pools can only be deployed with EAR applications. The advantage of using application-scoped database pools is that you can deploy and manage your application and your database pool as a single deployment unit. Standalone web and EJB applications can use server-wide database pools. The advantage of using server-wide database pools is that you can redeploy just the database pool without affecting the deployed applications that use the database pool. You can choose to deploy your database pool as a Server-wide pool or as an Application-scoped pool depending on your requirement.
Creating a server-wide database pool
In order to set up connectivity with any RDBMS from Apache Geronimo, you first need to obtain the JDBC drivers for that particular RDBMS. These drivers can be obtained from the database vendor or from a third party having a license to provide JDBC drivers for that RDBMS. Once you obtain the JDBC driver, you need to install it into Apache Geronimo's server repository. You can then set up a database pool using the TranQL resource adapters and the JDBC drivers. There are four ways in which you can set up a server-wide database pool, as we will see now.
Using the Administration Console Wizard
The steps for downloading and installing JDBC drivers and setting up a database pool using the Administration Console Wizard are given in the next example. We will create a database pool with the name TestDBPool for the HSQLDB embedded database. 1. Start the Apache Geronimo server instance and bring up the Administration Console in your favorite web browser, by using the URL http://localhost:8080/console. 2. Log in with the username system and password manager. 3. On the left-hand side of the Console Navigation pane under Services, click on the Database Pools link, as shown in the following screenshot:
[ 51 ]
Database Connectivity
4. This will bring up the Database Pools portlet, as shown in the next screenshot. The Database Pools portlet shows the list of pools that are already deployed on this Geronimo server instance. It provides three links to create a database pool in three ways, namely, by using the database pool wizard, by importing the database pool from JBoss 4, or by importing the database pool from Weblogic 8.1.
5. Click on Using the Geronimo database pool wizard. This brings up the first screen of a sequence of screens that will guide you through the process of creating a database pool. This is shown in the following screenshot:
[ 52 ]
Chapter 3
6. Enter the Name of Database Pool that you want to create, select the Database Type from the drop-down list, and then click on Next. For our example, enter the name TestDBPool and select HLSQLDB embedded as the Database Type. Click on Next to bring up the next screen, as shown in the following screenshot:
7. In this screen you need to enter values for the following fields: •
Driver JAR: The JAR file(s) that contain the database driver
•
DB User Name: The username used to connect to the database
•
DB Password: The password that is required to connect to the database
•
Confirm Password: The same as the DB Password, entered once more for confirmation
•
Database: The name of the database
8. We can see that the Driver JAR select box is empty, which means that the HSQLDB embedded driver is not present in the server repository. We can download and install this driver from the Administration Console. To do this, click on the Download a Driver button. If the select box is not empty, then you can select the corresponding driver if it is available. [ 53 ]
Database Connectivity
9. This brings us to the next screen, where we can select the driver that we want from the Select Driver drop-down list, and then click on Next. For our example, select HSQLDB 1.7.3, and then click on Next. This will bring up the next screen with a progress bar that shows the download progress of the driver, as shown in the next screenshot:
See the topic Installing unlisted drivers, for steps to manually download and install JAR files in the repository. 10. Once the download completes, the Driver JAR drop-down list in Step 2, Select Driver, JAR, Parameters, is filled with the name of the JAR driver that has been downloaded and installed in the Geronimo repository. 11. Enter values for the other fields, and then click on Next. The values we are entering are DB User Name: system, DB Password: manager, and Database: TestDB. The value entered for the Confirm Password field should be the same as the value for the DB Password field. Click on Next to go to the next screen, as shown in the following screenshot:
[ 54 ]
Chapter 3
12. In this screen, fill in the values for the following configuration properties: °
Transaction Type: The type of transactions that this connection pool supports
°
Pool Min Size: The minimum number of connections in the pool
°
Pool Max Size: The maximum number of connections in the pool
°
Blocking Timeout: The time period, in milliseconds, for which a caller will wait to obtain a connection from the pool
°
Idle Timeout: The amount of time, in minutes, after which an idle connection will be closed In order to test connectivity to the database instance that you specified in the database pool configuration, you can use the Test Connection button. If you want to skip the test and deploy then click on the Skip Test and Deploy button. In case you want to see the Geronimo-specific plan for this database pool, you can use the Skip Test and Show Plan button.
13. In order to test connectivity to the database instance that you specified in the database pool configuration, you can use the Test Connection button. 14. If you want to skip the test and deploy the connection pool, then click on the Skip Test and Deploy button. 15. If you want to see the Geronimo-specific plan for this database pool, then you can use the Skip Test and Show Plan button. 16. Clicking on the Skip Test and Deploy button will deploy and create the connection pool, and you will be taken back to the first screen of the Database Pools portlet that lists all the active database pools.
Installing unlisted drivers
If you want to download and install a driver that is not available in the list of downloadable drivers shown in the Administration Console, you will need to go to the download site for that particular RDBMS or database driver vendor and manually download the driver to a temporary location on your hard disk. From that location, you can install the driver into the server repository by using the Repository portlet.
[ 55 ]
Database Connectivity
In order to open the Repository portlet, you need to click on the Repository link in the Services section of the Console Navigation pane. The Repository portlet is shown in the following screenshot:
You need to use the Browse button to select the File on the disk that you downloaded and then complete the Group, Artifact, Version, and Type fields. This will result in the file being copied to the path. Actually, in most cases, the Artifact, Version, and Type are automatically detected by the portlet. Consider the case shown in this example. The name of the driver file is postgresql-8.3-604.jdbc3.jar. On selecting the file by using the file viewer that pops up on clicking on the Browse button, the Artifact, Version, and Type fields are completed with the values shown in the screenshot. If we enter the Group as org. jdbc.postgresql, then the archive will be installed as org.jdbc.postgresql/postgresql8.3/604.jdbc3/jar. The actual JAR file will be present in the repository in the org/ jdbc/postgresql/postgresql-8.3/604.jdbc3 directory, and will be named postgresql-8.3-604.jdbc3.jar. You can also manually copy JAR files to the repository. However, while doing this, the directory structure and the name of the JAR file should be the same as shown, that is, the JAR file should be present in the repository at ///.jar.
Once the driver has been installed in the server repository, it can be referred to as a dependency inside a Geronimo deployment plan for the TranQL connector for that database. The generic TranQL connector can be used for wrapping the drivers of any JDBC database driver.
Using the Deploy New portlet
The Administration Console has a Deploy New portlet for deploying artifacts to the server. You can deploy new applications as well as new database pools or JMS connectors. In order to deploy a database pool using this portlet, you need to provide [ 56 ]
Chapter 3
the portlet with the required TranQL connector and the corresponding deployment plan. You can use the Browse button to locate the required TranQL RAR file from the server repository, as well as to locate the deployment plan. Deployment plans can be generated through the Administration Console Wizard as follows: 1. Go to the Database Pools portlet, and click on the Using the Geronimo database pool wizard link to bring up the wizard, as shown in the following screenshot:
2. Enter the Name of Database Pool, say DerbyTestPool, and select the Database Type, say Derby embedded XA. Click on Next to bring up the next screen, as shown in the following screenshot:
[ 57 ]
Database Connectivity
3. Select the Driver JAR file, as shown in the previous screenshot. For our example, it should be org.apache.geronimo.configs/system-database/2.1.4/car. We select a car for an embedded Derby database because Geronimo already has an embedded Derby instance running for the system database. Therefore, by choosing a dependency on that configuration, the Derby classes are not loaded again and a new embedded Derby instance is not created. Instead a new Derby database is created using the same embedded Derby instance. °
Complete the Database Name field with the value DerbyTestDB.
°
Set the Create Database flag to true. This will result in a new Derby database being created if one does not already exist.
°
Complete the User Name and Password fields with system and manager, respectively.
°
Select a Transaction Type of XA.
°
Click on the Show Plan button to show the deployment plan, as shown in the following screenshot:
[ 58 ]
Chapter 3
4. Copy the plan from the text area and paste it in a new file called plan.xml. The contents of the plan.xml file are shown in the following listing:
console.dbpool DerbyTestPool 1.0 rar org.apache.geronimo.configs system-database 2.1.4 car javax.sql. DataSource DerbyTestPool manager D erbyTestDB system 10 0 [ 59 ]
Database Connectivity 5000 15
We will now go through the significance of the major elements in the plan: °
connectionfactory-interface: This should be javax.jms. ConnectionFactory.
°
name: The name that is used by other modules to refer to this
°
config-property-setting: This element is used to define properties that are specific to the resource adapter. The name of the property will be specified as the value of the name attribute and the value of the property will be given as the value of this element.
°
connectionfactory-interface: The interface that is implemented by the connection factory. This should be javax.sql.DataSource.
°
xa-transaction: Indicates that the resource adapter can participate in XA transactions.
°
transaction-caching: Indicates that connection sharing
°
single-pool: This specifies the connection pooling type, and
°
match-one: This is a connection pool match setting that
resource. The name should be unique across the scope (server or application) in which these resources are deployed. It is a good practice to have names that are unique across scopes.
must be enabled for resources in the same transaction.
means that a single connection pool will be used to pool all connections to this resource.
will select one connection from the pool and test whether it matches the connection request. If it does, then the connection is used. Otherwise, an error is thrown.
[ 60 ]
Chapter 3
5. Deploy the pool by using the connector \repository\
org\tranql\tranql-connector-derby-embed-xa\1.4\tranqlconnector-derby-embed-xa-1.4.rar and the path of the plan—that is, in
the Deploy New portlet enter the path of the TranQL RAR file in the Archive textbox and the path of the plan in the Plan textbox.
6. If you browse to the Database Pools portlet, then will now see this database pool listed.
Using the command-line deployer
In some distributions of Apache Geronimo, such as Little-G, the Administration Console is not present. You can also assemble a custom server without the Administration Console. In such an environment, you can still use the commandline deployer or GShell for deploying the database pools. Another instance where this is useful is when you have multiple servers on which you want to deploy the database pool. In this case, you can use the Administration Console Wizard to configure the database pool and generate a deployment plan on one server and use this deployment plan repeatedly on different servers, in order to deploy the database pool. In case you want to deploy your database pool from the command-line deployer, you need to follow the steps as follows: 1. Open the command line in Windows, or the shell in a Unix based OS, and change the directory to the /bin directory. 2. Next, invoke the deploy script from the bin directory. You need to provide the deploy script with the path to the TranQL RAR file and the deployment plan. 3. Assuming we are deploying the same database pool as the one in the previous section, the command will be deploy deploy where is the path to the TranQL RAR archive and the is the path to the deployment plan for that database pool. Assuming the plan file is saved to DerbyTestPool-plan.xml, the command would look like the following: deploy deploy \repository\org\tranql\tranql-connectorderby-embed-xa\1.4\tranql-connector-derby-embed-xa-1.4.rar DerbyTestPoolplan.xml
The JAVA_HOME or JRE_HOME should be pointing to a valid JDK or JRE in order to make the deployer scripts work.
[ 61 ]
Database Connectivity
Using GShell
You can also use Geronimo's command shell, 'GShell', for deploying the database pools. For doing this, you should first boot up GShell by running the gsh script (gsh.sh for a Unix-based OS, or gsh.bat for Windows). This will bring up the GShell prompt: @:/>
where is the username you use to log in and, is the hostname of the system. The command to deploy the database pool is deploy/deploy
GShell supports file separators of '/' and '\', but if the separator is '\', it should be escaped as '\\'. For example, C:\test\hello should be represented as C:\\test\\hello.
Creating an application-scoped database pool
An application-scoped database pool is visible only within the scope of the application. It is available to all of the modules that are present within an enterprise application (for example, war, ear, jar, and so on). It can also be made visible to other applications if they declare a dependency on the application containing the database pool. You can deploy an application-scoped database pool by adding an ext-module element to the application's Geronimo specific deployment plan.
To illustrate this, we have provided a sample application. This sample application is present at samples\Chapter-3 Database Connectivity\JDBC Sample ear. The ext-module section in the geronimo-application.xml file of the JDBC sample EAR application is shown below: JDBCDataSource org.tranql tranql-connector-derby-embed-xa rar
The sections with dashes are actually the same as those shown earlier in the plan.xml file. It has the following elements that are not present in the deployment plan for a server-scoped database connection pool: •
connector: Name of the connector.
•
external-path: Defines the TranQL resource adapter that will be used to deploy the connector plan. It consists of groupId, artifactId, type,
and so on, which are used to identify the resource adapter in the Geronimo repository.
After these two elements, the plan is identical to the one for the server-scoped database pool. Note that the dependencies present in the server-scoped plan are not present in the connector section of the application plan, as they are added as a dependency for the entire application. There is also no dependency on the database pool in the application plan, as it is contained in the application itself.
[ 63 ]
Database Connectivity
Creating a client-scoped pool
A client-scoped database pool is maintained by the Java EE client container, which runs in a JVM instance separate from the server. The database pool will be visible to the application client instance that runs inside this container. The client container will connect as a separate process to the database instance, and the database should be configured to accept connections from the client container. To illustrate, we have provided a sample application. This sample application is present at samples\ Chapter-3 Database Connectivity\JDBC Sample ear. The module plan for creating a client-scoped connection pool is shown below: JDBCSample-client-1.0.jar com.packtpub.jdbc JDBCSample-client 1.0 car com.packtpub.jdbc JDBCSample-client-server 1.0 car jdbc/DataSource DerbyTestPool org.tranql tranql-connector-derby-client-local rar
The first part of the code defines the environment in which the client runs in the client container. It contains elements such as module ID, dependencies, and class loader. This is followed by the section for the server environment. This will define the environment on the server that is required for the application client, and identify it by using the module ID.
[ 65 ]
Database Connectivity
Note that in this plan, there is a resource section that contains the actual plan for the database connector. The additional element here is the external-rar element, which points to the TranQL RAR file in the server's repository that must be used to deploy this database connection pool. The remaining elements are the same as that of normal server-side resource adapter deployment plans. A slight difference is seen in the above plan, as we are using the TranQL client RA for derby that supports local transactions. We use the client RA as the database instance is in the server's JVM and we are connecting from a JVM instance that is separate to the one in which the client container is running.
Editing an existing pool
If you want to make changes to a database pool that you created, then you can either redeploy a database pool with the same name, or edit it from the Administration Console. Once you edit the fields from the Administration Console, you will need to restart the database pool configuration so that the changes can take effect. The steps for doing this are as follows: 1. Open the Database Pools portlet. This will bring up a list of database pools. 2. Click on the Edit link corresponding to one of the database pools that we created in previous sections, say DerbyTestPool. This will bring up a screen, as shown in the following screenshot:
[ 66 ]
Chapter 3
3. You can change any of the editable fields in this page, namely Database Name, Create Database, User Name, Password, Confirm Password, Login Timeout, Pool Min Size, Pool Max Size, Blocking Timeout, and Idle Timeout. 4. After editing the fields, you can then click on the Save button. The values will be saved, and you will be taken back to the screen showing the list of installed database pools.
Importing a pool from another application server
Apache Geronimo also provides mechanisms to reuse database pool configuration from other application servers such a JBoss and BEA Weblogic. In the following section, we will see how we can import a database pool from JBoss. Assume that we have a JBoss plan named test-ds.xml. This plan is provided in the samples\Chapter-3 Database Connectivity\jboss-plan directory. The contents of the plan are shown below: TestDS jdbc:hsqldb:hsql://localhost:1701 org.hsqldb.jdbcDriver system manager 5 20 10
[ 67 ]
Database Connectivity
Go to the Database Pools portlet, and click on the Import from JBoss 4 link. This will bring up the next screen, which is shown in the following screenshot:
Use the Browse button to select the JBoss plan that you want to import. Next, click on the Next button to bring up the next screen, as shown in the following screenshot:
[ 68 ]
Chapter 3
Click on the Confirm and Deploy button to bring up the next screen, as shown in the following screenshot:
This screen will contain all of the details that are present in the JBoss deployment plan entered in the text boxes for the corresponding entries in the Apache Geronimo specific database pool deployment plan. Edit any field that you want to change, and then click on the Skip Test and Deploy button to deploy the database pool. You have now imported a database pool from JBoss and deployed it on Geronimo.
Creating an XA pool
Apache Geronimo supports the creation of XA database pools, which contain a pool of database connections that can join in XA transactions—that is, they can take part in a two-phase commit process. As there is a need for separate TranQL resource adapters for XA support for each database, Apache Geronimo supports XA with only a limited number of databases. [ 69 ]
Database Connectivity
The databases supported are: •
Apache Derby(Derby embedded XA, Derby network XA)
•
IBM DB2 (DB2 XA)
•
IBM Informix (In the works)
•
MySQL (MySQL XA)
•
Oracle (Oracle XA)
•
PostgreSQL (PostgreSQL XA)
In order to create an XA database pool, you need to select a database type in the Database Pools portlet as one of the above databases that have XA support, such as Derby embedded XA. The steps after selecting a database type are the same as that for local types except that the transaction type should be selected as XA. There may also be a few extra fields for XA connectors that need to be configured.
Using a database pool in an application
Once you have created a database pool, you can use it in your application to access the database that it provides connectivity with. Most applications other than the most trivial ones store data in databases and thereby require database access. In this section, we will walk through how we can configure an application to access a database through the database pool. We will look into how we can configure an application to use a server-scoped database pool as well as an application-scoped one. We will also see how we can configure an application to connect to the application-scoped database pool of a different application.
Accessing a server-scoped database pool
In order to access a server-scoped database pool from an application, you will need to give a dependency to the database pool in the application's Geronimo-specific deployment plan. We will illustrate this by using the JDBC sample application present in the directory of the samples for Chapter 3, Database Connectivity. The application consists of a servlet that connects to a database and then creates a table called CUSTOMER that consists of four columns. These columns are Name, Address, Phone, and Email. The application then inserts a record into the table.
[ 70 ]
Chapter 3
The application then retrieves that record and prints the details to your browser. The source code for the servlet is given as follows: package com.packtpub.cust; import java.io.*; import java.sql.Connection; import java.sql.ResultSet; import java.sql.Statement; import java.sql.SQLException; import javax.servlet.ServletException; import javax.servlet.http.*; import javax.sql.DataSource; import javax.annotation.Resource; public class CustomerInfoServlet extends HttpServlet { @Resource private DataSource ds; protected void service(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException { Connection conn = null; try { conn = ds.getConnection(); Statement stmt = conn.createStatement(); String createSQL = "CREATE TABLE CUSTOMER(Name char(50),Address char(50),Phone char(20),Email char(50))"; stmt.executeUpdate(createSQL); String insertSQL = "INSERT INTO TABLE CUSTOMER VALUES('Tom','Chapel Hill','234567','[email protected]')"; stmt.executeUpdate(insertSQL); ResultSet rs = stmt.executeQuery("SELECT * FROM CUSTOMERINFO"); res.setContentType("text/html"); PrintWriter out = res.getWriter(); out.print(""); out.print("Hello World Application "); out.println(""); out.println("
The DataSource, which is a connection factory to the connections in the pool, is obtained by resource injection. The @Resource annotation is used to specify that an instance of DataSource should be injected into this variable, as shown: @Resource private DataSource ds;
The connection is then obtained from the DataSource. A statement is created from the connection and then the executeUpdate method is called on the statement object to perform database operations, as shown: conn = ds.getConnection(); Statement stmt = conn.createStatement(); stmt.executeUpdate(createSQL); [ 72 ]
Chapter 3
The database plan that we will be using will be the same as the plan.xml file shown earlier. In case you have already deployed the plan, then you can deploy the application immediately. Otherwise, you will need to deploy the plan using the deployer, or the Deploy New portlet, as mentioned in the earlier sections on the deployment of database pools. After deploying the database pool, you will need to edit the geronimo-web.xml file of the application to have a dependency on the database pool, as well as a resource-ref element that maps the resource-refname to the database pool name. The plan is shown in the following illustration: com.packtpub.cust CustomerInfo 1.0 car console.dbpool DerbyTestPool /CustomerInfo jdbc/DataSource DerbyTestPool
You can see the dependency on the database pool, as well as the resource-ref mapping, in this web application plan. On deploying this application, it will be able to utilize the database pool named DerbyTestPool to connect to and interact with a Derby database instance.
[ 73 ]
Database Connectivity
Accessing an application-scoped database pool from the same application
In the case of an application-scoped database pool, the only difference is that there is no dependency on a database pool configuration. Instead, the database pool is defined in the application's deployment descriptor as a separate module. The mechanism to access the database pool in the application and the resource mapping in the deployment plan is same, as illustrated earlier in this section. Also you can add an application-scoped database pool only in an enterprise application. You cannot add it to standalone web or EJB applications. There is a sample application provided at samples\Chapter-3 Database Connectivity\JDBC Sample ear that is configured to use an application-scoped database pool. This application can be deployed by deploying the JDBCSample-ear-1.0.ear file, which is present in the modules\ear\target directory.
Accessing an application-scoped database pool from a different application
In the case of accessing an application-scoped database pool from a different application, the only difference is that the application that wants to access the database pool of a different application should have the application defining the database pool as its parent application—that is, it should have a dependency to the application defining the database pool.
Summary
In this chapter, we discussed the different options that Apache Geronimo provides to connect to relational database systems. We saw how to configure database pools of various scopes using different tools, such as the Administration Console, the command-line deployer, and GShell. We also took a peek into how we can import a database pool configuration from another application server, and how an enterprise application developer can configure an enterprise application to use the database pooling functionality provided by Apache Geronimo, for efficient database access. This covers most of the common things a Java EE developer using Apache Geronimo will need to know about database connectivity in order to enable him or her to use it to its fullest potential. In the next chapter, we will discuss the support provided by Geronimo for the Java Message Service (JMS). You will learn to configure the embedded JMS server, create JMS resources, and use JMS resources in Java EE applications.
[ 74 ]
JMS Connectivity Java Message Service (JMS) is an important functionality that has to be provided by Java EE application servers. JMS enables the sending and receiving of messages by the Java EE application components. It allows these application components to communicate with other components (both Java and non-Java), which may be remote or local, in an asynchronous fashion, through messages. This communication is facilitated by the Message Oriented Middleware (MOM), also known as message brokers that implement JMS. Message brokers provide reliable delivery of messages between the application components. The message broker that is used in Apache Geronimo is Apache ActiveMQ, an open source message broker from the Apache Software Foundation �(ASF). ActiveMQ is an embeddable message broker that is written in Java. In this chapter, you will learn about the following: •
Configuring ActiveMQ, which is embedded in Apache Geronimo
•
Using a resource adapter to connect to the ActiveMQ broker
•
Creating new JMS connection factories, JMS queues, and JMS topics
•
Configuring application components to use the messaging functionality provided by the embedded Apache ActiveMQ
Message broker configuration
In this section, we will take a look at how the message broker is integrated into Apache Geronimo, and, look into the various configuration options that Apache Geronimo provides for configuring the Apache ActiveMQ message broker.
JMS Connectivity
GBean configuration
The broker is instantiated and started in the org.apache.geronimo.configs/ activemq-broker/2.1.4/car configuration. This configuration has two GBeans.
ActiveMQ is the GBean that creates an instance of the broker and then starts it. The implementation class of this GBean is org.apache.geronimo.activemq. BrokerServiceGBeanImpl. This GBean only provides a few configuration attributes, but these attributes are enough to configure ActiveMQ. The attributes provided are as follows: •
brokerName: A name for this broker instance
•
dataSource: The JNDI name of the data source used for storing ActiveMQ message store data
•
dataDirectory: The directory where the ActiveMQ message store data is
•
brokerUri: The path of the broker configuration XML deployment descriptor
•
useShutdownHook: A Boolean value indicating whether the embedded ActiveMQ broker instance should use a shutdown hook or not.
stored. It is also used to store logfiles.
The values for these attributes, for the ActiveMQ GBean, can be found in the deployment plan for the broker configuration. This is shown below: possibly-unique-broker --> false var/activemq NoTxDatasource ActiveMQManager [ 76 ]
Chapter 4 ServerInfo MBeanServerReference
Here, a dataDirectory value of var/activemq, results in a data directory of /var/activemq. The useShutdownHook property is set to the default value of false, in order to inform the broker to not use a shutdown hook, as the broker will be shut down by the Apache Geronimo kernel. We can modify these values by making changes to the config.xml file in the /var/config directory. The change to be made is to add a tag to the corresponding configuration entry in config.xml after stopping the server, followed by restarting the server. You should edit the config.xml file only when the server is stopped. When the server is started, it reads the config.xml file into the memory and then it may make changes to the memory representation at runtime. When the server is stopped, it will overwrite the existing config.xml with the current representation of config.xml in memory. Therefore, any changes made to the config.xml file when the server is running will be lost.
For example, in the config.xml file, modify the module entry from:
to var/activemq1/data var/activemq1/broker.xml
This will result in the data directory becoming /var/activemq1/data. Additional configuration of the message broker can be performed by using the ActiveMQ configuration file. The location of the configuration file can be specified by using the GBean attribute brokerUri, as shown. The complete path in this case will be /var/activemq1/broker.xml. This XML file provides a lot more configuration options than those provided by the ActiveMQ GBean. [ 77 ]
JMS Connectivity
The default port used is 61616. This is configured through the ActiveMQPort property in the config-substitutions.properties file. config-substitutions.properties is a file that is present in the /var/config directory, and gives the values of variables that are used in the XML configuration files for Geronimo, as well as various services deployed on it.
Using the Administration Console
The Administration Console provides a JMS Server portlet that can be used to configure the Apache ActiveMQ embedded broker instance. This portlet lists the existing JMS listeners for ActiveMQ. You can start, stop, edit, and delete the existing JMS listeners. You can also add new listeners by clicking on the Add new … listener links provided in the portlet. See Chapter 10, Administration, for more details on using this portlet to configure ActiveMQ.
JMS resource scopes
JMS resources can be deployed in the Geronimo server with three different scopes. These are as follows: •
Server-wide: The resource is available across all of the applications and services that are deployed on the server instance. The resource can therefore be referenced and utilized by any application or service.
•
Application-scoped: The resource is available across all of the modules and services that make up an enterprise application. The resource can be accessed by other applications that have an application declaring the resource as their direct or indirect parent.
•
Application client-scoped: Application clients run in a client container in a JVM instance separate from the server instance, and they do not have access to server resources. Therefore, application clients can have their own resource adapters to connect to the message broker, and these can be used to access JMS resources in the client scope.
Creating JMS resources
There are three types of JMS resources that are commonly-used in Java EE enterprise applications. These are as follows:
[ 78 ]
Chapter 4
• • •
Connection factories Queues Topics
We can create all of these types of JMS resources with server scope through the Administration Console, or by manually creating the resource adapter deployment plan, and then deploying it through the deployer. The latter method can be used for creating application-scoped and application client-scoped JMS resources as well. Connectivity to these JMS resources is through the ActiveMQ resource adapter.
Creating Server-wide JMS resources
We can create server-wide JMS resources either by utilizing the Administration Console or by creating them manually. In this section, we will go through the steps involved in creating the server-wide JMS resources through the Administration Console. We will then export the deployment plan for the resource adapter, along with the admin objects that we created using the Administration Console, and use it to deploy the corresponding resource adapter and the JMS resources manually. We will then go through each of the elements in the plan and explain their significance. JMS resources, once created on the server, can be linked to resource references that can be used by the applications for lookup. They can also be injected by the respective containers into the Java EE artifacts such as EJBs, Servlets, and so on, within an application, through the dependency injection.
Using the Administration Console Wizard
The steps for deploying a JMS resource adapter and the associated resources through the Administration Console are as follows: 1. Log in to the Administration Console, and navigate to the JMS Resources portlet through the Console Navigation pane on the left-hand side. This portlet is shown in the following screenshot:
[ 79 ]
JMS Connectivity
2. The previous screenshot shows the JMS resource groups that are present on the server. You can see that there is one resource group that is already present. This is the default resource group that is present in an instance of Apache Geronimo, and has the name ActiveMQ RA. It consists of two Queues and a Connection Factory. 3. In order to create a new JMS resource group in ActiveMQ, click on the For ActiveMQ link in the Create a new JMS Resource Group section. This will bring up the screen shown in the following screenshot:
[ 80 ]
Chapter 4
4. Enter the Resource Group Name as Sample RA, the UserName as system, and the default Password as manager, respectively. Click on the Next button to bring up the screen shown in the following screenshot:
5. Next, click on the Add Connection Factory button to add a new connection factory. This will bring up the screen shown in the following screenshot:
6. Select the JMS Factory Type and click on the Next button. This will bring up the Configure Connection Factory screen, shown below:
[ 81 ]
JMS Connectivity
7. Enter the value of the Connection Factory Name field as SampleConnectionFactory and click on Next. This will take us back to the Current Progress screen shown earlier. The only difference being that the connection factory that we configured just now is also listed. 8. Next, click on the Add Destination button to bring up the screen that asks you to select the JMS Destination Type as shown in the following screenshot:
9. Select javax.jms.Queue and click on Next. This will bring up the Configure Destination screen, as shown in the following screenshot:
10. Enter the Message Destination Name and its PhysicalName. Click on Next to go back to the Current Progress screen, shown earlier. Both the JMS resources that we configured will now be listed. 11. Click on the Deploy Now button to deploy the configuration, and create these JMS resources. [ 82 ]
Chapter 4
At any time, you can click on the Show Plan button, on the Current Progress screen, to show the Apache Geronimo-specific resource adapter deployment plan. On the Show Deployment Plan screen, you can click on Deploy JMS Resource to complete the deployment, or you can click on Edit Configuration to go back to the Current Progress screen and continue adding more JMS resources. You can then save the plan to a file and edit the plan, if required, before deployment using the Geronimo ActiveMQ resource adapter, as we see later in this section. The generated plan is shown below: console.jms Sample RA 1.0 rar org.apache.geronimo.configs activemq-broker car
This section shows the environment that should be available, in order for the resource adapter to run in the application server. This includes its module ID and its dependencies. The next section configures the resource adapter instance, while providing it with the work manager that it should use, and also defines the connection factories that need to be created for this resource adapter. Sample RA manager system DefaultWorkManager [ 83 ]
In the following section, we define the connection pooling and transactional behavior of the resource adapter:
The next section shows the administered objects that we will be creating for this resource adapter instance. This includes various queues and topics. javax.jms.Queue org.apache.activemq.command.ActiveMQQueue SampleQueue SampleQueue javax.jms.Topic org.apache.activemq.command.ActiveMQTopic [ 84 ]
Chapter 4
We will now go through the significance of the major elements in the plan.xml file that are related to the JMS resource adapter that we are installing. These are as follows: •
resourceadapter-name: This is the name of the resource adapter. This name
is utilized to identify the resource adapter.
•
config-property-setting: This element is used to specify properties that are specific to the resource adapter. The name of the property will be specified as the value of the name attribute, and the value of the property will be given as the value of this element.
•
workmanager: This is used to link to the work manager to which the resource
•
connectionfactory-interface: This should be javax.jms.ConnectionFactory.
•
name: This is the name that is used to refer to this resource by other modules.
•
implemented-interface: This is the interface that is implemented by the connection factory. It can be javax.jms.QueueConnectionFactory or javax.jms.TopicConnectionFactory.
•
xa-transaction: Indicates that the resource adapter can participate in
adapter submits the work that it needs to get done.
The name should be unique across the scope (server or application) in which these resources are deployed. It is a good practice to have names that are unique across all scopes.
XA transactions.
•
transaction-caching: Indicates that connection sharing must be enabled
•
single-pool: This specifies the connection pooling type and means that
•
match-one: This is a connection pool match setting that will select one connection from the pool and test whether it matches the connection request. If it does, then the connection is used; otherwise an error is thrown.
•
adminobject-interface: The interface that the administered object will implement. This should match the entry in ra.xml for this resource adapter.
•
adminobject-class: The class of the administered object. This should match the entry in ra.xml.
•
message-destination-name: This is the name of the message destination or administered object. This name should be unique in the scope of the resource, and this name will be used by applications to refer to this administered object.
for resources in the same transaction.
a single connection pool will be used to pool all of the connections to this resource.
[ 85 ]
JMS Connectivity
Using the Deploy New portlet
You can use the Deploy New portlet in the Administration Console to deploy your JMS resources to the server. You will need to give the path to the ActiveMQ RAR in the Archive section, namely, \repository\org\apache\ geronimo\modules\geronimo-activemq-ra\2.1.4\geronimo-activemq-ra2.1.4.rar, and the path to the Geronimo-specific deployment plan in the Plan
text box. You can use the Browse buttons to open a file dialog to select the respective files.
Using the command-line deployer
You can also use the command-line deployer to deploy the JMS resource adapter. To deploy from the command line, change the current directory to /bin and run the following command: deploy deploy [module] [plan]
where [module] refers to the path of the module file \
repository\org\apache\geronimo\modules\geronimo-activemq-ra\2.1.4\ geronimo-activemq-ra-2.1.4.rar, and [plan] refers to the path of the
deployment plan file. You can also have the plan file packaged inside the module file as META-INF/geronimo-ra.xml, in which case you will not need to specify the plan file separately. This is valid for all types of modules, as well as when deploying through the Deploy New portlet or GShell.
Using GShell
You will need to start up GShell using the gsh script and then, at the GShell prompt, you will need to specify: deploy/deploy [module] [plan]
where [module] refers to the path of the module file \
repository\org\apache\geronimo\modules\geronimo-activemq-ra\2.1.4\ geronimo-activemq-ra-2.1.4.rar, and [plan] refers to the path of the
deployment plan file.
Creating application-scoped JMS resources
We can create JMS resources that are scoped to an enterprise application,—that is, resources that can be used by all of the modules in an enterprise application but that won't be visible to other applications
[ 86 ]
Chapter 4
If an application registers a dependency on the application that defines an application-scoped JMS resource, then that resource will be visible to both of these applications.
Application-scoped resources have the advantage of defining all of the resources that your application uses in the application's deployment descriptor. Therefore, on deploying the application, all of the resources that it depends on will be deployed along with the application. The same happens during undeployment when all of the resources also get undeployed. Thus, this enables us to package the application and all of its resources into a single deployable unit. The part of the application deployment plan for an application-scoped JMS resource adapter is shown as follows: -------------------- SampleRA org.apache.geronimo.modules geronimo-activemq-ra rar Sample RA manager system DefaultWorkManager javax.jms.ConnectionFactory [ 87 ]
This is very similar to the standalone deployment plan. The resource adapter plan is encapsulated in an ext-module element, and has a connector and external-path section, in addition to the main connector section that is more or less similar to the plan for the standalone server-wide resource adapter. The external-path section points to the resource-adapter that will be deployed by using this plan. This is the same resource adapter that will be used to connect to the ActiveMQ message broker and access the resources that we define in the deployment plan.
[ 88 ]
Chapter 4
Creating application client-scoped JMS resources
In this section, we will see how we can create JMS resources that are scoped to a Java EE application client module that will be running in a separate client container, in a JVM instance that is different from the one on which the Apache Geronimo application server is running. Application clients do not have access to server-scoped or application-scoped resources that are deployed on the server-side, and only have access to application client-scoped resources. The resource-adapter plan will be embedded in the plan for the application client (geronimo-application-client.xml) which in turn may be embedded in the application deployment plan (geronimoapplication.xml). Shown next is a sample deployment plan for deploying the same JMS resources as the ones in the previous plans: --------------------------------------- org.apache.geronimo.modules geronimo-activemq-ra rar Sample RA manager system DefaultWorkManager javax.jms. ConnectionFactory SampleConnectionFactory javax.jms. TopicConnectionFactory [ 89 ]
Notice that there is a resource element here that encapsulates the connector element as well as the external-rar element, which is analogous to the external-path element in the case of the application-scoped RA.
Using JMS resources in an application
The primary reason for us to configure JMS resources on the application server is for applications and services deployed on the server, to get access to these resources in a vendor-independent way. In this section, we will see how we can use the JMS resources in an application to send or receive messages. Applications can either use JMS resources that are deployed on the application server, or they can use JMS resources that are defined at the application level. [ 90 ]
Chapter 4
We have provided two sample applications that demonstrate the use of JMS resources in an application, namely, JMS Sample and JMS Sample ear. In both of these cases, the Java code and functionality will be the same. The only difference will be in the deployment descriptors. Both of these applications send messages to a topic and have the same codebase, but one of them defines the JMS resources used at the client scope, while the other uses server-scoped resources. The code is the same for both the modules. The application has a servlet named JMSServlet, which accesses the JMS resources. The sevlet code is shown below: package com.packtpub.jms; import java.io.IOException; import java.io.PrintWriter; import java.util.ArrayList; import java.util.List; import java.util.Vector; import javax.annotation.Resource; import javax.jms.Connection; import javax.jms.ConnectionFactory; import javax.jms.JMSException; import javax.jms.Message; import javax.jms.MessageConsumer; import javax.jms.MessageListener; import javax.jms.MessageProducer; import javax.jms.Queue; import javax.jms.Session; import javax.jms.TextMessage; import javax.jms.Topic; import javax.servlet.ServletConfig; import javax.servlet.ServletContext; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; public class JMSServlet extends HttpServlet { @Resource(name = "jms/ChatConnectionFactory") private ConnectionFactory connectionFactory; @Resource(name = "jms/ChatTopic") private Topic topic; protected void service(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException { MessageProducer producer = null; MessageConsumer consumer = null; Connection connection = null; [ 91 ]
Notice the @Resource annotations. These annotations are used to inform the container that it needs to inject objects of type javax.jms.ConnectionFactory and javax.jms.Topic into the two variables that have been annotated. The name attribute of these annotations is used to map the annotated element to the actual resource. The actual resources are mapped to the names used above in the server-specific deployment plan. In the case of a standalone application, this is given in the geronimo-web.xml file: jms/ChatConnectionFactory console.jms Sample RA 1.0 SampleConnectionFactory jms/ChatTopic SampleTopic
You can see here that the ref-name element maps to the name that we specify in the annotation, and the pattern element refers to the SampleConnectionFactory that we define in the JMS plan, which is shown in its code listing, above. The only difference is that if the resources are application-scoped is that, instead of specifying a dependency on the JMS resource adapter in our application plan, we will include the JMS resource adapter plan also in our application plan. This is shown in the previous code listing. If we are not using annotations for accessing the resources, then we will need to look them up from JNDI using the names that we configure in the ejb-jar.xml, resource-ref, and resource-env-ref elements. The applications will be present in the 6941_04/samples directory in the code bundle provided with the book. They can be built using Maven 2. The command to build them is mvn clean install. If you want to import the source code into Eclipse, then you can run mvn eclipse: eclipse from the root directory of the project and then use the Import existing projects into the workspace feature of Eclipse to import them.
[ 93 ]
JMS Connectivity
Connecting to a different provider
Apache Geronimo is a Java EE 5 certified application server, and thereby provides the ability to plug any resource adapter in, as long as it complies with the JCA 1.5 specification. This means that you can use other JMS providers by deploying their resource adapters on the server. The server will provide connection management, transaction management, lifecycle management, and security for the resource adapters that are deployed on it. This means that we can have Java EE artifacts that can access and utilize JMS resources irrespective of what message broker they are configured on. The access can be done using standard Java EE APIs in a vendor-neutral manner. We will not be covering this in this book as it is similar to how we configured connectivity to ActiveMQ. Most of the third-party message brokers that support Apache Geronimo will have documentation on how to deploy their resource adapters in Apache Geronimo.
Summary
In this chapter, we saw a detailed description of the ActiveMQ message broker configuration in Apache Geronimo. We also went through the different ways in which we can deploy JMS resource adapters and resources in Apache Geronimo. We saw the different scopes in which we can deploy the JMS resources, and the significance of these scopes. We then went through two sample applications with the same functionality, one of which used server-wide resources and the other which used application client-scoped resources. In the next chapter, we will discuss the deployment of Java EE enterprise applications, standalone EJB, and web applications. We will also learn to create Geronimo-specific deployment plans for deploying these applications in Geronimo.
[ 94 ]
Java EE Application Deployment In the previous two chapters, we went through how to set up different types of resource adapters in Apache Geronimo. These resource adapters provide connectivity to relational databases and messaging systems for applications and services deployed on Apache Geronimo. In this chapter, we will go through deploying different types of Java EE enterprise applications on Apache Geronimo. Although we will cover the Java EE artifacts that these applications will contain in a fairly detailed manner, our main focus will be on their configuration and deployment. We will also see examples of illustrating each of the artifacts that we discuss in this chapter. Finally, we will see how we can specify dependencies on other applications in order to access the artifacts and services that they provide. In this chapter, you will learn about: •
Deployment descriptors and deployment plans
•
The deploy tool and various deployment methods
•
Deployment of web, EJB, JPA, and EAR applications
•
Deployment of application clients
•
JavaMail
•
Web services
•
Transactions
Java EE Application Deployment
Deployment of applications
Deployment is an important step in the lifecycle of a Java EE application. So much so that most organizations have a deployer role dedicated to this step. The deployer will configure the application for the environment in which it is being deployed and will identify the resources that the application needs and map them to the correct references in the application. The process of mapping the actual resources to the references in the application is done by means of the Java EE deployment descriptors and server-specific deployment plans. We will now go into the details of these files.
Deployment descriptors
A deployment descriptor is an XML file that describes the Java EE module. It lists the Java EE components that make up the module, and defines the environment for these components. Java EE components have access to a naming service called JNDI, which is used to decouple the component from the resources and other components that it uses. The component will access these resources and other components by looking them up in the JNDI naming context. The names that can be used to access these components and resources in the JNDI context for that component or module are specified in the deployment descriptor. This allows the deployer to map components to different physical resources and components by simply modifying the mapping of the names in the deployment descriptor to server-specific resources. The deployment descriptors are also used to modify the security aspects of the components, as well as to map the components to logical names. The different types of deployment descriptors, as specified in the Java EE specifications, are as follows: 1. Web deployment descriptor: The web deployment descriptor file should be named web.xml, and should be present in the WEB-INF directory of your web module. 2. EJB deployment descriptor: The EJB deployment descriptor file should be named ejb-jar.xml, and should be present in the META-INF directory of the EJB module. 3. Application deployment descriptor: The application deployment descriptor should be named application.xml , and should be present in the META-INF directory of the EAR file in which the application is packaged. 4. Application client deployment descriptor: The application client deployment descriptor should be named application-client.xml. This file should be present in the META-INF directory of the application client module. 5. Resource adapter deployment descriptor: This file should be named as ra.xml and should be present in the META-INF directory of the resource adapter module. [ 96 ]
Chapter 5
We will be using the term deployment descriptor throughout this book to refer to the descriptors that are specified by Sun Microsystems as part of Java EE 5 and related specifications.
The component or module-specific JNDI naming context is actually immutable, that is, once it has been created during deployment it cannot be changed. This is mandated by the Java EE 5 specification.
Deployment plans
When we use the term deployment plans, we are referring to the server-specific XML files that help with the deployment. These files can be created by tooling, or by hand. The tooling that is present in Apache Geronimo for creating this is the Geronimo Eclipse Plugin (GEP) and the Plan Creator portlet in the Administration Console. There are the Geronimo-specific deployment plan counterparts for each of the Java EE 5 deployment descriptors. They are described below: 1. Web deployment plan: The web deployment plan file should be named geronimo-web.xml, and should be present in the WEB-INF directory of your web module. This maps the resource references in web.xml to server resources. 2. EJB deployment plan: The EJB deployment plan file should be named openejb-jar.xml, and should be present in the META-INF directory of the EJB module. This maps the resource references in ejb-jar.xml to resources on the server. 3. Application deployment plan: The application deployment plan should be named geronimo-application.xml, and should be present in the META-INF directory of the EAR file within which the application is packaged. 4. Application client deployment plan: The application client deployment plan should be named geronimo-application-client.xml. This file should be present in the META-INF directory of the application client module. 5. Resource adapter deployment plan: This file should be named geronimo-ra.xml, and should be present in the META-INF directory of the resource adapter module.
[ 97 ]
Java EE Application Deployment
The deployment plans map the resource references in the Java EE deployment descriptors to resources configured in the Application Server. The mapping of resources can therefore be changed by simply changing the server-specific deployment plan to point to another resource. All instances of the resource-ref, resource-envref, and message-destination-ref in the Java EE deployment descriptors have corresponding entries in the Geronimo-specific deployment plans, which point to actual server resources. We can see this by means of the following snippets from the descriptors for both web.xml and geronimo-web.xml, as shown below: jdbc/snoop javax.sql.DataSource Container Shareable jdbc/snoop DerbyTestPool
The server-specific deployment plans can also be specified at deployment time, as an extra attribute to the deployment tooling. In this case, you need not package it with the archive. If you have a deployment plan that is packaged both with the archive and with an external plan that you specify during deployment, then the external plan takes precedence over the packaged one.
The deploy tool
The deploy tool is a standalone tool that can be used for deploying applications and resource adapters onto remote as well as local server instances. The tool can be invoked by using the deploy command. The syntax of the deploy command can be obtained through the options help and help all. Try running deploy help all from the command prompt after changing to the /bin directory to get descriptions on all the options that are possible with the deploy command. The output for this command is shown in the following screenshot:
[ 98 ]
Chapter 5
Running the deploy help all command provides a detailed explanation on the commands that the deploy tool supports. We will also give a few examples of common deploy tool usage below: •
Local deployment
•
Remote deployment
•
Installing a library
•
Installing a plugin
•
Offline deployment
•
Redeploy
[ 99 ]
Java EE Application Deployment
Deployment from the Administration Console
Deployment can also be done by using the Deploy New portlet in the Administration Console. See Chapter 10, Administration, for more details on using this portlet.
Deployment through GShell
GShell is a command-line shell that can be used for administering Apache Geronimo instances. GShell provides commands for deployment related operations. See Chapter 10, Administration, for more details of GShell.
Web modules
Web applications are the most common type of Java EE applications. They are the simplest to develop and understand, and their deployment descriptors are not too verbose. In this section, we will be looking at the deployment descriptors and server-specific deployment plans that are required to deploy a web application on Apache Geronimo. The focus here will be on the deployment plan and the various elements in the plan. We will now see the deployment configuration needed for various web artifacts such as servlets, filters, and listeners.
Servlet
Servlets extend the capabilities of a server application that uses a request-response model. Servlets are commonly used with the HTTP protocol. Typically, servlets are used to process data submitted by an HTML form, generating dynamic content and managing state over the stateless HTTP protocol. An xml-fragment in the deployment descriptor used to define a servlet and map the servlet to a URL pattern is given below. HelloworldServlet sample.HelloworldServlet greeting Namaskar HelloworldServlet /HelloworldServlet
[ 100 ]
Chapter 5
The name of the servlet is specified by using the servlet-name element under the servlet tag. The servlet-class element is used to specify the fully-qualified name of the java class for this servlet. This class should implement the javax.servlet. Servlet interface. A servlet may have zero or more initialization parameters defined using the init-param tag. The name of the parameter is specified by using the param-name element and the value is specified using param-value element. These parameters can be retrieved from the ServletConfig file in the init() lifecycle method, as shown in the following snippet: private String greeting; public void init(ServletConfig config) { greeting = config.getInitParameter("greeting"); }
The URLs that the servlet will be serving are specified by using the servlet-mapping element. The servlet-name element under servlet-mapping specifies the name of the servlet, and the url-pattern element specifies the pattern of URLs that will be served by this servlet. Note that more than one servlet-mapping can be present for a servlet.
Filter
Filters are used to intercept the web requests before the requests are passed on to the web resources for a service. Filters do not create requests or responses. A filter that has no dependency on a specific web resource can be associated with more than one web resource. Filters are typically used to examine the incoming request and take the appropriate action, modify the requests and responses (headers, data, attributes, and so on), and block requests and responses. An XML fragment in the deployment descriptor used to define a filter and map the filter to a URL pattern is given below: HelloworldFilter sample.HelloworldFilter param1 Aloha HelloworldFilter /HelloworldServlet REQUEST
[ 101 ]
Java EE Application Deployment
The name of the filter is specified by using the filter-name element under the filter tag. The filter-class element is used to specify the fully-qualified name of the java class for this filter. This class should implement the javax.servlet.Filter interface. A filter may have zero or more initialization parameters, defined by using the init-param tag. The name of the parameter is specified by using the paramname element and the value is specified by using the param-value element. These parameters can be retrieved from the FilterConfig in the init() lifecycle method. The URLs that the filter will be filtering is specified by using the filter-mapping element. The filter-name element under filter-mapping specifies the name of the filter and the url-pattern element specifies the pattern of URLs that will be filtered by this filter. Note that more than one filter can filter the requests, and in this case, these filters will form a filter chain through which the requests pass. If a filter is to be applied to a particular servlet, then use servlet-name, instead of url-pattern, under filter-mapping. The servlet-name element can use wildcard characters so that the filter is applied to more than one servlet. The dispatcher element specifies the type of requests to which the filter applies. Allowed values for the dispatcher are REQUEST, FORWARD, INCLUDE, and ERROR. Multiple dispatcher elements can be used to specify a combination of these values. The explanation of these values is as follows: •
REQUEST: Filter applies to requests coming from clients
•
FORWARD: Filter applies to requests forwarded to a component
•
INCLUDE: Filter applies when the request is processed by an included component
•
ERROR: Filter applies when the request is processed by an error page mechanism
The order in which filters are invoked is the order in which filter-mapping declarations, which match a request URI to a servlet, appear in the list of filter-mapping elements.
Listener
Monitoring events in a servlet's lifecycle can be done by defining listener objects that get invoked upon the occurrence of the lifecycle events. The various listeners that are supported are as follows: •
Servlet context listener: A servlet context listener implements the
javax.servlet.ServletContextListener interface. The methods from
this listener are invoked when a web application's context is initialized or destroyed. A ServletContextEvent containing a ServletContext object is passed as a parameter to the listener method.
[ 102 ]
Chapter 5
•
•
Servlet context attribute listener: A servlet context attribute listener implements the javax.servlet.ServletContextAttributeListener interface. The methods from this listener are invoked when an attribute is added to, removed from, or replaced in the web application's context. A ServletContextAttributeEvent object containing the ServletContext, a name, and the value of the attribute are passed as parameters to the listener method. Servlet request listener: A servlet request listener implements the
javax.servlet.ServletRequestListener interface. Methods from this
listener are invoked when the request comes into or goes out of scope in a web application. A request is defined as coming into scope when it is about to enter the first servlet or filter in the web application, and is defined as going out of scope when it exits the last servlet or the first filter in the chain. A ServletRequestEvent object, containing the ServletContext and the ServletRequest, is passed as a parameter to the listener method. •
Servlet request attribute listener: A servlet request attribute listener implements the javax.servlet.ServletRequestAttributeListener interface. Methods from this listener are invoked when an attribute is added to, removed from, or replaced in a ServletRequest when the request is within the scope of the web application. A ServletRequestAttributeEvent object containing the ServletContext, the ServletRequest, the name, and value of the attribute is passed as a parameter to the listener method.
•
HTTP session listener: An HTTP session listener implements the javax. servlet.http.HttpSessionListener interface. The methods from this listener are invoked when an HTTP session is created or destroyed. An HttpSessionEvent object containing the HttpSession is passed as a parameter to the listener method.
•
HTTP session attribute listener: An HTTP session attribute listener implements the javax.servlet.http.HttpSessionAttributeListener interface. Methods from this listener are invoked when an attribute is added to, removed from, or replaced in an HTTP session. An HttpSessionBindingEvent object containing the HttpSession, the name, and value of the attribute is passed as a parameter to the method.
•
HTTP session binding listener: An object that wants to be notified when it is bound or unbound to an HttpSession as an attribute can implement the javax.servlet.http.HttpSessionBindingListener interface. Methods from this listener are invoked when the object is bound to or unbound from an HTTP session. An HttpSessionBindingEvent object containing the HttpSession, and the name and value of the attribute is passed as a parameter to the method. [ 103 ]
Java EE Application Deployment
•
HTTP session activation listener: An object that wants to be notified when the HTTP session to which it is bound to as an attribute is being activated or passivated can implement the javax.servlet.http. HttpSessionActivationListener interface. Methods from this listener are invoked when an HttpSession to which the object is bound to is activated or passivated. An HttpSessionEvent object containing the HttpSession is passed as a parameter to the listener method.
Servlet context listener, servlet context attribute listener, servlet request listener, servlet request attribute listener, HTTP session listener, and HTTP session attribute listener are registered in a web application by using the web application deployment descriptor. A sample XML fragment for registering such listeners is shown below: sample.HelloworldServletContextListener sample.HelloworldServletContextAttributeListener sample.HelloworldServletRequestListener sample.HelloworldServletRequestAttributeListener sample.HelloworldHttpSessionListener sample.HelloworldHttpSessionAttributeListener
The listener-class element specifies the fully qualified name of the Java class of the listener. HTTP session binding listeners and HTTPS session activation listeners get registered when an object implementing the respective interfaces is bound to an HTTP session as an attribute.
[ 104 ]
Chapter 5
Web deployment descriptor
The following are various elements in a web application deployment descriptor web.xml, the schema of which is given at http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd. •
context-param: The context-param element contains the declaration of a web application's servlet context initialization parameters.
•
session-config: The session-config element defines the session parameters for the web application.
•
mime-mapping: The mime-mapping element defines a mapping between an
•
welcome-file-list: The welcome-file-list element contains an ordered list of welcome-file elements. The welcome-file element contains the filename to be used as a default welcome file, such as index.html.
•
error-page: The error-page element contains the mapping of an error
extension and a mime type.
code or exception type to the path of a resource in the web application. The error-code parameter contains an HTTP error code, ex: 404. The exception-type parameter contains the fully-qualified class name of a Java exception type. The location element contains the location of the resource in the web application, relative to the root of the web application. The value of the location must have a leading '/'.
•
jsp-config: The jsp-config element is used to provide global configuration information for the JSP files in a web application. It has two sub-elements: taglib and jsp-property-group. The taglib element defines the syntax for declaring that a tag library is available to the application in the deployment descriptor. This can be done to override implicit map entries from TLD files and from the container.
•
security-constraint: The security-constraint is used to associate
•
login-config: The login-config is used to configure the authentication
•
security-role: The security-role contains the definition of a security role. The definition consists of an optional description of the security role and the security role name. See Chapter 6, Security, for more details on this element.
security constraints with one or more web resource collections. See Chapter 6, Security, for more details on this element.
method that should be used, the realm name that should be used for this application, and the attributes that are needed by the form login mechanism. See Chapter 6, Security, for more details on this element.
[ 105 ]
Java EE Application Deployment
•
•
•
jndiEnvironmentRefsGroup: This group keeps the use of the contained
JNDI environment reference elements consistent across Java EE deployment descriptors. message-destination: The message-destination specifies a message destination. The logical destination described by this element is mapped to a physical destination by the deployer. locale-encoding-mapping-list: The locale-encoding-mapping-list contains one or more locale-encoding-mapping(s). The locale-encodingmapping contains locale name and encoding name. The locale name must be either Language-code, such as "ja", defined by ISO-639 or Language-code_ Country-code, such as "ja_JP". The Country-code is defined by ISO-3166.
Annotations
The use of annotations in web artifact classes enables you to avoid JNDI lookups for resources, and EJB references as annotations provide for injection. The following are some annotations that are used in web artifact classes such as Servlets.
Resource annotation
The @Resource annotation is used to annotate resources such as JMS Connection Factories, JMS Queues, JMS Topics, DataSources, and so on. This annotation can be used on a field or a setter method. The name attribute of this annotation specifies the name relative to the java:comp/env where the resource is bound in the JNDI (See Chapter 8, JNDI). For example, an @Resource annotation with the name jms/TestQueue will result in the corresponding resource bound in the JNDI at java:comp/env/jms/TestQueue. For example, consider the @Resource annotation in the following code snippet: @Resource(name="jms/TestQueue") private Queue queue;
This results in the binding of the resource in the JNDI at java:comp/env/jms/ TestQueue. The following is the resource mapping in the web deployment plan
Here, the servlet field queue is injected with the physical resource SendReceiveQueue, mapped in the deployment plan. An @Resource annotation on a field of type Boolean, Byte, Character, String, Short, Integer, Long, Float, or Double will result in an injection of the corresponding env-entry value defined in the deployment descriptor. For example, consider the @Resource annotation defined in the following code snippet: @Resource(name="const/myEnvEntry") private String country;
This results in the env-entry value defined in the following deployment descriptor being injected into servlet field: const/myEnvEntry java.lang.String India
Here, the servlet field country is injected with the value India.
EJB annotation
The @EJB annotation is used to define an EJB reference in a web artifact class (for example, a Servlet). This annotation can be used on either a field or a setter method. The name attribute of the annotation specifies the name relative to the java:comp/env where the resource is bound in the JNDI (See Chapter 8, JNDI). For example, consider the @EJB annotation in the following code snippet: @EJB(name="ejb/LanguageService") LanguageService langService;
This results in an EJB reference bound in the local JNDI at java:comp/env/ejb/ LanguageService. The following is a snippet from a deployment plan that maps the EJB reference to an EJB: ejb/LanguageService test simple-app 1.0 simple-ejb.jar LanguageServiceBean [ 107 ]
Java EE Application Deployment
The reference mapped in the deployment plan is injected into the web artifact class at runtime. Here, the servlet field langService is injected with a reference to the LanguageServiceBean. The EJB can be looked up in the web application by using the following code: InitialContext ic = new InitialContext(); ic.lookup("java:comp/env/ejb/LanguageService");
Web deployment plan
The deployment plan for a web application named geronimo-web.xml can be packaged within the WAR file as WEB-INF/geronimo-web.xml or supplied as an external plan file during deployment. The schema geronimo-web-2.0.1.xsd of the deployment plan is shown graphically in the next screenshot:
[ 108 ]
Chapter 5
•
environment: Denotes the environment in which the application executes. This includes the class loading behavior, dependencies, and the module ID of the application. See Appendix A, Deployment plans, for more details.
•
context-root: The context-root that identifies the application. This is the first part of the URL that is used to access the web application. The context-root must start with a '/' and end with a string.
•
work-dir: The work directory name for use by the web application.
•
web-container: The web container in which the application will run.
•
container-config: Geronimo supports both Jetty and Tomcat web containers. This element for the web application needs to take container specific settings. It can hold a Tomcat element, a Jetty element, or both.
•
jndiEnvironmentRefsGroup: This group captures resource mapping to JNDI names. See Chapter 8, Naming and JNDI, for more details.
•
message-destination: message-destination is used to configure a JMS Queue or Topic, which acts like a destination for the messages delivered.
•
security-realm-name: The name of the security realm against which the application will authenticate. See Chapter 6, Security, for more details.
•
security: This is an abstract element that is used to support application level security features, that is, in the actual plan, this element will be replaced by other elements that implement this element.
•
service: This is an abstract element that is provided so that any schema elements that implement this can be used here. For example, the element for declaring GBeans are packaged along with this enterprise application.
•
persistence: Persistence configuration for the application.
[ 109 ]
Java EE Application Deployment
Tomcat specific configuration
Web applications that are intended to be deployed only on Geronimo with Tomcat as a web container can use a deployment plan conforming to the schema geronimo-tomcat-2.0.1.xsd, which is shown in the next screenshot:
The following is an explanation of the elements: •
host: The host element maps the web application to this particular host name.
•
cross-context: The cross-context is an indicative element to specify that the web application will use a dispatch request to other applications, and this cross context should be enabled. [ 110 ]
Chapter 5
•
disable-cookies: The presence of the disable-cookies element indicates that the cookies will not be used by the Tomcat web application and should be disabled.
•
valve-chain: The valve-chain provides the list of first element Tomcat valves chain for this web application.
•
listener-chain: The listener-chain provides the list of first element Tomcat lifecycle listener chains for this web application.
•
tomcat-realm: The tomcat-realm specifies the Tomcat security realm used by this web application.
•
manager: The manager provides the clustering implementation used by this web application.
•
cluster: The cluster provides the name of the cluster that this web application belongs to.
•
jndiEnviromentRefsGroup: The JNDI environment references group elements are used to map the resources to JNDI names. See Chapter 8, Naming and JNDI.
Jetty specific configuration
Web applications that are intended to be deployed only on Geronimo with Jetty as the web container can use a deployment plan conforming to the schema geronimo-jetty-2.0.2.xsd, which is shown in the next screenshot:
[ 111 ]
Java EE Application Deployment
The following is an explanation of the elements: •
host: The host element maps the web application to this particular host name.
•
virtual-host: The virtual-host element maps the web application to this particular host name.
•
session-manager: The session-manager provides the fully-qualified class name of the clustering implementation org.codehaus.wadi.jetty5. JettyManager used by this web application.
•
compact-path: Setting this to true makes paths such as http://localhost:8080/myapp//myresource.htm act the same as http://localhost:8080/myapp/myresource.htm
Sample web application
We have a sample web application named Helloworld-webapp, that has servlets, filters, and listeners. The source code for this application is provided in the samples for this book. After deploying the application, access the application at http:// localhost:8080/helloworld. Enter a name, and click on the getGreeting button. Notice that the output from filter and servlet is displayed in the browser. Also notice the injected values of the country and queue fields that is displayed in the server console window. Access the link http://localhost:8080/helloworld/hello.jsp to see the invocation of various listeners.
EJB applications
EJB applications are packaged as JAR files referred to as EJB JAR files. An EJB application is synonymous with the standalone EJB module (which is not packaged in an EAR). Geronimo provides the ability to deploy standalone EJB modules. The deployment descriptor ejb-jar.xml is packaged in the META-INF directory in the JAR file. As we will see later in this section, ejb-jar.xml may not be required, and the meta information in this case is derived from the annotations. Geronimo integrates OpenEJB to provide EJB3 support. Geronimo/OpenEJB fully supports Container Managed Persistence (CMP), although JPA is considered to be a better approach in Java EE. In this section, we focus on session- and message-driven EJBs.
[ 112 ]
Chapter 5
Annotations
In this section, we examine some annotations used in EJB3 applications. •
Stateless: The @Stateless annotation is used on a stateless session bean class. The name attribute of the annotation is used to specify the name of the EJB. If this attribute is not specified, then the default name of the EJB is the unqualified Java class name of the bean class.
•
Stateful: The @Stateful annotation is used on a stateful session bean class. The name attribute of the annotation is used to specify the name of the EJB. If this attribute is not specified, then the default name of the EJB is the unqualified Java class name of the bean class.
•
PostConstruct: The @PostConstruct annotation is used on a session bean method. This method is invoked after the EJB instance is created and all references have been injected.
•
PreDestroy: The @PreDestroy annotation is used on a session bean method. This method is invoked before the EJB instance is destroyed.
•
PostActivate: The @PostActivate annotation is used on a stateful session bean method. This method is invoked after the container has activated a passivated bean instance. Note that this method is applicable only to stateful session beans.
•
PrePassivate: The @PrePassivate annotation is used on a stateful session bean method. This method is invoked before the container passivated a bean instance. Note that this method is applicable only to stateful session beans.
•
MessageDriven: The @MessageDriven annotation is used on a messagedriven bean class. The name attribute of the annotation is used to specify the name of the EJB. If this attribute is not specified, then the default name of the EJB is the unqualified Java class name of the bean class. The activationConfig attribute of the annotation is used to specify the activation configuration parameters. The activation configuration parameters are specified by using the @ActivationConfigProperty annotation. The @ActivationConfigProperty annotation has two attributes, namely propertyName and propertyValue.
[ 113 ]
Java EE Application Deployment
•
EJB: The @EJB annotation is used on an EJB's fields or setter methods to define an EJB reference. The name attribute specifies the EJB reference name. If the name attribute is not specified, then the default value is class-name/field-name in the case of an annotation on a field, and class-name/property-name in the case of an annotation on a setter method. The EJB can be looked up from the beans context by using the reference name. For example, the EJB reference defined by the following code: @EJB(name="languageService") LanguageService langService;
can be looked up by using the following code: InitialContext ic = new InitialContext(); ic.lookup("languageService");
•
Resource: The @Resource annotation is used to annotate resources such as JMS Connection Factories, JMS Queues, JMS Topics, DataSources, and so on. This annotation can be used on a field or a setter method. The name attribute of the annotation specifies the name that can be used to look up the resource in the bean's context. For example, the @Resource annotation in the following code: @Resource(name="jdbc/ds") private DataSource ds;
results in resources bound in the bean's context at jdbc/ds. The following deployment plan maps the resource: HelloworldBean HelloworldServiceBean jdbc/ds SystemDatasource
Here, the bean's field ds is injected with the physical resource SystemDatasource mapped in the deployment plan.
[ 114 ]
Chapter 5
An @Resource annotation on a field of type Boolean, Byte, Character, String, Short, Integer, Long, Float, or Double will result in an injection of the corresponding env-entry value defined in the deployment descriptor. For example, the @Resource annotation defined in the following code: @Resource(name="country") private String country;
results in the env-entry value defined in the following deployment descriptor being injected into the bean field: HelloworldBean country java.lang.String USA
Here the bean field country is injected with the value USA. The @Resource annotation can be used on a SessionContext field to get the bean's context injected into the field. The following code: @Resource private SessionContext ctx;
results in the bean's context being injected into the field ctx.
[ 115 ]
Java EE Application Deployment
EJB deployment plan
The deployment plan for an EJB module is openejb-jar.xml and is packaged in the META-INF directory in the JAR file. The deployment plan can also be supplied as an external file during deployment. The schema geronimo-openejb-2.0.xsd is shown in the following image:
The following is an explanation of the various elements: •
environment: This element specifies the Geronimo environment for the EJB module. See Appendix A, Deployment Plans, for more details.
•
jndiEnviromentRefsGroup: The JNDI Environment references group elements are used to map the resources to JNDI names. See Chapter 8, Naming and JNDI, for more details. [ 116 ]
Chapter 5
•
message-destination: This element is used to configure references to a JMS queue or topic which are actually message destinations.
•
web-service-binding: This element provides the address and security information of the web service that is implemented by this EJB.
•
security: This is an abstract element that will be used for supporting application level security features, that is, in the actual plan, this element will be replaced by other elements that implement this element.
The schema openejb-jar-2.2.xsd of the EJB deployment plans is shown in the figure below:
The following is an explanation of the various elements: •
ejb-ql-compiler-factory: Specifies the fully-qualified class name of a Java class that can compile EJB-QL (Query Language) queries into SQL statements for a particular database product. This class must implement org.tranql.sql.EJBQLCompilerFactory.
•
db-syntax-factory: Specifies the fully-qualified name of a Java class that can customize CMP SQL statements for a particular database product. This class must implement org.tranql.sql.DBSyntaxFactory.
•
enforce-foreign-key-constraints: If this element is present, then Geronimo will execute insert, update, and delete statements in an order consistent with the foreign keys between tables. If this element is not present, then Geronimo may execute the statements in any order, but within the same transaction.
[ 117 ]
Java EE Application Deployment
•
enterprise-beans: This element is used to specify the references by entity, session, and message driven beans.
•
relationships: This element is used to map the container-managed relationships defined in the deployment descriptor to a specific database.
The following are the common elements under enterprise-beans: •
ejb-name: Specifies the name of the EJB to which the configuration applies. This must match the name specified by ejb-name under the deployment descriptor.
•
jndi-name: The name at which the home interface of the EJB is registered in the JNDI. This is applicable only if the EJB has a remote home interface.
•
local-jndi-name: The name at which the local home interface of the EJB is registered in the JNDI. This is applicable only if the EJB has a local home interface.
•
tss-link and tss: These elements are used to specify the CORBA security settings. This is applicable if the EJB is to be accessed over CORBA. See Chapter 7, CORBA, for more details on these elements.
Sample EJB application
The sample EJB application that we have provided has two session beans, namely, HelloworldBean and LanguageServiceBean, and a Message Driven Bean, namely, SampleMDB. The deployment descriptor for this application is given below: HelloworldBean sample.ejb3.HelloworldServiceBean postConstruct country java.lang.String USA [ 118 ]
Chapter 5
Note that this deployment descriptor adds to the metadata obtained through annotations in the java code of the beans. The deployment plan for this application is given below: test simple-ejb 1.0 jar org.apache.geronimo.configs system-database car packt-samples jms-resources rar HelloworldBean HelloworldServiceBean jdbc/ds SystemDatasource SampleMDB [ 119 ]
Java EE Application Deployment jms-resources
The JMS resources required by the MDB are deployed in the packt-samples/jmsresources/1.0/rar module. Notice that a dependency on this module is declared in the deployment plan.
Deploy the JMS resources
In order to run the sample EJB application, you must first deploy the JMS resources required by the Message Driven Bean. In order to do so, we deploy
\repository\org\apache\geronimo\modules\geronimoactivemq-ra\2.1.4\geronimo-activemq-ra-2.1.4.rar with the jmsresources.xml plan, provided under the samples.
Deploy the EJB sample
After deploying the JMS resources, deploy the EJB sample application sample-ejb.jar, provided under the samples.
Deploy the Web application
To test the sample EJB application, we have provided a sample web application named helloworld-web.war that has a servlet to invoke the EJBs and post messages to the message-destination configured with SampleMDB. Once deployed, we can access the application at http://localhost:8080/helloworld.
JPA Applications
The Java Persistence API (JPA) is a new programming model under the EJB3.0 specification for the management of persistence and object or relational mapping with Java EE and Java SE. With JPA, you can easily develop java applications that perform operations on an RDBMS by using java objects and mapping. In that way, java applications developed using JPA are not only portable across different platforms, but applications can also be easily developed by using simple yet powerful programming models that are provided by JPA. JPA insulates applications from all of the complexity and non-portable boilerplate code involved in database connectivity and operations. Geronimo integrates OpenJPA as the JPA provider for applications deployed in Geronimo. [ 120 ]
Chapter 5
The schema diagram of persistence_1_0.xsd is shown in the following figure:
A persistence unit is defined by using the persistence-unit element. Child elements of a persistence-unit are given below: •
description: A description of the persistence unit.
•
provider: The fully-qualified name of a provider class that supplies instances of EntityManager for this persistence unit.
•
jta-data-source: Container-specific name of the JTA DataSource to use.
•
non-jta-data-source: Container-specific name of the non-JTA DataSource to use.
•
mapping-file: File containing the mapping information.
•
jar-file: JAR file that should be scanned for entities.
•
class: Class to scan for annotations.
•
exclude-unlisted-classes: When this value is set to true, only the listed JARs and classes will be scanned for persistent classes. Otherwise, the enclosing JAR or directory will also be scanned.
•
properties: A list of vendor-specific properties as name/value pairs, specified as attributes in a property element.
The persistence.xml file is located under the META-INF directory of the EJB JAR file.
[ 121 ]
Java EE Application Deployment
Annotations
In this section, we will look at some annotations used in Container Managed Persistence (CMP) and Bean Managed Persistence (BMP) bean classes using JPA. •
Entity: The @Entity annotation is used on a POJO class that has at least one field or getter method that is annotated with the @Id annotation.
•
Id: The @Id annotation is used to annotate the field or getter method that specifies the primary key of the entity.
•
Table: The @Table annotation is used to specify the database table to which the entity bean will be mapped.
•
Column: The @Column annotation is used to specify the column to which the property is mapped.
•
GeneratedValue: The @GeneratedValue annotation is used to indicate that the container or the database will generate a value when a new entity instance is created.
•
PersistenceContext: The @PersistenceContext annotation is used to specify a dependency on a container-managed EntityManager persistence context.
•
PersistenceUnit: The @PersistenceUnit annotation is used to specify a dependency on an EntityManagerFactory. This annotation gives more control over the lifecycle of the EntityManager than the @PersistenceContext annotation does, in that the application, rather than the container, can create and destroy EntityManager instances.
Container-managed persistence
The use of @PersistenceContext on an EntityManager field results in an instance of a container-managed EntityManager being injected by the container. The EntityManager's persistent context propagates along with any active transactions; therefore, all references to EntityManager corresponding to the same persistence unit will have the same persistence context throughout the transaction. The lifecycle of the entity manager and the corresponding persistence context is managed by the container.
CMP sample application
The sample library application demonstrating Container Managed Persistence contains two entity classes, namely, Member and Book, along with a stateless session bean named LibraryBean. The session bean implementation class is shown below: @Stateless public class LibraryBean implements Library { [ 122 ]
Chapter 5 @PersistenceContext(type=PersistenceContextType.TRANSACTION) private EntityManager em; public void addBook(String name, String author) { Book book = new Book(); book.setBookId((int)System.nanoTime()); book.setName(name); book.setAuthor(author); em.persist(book); } ... }
Notice that the EntityManager will be injected by the container into the session bean field em. The default persistence scope of a container-managed EntityManager is TRANSACTION, and the transaction-type is JTA. The persistence.xml file for this application is as given below: CMP w JPA org.apache.openjpa.persistence.PersistenceProviderImpl LibraryDS sample.jpa.Member sample.jpa.Book
Notice that the two entity classes—Member and Book—associated with the persistence unit MembersUnit. The deployment plan openejb-jar.xml is as given below: packt.samples cmp-jpa-ejb [ 123 ]
Java EE Application Deployment 1.0 jar console.dbpool LibraryDS rar
Notice that the deployment plan defines a dependency on the database pool LibraryDS. To run the sample application, we first need to create a database and a database pool. In order to do so, create a database with the name LIBRARYDB by using the DB Manager portlet. Then deploy the database pool by using \
repository\org\tranql\tranql-connector-derby-embed-local\1.4\tranqlconnector-derby-embed-local-1.4.rar as the archive, and library-ds.xml as the plan file. Then deploy the cmp-jpa-ejb.jar, followed by cmp-ejb-web.war. Finally, access the URL http://localhost:8080/library/LibraryServlet?op= commit. We can now verify that two entries were added to the MEMBERS table and
one entry has been added to the BOOKS table in LIBRARYDB.
Bean-managed persistence
The use of @PersistenceUnit annotation on the EntityManagerFactory field results in the container injecting an EntityManagerFactory. The EntityManager is created from the EntityManagerFactory. The EntityManager's persistent context does not propagate with any active transactions. Therefore, the references to EntityManager corresponding to the same persistence unit will have a different persistence context across different components, which means that the modifications done to entities through one entity manager reference are not visible through the other entity manager references. The default persistence scope of the application-managed entity manager is EXTENDED. The transaction-type can be one of the JTA, in which case the EntityManager can join a transaction by calling the joinTransaction() method, or RESOURCE_LOCAL, in which case the EntityManager does not join the transaction. The lifecycle of the entity manager is not managed by the container, and it is the responsibility of the application to destroy the entity manager objects.
[ 124 ]
Chapter 5
BMP sample application
The sample library application demonstrating Bean-Managed Persistence contains two entity classes, namely, Member and Book, and a stateless session bean named Library2Bean. The session bean implementation class is shown below: @Stateless @TransactionManagement(TransactionManagementType.CONTAINER) public class Library2Bean implements Library { @PersistenceUnit(unitName="LibraryUnit") private EntityManagerFactory emf; private EntityManager em; @PostConstruct public void init(){ em = emf.createEntityManager(); } @PreDestroy public void destroy(){ em.close(); } public void addBook(String name, String author) { em.joinTransaction(); Book book = new Book(); book.setBookId((int)System.nanoTime()); book.setName(name); book.setAuthor(author); em.persist(book); } ... }
Notice that the EntityManagerFactory will be injected by the container into the session bean field emf. The session bean creates the EntityManager instance in the init() method and closes the EntityManager in the destroy() method. Also, notice that the business methods invoke joinTransaction() to join the transaction. The persistence.xml file for this application is as given below: BMP w JPA org.apache.openjpa.persistence.PersistenceProviderImpl [ 125 ]
Java EE Application Deployment LibraryDS sample.jpa.Member sample.jpa.Book
Notice the two entity classes Member and Book that are associated with the persistence unit LibraryUnit. The deployment plan openejb-jar.xml for this application is given below: packt.samples bmp-jpa-ejb 2.0 jar console.dbpool LibraryDS rar
This application also uses the same LibraryDS database pool as the CMP sample application. Therefore, we do not need to create a new database and database pool. To run the application, first deploy bmp-jpa-ejb.jar and then deploy bmp-ejbweb.war. Access the URL http://localhost:8080/library2/LibraryServlet? op=commit. We can now verify that two entries were added to the MEMBERSBMP table and one entry was added to the BOOKSBMP table in LIBRARYDB.
[ 126 ]
Chapter 5
Enterprise applications
Enterprise applications are packaged in EAR files or Enterprise Archives. An Enterprise application can contain any number of modules, which can be of any of the four Java EE types, namely, Web Module, EJB Module, Application Client Module, or Connector Module. They can also have a lib directory containing common libraries that are used by more than one of the modules. Enterprise applications generally package all of the modules together, and the modules can either have their own individual deployment plans packaged inside them or there can be one plan for the enterprise application that includes the deployment plans for all of the modules. In this section, we will examine the Geronimo-specific deployment plan for an enterprise application. We will then go through deploying a sample enterprise application, and also explain the application's Geronimo-specific deployment plan.
Deployment plan
The schema of the deployment plan for an enterprise application is shown graphically in the following figure:
[ 127 ]
Java EE Application Deployment
The deployment plan consists of the following elements: •
environment: Denotes the environment in which the application executes, which includes the class loading behavior, dependencies, and the module ID of the application. See Appendix A, Deployment Plans, for more details.
•
module: Denotes the modules that make up this enterprise application and that are included in the EAR file. There are elements for each type of module that can be present inside an EAR. These are: connector (for JCA Connector modules), ejb (for EJB modules), java (for Application clients), and web (for Web modules). Each of these module elements will contain the path to the module and the optional alt-dd element (alternate location of deployment descriptor inside the EAR). This is shown in the following image:
•
ext-module: Denotes the modules that make up this enterprise application that are external to the enterprise application, that is, modules that are not defined in the Java EE-specific deployment descriptor for the application. This is shown in the following image:
[ 128 ]
Chapter 5
The elements that make up the ext-moduleType are, for the most part, the same as the ones for the moduleType. The main difference is that instead of the alt-dd element, we will have either an internal-path element or an external-path element, which give the path to the external module. •
security: This is an abstract element that will be used for supporting application-level security features, that is, in the actual plan, this element will be replaced by other elements that implement this element.
•
service: This is an abstract element that is provided so that any schema elements that implement this can be used here, such as the element for declaring Gbeans that are packaged along with this enterprise application.
Application clients
Application clients are the client applications that are also Java EE components. They differ from Java clients that have access to the server environment and run inside a client container. The client container runs in a separate JVM instance and can be started from the command line. Application clients can be used for administration of the application that is deployed on the server, and can provide a rich client [ 129 ]
Java EE Application Deployment
experience. Access to the server environment means that the application client has access to server-provided services such as the JNDI component context, security, and so on. It also provides access to administered objects and connection factories deployed on the remote server instance. Thus, it can access database pools and JMS resources configured on the server. In this section, we will first look at the elements that make up the Apache Geronimo-specific application client deployment plan. We will then look at an application client and how to run it.
Deployment plan
The schema of the application client deployment descriptor is shown in the following figure:
[ 130 ]
Chapter 5
The deployment plan needs to be packaged along with the Java EE-specific deployment descriptor in the META-INF directory of the application client JAR file. It can also be included in the Apache Geronimo-specific application deployment plan if the application client is packaged along with the application in the application's EAR file. You can also specify the plan separately during the deployment of the application client, in which case there are no restrictions on the filename. The elements in the deployment plan are given below: Pictorial representations are only provided for elements that are unique to the application client deployment plan. For common elements, the pictorial representations can be found in Appendix A, Deployment Plans.
•
server-environment: This defines the server-side module environment settings for the application client. It consists of the following sub-elements:
°
moduleId: The ID of the server-side module.
°
dependencies: Server-side dependencies that the application client has.
°
hidden-classes: Classes that should be hidden from the parent class loaders so that they are picked up from the current module's class loader.
°
non-overridable-classes: Classes that cannot be overridden by the user and will always follow the parent-first delegation method. [ 131 ]
Java EE Application Deployment
°
inverse-classloading. If this element is present, the classes will be loaded with a child-first class loading policy, whereas, when it is not present, the classes will be loaded with a parent-first policy.
°
suppress-default-environment: This is an element that is not recommended to be used as it may give unpredictable results.
•
client-environment: This is the environment that the client container should provide for the application client to execute in. The elements inside this element are similar to the ones inside the server-environment element. The only difference is that they represent client-side artifacts.
•
gbean-ref: This element is used to map Gbean references to actual Gbeans that are deployed on the server. The diagrammatic representation of this element is given in Appendix A, Deployment Plans.
•
ejb-ref: The element ejb-ref is used to map EJB references to EJBs deployed in the server using the remote home and remote interface. The application that contains the EJB being referenced should be included in the dependency list of the application client's server environment. Also note that as the EJBs referenced are in a different JVM, all of the client interfaces should also be included in current application.
•
service-ref: This element is used to map service references to web services that are deployed on the server.
•
resource-ref: This element is used to map resource references to resources that are available on the server. The resources can be JDBC DataSources, JMS connection factories, or any other type that can be configured on the server. These resources are configured on the server side by using resource adapters. [ 132 ]
Chapter 5
•
resource-env-ref: This element is used to map resource-env-ref elements to administered objects that are deployed on the server.
•
message-destination: This element is used to configure references to a JMS queue or topic, which are actually message destinations. All of the references actually contain information that the client container needs to map the names to actual resources and Java EE components in the server so that it can make these resources or components available in the JNDI context for the application client.
•
default-subject: This is the subject that would be used for authentication by the client when no subject is provided.
•
realm-name: This is the name of the security realm that is configured in the server that the application client will use for validating the supplied JAAS login credentials.
•
callback-handler: This is the fully-qualified name of the JAAS callback handler class. This class should implement the javax.security.auth. callback.CallbackHandler interface, and have a no arg constructor. It will be instantiated and used to collect authentication information from the user.
•
resource: This element is used to define any module-scoped resources. The resource can be either external or internal to the application client. The connector element contains the plan for configuring the resource adapter. The pictorial representation is shown in the following figure:
[ 133 ]
Java EE Application Deployment
•
service: This is an empty generic element that can be extended by other modules. This is imported from the geronimo-module-1.2.xsd schema.
JavaMail
Apache Geronimo comes with its own JavaMail implementation. It makes a global mail session available to users, at the JNDI location ger:/MailSession. By default, the server provides support for email through the SMTP protocol. Other protocols, such as POP3 and IMAP, are also supported with a bit of configuration. The configuration of the default global mail session is shown below: smtp ger:/MailSession localhost 25
These attribute values can be overridden in the config.xml and config-substitutions.properties files. The entry in config.xml is shown next. The values of the variables ${SMTPHost} and ${SMTPPort} are given in config-substitutions.properties, and can also be overridden there. ${SMTPHost} ${SMTPPort}
You can also specify application-specific JavaMail session objects by adding the MailGBean and SMTPTransportGBean to the deployment plan of the application. The host, port, and jndiName values can be changed to reflect the settings for the application-specific mail session. Another thing to note is that the support for POP3 and IMAP protocols can be enabled by adding the protocol GBean and the respective store GBeans to the deployment plan of the application or to the global JavaMail configuration. The GBeans that need to be added are POP3StoreGBean, IMAPStoreGBean, and ProtocolGBean.
[ 134 ]
Chapter 5
Web Services
Java EE 5 supports two types of web services, namely POJO web services and EJB web services. The only element that we need to add to the Apache Geronimo deployment plan is a service-ref element, which is required to map the web service proxy to a JNDI location. Thus, in order to create a Java EE web service in Apache Geronimo, we do not need to add entries in the server-specific deployment plans. This element, and the sub-elements that comprise it, are shown in the following four figures:
The following figure shows the service-completion Type element:
The following figure shows the port-completion Type element:
[ 135 ]
Java EE Application Deployment
The following figure shows the port Type element:
The elements in the service-ref element are explained below: •
service-ref-name: The name of the service reference. This name will be the name under which the web service proxy object will be bound in the local JNDI context of the application or component.
•
service-completion: This element is used in case only a partial WSDL is available for the service that we are trying to reference. It contains information that is not present in the WSDL, but that is required to access the web service. It contains the following elements: °
service-name: This is the name of the service that this service-completion element provides information for.
°
port-completion: Information about the ports and their bindings. This element consists of the following two subelements: °
binding-name: The name of the binding for which this port-completion element provides information.
°
port: Information about the port, which overrides or augments the information that is given in the WSDL. This element is the only element required if we have a completed WSDL.
[ 136 ]
Chapter 5
•
port: This element maps the ports in the WSDL to their actual physical locations. °
port-name: Name of the port that is being mapped
°
protocol: The protocol that is required to be used to access this web service
°
host: The host on which this web service resides
°
port: The TCP/IP port on the host where the web service can be accessed
°
uri: The URI of the service
°
credentials-name: The name of the login module that will store the username and password of the current user Applications deployed on Apache Geronimo are capable of accessing secured web services, which needs the clients to be authenticated. To access such web services, a new login module needs to be used, that is, org.apache.geronimo.security.realm.providers. NamedUsernamePasswordCredentialLoginModule.This security realm saves the credentials of the current user, and then later in the service-ref element we need to specify the credentials-name element to match the name attribute of this login module.
EAR sample application
We will now show the deployment of a sample application that sets up an application-specific JavaMail session, and also declares an EJB web service. The application is a part of a library management system that does the following: •
Lists the books that have been lent to members of the library
•
Sends a mail to each of the members that have a book in their possession with the due dates and fine information
The two use cases can be executed from a web client using a JSP and the second use case can also be executed from a Java EE Application client. The application will send mails through an EJB component which will also be a web service. The books and the information on the members will be picked from a database by using a servlet and JDBC. We will be discussing the plans of the application, along with the output, below. The application is present in the samples/LibraryApp directory. The application consists of the following modules:
[ 137 ]
Java EE Application Deployment
•
web: This consists of a JSP, namely, list.jsp, which lists the members and the books lent to them. It also contains two servlets, namely, ListServlet and PopulateDBServlet. The context-root of the application is /LibraryApp, and the mappings of the servlets are /list and /SetupDB. The PopulateDBServlet should be called once after installation to create and populate the database. The ListServlet can be used to list the members and the books lent to them. It can also be made to send a mail to all of the members by passing the parameter sendMail=true in the request.
•
EJB: This consists of the MailBean stateless session bean and its local and remote business interfaces. The remote business interface is also configured to be the service interface, and this bean is exposed as a web service.
•
client: This consists of the application client that will consume the webservice MailService that is exposed by the previous module, and uses it to send mails to the member regarding the books that they have borrowed from the library.
All of the above modules are packaged into an EAR file, and the plan for this file is shown in the listing below. … LibraryApp-web-1.0.war /LibraryApp jdbc/DataSource DerbyTestPool LibraryApp-ejb-1.0.jar MailBean /Mail/MailService jdbc/DataSource DerbyTestPool [ 138 ]
Each of the module elements encapsulates a plan for one of the modules (web, EJB, or appclient). In the case of the web module, there is a resource-reference to jdbc/DataSource that is mapped to an actual database pool that we define later in the plan, namely, DerbyTestPool. In the EJB module's plan, we override the location of the web service it exposes (which is optional) and also map the same resource-reference. In the application client's deployment plan, we map a service-reference to the location of the service. You can see the JavaMail configuration in the following plan: … smtp mail/MailSession mail.debug=true
[ 139 ]
Java EE Application Deployment mail.smtp.host=127.0.0.1 mail.smtp.auth=false mail.smtp.port=25 JavaMailProtocol.smtp localhost 25
Deploying an EJB web service
In order to deploy an EJB as a web service, you do not need to make any changes to the Geronimo-specific deployment descriptor. You can override the location where the web service will be deployed through the web-service-address tag, as shown in the plan. All of the other configuration can be performed via annotations. These are shown in the sample code below: package com.packtpub.library.ejb; import javax.annotation.Resource; import javax.ejb.Stateless; import javax.jws.WebMethod; import javax.jws.WebService; import javax.mail.Session; import javax.sql.DataSource; import com.packtpub.library.ListUtility; @Stateless(name="MailBean") @WebService(serviceName = "MailService", portName="MailServiceSOAP11port", // endpointInterface = "com.packtpub.library.ejb.MailBusinessRemote", targetNamespace = "http://ejb.library.packt.com", wsdlLocation = "META-INF/wsdl/MailService.wsdl") public class MailBean implements MailBusinessRemote, MailBusinessLocal{ @Resource(name="mail/MailSession") Session mailSession; @Resource(name="jdbc/DataSource") private DataSource ds; @WebMethod [ 140 ]
You can see the interface and the EJB that has been annotated with the metadata that is required to expose them as a web service. Apache Geronimo has the capability to generate the WSDL from this, or you can also use Ant/Maven/Eclipse plugins of the Axis2 java2wsdl tooling. For more samples, please refer to the Geronimo documentation. When deploying this application, start the server with the property org.apache.geronimo.jaxws.builder.useSimpleFinder set to true. For example: java -Dorg.apache.geronimo.jaxws.builder. useSimpleFinder=true -Djava.endorsed.dirs=lib/endorsed -javaagent:bin/jpa.jar -jar bin/server.jar.
This is a workaround for a defect that exists in the server that throws an ArrayIndexOutOfBoundsException, and that is tracked here: https://issues.apache.org/jira/browse/GERONIMO-4243
[ 141 ]
Java EE Application Deployment
Transactions
A transaction is often defined as an indivisible unit of work. Transactions are used to maintain the integrity of data in business applications. A transaction can end either in a commit or in a rollback. A transaction that ends in commit will result in saving the data modifications done by its component statements. A transaction ends in rollback if any of its component statements fail. Data modifications are not saved in this case. In case of an EJB, how the beginning and ending of transactions—referred to as transaction boundaries—are set is determined by specifying whether the EJB uses containermanaged or bean-managed transactions. The type of transactions used by the EJB is specified by using the transaction-type element in the EJB deployment descriptor, or by using annotations, as discussed later in this section. The following XML fragment is an example of a session bean using container-managed transactions. HelloworldBean Container ...
Container-managed transactions
In an EJB with container-managed transactions, the transaction boundaries are set by the EJB container. Typically, the EJB container starts a transaction immediately before the execution of the EJB's method, and ends the transaction immediately after the EJB's method execution ends. Each method can run within a single transaction. Container-managed transactions do not require all EJB methods to be associated with transactions. The EJB methods associated with transactions are specified by setting transaction attributes. The scope of the transaction is controlled by transaction attributes. A transaction attribute can have one of the following values: •
Required: If the client is running within a transaction and invokes the EJB's method, then the method executes within that transaction. Otherwise, the container starts a new transaction before executing the EJB's method.
•
RequiresNew: If the client is running within a transaction and invokes the
EJB's method, then the container suspends that transaction, starts a new transaction to execute the EJB's method, and resumes the client's transaction upon the method completion. Otherwise, the container starts a new transaction before executing the EJB's method. [ 142 ]
Chapter 5
•
Mandatory: If the client is running within a transaction and invokes the EJB's method, then the method executes within that transaction. Otherwise, the container throws a TransactionRequiredException.
•
Supports: If the client is running within a transaction and invokes the EJB's method, then the method executes within that transaction. Otherwise, the container does not start a new transaction before executing the EJB's method.
•
NotSupported: If the client is running within a transaction and invokes the
•
Never: If the client is running within a transaction and invokes the EJB's method, then the container throws a RemoteException. Otherwise, the
EJB's method, then the container suspends that transaction before invoking the method, and then resumes the transaction after the method completes. Otherwise, the container does not start a new transaction before executing the EJB's method.
container does not start a new transaction before executing the EJB's method. A container-managed transaction is rolled back in the following two ways: •
By throwing a SystemException or RuntimeException: In this case, the EJB container automatically rolls back the transaction.
•
By invoking the setRollbackOnly() method of the EJB context: By calling this method of the EJB context, the EJB's method instructs the EJB container to rollback the transaction.
Annotations
Transaction attributes can be set by using deployment descriptor or using annotations.
TransactionManagement
The @TransactionManagement annotation is used to specify how the transactions are managed for the EJB. The value attribute of the annotation determines whether the EJB uses container-managed transactions or bean-managed transactions. If the value attribute is set to TransactionManagementType.CONTAINER, then the EJB uses container-managed transactions. If the value attribute is set to TransactionManagementType.BEAN, then the EJB uses bean-managed transactions. The default value of the value attribute is TransactionManagementType.CONTAINER.
[ 143 ]
Java EE Application Deployment
TransactionAttribute
The @TransactionAttribute annotation is used to specify the transaction attribute for an EJB or for individual methods of the EJB. The value attribute of the annotation determines the transaction attribute. A value of TransactionAttributeType. REQUIRED corresponds to transaction attribute Required from the previous section. A value of TransactionAttributeType.REQUIRED_NEW corresponds to transaction attribute RequiredNew. A value of TransactionAttributeType. MANDATORY corresponds to transaction attribute Mandatory. A value of TransactionAttributeType.SUPPORTS corresponds to transaction attribute Supports. A value of TransactionAttributeType.NON_SUPPORTED corresponds to transaction attribute NotSupported. A value of TransactionAttributeType. NEVER corresponds to transaction attribute Never. The default value is TransactionAttributeType.REQUIRED.
Bean-managed transactions
Unlike the container-managed transactions, where the EJB container demarcates the transaction, in bean-managed transactions, the session and message-driven beans explicitly demarcate the transaction in the code. A problem with containermanaged transactions is that an executing method can be associated with at most one transaction. Bean-managed transactions help overcome this problem and provide a finer-granulated control. You can use either JTA or JDBC transactions for bean-managed transactions. JDBC transactions are controlled by the transaction manager of the DBMS. The end of a transaction is marked by calling the commit or rollback method of the database connection. A transaction begins implicitly with the first SQL statement after the most recent connect, commit, or rollback statement. The Java Transaction API allows demarcation of transactions in transaction manager in an implementation independent way. JTA transactions are controlled by the Java EE transaction manager. JTA transactions are demarcated by invoking the begin, commit, and rollback methods of javax.transaction.UserTransaction interface. A bean instance can obtain the UserTransaction object by calling the EJBContext.getUserTransaction(). When using bean-managed transactions with a stateless session bean, the business method must end the transaction by committing or rolling back the transaction.
[ 144 ]
Chapter 5
In the case of a stateful session bean using a JTA transaction, the transaction is associated with the bean instance across multiple client calls. Even if the business method that is called opens and closes the database connection, the association remains in existence until the bean instance completes the transaction. In the case of a stateful session bean using JDBC transactions, the association between the transaction and the bean instance is retained by the JDBC connection across multiple client calls unless the connection is closed.
Support in Geronimo
Geronimo supports both user-managed and container-managed transactions. Geronimo provides an implementation of JTA v1.1. The connection managers in Geronimo can be configured for no transaction support, local transactions, or XA transactions. XA transactions involve more than one resource.
Setting transaction timeout
For transactions using JTA, UserTransaction.setTransactionTimeout() can be used to specify the maximum duration in seconds for which the transaction will run before aborting.
Transaction isolation levels
The transaction isolation level defines the level of visibility of the data modified during one transaction to the other transactions. The possible isolation levels are: •
Serializable: In this isolation level, the transactions execute as if they are executing one after another, serially rather than concurrently. This is the strictest isolation level.
•
Repeatable read: In this isolation level, the transaction can access the same row data repeatedly, with the certainty that it has not been modified by other transactions.
•
Read committed: In this isolation level, the transactions may read only data committed to the database.
•
Read uncommitted: In this isolation level, the transactions can read data from uncommitted changes by other transactions.
[ 145 ]
Java EE Application Deployment
The transaction isolation level can be set by calling the setTransactionIsolation() method on the Connection object, with the parameter value Connection. TRANSACTION_SERIALIZABLE, Connection.TRANSACTION_REPEATABLE_READ, Connection.TRANSACTION_READ_COMMITTED, or Connection.TRANSACTION_READ_ UNCOMMITTED. These values correspond to the Serializable, Repeatable read, Read committed, and Read uncommitted isolation levels respectively.
Transactions in web applications
Transactions in web application components can be demarcated using either javax.transaction.UserTransaction (that is, JTA) or java.sql.Connection (that is, JDBC). The UserTransaction object can be looked up in the JNDI by using java:comp/UserTransaction. The beginning of the transaction is marked by calling the begin() method of the UserTransaction object. The end of the transaction is marked by calling the commit() method, in which case the transaction is committed, or by calling the rollback() method, in which case the transaction is rolled back. In the case of JDBC transactions, the beginning of the transaction is implicitly marked with the first SQL statement after the most recent connect, commit, or rollback. The end of the transaction is marked by calling the commit() method on the connection, in which case the transaction is committed, or by calling the rollback() method on the connection, in which case the transaction is rolled back. The following is the LibraryServlet from the cmp-jpa-web.war used with the CMP JPA application above: /** * Library servlet */ public class LibraryServlet extends HttpServlet { @EJB Library library; @Override protected void service(HttpServletRequest request, HttpServletResponse response) throws IOException { UserTransaction tx = null; try { InitialContext ic = new InitialContext(); tx = (UserTransaction)ic.lookup("java:comp/UserTransaction"); } catch (NamingException e) { e.printStackTrace(); } response.setContentType("text/plain"); PrintWriter out = response.getWriter(); try { [ 146 ]
Notice that the servlet obtains the user transaction object through JNDI lookup. Also, notice that the transaction is committed only when the op parameter is specified as commit. Otherwise, the transaction is rolled back. We can verify that the database table is updated only when the transaction is committed.
[ 147 ]
Java EE Application Deployment
Summary
In this chapter, we have discussed the various methods of deploying Java EE applications. We have discussed the Java EE-specific deployment descriptors for web, EJB, and EAR applications, and Geronimo-specific deployment plans for mapping the resources defined in the deployment descriptors. We have shown how to create POJO web services and EJB web services. We have also covered JPA with Container Managed Persistence and Bean Managed Persistence. We have discussed how to use container-managed transactions and user-managed transactions. In the next chapter, we will look at one of the most important topics, namely security. We will discuss the different security mechanisms that Apache Geronimo provides to secure your Geronimo server and your enterprise applications.
[ 148 ]
Security Security is one of the important aspects of any Java EE server. Geronimo has a rich set of features that meet the security requirements for Java EE 5 compliance. In this chapter, we look at various aspects of security, namely, securing the server environment, various components on the server, such as the embedded database and so on, and securing the applications deployed on the server. You will learn about: •
The security standards implemented by Geronimo
•
Configuring the administrator access to the Geronimo server
•
Securing the embedded Derby database
•
Cryptographic security features provided by Geronimo
•
JAAS login modules implemented by Geronimo
•
Creating security realms
•
Creating credential stores
•
Configuring web, EJB, and EAR application security
•
Configuring Single sign-on (SSO)
Overview of security standards
Geronimo uses Java Authentication and Authorization Service (JAAS) login modules for user authentication and Java Authorization Contract for Containers (JACC), for authorization to server resources. Geronimo uses the Common Secure Interoperability Version 2 (CSIv2) protocol to support secure EJB access using CORBA.
Security
Java Authentication and Authorization Service (JAAS)
The Java Authentication and Authorization Service (JAAS) implements a Java version of the standard Pluggable Authentication Module (PAM) framework. JAAS simplifies Java security development by introducing an abstraction layer between the application and the underlying authentication mechanisms, thereby enabling applications to be independent from the authentication mechanism. This enables us to plug in new or updated authentication mechanisms without requiring modifications to the application. Applications initiate authentication by instantiating a LoginContext object, which in turn references a configuration that determines the authentication mechanisms or login modules to be used in performing the authentication. If authentication is successful, then the login modules update the JAAS subject with relevant principals and credentials, which are then used to make authorization decisions. Geronimo provides several JAAS login module implementations and principal and credential classes to easily configure security for applications deployed in Geronimo.
Java Authorization Contract for Containers (JACC)
The Java Authorization Contract for Containers (JACC) specification, JSR-115, defines new java.security.Permission classes to satisfy the Java EE 5 authorization model. JACC allows authorization decisions to be made based on these permission classes. Geronimo provides an implementation of JACC v1.1.
The Common Secure Interoperability Version 2 (CSIv2) protocol
The Common Secure Interoperability Version 2 (CSIv2) protocol is a protocol for implementing security features for inter-ORB communication. Geronimo integrates Apache Yoko in order to support CSIv2.
Securing the server directory
The first step towards securing the Geronimo server environment is to secure access to the server installation directory, which we refer to as . Some of the directories under that contain sensitive information are:
[ 150 ]
Chapter 6
•
var/config: .The config.xml file under this directory may contain passwords and so on.
•
var/security: This directory contains users.properties and groups. properties files which contain the user credentials used by the default security realm, geronimo-admin.
•
var/security/keystores: This directory contains cryptographic keystore
files used by the server.
•
var/derby: This directory contains the databases created when using embedded Derby database server. This directory may also have a derby.properties file containing user IDs and passwords for accessing the databases.
•
var/repository: The configuration directories created during deployment may have deployment plans, packaged as part of the archives, which contain passwords in clear text. Also, the config.ser files created during deployment may contain passwords in serialized java objects.
It is recommended to use the operating system provided security to restrict user access to the directory on the filesystem.
Securing the Administration Console, JMX server, and deployer
Access to the Administration Console, JMX server, and deployer is controlled by using the default security realm geronimo-admin. This realm uses the /var/security/users.properties file to store usernames and passwords, and the /var/security/groups.properties file to store group information for users. By default, this realm has one user, system, with a password of manager, and belonging to the admin group. Any user belonging to the admin group will have access to the Admininistration Console, JMX server, and deployer. The default credentials can be changed in the following ways: •
Edit the /var/security/users.properties file. The format of this file is one entry per line, in the form 'username=password'.
[ 151 ]
Security
•
Users and Groups portlet: Access this portlet in the Administration Console by using the user system and password manager to log in, and change the password for user system by clicking on the Edit link, as shown in the following screenshot:
Make sure that access to users.properties and groups.properties is controlled by using OS provided security features.
Securing the embedded Derby database
By default, the embedded Derby database server does not use authentication for database connections. Security for the Derby database can be enabled by creating a derby.properties file under the /var/derby directory. The contents of a sample properties file are shown below: derby.connection.requireAuthentication=true derby.authentication.provider=BUILTIN derby.user.userName1=password1 derby.user.userName2=password2 [ 152 ]
Chapter 6
Here, the authentication mechanism used is BUILTIN, whereby the usernames and passwords are specified in the properties file itself. The authentication methods that can be used are: •
BUILTIN—User credentials are specified in the derby.properties file
•
LDAP—Configure an LDAP server for authentication
•
User defined—Class should implement org.apache.derby.authentication.UserAuthenticator
In derby.properties, two users—"userName1" with password "password1" and "userName2" with password "password2" are created. Users can also be configured at the database level by using stored procedures. The following is an example of such a stored procedure: CALL SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY ('derby.user.userName3', 'password3')
By executing the stored procedure as shown, a user with a name of "userName3" and a password of "password3" is created.
Updating database pools
Once security is enabled for the embedded Derby database server, the pre-configured user credentials in the database pools using the databases in the Derby server should be updated to reflect the new credentials. This can be done in one of two ways: •
Before enabling Derby security, update the credentials by using the Database Pools portlet in the Administration Console and then enable Derby security, as discussed earlier.
•
Enable Derby security, edit the config.xml file to update the credentials, and then start Geronimo. The XML fragment to update credentials in a database pool is shown later in this section. Note that the config.xml file should be edited only when the server is stopped. Otherwise the changes will be lost.
The database pools that need to be updated are as follows: •
MonitoringClientDS
•
NoTxDatasource
•
SystemDatasource [ 153 ]
Security
•
jdbc/ActiveDS
•
jdbc/ArchiveDS
•
jdbc/juddiDB
If you intend to update the database pools by using the Administration Console, then you should make the update before enabling Derby security. Otherwise Geronimo server will not start. If you intend to update the database pools by editing the config.xml file, then you can use the following XML fragment, which shows the updates of the SystemDatasource database pool. username password
Here, org.apache.geronimo.configs/system-database/2.1.4/car is the name of the module containing the SystemDatasource database pool. You will need to obtain the module name for each of the database pools from the given list that needs to be updated. Start the Geronimo server after updating all of these database pools in the config.xml file.
Cryptographic security
Geronimo provides GBeans to manage the JSSE keystores and encrypt passwords. In this section, we will see how these GBeans can be used to manage the keystores and how digital certificates; encrypt passwords are saved to the config.xml file and the properties files used with security realms.
Keystores
JSSE keystores are used to store cryptographic keys and digital certificates. Geronimo provides GBeans to create and manage keystores and digital certificates. The FileKeystoreInstance class wraps a keystore file stored on a filesystem. The FileKeystoreManager class provides the ability to manage keystores in a filesystem directory. The digital certificates are used to configure SSL connectors in Geronimo. [ 154 ]
Chapter 6
The Keystores portlet in the Administration Console provides a convenient way to access the functionality provided by Geronimo. The functions provided are: • • • • • • •
Viewing keystores in the var/security/keystores directory Locking or unlocking a keystore for editing or availability Creating a new keystore Viewing the contents of a keystore Changing a keystore or key password Adding new private keys and certificates Generating certificate requests
Geronimo provides a default keystore named geronimo-default, which contains a self-signed certificate. The password for this keystore is secret. This default keystore contains one private key and a self-signed certificate entry with an alias of geronimo and a key password secret. Unless a new private key and certificate is generated, your server will be using the same private key and certificate that is used by a million other servers!
Keystores portlet
The Keystores portlet allows you to manage the JSSE keystores in order to configure SSL connectors on the Geronimo server. The portlet's initial screen is shown below:
The portlet lists the keystores in the var/security/keystores directory under . The Keystore File column shows the name of the file under the keystores directory. The Type column shows the JSSE keystore type of the keystore. The Contents column shows the content details for unlocked keystores only. Keystores start out as locked against editing and also not available for use by other components in the server. The Editable flag indicates whether the keystore has been unlocked for editing (by entering the keystore password), which lasts for the current login session. The Available flag indicates whether the keystore password has been saved in order to make the keystore available to other components on the server. [ 155 ]
Security
Creating a new keystore
To create a new keystore, click on the New Keystore link. This will display the screen shown in the next screenshot:
Enter the Keystore file name, Password for new keystore, select the Keystore Type, and click on the Create Keystore button. This will create a new keystore with the specified name and with no content. The newly-created keystore will automatically be unlocked for editing during the current login session.
Viewing the contents of a keystore
For all the keystores unlocked for editing, the Keystores portlet provides a link on the keystore filename to display all of the keystores that are unlocked for editing, as shown in the next screenshot, to display the contents of that keystore:
In the above screenshot, the newly-created keystore packt-keystore provides a link. Click on that link to view the contents. The following screenshot shows the portlet screen displaying the contents of the keystore:
[ 156 ]
Chapter 6
This view provides links to add a new Private Key, add a new Trust Certificate, and Change keystore password.
Adding a private key
To add a new private key to a keystore, click on the Create Private Key link while viewing the contents of the keystore. This will display a form, as shown in the screenshot below:
Complete the following fields: •
Alias for new key: An alias name for the private key entry. This must be unique among all of the private keys and trusted certificate entries in the keystore.
•
Password for new key: A password to protect the newly-created private key. It is recommended that this password be same as the keystore password.
•
Key size: The key's size in bits, for the RSA key pair to be generated. The larger the key size, the stronger the key. The recommended key size is 1024.
•
Algorithm: The certificate-signing algorithm to be used to sign the self-signed certificate.
•
Valid for (# of days): The validity period for the self-signed certificate. The suggested validity period for a private key is 365 days. [ 157 ]
Security
Complete the following Certificate Identity fields: •
Server Hostname (CN): This is the Common Name to be used in the certificate. Typically, this will be the DNS name of your server.
•
Division/Business Unit (OU), Company/Organization (O), City/Locality (L), State/Province (ST): Fields to reflect the identity of the server.
•
Country Code (2 char) (C): Two-character ISO 3166 country code that identifies the country.
After completing all of the above fields, click on Review Key Data. On the next screen, verify the certificate details. To edit any details, use the browser's back button. To go ahead with key generation, click on Generate Key. A new private key and self-signed certificate will be generated and saved to the keystore. The keystore details screen will now list the newly-generated private key entry, as shown in the screenshot below:
You can view the contents of the private key by clicking on the Alias (packt-cert in this case) or the View link provided against the private key.
Adding a trusted certificate
To add a new trusted certificate to a key store, click on the Add Trust Certificate link while viewing the keystore contents. On the next screen, enter the certificate text in the Trusted Certificate field, enter an Alias for the certificate, and click on the Review Certificate button. Note that the alias entered must be unique among all of the private key and trusted certificate entries in the keystore. The next screen displays the details of the certificate. Click on the Import Certificate button to add this certificate to the keystore as a trusted certificate. Once added, the keystore details screen will list the trusted certificates, as shown in the screenshot below:
[ 158 ]
Chapter 6
You can view the contents of the trusted certificate by clicking on the Alias (packt-trust-cert in this case) or the View link provided next to the trust certificate entry.
Deleting a private key or trusted certificate
While viewing the contents of a keystore, click on the alias or the View link provided next to the private key or trusted certificate entry. The next screen will show the details of the private key or trusted certificate. This screen will include a Delete Entry link. Click on this link and confirm deletion in the popup dialogbox to delete the private key or trusted certificate from the keystore.
Changing a keystore password
To change the password of a keystore, click on the Change keystore password link while viewing the contents of the keystore. On the next screen, enter the current password of the keystore as the old password, enter the new password, and click on the Change Password button. Upon successfully changing the password, the portlet will display a message indicating that the password for the keystore has been changed.
Unlocking keystore for availability
For a keystore to be usable by server components, it must be unlocked for availability. Once the keystore is unlocked for availability, the keystore and key passwords are stored in config.xml file such that the keystore is unlocked for availability for subsequent runs of the server. For a keystore that is locked for availability, the Keystores portlet will show a lock icon under the Available column. To unlock a keystore for availability, click on the lock icon. This will show a screen similar to the one shown in the next screenshot:
[ 159 ]
Security
Enter the keystore password and click on Unlock Keystore to go to the next screen, shown in the screenshot below:
Upon successfully unlocking the keystore, the portlet will display a message indicating success. The keystore can now be used by other server components.
Unlocking a keystore for editing
Upon accessing the Keystores portlet for the first time after logging on to the Administration Console, you will find that the keystores are locked for editing. In order to edit a keystore, you have to unlock the keystore by providing the keystore password. To do so, click on the lock icon displayed in the Editable column against the keystore name. On the next screen, enter the keystore password and click on Unlock Keystore. Upon successfully unlocking the keystore for editing, the portlet will display a message indicating success. The keystore will remain unlocked for editing for the current login session, unless explicitly locked.
Locking a keystore for editing or availability
A keystore that is unlocked for editing and/or availability is indicated by showing an 'unlocked' icon in the Editable and Availability columns against the keystore name. To lock the keystore for editing or availability, click on the corresponding unlocked icon. Attempting to lock a keystore for availability will display a dialogue to confirm the action. Once confirmed, the keystore will be locked and a lock icon will show in place of the unlocked icon. Note that locking and unlocking the keystore for editing is within the scope of the current login session, whereas locking and unlocking the keystore for availability will be persisted in the server and will immediately affect any server components using that keystore.
[ 160 ]
Chapter 6
View private key details
While viewing the keystore contents, to view the details of a private key entry, click on the Alias or the view link shown against that private key entry. This will show a screen similar to the one shown in the screenshot below:
The Certificate Info section shows the details of the certificate stored in the keystore for that private key. The links provided above the Certificate Info section let you operate on the private key entry. Note that the Generate CSR, Import CA reply, and Change key password links will appear only when the keystore is unlocked for editing as well as availability.
Changing a Private Key password
To change the password of a Private Key, click on the Change key password link on the screen that shows Private Key details. On the next screen, enter the current key password for the Old password, enter the New password, and click on the Change Password button. If the password is changed successfully, the portlet will display a message indicating success.
Generating CSR for a Private Key
A Certificate Signing Request (CSR) for a Private Key is used to request a digital certificate from a Certification Authority (CA). To generate a CSR for the private key, click on the Generate CSR link on the screen that shows the Private Key details.
[ 161 ]
Security
The next screen will show the base-64 encoded PKCS10 Certificate Request text, as shown in the next screenshot:
Copy the text shown under PKCS10 Certification Request into a text file, and send it to the Certificate Authority to obtain a digital certificate.
Importing the CA Reply for a Private Key
A digital certificate issued by a CA in response to the CSR sent to the CA will be in a PKCS7 encoded format. In order to use this certificate, it must be imported into the key store that contains the private key to which the certificate corresponds. The Keystores portlet provides an Import CA reply function to import the certificate issued by a CA. To import the certificate, click on the Import CA reply link on the private key details screen. On the next screen, enter the certificate text in the PKCS7 Certificate Reply field and click on Save to complete the import. The imported certificate details will show under the Certificate Info for the Private Key.
Preparing a keystore for use with SSL
We have seen the various functions provided by the Keystores portlet to manage a JSSE keystore file. In this section, we will aggregate the sequence of steps in getting a keystore ready for use with SSL configuration.
[ 162 ]
Chapter 6
The steps involved in creating a new Private Key and certificate ready for use with SSL configuration, are as follows: 1. Create a new keystore—See the Create a new keystore section. The newly-created keystore will not have any private key or trusted certificate entries. 2. Create a new Private Key—See the Adding a Private Key section. This is done while viewing the contents of the keystore. Unlock the keystore for editing if it is not already unlocked. A self-signed certificate will be generated along with the private key. 3. Unlock keystore for availability. If you intend to use a self-signed certificate and do not plan to obtain a certificate from an external CA, then you will not need to go through the next steps. Otherwise, follow the steps below: 1. Generate a CSR—The Certificate Signing Request text contains the Distinguished Name information and Public Key which will be used by a CA to issue a certificate. Note that the keystore needs to be unlocked for editing as well as availability, in order to generate CSR text for a Private Key. 2. Send the CSR to the CA and obtain a certificate. This is an offline process with regard to the Keystores portlet. 3. Import CA Reply—Once a reply is received from the CA, import the certificate issued by the CA into the keystore. The keystore and Private Key are now ready for SSL configuration. A trust store is used when you require clients using SSL to connect to the server and authenticate to the server by using digital certificates. You may use the keystore containing the private key as a trust store, but it is recommended that you use a keystore with only trusted certificates as a trust store. Follow the steps below to prepare a keystore for use as a trust store: 1. Create a new keystore—See the Create a new keystore section. The newly-created keystore will not have any private key or trusted certificate entries. 2. Unlock the keystore for availability. 3. Add a Trust Certificate—Repeat this step for each of the trusted certificate, you want to add to the keystore. The key store is now ready for use as a trust store in SSL configurations enabled for client authentication. [ 163 ]
Security
Certificate Authority portlet
The Certificate Authority portlet allows you to create your own Certification Authority (CA) for issuing digital certificates. The portlet provides functions to create a self-signed certificate for the CA, manage certificate requests received through a CA helper web application, issue new certificates using CSR text, and search for issued certificates.
Protecting passwords
The passwords saved to the config.xml file are encrypted with a hardcoded key by default, which is created during the server build and packaged in the binary distributions. To enable the Geronimo server to generate and use a new key for encrypting passwords, Geronimo provides a ConfiguredEncryption GBean. This GBean should be added to rmi-naming configuration by adding the following XML code under the org.apache.geronimo.configs/rmi-naming/2.1.4/car module entry in the config.xml file: var/security/ConfiguredSecretKey.ser ServerInfo
This will create a new key when the GBean is started for the first time, and will save it to the path specified. After that, the GBean will keep using the saved key from the location specified. If you put a serialized SecretKeySpec in this location, then the GBean will use that instead of creating a new key.
HTTPS connectors
Typically, digital certificates are used to enable web server authentication and secure communication between web browser and web server. This is done by making the web container available on an HTTPS port. Geronimo provides GBeans to create and configure HTTPS connectors for both Jetty and Tomcat web containers. The HTTPS connectors can also be configured for authenticating web clients by using digital certificates.
[ 164 ]
Chapter 6
Tomcat HTTPS connectors
The Geronimo Tomcat distribution is configured with a default HTTPS connector on port 8443. This connector uses the private key entry geronimo in the default keystore geronimo-default, and is only configured for server authentication. New HTTPS connectors can be created, and existing HTTPS connectors can be edited, by using the Web Server portlet in the Administration Console. See Chapter 10, Administration, for details on using the Web Server portlet. Apart from the common connector attributes such as uniqueName, address, and port, the important connector attributes that are relevant to HTTPS configuration are as follows: •
keyStore: The location of the file that holds the keystore relative to the
directory.
•
algorithm: The certificate-encoding algorithm to be used. Allowed values are Default, SunX509, and IbmX509. Choose Default if the connector need not be reconfigured when the server is to be started using a different JRE than Sun JRE.
•
ciphers: A comma-separated list of the encryption ciphers that may be used. If not specified, then any available cipher may be used. This attribute can be left blank.
•
clientAuth: Set this to true if you want the SSL stack to require a valid certificate chain from the client before accepting a connection.
•
keyAlias: The alias used for the server certificate in the keystore. If not specified, then the first key read from the keystore will be used.
•
keyStorePass: The password used to access the keystore file. This is also the password used to access the server private key within the keystore, so the two passwords must be set to be the same value on the keystore.
•
keyStoreType: Set the keystore type. There is normally no reason not to use the default (JKS).
•
sslProtocol: Set the HTTPS protocol. This should normally be set to TLS, although some (IBM) JVMs don't work properly with popular browsers unless it is changed to SSL.
•
trustStore: The location of the keystore containing the trusted certificate entries, including Certificate Authority (CA) certificates (the path specified is relative to directory). This attribute is used only if clientAuth is true.
•
trustStorePass: The password to access the trust store.
•
trustStoreType: Set the trust store type. There is normally no reason not to use the default (JKS). [ 165 ]
Security
Jetty HTTPS connectors
The Geronimo Jetty distribution is configured with a default HTTPS connector on port 8443. This connector uses the default keystore geronimo-default, and is only configured for server authentication. New HTTPS connectors can be created, and existing HTTPS connectors can be edited, by using the Web Server portlet in the Administration Console. Apart from the common connector attributes uniqueName, host, and port, the important connector attributes that are relevant to HTTPS configuration are as follows: •
keyStore: The keystore to use for accessing the server's private key.
•
clientAuthRequired: If this is set, then the clients connecting through this connector must supply a valid client certificate.
•
secureProtocol: This should normally be set to TLS, although some (IBM) JVMs don't work properly with popular browsers unless it is changed to SSL.
•
trustStore: The keystore containing the trusted certificate entries, including Certificate Authority (CA) certificates. This is used only when clientAuthRequired is true.
The keyStore and trustStore here use the names of the KeyStoreGBean wrapping the keystore file.
JAAS login modules
Geronimo provides implementations of login modules that allow you to store authentication credentials in a variety of data stores, such as simple text files, databases, and LDAP servers. Geronimo also provides login modules to enable auditing, lockout on repeated unsuccessful login attempts, and storing user credentials for later use by the application. To access these data stores and enable additional features, you need to create and appropriately configure security realms. Now, let us look at the various login module implementations provided by Geronimo.
Login modules for authentication
Geronimo provides login module implementations that are used for user authentication. Let us look at these login modules and learn about the data stores that each one supports.
[ 166 ]
Chapter 6
PropertiesFile login module
PropertiesFileLoginModule is the simplest of all login module implementations
provided by Geronimo. Authentication information can be managed by using a text editor. The underlying data store that is used by a PropertiesFileLoginModule consists of two properties files, one for the user authentication data, referred to as the users properties file, and another for the grouping data, referred to as the groups properties file. The following is a sample users properties file: #Entries are in the format username=password and one entry per line only packtadmin=admin packtuser1=user1 packtuser2=user2 vamsi=password1 manu=password2
The following is a sample groups properties file: #Entries are in the format groupname= #We have three groups namely Admin, User, and Author Admin=packtadmin User=packtuser1,packtuser2,packtuser3 Author=vamsi,manu
Be aware that the usernames used in the groups properties file must also exist in the users properties file. A user may belong to zero or more groups.
To use these properties files in a security realm, they should be placed in a directory under , typically under /var/security.
[ 167 ]
Security
The options used by PropertiesFileLoginModule are as follows. •
usersURI: The location of a properties file, relative to the directory, holding user and password information.
•
groupsURI: The location of a properties file, relative to the
directory, holding group information.
It is not necessary to store the original passwords to be able to compare them with user-provided passwords. Cryptographic message digests can be used to compare a user provided password with an original password without having to store the original password. PropertiesFileLoginModule supports passwords digested with cryptographic hash functions such as MD5, SHA1, and so on. It provides for using HEX and BASE64 encodings to represent the binary hash values as text. To use digested passwords, use the following options: •
digest: Message digest algorithm (for example, MD5, SHA1, and so on) used on the passwords. Do not specify this option if you are using clear text passwords.
•
encoding: Encoding to use for digests (for example, HEX and BASE64). This is used only if a message digest algorithm is specified. If no encoding is specified, HEX will be used.
Upon successful authentication, the PropertiesFileLoginModule populates the JAAS subject with one GeronimoUserPrincipal with the authenticating username and one GeronimoGroupPrincipal with the group name for each group that the user belongs to.
SQL login module
SQLLoginModule can be configured to authenticate users based on credentials stored in a relational database. You will need to create tables and enter data in the database. You will need to specify two SQL statements to retrieve user and group information. To connect to the database, the SQLLoginModule can be configured to either use JDBC directly or use the connection pools in Geronimo.
The options used by SQLLoginModule are as follows: •
userSelect: As the name suggests, this is an SQL statement used to load
•
groupSelect: This is an SQL statement used to load group information for
username and password information. It should return two columns, the first holding a username and the second holding a password.
a user. It should return two columns, the first holding a username and the second holding a group name. [ 168 ]
Chapter 6
Both statements can use the PreparedStatement syntax of "?" for a parameter, in which case the username will be set for every parameter. Similar to PropertiesFileLoginModule, SQLLoginModule also supports passwords digested with cryptographic hash functions such as MD5, SHA1, and so on, and encoded in either HEX or BASE64 formats. To use digested passwords, use the following options: •
digest: Message digest algorithm (for example, MD5, SHA1, and so on) used on the passwords. Do not specify this option when using clear text passwords.
•
encoding: Encoding to use for digests (for example, HEX and BASE64). This is used only if a message digest algorithm is specified. If no encoding is specified, then HEX will be used.
For database connectivity using JDBC directly, the SQLLoginModule uses the following options: •
jdbcDriver: The fully-qualified JDBC driver class name
•
jdbcURL: The JDBC URL that specifies the location of the database to
•
jdbcUser: The username used to connect to the database with
•
jdbcPassword: The password used to connect to the database with
connect to
For database connectivity using database pool, the SQLLoginModule uses the following options: •
dataSourceName: The name of the database pool.
•
dataSourceApplication: The name of the application containing
the database pool. Specify "null" if the database pool is a server-wide database pool.
You will need to specify either JDBC or data source options for database connectivity. Upon successful authentication, the SQLLoginModule populates the JAAS subject with one GeronimoUserPrincipal with the authenticating username and one GeronimoGroupPrincipal with the group name for each group that the user belongs to.
LDAP login module
An LDAPLoginModule authenticates users based on credentials stored in an LDAP server. This login module can be configured to use either an LDAP server running either internally within the Geronimo instance, or an external LDAP server. [ 169 ]
Security
The LDAPLoginModule uses the following options for connectivity to the LDAP server. •
initialContextFactory: The fully-qualified class name of the initial context factory. If you don't know what to use here, then you should use com.sun. jndi.ldap.LdapCtxFactory.
•
connectionURL: A URL that describes how to connect to the LDAP server. Normally, this will be ldap://ldap-server-hostname:389
•
connectionUsername: The username used to connect to the LDAP server.
•
connectionPassword: The password used to connect to the LDAP server with.
•
connectProtocol: The connection protocol used to communicate with the LDAP server. This is normally left blank, although it can be set to SSL if the server supports it.
•
authentication: The security level to use, which can be none, simple, or strong. The usual value is simple. If this property is unspecified, then the behavior is determined by the service provider.
This should be an administrator or Directory manager who has access to examine other users' passwords.
The LDAPLoginModule uses the following options to retrieve user and group information: •
userBase: The base LDAP context (location) to search for users. The search may look in this location only or in all subcontexts, depending on the settings for userSearchSubtree, which is described below.
•
userSearchMatching: The LDAP attribute search string used to find the
•
userSearchSubtree: If set to true, then subtrees under the userBase will be searched for users too. If set to false, then only the userBase location itself
user. RFC 2254 filters are allowed, and normally the parameter {0} is used to identify the username. A typical value would be uid={0} or cn={0}.
will be searched.
•
roleBase: The base LDAP context (location) to search for roles. The search may look in this location only or in all subcontexts, depending on the settings for roleSearchSubtree, which is explained below.
•
roleName: The LDAP attribute type that corresponds to the role name. This is often set to cn.
•
roleSearchMatching: The LDAP attribute search string to be used on a role
to find the users who are members of the role. This is used when the role has many attributes with the same name, but with different values (one per user). Normally, the parameter {0} is used to identify the username. A typical value would be member={0} or memberUID={0}. [ 170 ]
Chapter 6
•
roleSearchSubtree: If set to true, then subtrees under the roleBase will be searched for roles too. If set to false, then only the roleBase location itself will be searched.
•
userRoleName: If the role entry does not have an attribute for users, but
instead the user entry has an attribute for roles, then this should be used instead of the roleSearchMatching. It names the attribute on a user that lists a role that the user has. A typical value would be memberOf={0}.
Upon successful authentication, the LDAPLoginModule populates the JAAS subject with one GeronimoUserPrincipal with the authenticating username and one GeronimoGroupPrincipal with the group name for each group that the user belongs to.
CertificatePropertiesFile login module
A CertificatePropertiesFileLoginModule authenticates users based on a digital certificate, and the distinguished name of the client is mapped to a username. The underlying data store that is used by a CertificatePropertiesFileLoginModule consists of two properties files, one for the username to certificate name mapping, referred to as the certificate users properties file, and another for the grouping data, referred to as the groups properties file. The following is a sample certificate user properties file: #Entries are in the format username=certificatename and one entry per line only packtadmin=CN=Packt Admin,O=Packt,C=GB packtuser1=CN=Packt User1,O=Packt,C=GB packtuser2=CN=Packt User2,O=Packt,C=GB packtuser3=CN=Packt User3,O=Packt,C=GB vamsi=CN=Vamsi,O=IBM,C=IN manu=CN=Manu George,O=IBM,C=IN
The following is a sample groups properties file: #Entries are in the format groupname= #We have three groups namely Admin,User and Author Admin=packtadmin User=packtuser1,packtuser2,packtuser3 Author=vamsi,manu
Be aware that the usernames used in the groups properties file must also exist in the certificate users properties file. A user may belong to zero or more groups. [ 171 ]
Security
To use these files in a security realm, they should be placed in a directory under , typically under /var/security. The options used by CertificatePropertiesFileLoginModule are as follows: •
usersURI: The location of a properties file (relative to the directory) that holds the certificate to user mapping information. The format of each line should be username=certificatename, where certificatename is X509Certificate.getSubjectX500Principal().getName().
•
groupsURI: The location of a properties file (relative to the directory) that holds the group information. You need to configure an HTTPS connector with client authentication enabled in order to use this login module.
Using custom login modules
Apart from the login module implementations provided by Geronimo, you can use your custom login module implementations to suit your user credential data stores to secure your applications and resources in Geronimo. It is recommended that you use GeronimoUserPrincipal and GeronimoGroupPrincipal for adding principals to the JAAS subject.
Special purpose login modules
Geronimo provides login module implementations for special purposes such as auditing, lockout, and storing the user-supplied credentials for later use in the applications. We will examine these login modules and see how the purpose served by these login modules is useful.
FileAudit login module
The FileAuditLoginModule allows you to log all login attempts to a file. This login module uses the following option: •
file: The location of a file to which all login attempts will be logged. The path should be relative to the directory.
The FileAuditLoginModule does not add any principals or credentials to the JAAS subject. This login module should be used along with an authenticating login module. [ 172 ]
Chapter 6
RepeatedFailureLockout login module
The RepeatedFailureLockoutLoginModule allows you to configure locking out a specific username for a certain duration (call it lockout duration) if a specified number of login failures occur within a specified time span for that username. After this specified number of failed login attempts, even if the user provides the correct credentials for that username, Geronimo will report a login failure until the lockout duration since the last login attempt has elapsed. This is a defense against brute force account cracking attacks. The RepeatedFailureLockoutLoginModule uses the following options: •
failureCount: The number of failed login attempts after which lockout
•
failurePeriodSecs: The period of time in seconds during which the failed
•
lockoutDurationSecs: The time duration in seconds for which the
should occur
login attempts should occur to cause the username to be locked out
username should be locked out
The RepeatedFailureLockoutLoginModule does not add any principals or credentials to the JAAS Subject. This login module should be used along with an authenticating login module.
GeronimoPasswordCredential login module
The GeronimoPasswordCredentialLoginModule allows you to store the user supplied username and password in a private credential in the JAAS subject for later use by applications after the login process has completed. This login module does not use any options. It adds a GeronimoPasswordCredential containing the username, and password to the private credentials in the JAAS subject.
NamedUsernamePasswordCredential login module The NamedUsernamePasswordCredentialLoginModule allows you to store the username and password in a private credential in the JAAS subject under a specific credential name for later use by applications, after the login process has completed. The NamedUsernamePasswordCredentialLoginModule uses the following option: •
Name: A name for the credential under which the username and password
will be stored.
This login module adds a NamedUsernamePasswordCredential containing the credential name, username, and password to the private credentials in the JAAS subject. [ 173 ]
Security
Security realms
A security realm is a composition of one or more login modules and is equivalent to a JAAS LoginContext. By using a combination of authenticating login modules and special purpose login modules discussed earlier, you can create security realms that can not only be used to authenticate users, but can also be used to enable special features such as auditing and lockout on repeated failed login attempts. In this section, we will see how to create and deploy a security realm in Geronimo.
Creating a security realm
There are two ways to create a security realm in Geronimo. They are: •
By using the Security Realms portlet in the Administration Console
•
By deploying a security realm plan
Using the Security Realms portlet
The Security Realms portlet in the Administration Console provides a step-by-step process to easily create a security realm, as follows: 1. The process of creating a security realm is initiated by clicking on the Add new security realm link in the portlet. Then, you enter a name for your security realm and select the Realm Type, as shown in the following screenshot:
[ 174 ]
Chapter 6
The Name of Security Realm should be different to any of the existing security realms on the server. Select the Realm Type based on the data store containing the user credential information. The available options are: °
Properties File Realm: Uses a PropertiesFileLoginModule for authenticating users
°
Database (SQL) Realm: Uses the SQLLoginModule for authenticating users
°
LDAP Realm: Uses an LDAPLoginModule for authenticating users
°
Certificate Properties File Realm: Uses a
CertificatePropertiesFileLoginModule for
authenticating users °
Other: Select this option if you want to create a security realm based on your own custom login module implementation
2. In the second step, you configure the options for the login module selected in Step 1.The next screenshot shows Step 2 of creating a Properties File Realm.
In this example, in Step 2, we configure the two properties files used by the PropertiesFileLoginModule.
[ 175 ]
Security
Make sure that you copy the packt-users.properties and packt-groups.properties files provided in the samples to the /var/security directory. Otherwise, the current example security will fail to authenticate users.
3. In Step 3, you can enable Advanced Configuration for the security realm, as shown in the following screenshot:
The explanations of the features in Advanced Configuration are as follows: °
°
°
°
Enable Auditing: Selecting this feature results in a
FileAuditLoginModule being added to the login modules for
the realm Enable Lockout: Selecting this feature results in a RepeatedFailureLockoutLoginModule being added to the login modules for the realm Store Password: Selecting this feature results in a GeronimoPasswordCredentialLoginModule being added to the login modules for the realm Named Credential: Selecting this feature results in a NamedUsernamePasswordCredentialLoginModule being added to the login modules for the realm [ 176 ]
Chapter 6
At this stage, you have the option of testing your security realm or you can deploy the realm without testing or show the realm plan that could then be used to deploy the realm using any of the Geronimo deployment options. The following is the security realm deployment plan for packt-properties-realm generated for our current example: console.realm packt-properties-realm 1.0 car org.apache.geronimo.framework j2ee-security car packt-properties-realm ServerInfo packt-properties-realm org.apache.geronimo. security.realm.providers.PropertiesFileLoginModule var/security/ packt-users.properties var/security/ packt-groups.properties [ 177 ]
The security realm can be deployed or the generated deployment plan can be copied to a file and then deployed by using any of the deployment options. The security realm will be deployed under the module name console.realm/packtproperties-realm/1.0/car. During realm creation using the Security Realms portlet, you can test a login and observe the GeronimoUserPrincipal and GeronimoGroupPrincipal(s) added to the JAAS subject.
Security realm deployment plan
Let us examine the structure of the security realm deployment plan. Important points to observe in the deployment plan are as follows: •
The module has a dependency on org.apache.geronimo.framework/j2eesecurity//car defined in the element. See Appendix A, Deployment plans, for details on the element.
•
The plan defines a GBean of type GenericSecurityRealm by using a element. The name of the GBean defined in the name attribute of the GBean element and the realmName attribute of the GBean defined using element under are both in the packt-properties-realm.
•
The security realm GBean has a reference named LoginModuleConfiguration defined using an element, which defines the login modules that constitute the security realm.
•
The login module configuration defines five login modules, one corresponding to the Realm Type and one corresponding to each of the following advanced features selected: °
Each login module is defined using a element. The control-flag attribute of the element defines the JAAS control-flag for the login module in the login configuration.
°
The element is used to define a login domain to which the authentication corresponds. This information is used for advanced authorization using principal wrapping.
°
The element is used to specify the fully-qualified name of the login module class.
°
The element is used to specify the options used by login module implementation. The option name is specified by using the name attribute.
[ 179 ]
Security
•
The control-flag for authenticating the login module, in this case, PropertiesFileLoginModule, is "REQUIRED". The control-flag for RepeatedFailuresLockoutLoginModule is "REQUISITE", as this login module influences the overall authentication in addition to the authenticating login module.
Principal wrapping
We have observed that upon a successful login, the authenticating login module implementations add GeronimoUserPrincipal and GeronimoGroupPrincipal to the JAAS subject. Geronimo cannot distinguish between two different principals that have the same name and same principal class but were produced by two different login modules. To provide this distinction, Geronimo has a wrap-principals option. When this option is enabled, by setting the wrap-principals attribute in the login-module element to "true", Geronimo will "wrap" the principals to track which login module and security realm each principal came from. In the login module configuration, the login domain name is specified by using the login-domain-name child element of the login-module element. For each GeronimoUserPrincipal and GeronimoGroupPrincipal added by the authenticating login module, Geronimo will add one DomainPrincipal (wrapping the base principal along with the domain name) and one RealmPrincipal (wrapping the base principal with the domain name and the realm name) to the JAAS subject.
Application security
So far we have seen how to create security realms in Geronimo that can authenticate users based on credentials stored in a variety of data stores. We will now see how these security realms can be used to secure web, EJB, and EAR applications running in Geronimo.
Configuring web application security
A web application's security is configured by creating security roles and security constraints in its Java EE specific deployment descriptor web.xml file. These security roles are mapped to principals in a server-specific deployment plan, geronimo-web.xml in the case of Geronimo, at application deployment time. The sample application used in this section consists of three JSPs—one with unrestricted access, one accessible by the admin role, and another accessible by the user role. The deployment descriptor web.xml for this application is shown below: MyWebApp [ 180 ]
Chapter 6 BASIC packt-properties-realm admin user Admin /admin/* GET POST admin User /user/* GET POST user
Important points to observe in the web.xml file are as follows: •
The tag specifies the method used to authenticate the users and any additional required configuration. In this example, the value BASIC for auth-method means that the login will use a dialog box displayed by the browser. For this auth-method, you can optionally specify a value for realm-name that will be displayed in the dialog box for login.
•
The tag declares the security roles that you want to use in this application. There can be zero or more security roles in an application. In this example, two security roles, namely, admin and user are used. [ 181 ]
Security
•
The tag declares the authorization constraints for resources and the tag specifies the URL pattern to which the constraint should apply. In this example, /admin/* means that all URLs starting with "/admin/" will be subject to this security constraint. Assuming that the application is available at http://localhost:8080/mywebapp, some of the URLs would be http://localhost:8080/mywebapp/admin/admin. jsp, http://localhost:8080/mywebapp/admin/another.jsp, and so on. The tag specifies the security roles that have access to the URL pattern.
The tag in login-config inside the application deployment descriptor enables you to specify the authentication method to be used by the web application. Valid values are BASIC, DIGEST, FORM, and CLIENT-CERT. These options are explained as follows: •
When BASIC or DIGEST is specified, the login happens using a browser-specific dialog box. The BASIC auth-method is used in some of the sample applications used in this book.
•
For FORM auth-method, the login happens using a login page configured using form-login-config. The following is an example of a web application deployment descriptor that configures FORM authentication: FORM Not required for FORM auth /login/login.jsp /login/loginerror.jsp
An example of how the form should be coded into the HTML page is as follows:
The action of the login form must always be j_security_check. The j_username input field should be used to get the username, and the j_password input field should be used to get the user's password. •
CLIENT-CERT is used if the application uses digital certificates for
client authentication.
[ 182 ]
Chapter 6
The deployment plan for this application in geronimo-web.xml, is as follows: packt-samples MyWebApp 1.0 war console.realm packt-properties-realm 1.0 car mywebapp packt-properties-realm
[ 183 ]
Security
Important points to note in the geronimo-web.xml file are as follows: •
The module has a dependency on console.realm/packt-propertiesrealm/1.0/car, which is defined in the element. This dependency is added to make sure that the security realm is started before starting the application. See Appendix A, Deployment plans, for details on the element.
•
The tag specifies the name of the security realm against which this application should authenticate. Recall that packt-properties-realm is the name used for the properties file realm that you created earlier.
•
The tag under lets you configure the principals that should be mapped to each role. The role-name attribute is used to specify the role to which the principal elements inside the role tag are to be mapped. Here, the admin role is mapped to a GeronimoGroupPrincipal with a name of Admin, and the user role is mapped to two principals—a GeronimoGroupPrincipal with the name User and a GeronimoUserPrincipal with the name vamsi. Recall that when a user logs into packt-properties-realm, the subject is populated with a GeronimoUserPrincipal with the username and zero or more GeronimoGroupPrincipals with the names of all of the groups that the user belongs to.
If you have configured principal wrapping in your security realm, then you can use the realm-principal and login-domain-principal elements in principal to role mapping in the security configuration of your application's deployment plan. The following is an example of security configuration using realm-principal and login-domain-principal:
[ 184 ]
Chapter 6
The login domain name is specified by using the domain-name attribute of the realm-principal and login-domain-principal elements. The security realm name is specified by using the realm-name attribute of the realm-principal element.
Running the sample web application
To run the sample web application, deploy mywebapp-1.0.war provided under the samples. Access the application at http://localhost:8080/mywebapp. Click on the Admin link on the home page, and log in using the userid/password packtadmin/admin. The page will display the details of the user logged in, the roles to which the user belongs, and the principals and credentials in the JAAS subject.
Configuring EJB application security
EJB applications use role-based security for bean-level and method-level security. Authentication and authorization under which each method executes is configured in the Java EE specific deployment descriptor file, ejb-jar.xml. The security roles are mapped to principals in Geronimo-specific deployment plans. We will now see how to define security roles and configure method permissions for EJBs.
Defining security roles in the deployment descriptor
Security roles are defined in the deployment descriptor file ejb-jar.xml by using the security-role element in the assembly descriptor. The role-name child element specifies the name of the security role. The following deployment descriptor defines two roles, namely, ejbuser and ejbadmin: Normal User role ejbuser Administrator role ejbadmin
[ 185 ]
Security
Declaring method permissions in the deployment descriptor
To configure the security identity to invoke the methods in an EJB, we use the security-identity element in the bean definitions under the enterprise-beans element in ejb-jar.xml. We configure the bean method permissions by using the method-permission element under assembly-descriptor. An XML fragment of the EJB application deployment descriptor used to configure the method permissions for MySessionBean in our sample application is as follows: ... MySessionBean ... ... ... ejbuser MySessionBean userMethod ejbadmin MySessionBean adminMethod MySessionBean commonMethod [ 186 ]
Chapter 6 MySessionBean noaccessMethod
Let's take a peek at the various XML elements used in this example: •
The security-identity element specifies the security identity to be used to invoke methods in MySessionBean.
•
The use-caller-identity element specifies that the caller's security identity be used as the security identity for the execution of methods of the enterprise bean. Another option is to use a run-as element to specify that a run-as identity can be used to invoke the bean's methods, as we will show later.
•
The method element of method-permission specifies the security permissions for one or more methods in a bean.
•
You can specify permissions using one or more role-name elements—one for each role that is allowed to access the method. A single empty role-name element means that the role has no access to the method. You specify unrestricted access permission by using an unchecked element.
•
The method's ejb-name element specifies the name of the EJB. The method-name element specifies the name of the method. A value of * for method-name corresponds to all methods in the EJB.
•
A specific method-name corresponds to all methods of that name, including any overloaded methods. To specify a particular method from overloaded methods, use the method-params element.
•
You can configure method-permission for methods in the bean's Home, Remote, Local, and LocalHome interfaces. To specify the permission for a method in a particular interface, use the method-intf element under method with the corresponding value.
In the given example of the MySessionBean, we have configured: •
userMethod to be accessible by ejbuser role
•
adminMethod to be accessible by ejbadmin role
•
commonMethod to have unrestricted access
•
noaccessMethod to be inaccessible by any role [ 187 ]
Security
Using annotations to define roles and permissions
In EJB3 enterprise beans, you can configure the bean-level and method-level security by using security annotations. In this section, we discuss the various security annotations (@DeclareRoles, @DenyAll, @PermitAll, and @RolesAllowed) and how they affect the security configuration. Note that we'll discuss the @RunAs annotation later in this chapter.
Defining security roles
You define security roles by using a @DeclareRoles annotation on a bean class, as shown below: @Stateless @DeclareRoles({"ejb3user", "ejb3admin"}) public class MyEjb3ServiceBean implements MyEjb3Service { ... }
In this example, MyEjb3ServiceBean defines two security roles, namely ejb3user and ejb3admin.
Configuring method permissions
You configure permissions for enterprise beans methods by using the @DenyAll, @PermitAll, and @RolesAllowed annotations. The @PermitAll and @RolesAllowed annotations can be applied to the bean class as well as to bean methods, whereas the @DenyAll annotation can be applied only on bean methods. An annotation applied to a class is applicable to all of the methods in the class. An annotation applied to a method overrides any annotation applied to the class. The MyEjb3ServiceBean class is shown as follows: @Stateless @DeclareRoles({"ejb3user", "ejb3admin"}) public class MyEjb3ServiceBean implements MyEjb3Service { @Resource private SessionContext ctx; @PermitAll public String commonMethod() { return logCall("commonMethod"); } @RolesAllowed({"ejb3user"}) public String userMethod() { return logCall("userMethod"); } @RolesAllowed({"ejb3admin"}) public String adminMethod() { [ 188 ]
This example defines the following access configuration: •
commonMethod has unrestricted access
•
userMethod is accessible by the ejb3user role
•
adminMethod is accessible by the ejb3admin role
•
noaccessMethod is not accessible by any role
Mapping principals to roles in the EJB deployment plan
The security roles defined in the EJB deployment descriptor and the roles defined by using the @DeclareRoles annotation are mapped to principals in the EJB deployment plan openejb-jar.xml. The following code snippet shows an example of a principal to role mapping in the EJB deployment plan:
[ 189 ]
Security
Notice that the security roles in the ejb-jar.xml file and security roles in the @DeclareRoles annotation are mapped to principals as follows: •
The ejbuser role is mapped to a GeronimoGroupPrincipal with the name User
•
The ejbadmin role is mapped to a GeronimoGroupPrincipal with the name Admin
•
The ejb3user role is mapped to a GeronimoGroupPrincipal with the name User
•
The ejb3admin role is mapped to a GeronimoGroupPrincipal with the name Admin and a GeronimoUserPrincipal with the name packtuser3
Running the EJB sample application
To access the EJBs in the EJB sample application, we have created a web application. Follow the steps, as shown, to deploy and run the EJB sample application and the web application: 1. Deploy the myejbapp-1.0.jar application by using a command-line deployer or the Deploy New portlet. 2. Deploy the myejbwebapp-1.0.war application by using a command-line deployer or the Deploy New portlet. 3. Access http://localhost:8080/myejbwebapp. Because the user has not logged into the application, only commonMethod in MySessionBean, and MyEjb3ServiceBean, which has unrestricted access, can be invoked from the home page. All of the other method invocations will result in AccessException or an EJBAccessException, as the principal is not authorized.
4. Access http://localhost:8080/myejbwebapp/bank/. Log in with the username packtadmin and the password admin.
[ 190 ]
Chapter 6
5. Because the user is now logged in as packtadmin, the JAAS subject contains GeronimoUserPrincipal with the name packtadmin and GeronimoGroupPrincipal with the name Admin. The user maps to the ejbadmin and ejb3admin roles, as per the role mapping. Hence, the user can access commonMethod, which has unrestricted access, and adminMethod, which is accessible by the ejbadmin role for MySessionBean, and the ejb3admin role for MyEjb3ServiceBean. The userMethod and noaccessMethod will result in an AccessException or an EJBAccessException upon invocation. userMethod is accessible by the ejbuser role (ejb3user role for MyEjb3ServiceBean), and noaccessMethod is not accessible by any role. 6. Open a new browser window and access http://localhost:8080/ myejbwebapp/customer/. Log in with the name packtuser3 and the password user3. Because the user is now logged in as packtuser3, the JAAS subject contains
GeronimoUserPrincipal with the name packtuser3 and GeronimoGroupPrincipal with the name User. The user maps to the ejbuser, ejb3user, and ejb3admin roles, as per the role mapping. In MySessionBean, the user can access commonMethod, which has unrestricted access, and the userMethod, which is accessible by the ejbuser role. In MyEjb3ServiceBean, the user can access commonMethod, which has unrestricted access, the userMethod that is accessible by the ejb3user role, and adminMethod, which is accessible by the ejb3admin role. All other methods will result in an AccessException or an EJBAccessException upon invocation.
Configuring entity bean security
You can configure entity bean security by using the deployment-descriptor and security annotations in the same way as we did for session bean security. The following code snippet shows the assembly-descriptor from a sample EJB application with an entity bean. Bank Manager manager manager MyBank create
In this example, we configured the create method on the home interface of the MyBank entity bean to be accessible only by the manager role. [ 191 ]
Security
Run-as and default subjects
In addition to configuring method permissions for a bean's methods, you can configure a run-as role for the bean, in order to specify the security identity with which the bean invokes other beans. This configuration is useful when a bean's method needs to invoke other beans with a different security identity than the security identity with which it is invoked. An example of this would be where a message-driven bean method that is invoked with no security identity invokes a secured session-bean method. You configure the security credentials that constitute the subject for run-as role security in the deployment plan. In Geronimo releases prior to 2.0, security configuration for run-as and default subjects were constructed by using the principals and credentials specified using the default-principal tag and the designated-run-as attribute of principal. Starting with Geronimo 2.0, all security flows from subjects are created by logging into a security realm. To use these subjects, you need to supply login information for every such subject. This login information is captured in a credential store.
Credential store
Geronimo provides an implementation of credential store, namely SimpleCredentialStoreImpl, that allows the configuration of a credential store by using XML in the deployment plans. The following code snippet shows the credential store we use in the sample applications: World Clock /WorldClockPortlet [WorldClockPortlet] PlutoPortalServices [ 241 ]
Geronimo Plugins
In the geronimo-web.xml file, we add dependencies to the pluto-support plugin and the World Clock plugin, as both of these will be used by our portlet. The Pluto-support plugin will provide the Pluto functionality, as well as both the ACE GBean and PortalContainerServicesGBean. We also specify an instance of the ACE GBean to start with this web module so that it can add the portlets to the Administration Console. We specify three attributes, namely, pageTitle, portletContext, and portletList, which specify the page title, portlet context, and the portlets that this GBean is going to add to the Administration Console, respectively. We also add a reference to the PortalContainerServicesGBean. 6. Finally, we create a portlet.xml file, as shown below, which specifies the portlet mode, title, and name. Clock Plugin portlet WorldClockPortlet World Clock Portlet com.packt.plugins.ClockPortlet text/html VIEW World Clock Portlet
Ensure that the portlet-name matches the one in web.xml. 7. Once you have created these files, build the web application by invoking the following command from the ClockWebApp directory: mvn clean install
8. Deploy the WAR file created to the Apache Geronimo server where you had previously deployed the World Clock plugin.
[ 242 ]
Chapter 9
Once you log in to the Administration Console, you will notice a World Clock link at the bottom of the console navigation menu in the Other section. Clicking on it will bring up the page shown in the following screenshot:
Plugins portlet
The Plugins portlet enables a user to dynamically install new features into the Geronimo server, create plugins out of existing configurations on the server, and create server assemblies consisting of some or all of the existing plugins in the server. By using the Install Geronimo Plugins section, you can search for plugins in a plugin repository or add new repositories for plugin searches. You can also download running configurations from another Geronimo server, just as if you're browsing and installing third-party plugins by using the repository URL http://remote-geronimo-server:8080/plugin/maven-repo/ and providing the administrator username and password.
[ 243 ]
Geronimo Plugins
In order to search for plugins, select the repository URL, and click on Show Plugins in selected repository. This will show all of the available plugins in that repository, as shown in the next screenshot:
A check mark in the Installable column for the plugin name indicates that the plugin is installable. You can click on the plugin name to view the details of the plugin. You can select one or more plugins, and click on Install to install the plugins. The portlet will show the status as the plugins are installing and display a confirmation message once completed. The Create Geronimo Plugin section lets you create a new plugin out of an existing configuration on the server. Select the configuration to be exported as a plugin, and click on the Export Plugin button. On the next page, you can fill in various details, such as Download Repositories that need to be looked in for downloading Dependencies, a Description of the plugin, the Geronimo Versions on which the plugin can be installed, JVM versions, the dependencies of this plugin on other configurations or artifacts, Prerequisite configurations, and so on. The fields have detailed explanation on this page. After completing the fields, click on Save Plugin Data. On the next screen, click on the Export Plugin button to save the plugin to filesystem. The configuration will be saved as a configuration archive (CAR) file. [ 244 ]
Chapter 9
Custom server assemblies and server profiles
Apache Geronimo provides a feature known as custom server assemblies. This allows users to assemble servers that are customized to their needs. They can assemble the application servers that contain their applications or plugins prepackaged with only the additional dependent modules that their applications or plugins require. We will go through the steps to assemble a custom server that contains the World Clock plugin as follows: 1. Log in to the Administration Console, and go to the Plugins portlet. 2. In the Assemble Server portlet, click on the Assemble a server button. This will bring up the screen shown in the following screenshot:
[ 245 ]
Geronimo Plugins
3. Enter the groupId, artifactId, version, and the target path where the assembly should be saved under the directory, and select the required format. Select the plugins that need to be included in the assembly, and click on the Assemble button. Always select Geronimo Assemblies :: Boilerplate Minimal. Select the WorldClock plugin. The WorldClock plugin does not need any other Apache Geronimo's services, so we need not include any other assemblies. 4. Click on the Assemble button at the bottom of the screen. This will bring up the screen shown in the next screenshot:
5. Click on the Assemble button to assemble the custom server. Once the server assembly process is complete, a screen with the status and the location of the created assembly will pop up. 6. Now stop the current server, and start the server you just assembled. You will see that the WorldClock plugin is started, as the time will be printed out during startup. You can also assemble custom servers through deploy/assemble command in GShell.
[ 246 ]
Chapter 9
Summary
In this chapter, we saw how Apache Geronimo's plugin architecture provides the capability for users to extend the functionality of the server. We saw how we can develop a plugin and deploy it to the server. We also had a look at the pluggable administration console, and how to create and plug in a new Administration Console portlet. We also saw how Apache Geronimo allows users to export custom server assemblies. In conclusion, Apache Geronimo turns out to be a very modular, customizable, and flexible application server. In the next chapter, we will see how we can administer Apache Geronimo. We will look into administering the different resources, plugins, and applications that are deployed on the server, as well as other server configuration options.
[ 247 ]
Administration Java EE server administration can be a daunting task. Geronimo proves otherwise. Thanks to the Geronimo project's foremost guiding principle—ease of use, Geronimo provides a powerful and user-friendly Administration Console that simplifies various administrative tasks, be it administering the web container, managing the applications, or monitoring the server. In this chapter, we will go through the common administration tasks in an application server and see how these tasks are performed in Geronimo. You will learn about: •
The Administration Console
•
Web server administration
•
JMS server administration
•
Monitoring the server
•
GShell
Administration Console
The Administration Console is a very powerful and user-friendly web application that simplifies several aspects of administering Geronimo. After the Geronimo server has been started, the Administration Console can be launched by using the URL http://localhost:8080/console. The default username is system, with a password of manager.
Administration
The welcome screen is shown in the next screenshot:
The Administration Console consists of several portlets based on the JSR 168 standard implemented by Apache Pluto. The Console Navigation pane on the left-hand side groups these portlets into different groups based on their function, for easy navigation. Server, Services, Applications, Security, Debug Views, and Embedded DB are the portlet groups in the Administration Console. You can add [ 250 ]
Chapter 10
new portlets and portlet groups to the extensible Administration Console by creating Administration Console extensions. Let us now examine each of the portlet groups and see what these portlets have to offer.
Server portlets
The portlets in the Server group allow you to manage server components such as the Web server, and JMS server, and monitor the JVM that is running the Geronimo server.
Information portlet
The Information portlet, as the name suggests, displays information about the server, such as the Version and Build of the Geronimo server, the server start and up times, details of the Operating System on which the server is running, details of the JVM version, and Server Memory Usage. The portlet screen is shown in the next screenshot:
[ 251 ]
Administration
This portlet also provides a graph showing the current memory usage by the server.
Java System Info portlet
The Java System Info portlet displays the details of Java system properties set in the JVM that is running the server. The system properties are grouped into several groups, namely Java, Virtual Machine, Operating System, Sun, User, and Etc, for better presentation.
Server Logs portlet
The Server Logs portlet lets you view the server logs. This portlet features the following: •
Log Manager: Enables you to temporarily change the server log settings in the configuration file used by log4j, such as the refresh interval, and log level. Note that these changes will be effective only for the current run of the server. The log4j configuration file value can be overridden at server startup by using the org.apache.geronimo.log4jservice.configuration system property.
•
Server Log Viewer: Enables you to view the messages that have been logged to geronimo.log. You can also filter the messages based on the line number in the log file, the message log level, and lines containing a specified text, with or without exception details.
•
Web Access Log Viewer: Allows you to view the details of requests coming into the web container. You can also filter the messages based on a date range, requests coming in from a specified remote address, requests coming in from a specific logged in user, the request method (GET, POST, and so on.), the requested URI, and line numbers in the log. See the section Web Server Administration, for more details on the Web Access Log Viewer.
•
Derby Log Viewer: Allows you to view the database logs of the embedded Derby database. You can also filter the results based on line numbers and lines containing a specified text.
Shutdown portlet
The Shutdown portlet allows you to shut down a running server from the Administration Console. Note that shutting down the server will disable the Administration Console, and the Administration Console will not be available again until the server is re-started. Use this portlet with caution.
[ 252 ]
Chapter 10
Web Server portlet
The Web Server portlet allows you to view the web server statistics, and manage the network connectors for the web container: Start, Stop, Restart, Edit, or Delete existing connectors, and create new HTTP, HTTPS, and AJP connectors. See the section, Web Server Administration, for more details.
Thread Pools portlet
The Thread Pools portlet lists the thread pools defined in the server, and lets you monitor the thread pools.
Apache HTTP portlet
The Apache HTTP portlet walks you through the process of configuring access to Geronimo through the Apache HTTP server, by using the mod_jk.so Apache module. See, Chapter 12, Clustering, for more details on using this portlet.
JMS Server portlet
The JMS Server portlet allows you to monitor and manage the ActiveMQ JMS server embedded in Geronimo. You can start, stop, edit, or delete existing JMS network listeners, and create new tcp, stomp, vm, udp, and multicast JMS network listeners. See the section JMS Server Administration for more details on using this portlet.
Monitoring portlet
The Monitoring portlet allows you to monitor local and remote Geronimo servers by creating graphs for specific server attributes exposed through MBeans, and compose views consisting of graphs. See the section Monitoring the server for more details on using this portlet.
Services portlets
The portlets in the Services portlet group allow you to access the repository service and resource adapters for the database and JMS.
[ 253 ]
Administration
Repository portlet
The Repository portlet displays the list of artifacts installed in the server's repository. It also allows you to install a new artifact into the repository. To see how an artifact can be used, click on the link provided over the artifact name. The portlet screen is shown in the next screenshot:
To upload an artifact to the repository, select the File option, under Add Archive to Repository. Complete the Group, Artifact, Version, and Type fields for the artifact, and click on the Install button. Note that the portlet may compute Artifact, Version, and Type values from the filename and populate these fields automatically. You can change these values as required. In the example in the above screenshot, once uploaded, the artifact will be available at libs/mylib/1.2/jar.
Database Pools portlet
The Database Pools portlet displays all of the database pools that are available on the server. This portlet also provides a wizard that will take you through a step-by-step process to create new database pools. See Chapter 3, Database Connectivity, for more details on using this portlet.
[ 254 ]
Chapter 10
JMS Resources portlet
The JMS Resources portlet displays all of the available JMS resource groups on the server. It also provides a wizard that can be used to add new JMS resources for ActiveMQ or any other JMS provider. See Chapter 4, JMS Connectivity, for more details on using this portlet.
Applications portlets
The portlets in the Applications group of portlets allow you to manage applications and services running on the Geronimo server. The administration tasks include installing new applications or services, starting, stopping, restarting, and uninstalling existing applications or services, installing plugins, creating plugins from configurations running in the server, assembling servers from the plugins in the current server, and so on. We will now go through the functions provided by various portlets in the Applications group.
Deploy New portlet
The Deploy New portlet allows you to install new applications and services on a Geronimo server. The portlet screen is shown in the screenshot below:
You can deploy an archive, a plan, or both. Select the archive file to be deployed in the Archive field, and/or the plan file in the Plan field. If the installed application or service is to be started once it has been installed, then select the option Start app after install (this option is selected by default). If the deployment step should replace an existing application or service with the same module ID as the one to be deployed, then select the Redeploy application option. Click on the Install button to complete the deployment operation.
[ 255 ]
Administration
System Modules portlet
The System Modules portlet lists the configurations that form the core of Geronimo, and the configurations that deploy services such as security realms. Apart from listing the configurations, this portlet provides links to Start, Stop, Restart, and Uninstall individual configurations. Notice that the portlet disables links to Stop, Restart, and Uninstall some of the configurations. The links corresponding to the Geronimo-provided components are disabled to prevent accidental stopping of the configurations, which may prevent the server from starting, or disable the Administration Console. To enable all of the command links, select the Expert User checkbox. Select the Show parent and child components checkbox to display the direct parent and child configurations for each of the listed configurations.
Web App WARs portlet
The Web App WARs portlet lists all of the standalone web applications that are deployed in the server. The portlet provides links to Start, Stop, Restart, and Uninstall individual web applications. Notice that the portlet disables links to Stop, Restart, and Uninstall Geronimo-provided components. To enable all of the command links, select the Expert User checkbox. Select the Show parent and child components checkbox to display the direct parent and child configurations for each of the listed configurations. For each of the running web applications, the URL column provides a link to access that web application.
EJB JARs portlet
The EJB JARs portlet lists all of the standalone EJB applications that are deployed on the server. The portlet provides links to Start, Stop, Restart, and Uninstall individual EJB applications. Notice that the portlet disables links to Stop, Restart, and Uninstall Geronimo-provided components. To enable all of the command links, select the Expert User checkbox. Select the Show parent and child components checkbox to display the direct parent and child configurations for each of the listed configurations.
Application EARs portlet
The Application EARs portlet lists all of the enterprise applications that have been deployed on the server. The portlet provides links to Start, Stop, Restart, and Uninstall individual EAR applications. Notice that the portlet disables links to Stop, Restart, and Uninstall Geronimo-provided components. To enable all of the command links, select the Expert User checkbox. Select the Show parent and child components checkbox to display the direct parent and child configurations for each of the configurations listed. The URL column provides links to any web applications that are a part of the EAR application. [ 256 ]
Chapter 10
J2EE connectors portlet
The J2EE Connectors portlet lists the configurations that deploy database pools and JMS resources. The portlet provides links to Start, Stop, Restart, and Uninstall individual configurations. Notice that the portlet disables links to Stop, Restart, and Uninstall Geronimo-provided components. To enable all of the command links, select the Expert User checkbox. Select the Show parent and child components checkbox to display the direct parent and child configurations for each of the listed configurations.
App Clients portlet
The App Clients portlet lists all of the Java EE application clients that are deployed on the server.
Plan Creator portlet
The Plan Creator portlet lets you create a Geronimo deployment plan in a step-by-step process for deploying applications in Geronimo, and then deploy the application on the Geronimo server. This is a work-in-progress and the portlet in Geronimo v2.1.4 only supports web applications. In order to create a deployment plan, we select the Archive file, and then click on Configure. In the first step, you configure the environment for your application, such as the configuration ID, and the class loader settings such as Hidden Classes, Non Overridable Classes, and Inverse Class Loading. You also configure a context-root for your web application. Note that the portlet provides default values for many fields. After editing or completing the required fields, click on Next. In the second step, you configure EJB, EJB Local, JDBC Connection Pool, JavaMail Session, JMS Connection Factory, JMS Destination, and the Web Service references that your application is using. For each of the EJB references, the portlet provides a drop-down list containing all of the EJBs available on the server. For each JDBC Connection Pool resource reference, the portlet will provide a drop-down list with all of the DB Pools available on the server. All you need to do is select the resource to be mapped to for each of the references, and then click on Next. In the third step, you configure the Security elements, if your application is using security. You select the Security Realm and Create role-to-principal mapping for each of the security roles. In order to add a principal to a role, select a type of principal in the Add dropdown, select the principal class in the Class dropdown, specify the principal name in the Name field, complete in any additional fields, depending on the type of principal (for example, selecting Login Domain Principal will require you to fill in the domain name), and then click on Add. Repeat the procedure to add more principals to the role. [ 257 ]
Administration
In order to specify the default Subject and run-as Subjects, select the Advanced Settings checkbox. Once that is done, click on Next to go to the next step. In the fourth step, you configure the Dependencies on existing configurations for your application. In this step, the portlet displays the list of configurations on the server. Note that the dependencies corresponding to the configuration that you have performed in the previous steps are automatically selected. You will only need to configure any additional dependencies in this step. Once that is done, click on Next to see the created plan. The portlet will display the created plan in an editable text area. At this stage, you can make any changes that you wish to make to the generated deployment plan. When you have finished, click on the Deploy WAR button to deploy your application with the generated plan. You may also save this plan to an external file and use the Deploy New portlet to deploy your application with the saved plan.
Embedded DB portlets
The portlets in the Embedded DB portlet group provide information on the Embedded Derby database server, and let you manage the databases on the server.
DB Info portlet
The DB Info portlet displays complete information regarding the database SystemDatabase on the Embedded Derby database server. The information displayed includes the version of Apache Derby, the Name and Version of the JDBC driver, the JDBC version level, the functions supported by the database, and so on.
DB Manager portlet
The DB Manager portlet enables you to manage the databases created in the Embedded Derby database server. The portlet screen is shown next:
[ 258 ]
Chapter 10
The DB Viewer lists the databases on the server. You can view the list of application tables, by clicking on the Application link listed under the View Tables column against the database name. You can view the list of system tables by clicking on the System link listed under the View Tables column against the database name. The following screenshot shows the application tables in SystemDatabase:
Click on the View Contents link provided against any table name to view the rows in that table.
[ 259 ]
Administration
The Run SQL section allows you to create new databases, delete existing databases, and run SQL commands against an existing database. To create a new database, enter the database name in the Create DB field, and click on Create. To delete a database, select the database name in the drop-down list provided against Delete DB, and click on Delete. To run SQL, select the database name in the drop-down list provided against the Use DB field, enter the SQL text in the SQL Command/s field, and click on Run SQL. Use a semicolon to separate multiple SQL statements. Results will be displayed for a single Select statement.
Debug Views portlets
The portlets in the Debug Views portlet group let you examine the internal state of the Geronimo server without having to use any external tools.
JMX Viewer portlet
The JMX Viewer portlet allows you to connect to the Geronimo's MBeanServer and manage the MBeans without having to use an external monitoring and management console such as JConsole. The portlet screen is shown in the next screenshot:
[ 260 ]
Chapter 10
You can browse the MBeans, search for MBeans, view attributes, execute operations, and view MBean information and statistics. You can navigate to the MBeans by using the tree structure provided on the left. The Attributes tab displays the names and values of the attributes of the MBean selected on the left-hand side. The Operations tab allows you to invoke the operations exposed by the MBean. The Info tab provides the identity details of the MBean such as abstractName, objectName, j2eeType, and so on. The Stats tab displays the statistics for statisticsProvider MBeans. The Search tab allows you to search for MBeans by providing Object Name Pattern.
LDAP Viewer portlet
The LDAP Viewer portlet lets you connect to an LDAP server and browse the LDAP directory. The portlet screen is shown in the next screenshot:
In the Connection Info tab, complete the following fields: •
Host: The hostname or IP address of the LDAP server.
•
Port: The port on which the LDAP server is running.
•
Version: Select the version of the LDAP protocol being used.
•
Base DN: The top level of the LDAP directory tree.
•
SSL: If you select this option, then the port is SSL-enabled.
•
Anonymous Bind: Select this option if the connection to the LDAP server should be anonymous. Otherwise, complete the User DN and Password fields.
•
User DN: The distinguished name of the user to use when connecting to the LDAP server.
•
Password: The credentials of the user specified in the User DN field, for connecting to the LDAP server. [ 261 ]
Administration
Click on Connect to connect to the LDAP server. Once connected, you can navigate through the directory tree. The following screenshot shows the directory entry for uid=admin, ou=system:
The Attributes tab shows the various attribute names and values of the directory entry selected in the tree on the left. You can search the directory by using the Search tab, as shown in the next screenshot:
Complete the following fields: •
Search DN: The distinguished name to search for.
•
Filter: The filter criteria for the results matching the search DN.
•
Search scope: Select One level if the matching entries have to be directly below the base. Select Sub-tree level to match entries at any level in the directory tree.
Click on Search to view the entries matching the specified criteria. [ 262 ]
Chapter 10
ClassLoader Viewer portlet
With multiple class loaders in a Java EE application server, instances of ClassNotFoundException, NoClassDefFoundError due to classes not loaded, classes loaded into multiple class loaders, and classes not available for loading can become a debugging nightmare for developers. The ClassLoader Viewer portlet allows you to search for classes loaded in the various class loaders in JVM running on the Geronimo server. The portlet screen is shown in the next screenshot:
The portlet displays the class loaders as a tree, starting with the JVM's extensions class loader at the root. For each class loader, expand the Classes child to view the classes currently loaded. Expand the Interfaces child to view the interfaces currently loaded. Next to the Interfaces is the list of all of the child class loaders of that class loader. Expand the child class loader entries to further browse the classes, interfaces, and their child class loaders. Geronimo uses a multi-parent class loader architecture. With this, it is possible that a class loader has more than one direct parent. The ClassLoader Viewer portlet provides the ability to invert the class loader tree so that all of the direct parent class loaders are displayed with each class loader.
[ 263 ]
Administration
The following screenshot shows the inverted class loader tree for a database pool:
Notice that in this example, the console.dbpool/LibraryDS/1.0/rar class loader has three direct parent class loaders with IDs: org.apache.geronimo.configs/j2eeserver/2.1.4/car, org.apache.geronimo.configs/system-database/2.1.4/car, and org.apache.geronimo.configs/transaction/2.1.4/car. Furthermore, the org.apache.geronimo.configs/system-database/2.1.4/car class loader has three direct parent class loaders with IDs: org.apache.geronimo.configs/ derby/2.1.4/car, org.apache.geronimo.configs/j2ee-server/2.1.4/car, and org.apache. geronimo.configs/transaction/2.1.4/car. In order to search for a class, enter the class name in the Search Text field and click on Find. To find the next result, click on Find Next. To restrict the search to a selected part of the tree, click on the element, and then Search only selected.
[ 264 ]
Chapter 10
JNDI Viewer portlet
The JNDI Viewer portlet allows you to view the various resources bound to JNDI in the Global Context, along with the context of each of the artifacts, such as servlets, EJBs, web modules, EJB modules, resource adapter modules, and enterprise applications. The portlet screen is shown in the next screenshot:
[ 265 ]
Administration
The following screenshot shows the JNDI names bound in the context of a session bean and a web application.
Note the JNDI entries bound in the context of LibraryBean in the EJB application packt.samples/cmp-jpa-ejb/1.0/jar shown above. You can also see the JNDI entries bound in the context of the web application org.apache.geronimo.plugins/ mconsole-tomcat/2.1.4/car. You can search for a specific text. To do this, enter the text in the Search Text field, and then click on Find. If the text search is to be case sensitive, then select the Case Sensitive option. If you want to restrict the search to a selected sub-tree, then select the Search only selected option.
[ 266 ]
Chapter 10
Dependency Viewer portlet
The Dependency Viewer portlet lets you view the dependencies between various configurations deployed on the Geronimo server, and also list the artifacts in the repository. The portlet screen is shown in the next screenshot:
You can browse the configurations of various enterprise applications, EJB applications, web applications, resource adapters, application clients, and system modules deployed on the server. For each of the configurations, expand the dependencies to view the parent configurations and dependencies on the artifacts in the repository. You can also perform a text search by entering the text in the Search Text field, and then clicking on the Find button. Click on Find Next to search for the next occurrence of the text. Select the Search only selected option to restrict the search to a selected sub-tree.
[ 267 ]
Administration
Web Server administration
The Web Server portlet in the Server portlet group allows you to manage the network connectors for the web container, and view web server statistics. In this section, we will see how the Web Server portlet can be used to perform various web server administration tasks. The Web Server portlet screen is shown in the next screenshot:
The portlet lists the existing network connectors for the web container. The Protocol column displays the protocol used by the connector. The links provided in the Actions column allow you to manage the connectors. To stop a running connector, click on the Stop link under Actions. To start a stopped connector, click on the Start link under Actions. To stop and start a running connector, click on the Restart link under Actions. The Restart link is particularly useful when you want to restart a connector that is listening on the same port as the one on which you are accessing the Administration Console application. To edit the settings of a connector, click on the Edit link under actions. The next screen will show the connector attributes. Edit the attributes as necessary, and then click on Save to return to the Network Listeners screen. Note that any changes to a network connector will not take effect until the connector is started again, either by using Restart, or Stop and then Start. To delete an existing connector, click on the Delete link under Actions, and confirm the deletion in the pop-up dialogbox. For a Tomcat web container, you can add blocking IO (BIO), non-blocking IO (NIO), and Apache Portable Runtime (APR) connectors for the HTTP and HTTPS protocols. To add new connectors to the Tomcat web container, use the links provided under Add new section.
[ 268 ]
Chapter 10
HTTP connectors
To add a new BIO HTTP connector, click on the Tomcat BIO HTTP Connector link. This will show a screen similar to the one shown in the next screenshot:
The Attribute column shows the name of the attribute. The Type column shows the attribute type. The Value column provides a field in which you can enter a value for the attribute. The Description column gives a detailed description of the attribute. Required attributes are indicated by an asterisk. For a BIO HTTP connector, the following attributes are required: •
uniqueName: A name to identify the connector. This name has to be different from the name of any other web connectors on the server.
•
address: Host name or IP address to bind the connector to. Common values are 0.0.0.0 (all interfaces) or localhost (local connections only).
•
port: The TCP/IP port to which the connector will be bound.
[ 269 ]
Administration
Enter the values for these required attributes. The remaining fields are optional, and most fields are populated with the default values. You may edit or enter values for the optional fields, as necessary. Once that is done, click on Save to create a new BIO HTTP connector and return to the list of connectors. The newly-added connector will be started automatically. To add a new NIO HTTP connector, click on the Tomcat NIO HTTP Connector link under the Add new section. Enter the required attributes: uniqueName, address, and port. The remaining attributes are optional and most of them are populated with default values. Edit or enter the values for these optional attributes as necessary. Once that is done, click on Save to create a new NIO HTTP connector, and return to the list of connectors. The newly-added connector will be started automatically. To use APR connectors for a Tomcat web container, you will need to install the APR native components. See the Tomcat documentation, available at http://tomcat.apache.org/tomcat-6.0-doc/apr.html, for details on installing the components required for APR. Once the APR components are installed, you can create APR connectors. In order to add a new APR HTTP connector, click on the Tomcat APR HTTP Connector link under the Add new section. This will show a screen, similar to the one shown in the next screenshot:
[ 270 ]
Chapter 10
Enter the required attributes: uniqueName, address, pollTime, pollerSize, port, sendfileSize, and useSendfile. Here, the attributes pollTime, pollerSize, sendfileSize, and useSendfile are APR-related attributes. The default values of attributes are populated automatically. Edit or enter the values for all of the attributes. When finished, click on Save to create a new APR HTTP connector, and return to the list of connectors. The newly-added connector will be started automatically.
HTTPS connectors
For HTTPS connectors, you will need to configure the SSL-related attributes in addition to the attributes for an HTTP connector. To create a BIO HTTPS connector, click on the Tomcat BIO HTTPS Connector link under the Add new section. This will show a screen similar to the one shown in the screenshot below:
[ 271 ]
Administration
The additional attributes related to SSL configuration are: •
keystoreFile: The file that holds the keystore. The value for this attribute is the path of the file relative to the directory.
•
algorithm: The certificate encoding algorithm to be used. Set this to Default so that the connector does not need to be reconfigured if the server is started with a different JVM.
•
ciphers: A comma-separated list of the encryption ciphers that may be used. If not specified, then any available cipher may be used.
•
clientAuth: Set to true if you want SSL to require a valid certificate chain from the client before accepting a connection.
•
keyAlias: The alias used for the server certificate in the keystore. If not specified, then the first key read in the keystore will be used.
•
keyStorePass: Set the password used to access the keystore file. This is also the password used to access the server private key within the keystore (so the two passwords must be set to be the same on the keystore).
•
keyStoreType: Set the keystore type. Normally, this is set to the default JKS.
•
sslProtocol: This should normally be set to TLS, although some (IBM) JVMs don't work properly with popular browsers unless this attribute is set to SSL.
•
trustStoreFile: The trust store file used to validate client certificates. The value for this attribute is the path of the file relative to the directory.
•
truststorePass: The password to access the trust store.
•
truststoreType: Set the keystore type of the trust store file. Normally, this is set to the default JKS.
The truststoreFile, truststorePass, and truststoreType attributes are only required if clientAuth attribute is set to true. In addition to the uniqueName, address, and port attributes, enter the values for the SSL-related attributes as well as the attributes required for an HTTP connector. When you have finished, click on Save to create a new BIO HTTPS connector, and return to the list of connectors. The newly-added connector will be started automatically. An NIO HTTPS connector can be created in a similar manner by completing the above SSL-related attributes in addition to the normal connector attributes.
[ 272 ]
Chapter 10
AJP connectors
To create a new AJP connector, click on the Tomcat AJP Connector link under the Add new section. This will show a screen similar to the one shown in the next screenshot:
For an AJP connector, the following attributes are required: •
uniqueName: A name to identify the connector. This name has to be different from the name of any other web connectors on the server.
•
address: Hostname or IP address to bind the connector to. Common values are 0.0.0.0 (all interfaces) or localhost (local connections only).
•
port: The TCP/IP port to which the connector will be bound.
Enter the values for these required attributes. The remaining fields are optional, and most fields are populated with default values. You may edit or enter values for the optional fields as necessary. When finished, click on Save to create a new AJP connector and return to the list of connectors. The newly-added connector will be started automatically.
[ 273 ]
Administration
Web Server Logs
The Server Logs portlet in the Server portlet group provides a Web Access Log Viewer. The portlet screen is shown below:
You can filter the access logs by date range, the identity of the user accessing the web container, the request method and URI, and can also limit number of results to display. The following is a description of each of the fields: •
From (MM/DD/YYYY): The start date of the log entries to search for.
•
To (MM/DD/YYYY): The end date of the log entries to search for.
•
Ignore Dates: Select this to ignore the dates in the search criteria.
•
Remote Address: The remote address from which the web request is received.
•
Authenticated User: The authenticated username from which the web request is received.
[ 274 ]
Chapter 10
•
Request Method: The HTTP request method for the web request. Supported values are GET, PUT, POST, DELETE, and ANY. Select ANY to ignore the request method in the search.
•
Requested URI: The URI of the resource requested. The value entered here will be mapped to the start of requested URIs in the web request.
•
Start Result: The line number in the logfile from which the log entries are to be searched.
•
Max Results: The maximum number of log entries to be displayed.
Enter the values for the required fields, and then click on Filter Log to activate the filter criteria for the first time. To search for the logs once again with the same criteria, click on Refresh.
JMS server administration
Apache Geronimo integrates Apache ActiveMQ as a JMS provider. In this section, we will see how to administer the ActiveMQ server embedded in Geronimo.
JMS listeners
The JMS Server portlet in the Server portlet group enables you to manage the existing JMS Network Listeners and create new network listeners for ActiveMQ. The portlet screen is shown below:
[ 275 ]
Administration
The JMS Network Listeners section lists the existing network listeners. By default, Geronimo provides listeners for the stomp and tcp protocols. You can stop, start, edit, or delete existing listeners by clicking on the corresponding links provided in the Actions column against a connector name. Note that any changes made to a listener that is running will not take effect until that listener is stopped and restarted. You can create new network listeners for ActiveMQ by clicking on the links provided under Add connector to ActiveMQ. You can create listeners for tcp, stomp, vm, udp, and multicast protocols. For example, to create a new listener for the tcp protocol, click on the Add new tcp listener link. This will display a screen similar to the one shown below:
Enter a Unique Name for the listener, the Host, and Port to bind the listener to, and then click on Save. This will add a new JMS network listener with the tcp protocol for ActiveMQ.
Monitoring the server
The Monitoring portlet in Server portlets group allows you to monitor a local or a remote Geronimo server. The console is designed to monitor a Geronimo instance running in a separate JVM. The console can gather statistics and performance data from multiple Geronimo servers, and display this data graphically. The Monitoring console uses the Management EJB (MEJB) to gather statistics from a remote Geronimo server. You may also use JMX to gather statistics from a remote server, but this would require the remote server to install and run the org.apache.geronimo.plugins. monitoring/agent-car-jmx/2.1.4/car plugin. The portlet screen is shown below:
[ 276 ]
Chapter 10
The Monitoring console defines Servers and Graphs with statistics collected from servers, and Views consisting of one or more graphs. In this section, we will see how the Monitoring console plugin can be used to monitor a Geronimo server.
Adding a Server
To add a server for monitoring, click on the Add a new server link. This will show a screen similar to the one shown below:
Complete the following fields: •
Name: A name to identify this server.
•
IP/Hostname: Hostname or IP address of the server to be monitored.
•
Protocol: Select EJB to use the MEJB. Select JMX to use the JMX server in the remote JVM.
•
Port: The port number to connect to the server. The default port number is 4201 for EJB and 1099 for the JMX protocol.
•
Username: The administrator username of the remote server.
•
Password: The password for the username entered above.
[ 277 ]
Administration
Click on Add to complete adding this server. The newly-added server will be listed under Servers, as shown in the screenshot below:
The server is enabled by default. In order to disable the server, click on the Disable link under the Actions column. To edit an existing server, click on the Edit link under Actions. On the next screen, after editing the fields, click on Save to save your changes. A text of Online in the Status column indicates that the Monitoring console is able to connect to the server. Data collection is disabled by default. Enable data collection by clicking on the Enable Query link under actions. After enabling data collection, click on the link provided in the Name or IP/Hostname column to view the live statistics for chosen MBeans, as shown in the next screenshot:
[ 278 ]
Chapter 10
The Statistics Collected column shows the MBeans that are enabled for statistics collection. The Statistics Available column shows the MBeans that can be enabled for statistics collection. To disable statistics collection, click on the X next to the MBean name in the Statistics Collected column. To enable statistics collection, click on the + next to the MBean name under the Statistics Available column.
Adding a Graph
To add a graph, click on the Add a new graph link. This will display a screen similar to the one shown in the next screenshot:
Complete or select the following fields: •
Server: Select a server from which the statistics will be collected.
•
Name: A unique name for the graph.
•
Description: A description for this graph.
•
X axis label: A label for the horizontal axis.
•
Y axis label: A label for the vertical axis.
•
Timeframe: A time frame for the graph. [ 279 ]
Administration
•
Mbean: The Mbean on the server that will provide the statistics.
•
Data series: Select As-is for the value as it is or Change (Delta) in for the difference. Select the statistic.
•
Math operation: Select an operation to combine more than one statistic for the graph.
•
Data series2: Select As-is for the value as it is or Change (Delta) in for the difference. Select the statistic.
Click on Add to add the new graph. The new graph will be shown under Graphs. To edit the graph, click on the Edit link under the Actions column. Click on the graph name to view the graph in a pop-up window.
Creating a new view
You can create a view consisting of graphs. In order to create a view, click on the Create a new view link. This will display a screen similar to the one shown below:
[ 280 ]
Chapter 10
Complete the Name and Description fields for the view, and select the Graphs to be displayed in the view. Click on Save to add the view. The new view will be shown under Views. To edit a view, click on the Edit link provided under the Actions column. Click on the view name to see the graphs in the view. The following screenshot shows a sample view:
This view shows two graphs. The first graph shows the current heap proportion to max heap size over time. The second graph shows the current heap size over time. Note that you can also compose views consisting of graphs from different servers.
[ 281 ]
Administration
GShell
GShell is a command-line processor for creating command-line applications for administering the Geronimo server. GShell supports command editing, command history, I/O redirection, and so on. Geronimo administration commands such as startup, shutdown, and deploy are implemented by using GShell. In this section, we will see how GShell can be used to administer a Geronimo server.
Starting and exiting GShell
GShell can be started by using the script file gsh provided in the /bin directory. The GShell window is shown below:
[ 282 ]
Chapter 10
The quit or exit command will exit from the GShell environment.
Getting help
Use the help command to get a list of supported commands. To get help on any command, use the --help option with that command. The following screenshot shows help for the geronimo/start-server command:
The first column shows the long and short form of each option, and the second column provides an explanation of the option.
Supported commands
The GShell environment supports the following commands: •
geronimo/start-server: Starts a Geronimo server. If the --background option is not used, then the server will run in the shell, and you will need to open another shell to interact with the server.
[ 283 ]
Administration
•
geronimo/stop-server: Stops a Geronimo server. Use the --hostname and --port options to specify the RMI host and port of the server to be stopped.
The default values are localhost and 1099. You will be prompted for the username and password if you have not specified the credentials by using the --username and --password options.
•
geronimo/start-client: Starts an application client. Specify the configuration name of the application client and the application client arguments on the command line.
•
geronimo/wait-for-server: Waits for the start of a Geronimo server to complete the startup. Use the --hostname and --port options to specify
the RMI host and port of the server to be stopped. The default values are localhost and 1099. You will be prompted for the username and password if you have not specified the credentials by using the --username and --password options. •
deploy/connect: Connects to a running Geronimo server such that further deploy commands will not require the host, port, username, and password to be specified, until disconnected. Use the --hostname and --port options to specify the RMI host and port of the server to connect to. The default values are localhost and 1099. You will be prompted for the username and password if you have not specified the credentials by using the --username and --password options.
•
deploy/disconnect: Disconnects a Geronimo server that was connected earlier by using deploy/connect.
•
deploy/distribute: Executes the distribute deployer operation. Specify the module and plan files as arguments. Use the --inPlace option to specify in-place deployment. Use the --targets option to specify the deployment target configuration stores. Use the --hostname and --port options to
specify the RMI host and port of the target server. The default values are localhost and 1099. You will be prompted for the username and password if you have not specified the credentials by using the --username and --password options. •
deploy/restart: Restarts a running configuration and any running child configurations. Specify the configuration ID as an argument. Use the --hostname and --port options to specify the RMI host and port of the target server. The default values are localhost and 1099. You will be prompted for the username and password if you have not specified the credentials by using the --username and --password options.
[ 284 ]
Chapter 10
•
deploy/install-plugin: Installs a plugin into the Geronimo server. Specify the plugin file as an argument. Use the --hostname and --port options to specify the RMI host and port of the target server. The default values are localhost and 1099. You will be prompted for the username and password if you have not specified the credentials by using the --username and --password options.
•
deploy/deploy: Deploys the specified module and/or plan file. Specify the module and plan files as arguments. Use the --inPlace option to specify in-place deployment. Use the --targets option to specify the deployment target configuration stores. Use the --hostname and --port options to
specify the RMI host and port of the target server. The default values are localhost and 1099. You will be prompted for the username and password if you have not specified the credentials by using the --username and --password options. •
deploy/redeploy: Redeploys a specified module and/or plan file. Specify the module file, plan file, and the configuration ID as arguments. Use the --hostname and --port options to specify the RMI host and port of the target server. The default values are localhost and 1099. You will be prompted for the username and password if you have not specified the credentials by using the --username and --password options.
•
deploy/undeploy: Uninstalls a specified configuration. Specify the configuration ID as an argument. Use the --hostname and --port options to specify the RMI host and port of the target server. The default values are localhost and 1099. You will be prompted for the username and password if you have not specified the credentials by using the --username and --password options.
•
deploy/list-modules: List the configurations deployed on the server. Use the --hostname and --port options to specify the RMI host and port
of the target server. The default values are localhost and 1099. You will be prompted for the username and password if you have not specified the credentials by using the --username and --password options.
•
deploy/install-library: Installs a specified library file in the repository. Specify the group ID by using the --groupId option. Artifact ID, version, and type will be determined based on the file name. Use the --hostname and --port options to specify the RMI host and port of the target server. The default values are localhost and 1099. You will be prompted for the username and password if you have not specified the credentials by using the --username and --password options.
[ 285 ]
Administration
•
deploy/list-targets: Lists the available target configuration stores on the server. Use the --hostname and --port options to specify the RMI host and
port of the target server. The default values are localhost and 1099. You will be prompted for the username and password if you have not specified the credentials by using the --username and --password options.
•
deploy/stop: Stops a specified configuration and any child configurations
that are running. Specify the configuration ID as an argument. Use the
--hostname and --port options to specify the RMI host and port of
the target server. The default values are localhost and 1099. You will be prompted for the username and password if you have not specified the credentials by using the --username and --password options.
•
deploy/start: Starts a specified configuration and any parent configurations
•
deploy/list-plugins: Lists the available plugins in a plugin repository. Specify the repository URL by using the --repository option. Use the option --refresh-list to refresh the plugin list. Use the option --refreshrepository to refresh the repository. This is an interactive command. If a
that are currently not running. Specify the configuration ID as an argument. Use the --hostname and --port options to specify the RMI host and port of the target server. The default values are localhost and 1099. You will be prompted for the username and password if you have not specified the credentials by using the --username and --password options.
repository is not specified, then you will be able to select a repository from the plugin repositories that have been added to the server. Once the list of plugins is displayed, you will have the option to install the plugins by providing the number in the displayed list. Use the --hostname and --port options to specify the RMI host and port of the target server. The default values are localhost and 1099. You will be prompted for the username and password if you have not specified the credentials by using the --username and --password options. •
deploy/assemble: Assembles a server from the current server with some or
all of the configurations on the current server. Specify the group ID, artifact ID, and version by using the --groupId, --artifact, and --version options. Specify an archive format of .zip or tar.gz by using the option --format. Use the --path option to specify the location of the assembly relative to the directory. Use the --hostname and --port options to specify the RMI host and port of the target server. The default values are localhost and 1099. You will be prompted for the username and password if you have not specified the credentials by using the --username and --password options.
[ 286 ]
Chapter 10
•
deploy/login: Saves the username and password for this connection so
that further deployment operations to this connection will not require the user credentials to be specified. Use the --hostname and --port options to specify the RMI host and port of the target server. The default values are localhost and 1099. Use the --username option to specify the username and --password option to specify the password.
•
jaxws/wsimport: Generates JAX-WS artifacts from WSDL. Run the command with the --help option to get detailed information on running the command.
•
jaxws/wsgen: Generates JAX-WS artifacts from a class. Run the command with the --help option to get detailed information on running the command.
The following are some general purpose commands supported by GShell: • • • • • • • • • • •
source: Loads a file or URL into the current shell. Use this command to
execute a command script that has been saved to a file. set: Sets a variable. unset: Unsets a variable. help: Shows the online help for a command. clear: Clears the terminal screen. ?: Alias for help. echo: Echoes or prints arguments to STDOUT. quit: Alias for exit. exit: Exits the shell. . (dot): Alias for source. print: Alias for echo
These commands can be used to create rich command scripts to administer a Geronimo server.
Summary
In this chapter, we have seen how various portlets in the Administration Console simplify administrative tasks such as managing web server connectors, managing applications, managing databases and JMS resources, monitoring the server, and viewing the logs. We have also gone through the features of GShell, which provides a scripting environment to manage a Geronimo server. In the next chapter, we will discuss the Geronimo Eclipse Plugin. You will learn how to install the Geronimo Eclipse Plugin in Eclipse IDE and how to develop, deploy, and debug Java EE applications on the Geronimo server. [ 287 ]
Geronimo Eclipse Plugin The Geronimo Eclipse Plugin (GEP), as the name suggests, is a plugin for the Eclipse framework that extends the web tools framework provided by Eclipse to provide support for Apache Geronimo-specific artifacts. The GEP is a power tool for application developers who want to rapidly develop, deploy, test, and debug their applications in the development and test environment that is provided by the plugin. GEP does this by integrating Eclipse, the Web Tools Platform (WTP), and Apache Geronimo to provide an IDE with a rich feature set that leverages the features of each of its constituent components. The Geronimo Eclipse Plugin also provides developers with a comprehensive set of deployment plan editors that greatly simplify the process of creating Apache Geronimo-specific deployment plans for Java EE artifacts that you want to deploy on the server. The Geronimo Eclipse Plugin is an important component in driving the adoption of Apache Geronimo by making Java EE 5 development and troubleshooting easier for users of the Apache Geronimo application server. In this chapter, we will introduce you to Eclipse and the Web Tools Platform, and then guide you through installing the Geronimo Eclipse Plugin onto Eclipse with WTP. We will then go through the various features of the GEP and finally show how to develop the sample application, by using the Geronimo Eclipse Plugin. The topics discussed are as follows: •
Eclipse and web tools framework
•
GEP download and installation
•
Developing an application using GEP
•
Deploy, and run or debug the application in Geronimo
Geronimo Eclipse Plugin
Eclipse and the web tools framework
Eclipse is an open source Integrated Development Environment (IDE) from the Eclipse Foundation. It is an IDE written mostly in Java but not limited to being an IDE for Java. It supports a variety of languages like C, C++, Groovy, Java, and so on, by means of plugins. It is based on the OSGi framework. Eclipse is one of the most popular and widely-used IDEs for Java developers. It is also used by many third party vendors as the base for their commercially available IDEs, which actually are Eclipse, bundled with their custom plugins. The Eclipse community also develops and maintains a rich ecosystem of open source plugins for the base Eclipse IDE, as subprojects. One of these subprojects is the Web Tools Platform, which extends Eclipse with a set of features that are commonly required for Java EE development. It provides source and deployment descriptor editors for editing a variety of Java EE artifacts, as well as wizards for creating common Java EE components. It also provides tools for the deployment, testing, and debugging of Java EE applications on various application servers, as well as extension points for creating plugins for other application servers.
Download and installation
You can download Eclipse from the Eclipse Foundation’s web site http://www.eclipse.org. The latest released version of the Eclipse IDE , as of the time of writing, is Eclipse Ganymede. After installing Eclipse, you will need to download and install the Web Tools Platform on top of Eclipse. Otherwise, you can download an Eclipse version that includes the Web Tools Platform from the link http://www.eclipse.org/downloads/packages/. Select the Eclipse IDE for Java EE developers link to download the Eclipse IDE along with the Web Tools Platform. Ensure that you download the above-mentioned Eclipse package, as it contains all of the plugins that are prerequisites of the Geronimo Eclipse Plugin. For the Windows platform, the download will be provided as a ZIP archive. Extracting it will create a directory called eclipse. Open the eclipse directory and run the eclipse.exe executable, to bring up the dialog box shown below. If you are using a Unix-based platform (for example, Linux or Mac OS), the steps will be slightly different, and you would need to download the package for that particular platform. You would then need to extract the tar.gz or tar.bz2 archive to a directory represented by $ECLIPSE_HOME. You will need to invoke $ECLIPSE_HOME/eclipse in order to bring up a dialog similar to the one shown next:
[ 290 ]
Chapter 11
Click on OK to bring up the workspace. This will take you to the welcome screen. Click on the workbench icon to open up the workbench, where you can create and develop Java EE 5 artifacts. This is shown in the following screenshot:
[ 291 ]
Geronimo Eclipse Plugin
GEP download and installation
We have already downloaded and installed the prerequisites for the Geronimo Eclipse Plugin, namely: •
JDK 1.5
•
Eclipse IDE for Java EE (Ganymede or Europa), which includes WTP
•
Apache Geronimo application server
Follow the steps below to install GEP: 1. Launch Eclipse, to bring up the workspace, as shown in the previous screenshot. Eclipse will be launched with the Java EE perspective by default. 2. In the bottom of the rightmost pane, select the Servers tab, and right-click on New | Server. This will bring up the screen that is shown in the next screenshot:
[ 292 ]
Chapter 11
3. Click on the Download additional server adapters link to bring up the Install New Server Adapter dialog box, as shown in the next screenshot:
4. Select Geronimo v2.1 Server Adapter, and then click on Next. 5. Read and Accept the license agreement, and then click on Finish. 6. You will see a dialog box, informing you that support for Apache Geronimo will be installed. Click on OK to start the download and installation of the Geronimo Eclipse Plugin. After installation, Eclipse will be restarted, and you will again need to select the workspace to bring up the workbench. Continue with the next steps to create a Geronimo Server instance.
[ 293 ]
Geronimo Eclipse Plugin
7. In the Servers tab in the lower-right pane, select New | Server. This will bring up the screen shown in the following screenshot:
[ 294 ]
Chapter 11
8. Expand Apache, select Apache Geronimo v2.1 server, and then click on the Next button. This will bring up the screen shown in the next screenshot:
9. Enter the Application Server Installation Directory as , and select the correct JRE from the list of Installed JRE. Click on Next to bring up the next screen, or click on Finish to complete the installation. If you click on Finish, then you can skip the remaining steps. 10. If you click on Next, then you get the next screen where you can specify the location of the Apache Geronimo source code so that you can step through the Geronimo source code as well, when debugging your application. This is shown in the next screenshot:
[ 295 ]
Geronimo Eclipse Plugin
11. Clicking on the Next button will bring up a window where you can specify the Hostname, Administrator id, and Administrator password. The fields will be populated with default values. It will also show the RMI Naming and Web Connector ports. This is shown in the next screenshot:
[ 296 ]
Chapter 11
12. Click on Finish, and an instance of the Apache Geronimo application server will be created in your workspace. 13. You can right-click on the server to bring up a list of options, including Start and Stop. Select Start in order to start the instance. On starting the server, the state of the server, displayed in Eclipse, will change to started. This is shown in the next screenshot:
[ 297 ]
Geronimo Eclipse Plugin
Developing an application in GEP
We will now go through the steps that are involved in developing an enterprise application using the Geronimo Eclipse Plugin. We will use Java EE components from an existing sample application for our convenience, namely LibraryApp, which we saw in Chapter 5. The steps are as follows: 1. Firstly, we will need to create the project in Eclipse. For doing this, right-click on the project explorer tab on the left-hand side of the workbench, and select New | Enterprise Application Project. This will bring up the EAR Application Project window, as shown in the next screenshot:
2. Enter the Project name as LibraryApp, and click on Next. The next screen that comes up shows the Java EE Module Dependencies. This is shown in the following screenshot:
[ 298 ]
Chapter 11
3. Click on the New Module button to bring up the Create default Java EE modules window, as shown in the next screenshot:
[ 299 ]
Geronimo Eclipse Plugin
4. Deselect the Create default modules checkbox to get options to create specific modules. By default, one module of each Java EE type is selected to be created. Click on Finish. 5. On the next screen, select the Create deployment descriptor checkbox, and click on Next to finish creating the application structure. This is shown in the next screenshot:
You will now have the application created with both Java EE 5 descriptors and Apache Geronimo-specific deployment plans.
[ 300 ]
Chapter 11
6. Clicking on the Apache Geronimo-specific deployment plan will bring up the deployment plan editors for that specific plan. The deployment plan editor for the plan of the application client module is shown in the next screenshot:
Note that the generated plans have certain fields filled in automatically. Now we can go through developing the application, as explained in the next steps.
[ 301 ]
Geronimo Eclipse Plugin
7. Firstly, we will create the EJB in the application, namely MailBean. Right-click on the EJB project, namely, LibraryAppEJB and select new -> Session Bean. This will bring up the pop-up window shown in the next screenshot:
8. Complete the fields, as shown in the screenshot, and click on Finish to create the EJB and its remote and local interfaces.
[ 302 ]
Chapter 11
9. Similarly, to create a Servlet, right-click on the Web project LibraryAppWeb, and select New | Servlet to bring up the pop-up window shown in the next screenshot:
10. Enter the fields, as shown in the above screenshot, and click on Next to bring up the Create Servlet screen, as shown in the next screenshot, where you can enter the URL mappings and initialization parameters:
[ 303 ]
Geronimo Eclipse Plugin
11. Click on Next to add any interfaces and methods to the generated Servlet, and then click on Finish. This will generate a stub for the Servlet, which you can fill with your code. The application client project will already have an application client class that you can enter your client code into. 12. To create a web service, right-click on the Web project, and select New | Other | Web Services | Web Service. This will bring up the dialog box shown in the following screenshot:
13. You can follow the instructions in the dialog to create a new web service. [ 304 ]
Chapter 11
The deployment plans can be edited by using the deployment plan editors, and you can click on the Source tab if you want to manually edit the XML file. Thus, we have seen how we can develop common Java EE artifacts in the Geronimo Eclipse Plugin. Support for the development of Java EE artifacts is implemented by WTP, and the steps can be found in greater detail in the WTP documentation.
Deploying and running or debugging the application in Geronimo
You can deploy the applications that you develop into the application server from the Eclipse environment by using the Geronimo Eclipse Plugin. You can right-click on the server instance shown in the Servers tab, and then select, add, or remove projects. This will bring up the Add and Remove Projects dialog box. The Available projects section will list the projects that are available in your workspace. You can select the one that you want to deploy on the server, and then click on Add. This will move the selected project to the Configured projects list. This is shown in the next screenshot:
[ 305 ]
Geronimo Eclipse Plugin
You can click on the Finish button to deploy and start the application. You can also launch the Administration Console, in case you want to view or create server-scoped resources, or perform other administrative tasks, by right-clicking on the server and selecting Launch Administrative Console in the pop-up menu that is displayed. You can run the application by right-clicking on the application and selecting Run As | Run on Server from the pop-up menu that is displayed. You can debug the application by right-clicking on the application and selecting Debug As | Debug on Server from the pop-up menu that is displayed. If your server has already started, then a dialog box will be displayed, asking you for permission to switch to debug mode, which will require a server restart. Once you click on OK, the server and your application will be restarted in debug mode, and the application will stop during its execution at any breakpoints that you have defined.
Summary
In this chapter, we saw how the Geronimo Eclipse Plugin integrates Apache Geronimo with the Eclipse Web Tools Platform to provide a powerful environment for rapid application development. We also saw how we can develop, deploy, run, and debug Java EE 5 applications by using Eclipse WTP and the Geronimo Eclipse Plugin. In the next chapter, we will look at the clustering and load balancing features provided by Apache Geronimo for high availability and scalability.
[ 306 ]
Clustering A cluster is a group of linked servers working closely together to provide enterprise services—Servlets and EJBs—as if it were a single server. Clusters can be used for various reasons such as high-availability, load balancing, and so on. Configuring multiple servers to form a cluster is referred to as Clustering. These servers, referred to as nodes in the cluster, could be running on the same system or separate systems. Typically, the nodes exchange messages to synchronize data, such that any node can process the requests in a distributed application. Geronimo provides a rich set of features for creating multiple servers from the same installation (referred to as a vertical cluster), easy application management across multiple server installations on multiple systems (referred to as a horizontal cluster), and session replication between nodes in the cluster. In this chapter, we will examine the various features provided by Geronimo for the clustering of web applications and configure an Apache web server to achieve load balancing and high availability. You will learn about: •
Clustering support in Geronimo
•
Getting Geronimo server and your application ready for clustered deployment
•
Load balancing your clustered application by using Apache web server
•
Running multiple server instances from a single Geronimo installation
•
Farming
Clustering
WADI
Geronimo supports the clustering of web applications by using WADI, Application Distribution Infrastructure. When a clustered web application is deployed in Geronimo, the deployer adds dependencies on two configurations: •
•
org.apache.geronimo.configs/clustering//car: This configuration
contains runtime dependencies that the clustered application must have. This configuration also has a Node GBean that defines a unique node name with which the Geronimo server instance will be identified in the cluster. Use the clusterNodeName property in var/config/config-substitutions. properties to reconfigure the node name of your Geronimo server instance. org.apache.geronimo.configs/wadi-clustering//car: This configuration
contains WADI-related GBeans used to configure the behaviour of clustered applications and the WADI group communication service shared by all of the clustered applications to communicate with each other.
The number of replicas to be maintained across the cluster for a session is configured as 2 by the DefaultBackingStrategyFactory GBean. To reconfigure the number of replicas, use the ReplicaCount property in var/config/config-substitutions.properties. The name for the cluster and endpoint URI are configured by the DefaultDispatcherHolder GBean. To reconfigure these, use the ClusterName and EndPointURI properties in var/config/config-substitutions.properties. WADI uses multicast for dynamic discovery of nodes in the cluster. So the server instances that want to use WADI for session replication must be running on the same subnet that supports multicast. Each node has a group communication component containing a Dispatcher and ServiceSpace wrapped in a TribesDispatcherHolder GBean and Cluster wrapped in a BasicWADICluster GBean. The group communication components can see each other and dispatch messages between them. Geronimo uses the WADI integration of Tribes for group communication. For more details on this, you can visit the Apache WADI project hosted at http://incubator.apache.org/wadi/ and Apache Tribes web page at http://tomcat.apache.org/tomcat-6.0-doc/tribes/introduction.html.
Updating deployment descriptor and deployment plan
In the Java EE deployment descriptor web.xml for your web application, you must mark the application as distributable by adding the optional element. The following shows the deployment descriptor for the Helloworld Cluster sample: [ 308 ]
The Geronimo-specific deployment plan geronimo-web.xml must define the element for a clustered application to be deployed in a Geronimo Tomcat distribution. For a clustered application to be deployed in a Geronimo Jetty distribution, use the element. The following is the deployment plan of the helloworld-cluster sample from geronimo-web.xml: packt-samples helloworld-cluster 1.0 war /helloworld-cluster
[ 309 ]
Clustering
The org.apache.geronimo.configs/tomcat6-clustering-builder-wadi//car configuration must be running in order to deploy your clustered application. Otherwise, the element will not be recognized, and the deployment will fail. This configuration contains the TomcatClusteringBuilder GBean that adds the necessary dependencies on org.apache.geronimo.configs/ tomcat6-clustering-wadi//car for clustering support. Starting your clustered application will automatically start the WADI-related configurations.
Load balancing with Apache web server Apache web server, with its mod_jk plugin, can be used to load balance clustered applications deployed in Geronimo, by using the AJP Network connectors. In this section, we will see how to configure the Apache web server for load balancing and high availability.
Installing the Apache web server
The Apache web server can be downloaded from the website http://httpd. apache.org/. We have used version 2.2.11 on Windows XP to run our sample applications. You may use any 2.2.x or 2.0.x version of Apache web server. Download the binary for your operating system, and install the Apache web server. We will refer to this installation directory as .
Web app in Geronimo served through Apache web server
We have provided a simple web application, helloworld-cluster, with one static page and one servlet, to demonstrate how a web application running in Geronimo can be served using Apache web server. The HelloWorldServlet stores a counter in the HTTP session and increments the counter with each request received from the same browser session. We will first demonstrate serving this application through the Apache web server and then move on to clustering this application. Deploy the application by using the Deploy New portlet. The application is available in Geronimo at the link http://localhost:8080/helloworld-cluster/. We will now configure access to this application through Apache Web Server.
[ 310 ]
Chapter 12
Apache HTTP portlet
The Apache HTTP portlet in the Administration Console walks you through the process of configuring access to Geronimo through the Apache HTTP server by using mod_jk. The tool will generate the necessary configuration information based on the inputs provided by you in a step-by-step process. ���������������������������� After completing the steps, you will have the configuration text to use with workers.properties and httpd.conf. Follow ����������������������� the steps below: 1. Launch the Apache HTTP portlet by clicking on the Apache HTTP link under Server in the Console Navigation pane. The portlet screen is shown next:
2. Click on Get Started to go to the Basic Configuration screen, as shown below:
[ 311 ]
Clustering
3. Select the Operating System, enter the Path to workers.properties and the mod_jk log file location. Click on Next to go to the Web App Selection screen, as shown below:
4. For all of the web applications that you want to be accessible through the Apache web server, select the checkbox under the Through Apache column. If you want the Apache web server to serve the static content for an application, then select the checkbox under the Static Content column. In Dynamic Paths, enter the URL paths that should be passed on to Geronimo if the static content is served by the Apache web server. Click on Finish to see the screen with the configuration results, as shown next:
[ 312 ]
Chapter 12
This screen provides step-by-step instructions on configuring the Apache web server with the mod_jk plugin. Let us go over each of the steps: 1. In Step 1: Configure Geronimo for AJP, if there is an AJP connector configured already, you do not need to do anything. Otherwise, you will need to create an AJP connector. See Chapter 10, Administration, for details of how to do this. The AJP host and port will be used in Step3. 2. In Step 2: Install mod_jk, you will need to download and install the mod_jk plugin. The mod_jk plugin can be downloaded from the Apache Tomcat website, at http://tomcat.apache.org/download-connectors. cgi. You may either download the source and build the plugin yourself or download the binaries from http://www.apache.org/dist/tomcat/tomcatconnectors/jk/binaries/. Download the binary version relevant to your Operating System and your version of Apache web server, and save it to the /modules directory. Add the following lines of code to the httpd.conf file, which is located under the /conf directory: LoadModule jk_module modules/mod_jk.so
[ 313 ]
Clustering
Make sure that the name under which the mod_jk module file is saved under the modules directory appears in the LoadModule directive.
3. In Step 3: Create a workers.properties file, you create the workers. properties file. The configuration generated for workers.properties is as follows: worker.list=geronimo_ajp13 worker.geronimo_ajp13.port=8009 worker.geronimo_ajp13.host=localhost worker.geronimo_ajp13.type=ajp13
The complete path of the file will be used in the JkWorkersFile directive, as we will see in the next step. 4. In Step 4: Apache Configuration, you add additional configuration to the httpd.conf file. The configuration generated for httpd.conf is as follows: JkWorkersFile C:\geronimo-tomcat6-javaee5-2.1.4\var\config\ workers.properties JkLogFile C:\geronimo-tomcat6-javaee5-2.1.4\var\log\ apache_mod_jk.log JkLogLevel error JkMount /CAHelper/* geronimo_ajp13 JkMount /helloworld-cluster/* geronimo_ajp13 Alias /helloworld-cluster "/C:/geronimo-tomcat6-javaee5-2.1.4/ repository/packt-samples/helloworld-cluster/1.0/ helloworld-cluster-1.0.war/" Options Indexes FollowSymLinks allow from all AllowOverride None deny from all
The JkWorkersFile directive loads the workers defined in workers.properties. The JkLogFile directive configures the logfile for mod_jk module. The JkMount directive specifies the path and the worker to which the requests will be routed. Note that the worker geronimo_ajp13 is defined in workers.properties. [ 314 ]
Chapter 12
5. In Step 5: Restart Apache, you restart the Apache web server so that the configuration changes take effect.
Accessing the sample app through Apache web server
We have now configured access to the helloworld-cluster web application through Apache web server by using the mod_jk module and AJP connector provided by Geronimo. Access the application at http://localhost/helloworldcluster/. Enter a name in the form displayed, and click on getGreeting. The next page displays a greeting message along with the request information and the counter value from the session. Notice that the counter value displayed for the first access of the HelloWorldServlet is 1 and the new session value is true. Now access the application at http://localhost:8080/helloworld-cluster/ in the same browser window. Enter a name in the form displayed, and click on getGreeting. Notice that the counter value displayed on the next page is 2 and the new session value is false. The server.name indicates the server instance serving the request. Notice that the server.name value is default. This means the same application is served at both the URLs and the requests are forwarded by Apache web server to Geronimo. We will now see how this application can be clustered using Geronimo.
Running multiple server instances from a single installation Geronimo provides an easy way of creating and running multiple server instances from a single Geronimo installation. All you need to do is copy a few directories and set a few system properties, and you will have a new server instance with all of the configurations in the default instance. We will now create another instance of the Geronimo server in which we have deployed the helloworld-cluster sample application. This new instance will run in a different JVM on a different set of server ports. The two server instances replicate sessions between them such that the instance that is serving the request during a session is transparent to the user. To create a new server instance, follow the steps below:
1. Choose a name for your new server instance (for example, inst2) and create a directory with that name under the directory. We will refer to the instance name as .
[ 315 ]
Clustering
2. Make sure that the server is not running, and copy the contents of the /var directory, along with all of its subdirectories, to the //var directory. We will refer to the / directory as . In our example, copy to the /inst2/var directory, and the will be /inst2. 3. Open the /var/config/config-substitutions. properties file, and change the following properties: °
°
PortOffset: Change PortOffset from 0 to any integer, such that none of the server ports are in conflict. In our example, we use 10 for the PortOffset. clusterNodeName: Use this property to set a name for the
cluster node.
You can now start the new server instance by setting the system property org.apache.geronimo.server.name to the name of the server instance. You can use the JAVA_OPTS environment variable to set the system property. To start the server instance inst2, use the following commands, in a Windows environment: set JAVA_OPTS=-Dorg.apache.geronimo.server.name=inst2 /bin/geronimo run
This will start the server instance inst2. The following image shows the output in the command window at server startup:
[ 316 ]
Chapter 12
Notice that all of the server ports are offset by the PortOffset value of 10. The Administration Console for this server instance is available at the URL http://localhost:8090/console. With the exception of the var directory, this server instance will share the lib, repository, and other directories with the default server instance. The configurations and clustered web applications deployed in the default server will all be available on this new server instance too. At this stage, the helloworld-cluster application is available in the server instance inst2 at the URL http://localhost:8090/helloworld-cluster/. Access the application at http://localhost:8090/helloworld-cluster/ in the same browser window from which you accessed http://localhost/helloworld-cluster/. Enter a name in the form displayed, and then click on getGreeting. Notice that the counter value displayed on the next page is one more than the previous value, and the new session value is false. Even though the request is served by the application running on the new server instance inst2, as indicated by the server.name value, a new session is not created because the session state has been replicated from the default instance to inst2. However, the Apache web server is configured to forward requests only to default instances.
Clustered Helloworld-cluster application
We will now look at the configuration needed so that the two instances of the helloworld-cluster application available at http://localhost:8080/ helloworld-cluster/ and http://localhost:8090/helloworld-cluster/ are served as one logical application, by using Apache web server, the mod_jk module, and AJP connectors in Geronimo.
Updating workers.properties
To use the server instance inst2 with mod_jk, we will need to create another worker similar to geronimo_ajp13 in workers.properties. This second worker will point to the AJP connector in inst2. The configuration is as given below: worker.list=geronimo_inst2_ajp13 worker.geronimo_inst2_ajp13.port=8019 worker.geronimo_inst2_ajp13.host=localhost worker.geronimo_inst2_ajp13.type=ajp13
Add this configuration to workers.properties.
[ 317 ]
Clustering
The two workers geronimo_ajp13 and geronimo_inst2_ajp13 are of type ajp13. Now create another worker of type lb to balance the load between geronimo_ajp13 and geronimo_inst2_ajp13, as given below: worker.list=loadbalancer worker.loadbalancer.type=lb worker.loadbalancer.balance_workers=geronimo_ajp13,geronimo_inst2_ ajp13
You can use the lbfactor property to specify the how the load should be distributed between the workers. The load balancing factor is compared with other workers that comprise the load balancer. For example, if one worker has lb_factor twice as high as compared to the other worker, then it will receive twice as many requests. The configuration is given below: worker.geronimo_ajp13.lbfactor=2 worker.geronimo_inst2_ajp13.lbfactor=1
Here, geronimo_ajp13, that is, the default instance, will receive twice the number of requests of geronimo_inst2_ajp13, that is, instance inst2. You can also enable sticky sessions by setting the sticky_session property of loadbalancer to True. Enabling a sticky session ties a user session to a particular server instance such that subsequent requests are routed to the same instance, thus eliminating the need for session replication. If the server instance serving the request goes down, then any data stored in the session will be lost. The configuration for enabling sticky session is given below: worker.loadbalancer.sticky_session=True
See http://tomcat.apache.org/connectors-doc/reference/workers.html for complete configuration options for workers.properties. Now update the JkMount directive for /helloworld-cluster/* in httpd.conf to use the loadbalancer worker instead of geronimo_apj13. The configuration to do this is given below: JkMount /helloworld-cluster/* loadbalancer
Restart the Apache web server so that the configuration changes take effect. The helloworld-clustered application is now clustered with two nodes. Access the application at http://localhost/helloworld-cluster/. Enter a name, and click on getGreeting. The application screen is shown in the following screenshot.
[ 318 ]
Chapter 12
In this screen, notice the server.name value , which can be used to identify the Geronimo server instance that served the request, and stop that server instance. Now refresh or reload the page in the browser to display a screen similar to the one shown in the following screenshot:
[ 319 ]
Clustering
Notice that the request is now served by the other running server instance, and the counter value is incremented, indicating that the session state has been replicated to the second server instance.
Farming
By creating a new server instance by using the multiple instances feature provided by Geronimo, the new instance will have available all of the applications and configurations deployed on the default instance available and with the same runtime state. Any new application or configuration or plugin deployed in one instance will not automatically be added to the other instances. If the newly-deployed configuration adds any content to config.xml, config-substitutions.properties, and so on, then the content will not be added to the corresponding files in the other instances. If you are using multiple installations of Geronimo without the Farming feature, then you will need to deploy your clustered application on each server installation. Starting and stopping the application also needs to be done for each server installation. The Farming feature provided by Geronimo enables you to deploy an application to a cluster of Geronimo servers with a single deployment step. Once deployed to a cluster, this application can then be transparently started, stopped, or undeployed across all of the cluster members. In this section, we will look at the configuration needed on the cluster members in order to enable farming and deployment of applications in the cluster.
Cluster member configuration
Each cluster member should be given a unique name. Also, the remote deployer URL for each cluster member needs to be configured correctly. In order to do so, update the clusterNodeName and RemoteDeployHostname properties in the var/config/config-substitutions.properties file under each server instance. In the default server instance, for each additional cluster member, local or remote, add a BasicNodeInfo GBean to the farming configuration org.apache.geronimo. configs/farming/2.1.4/car in config.xml, in order to configure the connection to the cluster member using JMX. The GBean XML definition is given below: NODE2
[ 320 ]
Chapter 12 system manager rmi node2hostName 1109 JMXConnector false
Make sure that the properties under extendedJMXConnectorInfo reflect the correct values required to connect to the Geronimo server instances.
Farm deployment
To use farm deployment, the farming configuration org.apache.geronimo.configs/ farming/2.1.4/car must be running on all of the cluster members. This configuration contains MasterConfigurationStore and ClusterStore GBeans. If the configuration
is not started already, then you can start it by using the System Modules portlet. To deploy your application to the cluster, use the following command:
A configuration with the configuration ID as it would be derived from regular deployment of the module and/or plan to the MasterConfigurationStore on the default server. This configuration contains GBeans to start, stop, and undeploy the application or configuration across the cluster members. A configuration with a configuration ID that is derived by adding
_G_SLAVE to the artifactId of the configuration ID from above to the MasterConfigurationStore in the default server and to the ClusterStore
in each of the cluster members.
[ 321 ]
Clustering
To start the application across all cluster members, use the following command: \bin\deploy.bat start
To stop the application across all cluster members, use the following command: \bin\deploy.bat stop
To undeploy the application across all cluster members, use the following command: \bin\deploy.bat undeploy
Here, the configuration ID is the ID derived in the first step above.
Running a sample application with Farm deployment
For this sample, we will use the helloworld-cluster sample with the farming-geronimo-web.xml deployment plan. We will use two separate installations of Geronimo server. Follow the steps below to run the sample application: 1. Extract the Geronimo Tomcat 2.1.4 distribution to a directory of your choice. We will refer to this directory as . 2. To create a second installation of Geronimo, extract the Geronimo Tomcat 2.1.4 distribution to a different directory of your choice. We will refer to this directory as . 3. Update the /var/config/config-substitutions. properties to change the PortOffset to 10, and the clusterNodeName to NODE2. 4. Add the BasicNodeInfo GBean��������������������������� definition given above to /var/config/config.xml under apache.geronimo. configs/farming/2.1.4/car. Make sure that the host property value is localhost. 5. Start the servers for both of installations. 6. Start apache.geronimo.configs/farming/2.1.4/car configuration in both of the instances through the System Modules portlet in the respective Administration Consoles at http://localhost:8080/console and http://localhost:8090/console.
[ 322 ]
Chapter 12
7. Deploy the helloworld-cluster application with the farming-geronimoweb.xml plan, by file using the command below: \bin\deploy distribute –-targets "org.apache. geronimo.configs/farming/2.1.4/car?ServiceModule=org.apache. geronimo.configs/farming/2.1.4/car,j2eeType=ConfigurationStore,na me=MasterConfigurationStore" helloworld-cluster-1.0.war farminggeronimo-web.xml
Note that this command will deploy a virtual configuration packt-samples/ helloworld-farming/1.0/war to the MasterConfigurationStore in the server at . This configuration contains GBeans to stop, start, and undeploy together the actual application deployed to the ClusterStore with configuration ID packt-samples/helloworld-farming_G_SLAVE/1.0/war in the servers at and . 8. Start the application deployed in all of the instances at once by using the following command: \bin\deploy start "packt-samples/helloworldfarming/1.0/war"
Now the application is available at URLs http://localhost:8080/helloworld-farming/ on the first server and http://localhost:8090/helloworld-farming/ on the second server. 9. Add the following line to httpd.conf, and restart the Apache web server: JkMount /helloworld-farming/* loadbalancer
The sample application is now available through the Apache web server at the URL http://localhost/helloworld-farming/. Access the application, enter a name, and click on getGreeting. The next page will display a greeting message along with the details of the request received in the Geronimo server. The org.apache. geronimo.server.home value indicates the server instance serving the request. Refresh or reload the page a few times, and notice that the application is load balanced along with session replication between the two server instances.
Summary
We have discussed vertical clustering using the multiple instances feature, horizontal clustering, and easy application management by using the farming support provided by Geronimo. We have also configured session replication by using WADI, and load balancing by using the Apache web server, mod_jk module, and AJP connectors. We have demonstrated the same by using the helloworld-cluster web application sample. In the next chapter, we will discuss the support provided by Geronimo for logging. You will learn to configure application logging using the various logging frameworks provided by Geronimo. [ 323 ]
Logging The ability to log important events or errors for problem diagnosis and then checking of application execution is very important. The ability to log certain statements selectively while others are not logged, depending on the context in which the application is running, is also important. An application that is deployed in Apache Geronimo can use any custom logging mechanism to log its messages. However, Apache Geronimo uses log4j and slf4j for logging server log messages. Applications deployed in Geronimo can also leverage the functionality of these logging frameworks. In this chapter, we will see how an application developer can configure logging for his application in Apache Geronimo, by using some common logging frameworks. The frameworks that we will be covering are: • • •
Apache log4j Java logging API slf4j logging adapter
We will start by briefly looking at each of the logging frameworks mentioned above, and will then go into how the server logs events and errors and where it logs them to. After examining them, we will look into the different ways in which we can configure application logging. •
Apache log4j: Log4j is an open source logging framework that is developed by the Apache Software Foundation. It provides a set of loggers, appenders, and layouts, to control which messages should be logged at runtime, where they should be logged to, and in what format they should be logged. The loggers are organized in a tree hierarchy, starting with the root logger at the top of the hierarchy. All loggers except the root logger are named entities and can be retrieved by their names. The root logger can be accessed by using the Logger.getRootLogger() API, while all other loggers can be accessed by using the Logger.getLogger() API. The names of the loggers follow the rule that the name of the parent logger followed by a '.' is a prefix to the child logger's name. For example, if com.logger.test is the name of a logger, then its direct ancestor is com.logger, and the prior ancestor is com.
Logging
Each of the loggers may be assigned levels. The set of possible levels in an ascending order are—TRACE, DEBUG, INFO, WARN, ERROR, and FATAL. If a logger is not assigned a level, then it inherits its level from its closest ancestor. A log statement makes a logging request to the log4j subsystem. This request is enabled only if its logging level is higher than or equal to its logger's level. If it is lower than the log, then the message is not output through the configured appenders. Log4j allows logs to be output to multiple destinations. This is done via different appenders. Currently there are appenders for the console, files, GUI components, JMS destinations, NT, and Unix system event loggers and remote sockets. Log4j is one of the most widely-used logging frameworks for Java applications, especially ones running on application servers. It also provides more features than the other logging framework that we are about to see, that is, the Java Logging API. •
Java Logging API: The Java Logging API, also called JUL, from the
java.util.logging package name of the framework, is another logging
framework that is distributed with J2SE from version 1.4 onwards. It also provides a hierarchy of loggers such as log4j, and the inheritance of properties by child loggers from parents just like log4j. It provides handlers for handling output, and formatters for configuring the way that the output is displayed. It provides a subset of the functionality that log4j provides, but the advantage is that it is bundled with the JRE, and so does not require the application to include third-party JARS as log4j does.
•
SLF4J: The Simple Logging Facade for Java or SLF4J is an abstraction or facade over various logging systems. It allows a developer to plug in the desired logging framework at deployment time. It also supports the bridging of legacy API calls through the slf4j API, and to the underlying logging implementation. Versions of Apache Geronimo prior to 2.0 used Apache Commons logging as the facade or wrapper. However, commons logging uses runtime binding and a dynamic discovery mechanism, which came to be the source of quite a few bugs. Hence, Apache Geronimo migrated to slf4j, which allows the developer to plug in the logging framework during deployment, thereby eliminating the need for runtime binding.
Configuring Apache Geronimo logging
Apache Geronimo uses slf4j and log4j for logging. The log4j configuration files can be found in the /var/log directory. There are three configuration files that you will find in this directory, namely:
[ 326 ]
Chapter 13
•
client-log4j.properties
•
deployer-log4j.properties
•
server-log4j.properties
Just as they are named, these files configure log4j logging for the client container (Java EE application client), deployer system, and the server. You will also find the corresponding log files—client.log, deployer.log, and server.log. The properties files, listed above, contain the configuration of the various appenders, loggers, and layouts for the server, deployer, and client. As mentioned above, log4j provides a hierarchy of loggers with a granularity ranging from the entire server to each class on the server. Let us examine one of the configuration files: the server-log4j.properties file: •
This file starts with the line log4j.rootLogger=INFO, CONSOLE, FILE. This means that the log4j root logger has a level of INFO and writes log statements to two appenders, namely, the CONSOLE appender and the FILE appender. These are the appenders that write to the console and to files respectively. The console appender and file appenders are configured to write to System.out and to /var/log/geronimo.log.
•
Below this section, there is a finer-grained configuration of loggers at class or package levels. For example, log4j.logger.openjpa.Enhance=TRACE.
•
It configures the logger for the class log4j.logger.openjpa.Enhance to the TRACE level. Note that all of the classes that do not have a log level defined will take on the log level of their parents. This applies recursively until we reach the root logger and inherit its log level (INFO in this case).
Configuring application logging
We will be illustrating how applications can log messages in Geronimo by using two logging frameworks, namely, log4j and JUL. We will also illustrate how you can use the slf4j wrapper to log messages with the above two underlying implementations. We will be using a sample application, namely, the HelloWorld web application to illustrate this.
Using log4j
We can use log4j for logging the application log to either a separate logfile or to the geronimo.log file. We will also illustrate how the logs can be written to a separate file in the /var/log directory, by using a GBean.
[ 327 ]
Logging
Logging to the geronimo.log file and the command console
Logging to the geronimo.log file and the command console is the simplest way to do application logging in Geronimo. For enabling this in your application, you only need to add logging statements to your application code. The HelloWorld sample application has a servlet called HelloWorldServlet, which has the following statements for enabling logging. The servlet is shown below. package com.packtpub.hello; import java.io.*; import javax.servlet.ServletException; import javax.servlet.http.*; import org.apache.log4j.Logger; public class HelloWorldServlet extends HttpServlet { Logger logger = Logger.getLogger(HelloWorldServlet.class.getName()); protected void service(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException { res.setContentType("text/html"); PrintWriter out = res.getWriter(); out.print(""); logger.info("Printing out "); out.print("Hello World Application"); logger.info("Printing out Hello World Application"); out.print(""); logger.info("Printing out "); out.print("Hello World"); logger.info("Printing out Hello World"); out.print(""); logger.info("Printing out "); out.print(""); logger.info("Printing out "); logger.warn("Sample Warning message"); logger.error("Sample error message"); } }
Deploy the sample HelloWorld-1.0.war file, and then access http://localhost:8080/HelloWorld/. This servlet will log the following messages in the command console, as shown in the image below:
[ 328 ]
Chapter 13
The geronimo.log file will have the following entries: 2009-02-02 20:01:38,906 INFO [HelloWorldServlet] Printing out 2009-02-02 20:01:38,906 INFO [HelloWorldServlet] Printing out Hello World Application 2009-02-02 20:01:38,906 INFO [HelloWorldServlet] Printing out 2009-02-02 20:01:38,906 INFO [HelloWorldServlet] Printing out Hello World 2009-02-02 20:01:38,906 INFO [HelloWorldServlet] Printing out 2009-02-02 20:01:38,906 INFO [HelloWorldServlet] Printing out 2009-02-02 20:01:38,906 WARN [HelloWorldServlet] Sample Warning message 2009-02-02 20:01:38,906 ERROR [HelloWorldServlet] Sample error message Notice that only the messages with a logging level of greater than or equal to WARN are being logged to the command console, while all the INFO, ERROR, and WARN messages are logged to the geronimo.log file. This is because in server-log4j. properties the CONSOLE appender's threshold is set to the value of the system property, org.apache.geronimo.log.ConsoleLogLevel, as shown below: log4j.appender.CONSOLE.Threshold=${org.apache.geronimo.log. ConsoleLogLevel}
The value of this property is, by default, WARN. All of the INFO messages are logged to the logfile because the FILE appender has a lower threshold, of TRACE, as shown below: log4j.appender.FILE.Threshold=TRACE
Using this method, you can log messages of different severity to the console and logfile to which the server messages are logged. This is done for operator convenience, that is, only high severity log messages, such as warnings and errors, are logged to the console, and they need the operator's attention. The other messages are logged only to a file.
[ 329 ]
Logging
Logging to a separate log file
In case you want your application to log to a separate logfile so that there is a separation of the log messages from the server and your application, you can follow the method described next. You can also follow this method in case your application bundles a version of log4j. In both of these cases, we use the hidden-classes feature of Geronimo to hide the log4j implementation that is bundled along with the server. This causes the application class loader to load the log4j JAR that is bundled along with your application or is given as a dependency to your application. The freshly-loaded log4j classes will again cause a new logger hierarchy, starting with a new root logger, for the application that is not aware of the log4j configurations at the server level. This application-level root logger and its descendants can be configured through a log4j.properties file in the classpath of the application. We will illustrate this by using the previous application, but this time adding the hidden-classes element to the deployment plan geronimo-web.xml. Do not forget to hide the log4j.properties file in the parent class loaders that are also using the hidden-classes element. Otherwise, your log4j implementation may get configured by any other log4j.properties file that is present in your parent class loaders. This is because resources are loaded by class loaders through a parent-first policy. You can hide the resources in the parent class loaders by using the hidden-classes element.
Add the following lines to the Geronimo deployment plan of the HelloWorld sample: org.apache.log4j log4j
The first entry is to hide the log4j classes that are packaged with Apache Geronimo, while the second entry is to hide the log4j.properties files that may be present in parent class loaders of the application. You will also need to add a dependency on the log4j JAR in the server repository, or add the log4j JAR to your application's lib directory.
[ 330 ]
Chapter 13
Now you will need to configure this new instance of log4j. For this, you either need to write code to programmatically configure the loggers (for example, you want to configure your application's logging levels only through your application's user interface) in order to load custom log4j configuration files, or you need to have a log4j configuration file in your application's classpath, with a name of log4j. Log4j automatically recognizes and loads files called log4j.properties or log4j.xml, and uses the entries in these files to configure itself. In the sample, we have a log4j.properties present in the classes directory, and this will be used to configure the log4j instance in case the log4j implementations used by the parent class loaders are hidden. The contents of this file are shown below: log4j.rootLogger=INFO, CONSOLE, FILE log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender log4j.appender.CONSOLE.Threshold=TRACE log4j.appender.CONSOLE.Target=System.out log4j.appender.CONSOLE.layout=org.apache.log4j.SimpleLayout log4j.appender.FILE=org.apache.log4j.RollingFileAppender log4j.appender.FILE.Threshold=TRACE log4j.appender.FILE.layout=org.apache.log4j.SimpleLayout log4j.appender.FILE.append=true log4j.appender.FILE.file=${org.apache.geronimo.server.dir} /var/log/helloworldapp.log log4j.appender.FILE.bufferedIO=false log4j.appender.FILE.maxBackupIndex=3 log4j.appender.FILE.maxFileSize=10MB
The output will be logged to the file /var/log/helloworldapp. log, as the property log4j.appender.FILE.file is configured and the value of the property org.apache.geronimo.server.dir maps to the
directory. It will also be logged to the console. Because both the appenders have the same logging threshold, the same log messages will be output to both the log file and the console. Deploy the sample application HelloWorld-SLF4J-1.0.war, and then access http://localhost:8080/HelloWorldSLF4J/. The output in this case will look as shown in the image below:
This is different from the previous output, as this time we are using a different layout, namely, org.apache.log4j.SimpleLayout for the log messages. [ 331 ]
Logging
Logging using the ApplicationLog4jConfigurationGBean
Geronimo provides a GBean for configuring logging. You can use this in case you want to use the log4j implementation that is loaded and used by Apache Geronimo, but want to log your output to a different file. We will discuss the steps to do this below: • You will need to add an instance of the
ApplicationLog4jConfigurationGBean to the application's Apache Geronimo-specific deployment plan. This is shown below: var/HelloWorld/HelloWorldlog4j.properties ServerInfo
• The entry shown above will configure the
ApplicationLog4jConfigurationGBean so that it makes log4j load the configuration file that is specified through the attribute log4jFile, and then use it to add additional configurations to the server implementation of log4j. You can also specify this GBean, as shown below, in case the log4j properties file is in your application's classpath. log4j.properties
• You should now configure application-specific logging in your log4j.properties file. This GBean prevents you from overriding global logging settings, but you can configure appenders for your application-specific loggers, as shown in the example below: #Add an appender to the HelloWorld App package logger: log4j.logger.com.packtpub.hello=INFO, helloworld #Do not add the logs to geronimo.log: log4j.additivity.com.packtpub.hello=false #Configure appenders for the helloworld app loggers: log4j.appender.helloworld=org.apache.log4j. DailyRollingFileAppender log4j.appender.helloworld.File=${org.apache.geronimo.server.dir}/ var/log/HelloWorldApp.log log4j.appender.helloworld.layout=org.apache.log4j.SimpleLayout [ 332 ]
Chapter 13
Using the Java Logging API
The Java logging API, by default, uses the /jre/lib/logging. properties file for configuring Loggers, Handlers, and Formatters. You can change the default logging configuration for all programs using that JRE and the Java logging API, by editing this file. You can also specify two system properties to change the logging configuration for each run of the JRE. These properties are: •
java.util.logging.config.file: The value of this property should be the path of a file in the properties file format that contains the initial logging configuration.
•
java.util.logging.config.class: The value of this property should be
the fully-qualified name of the class whose constructor is responsible for reading in the initial configuration.
If you need to set these at startup for Apache Geronimo, then you can use the GERONIMO_OPTS or the JAVA_OPTS environment variable, as shown below: set GERONIMO_OPTS=-Djava.util.logging.config.file=C:\xyz\logging. properties
The default configuration configures a ConsoleHandler with a SimpleFormatter and the log level set to INFO. You can programmatically configure the Java Logging API to accept different log files. You can do this either in a custom GBean or in the code that is executed during the startup of your application, for example ServletContextListener.
Using the SLF4j logging adapter
Apache Geronimo uses slf4j over log4j for logging purposes. Geronimo ships with the following slf4j modules included in the repository: •
slf4j-api
•
slf4j-log4j12
•
jcl-over-slf4j
•
jul-to-slf4j
Getting your application to use slf4j for logging is a very simple process. We will demonstrate this by converting the application that we have been using up to now, that is, the HelloWorld application, to use slf4j for logging.
[ 333 ]
Logging
The first step in this is to add dependencies to the slf4j-api and slf4j-log4j12 JARs. We will then need to import the slf4j classes that we are going to use for logging in our class. These import statements are shown below: import org.slf4j.Logger; import org.slf4j.LoggerFactory;
In the next step, remove the previous import of the log4j logger and then replace the log4j API for getting the logger: Logger logger = Logger.getLogger(HelloWorldServlet.class.getName());
with the slf4j API: Logger logger = LoggerFactory.getLogger(HelloWorldServlet.class);
You will now be able to use slf4j for logging to the geronimo.log file. If you want to log to a separate file, then you can either use the hidden-classes element or the ApplicationLog4jConfigurationGBean. The log4j configurations remain the same. The only additional thing that you should remember if you are using hidden-classes is that you should also hide the slf4j implementation that is shipped with Geronimo, that is, the org.slf4j package. The converted application is provided in the samples directory, and is called HelloWorld-SLF4J. Thus, we can see that, at deployment time, we can deploy a static JAR—configured to work with either JUL or log4j—so that a developer can use JUL/slf4j, but the application can be deployed with log4j/slf4j without changing even a single line of code. This is the advantage that using a logging facade provides.
Summary
In this chapter, we have seen the various logging frameworks supported by Geronimo, namely, LOG4J, JUL, and SLF4J. We have discussed how the application server and application-specific logging can be configured using these frameworks. In the next chapter, we will introduce you to some advanced Apache Geronimo concepts and provide you with a view of the internals of Apache Geronimo.
[ 334 ]
Geronimo Internals Apache Geronimo consists of a kernel that provides dependency management, configuration management, lifecycle management, and repository services. A GBean is a basic building block in Geronimo that wraps a service or provides a service by itself. GBeans are grouped into configurations that start and stop as a group. These configurations are themselves GBeans that use the services of other GBeans such as the repository and so on. As a result, they provide us with a hierarchy of GBeans, using services from one another in a neatly choreographed way. In this chapter, we will look at the building blocks of Geronimo that enable it to provide the services required of a Java EE 5-compliant application server. This chapter is divided into three major sections, dealing with: • • •
Services provided by Geronimo Configurations and deployment Development and deployment of GBeans
Services provided by Geronimo
We will look at some of the low-level services provided by Geronimo.
Kernel
The Kernel interface provides methods to obtain various services such as LifecycleMonitor, DependencyManager, ProxyManager, and so on. It also provides methods to query GBeans, load, start, stop, unload GBeans, set, and get GBean attributes, and invoke methods on GBeans. You can instantiate a kernel instance by using the KernelRegistry.getSingleKernel() API. We will now look at some of the APIs in the Kernel, and their uses: •
getDependencyManager(): Returns the DependencyManager kernel service. The DependencyManager uses the nomenclature of parent-child, where a child is dependent on a parent. DependencyManager is used to manage dependencies between GBeans.
Geronimo Internals
•
getLifecycleMonitor(): Returns the LifecycleMonitor kernel service.
•
getNaming(): Returns the naming system used by the kernel.
•
getProxyManager(): Returns the ProxyManager kernel service. ProxyManager manages kernel proxies. All proxies include an implementation of GeronimoManagedBean.
•
loadGBean(): Loads a specific GBean into the kernel, using a specified
class loader.
•
isLoaded(): Returns true if a GBean is registered in the kernel under the specified name.
•
getGBean(): Returns the GBean registered in the kernel with the
specified name.
•
startGBean(): Starts the GBean registered in the kernel with the
•
startRecursiveGBean():Starts the GBean registered in the kernel with the specified name, along with and all of its child GBeans as registered in the DependencyManager.
•
isRunning(): Returns true if the specified GBean is running.
•
stopGBean(): Stops the GBean with the specified name.
•
unloadGBean(): Unloads the GBean with the specified name.
•
getGBeanState(): Returns the state of the GBean with the specific name.
•
getGBeanStartTime(): Returns the starting time of the GBean with the
•
getClassLoaderFor(): Returns the class loader used to register the
•
getGBeanInfo(): Returns the GBeanInfo of a specified GBean instance.
•
getGBeanData(): Returns the GBeanData of a specified GBean instance.
•
listGBeans(): Returns a list of GBean names loaded in the kernel that match a specified abstract name query.
• •
specified name.
specified name.
specified GBean.
getAttribute(): Returns the value of a specific attribute in a specified
GBean instance.
setAttribute(): Sets the value of a specific attribute in a specified
GBean instance.
[ 336 ]
Chapter 14
•
invoke(): Invokes a specified method on a specified GBean instance.
•
getAbstractNameFor(): Returns the abstract name for the service represented by the specified object.
•
getShortNameFor(): Returns the short name for the service represented by
•
boot(): Boots the kernel.
•
getBootTime(): Returns the boot time of the kernel.
•
registerShutdownHook(): Registers a runnable object to run at
•
unregisterShutdownHook(): Unregisters a runnable object registered earlier using the registerShutdownHook() API.
•
shutdown(): Shuts down the kernel.
•
isRunning(): Returns true if the kernel is booted.
•
getStateReason(): Returns the state message associated with a
the specified object.
kernel shutdown.
specified GBean.
ServerInfo
The ServerInfo contains information about the server, and functions to resolve pathnames. The interface definition is given below: public interface ServerInfo { public File resolve(final String filename); public File resolveServer(final String filename); public String resolvePath(final String filename); public String resolveServerPath(final String filename); public URI resolve(final URI uri); public URI resolveServer(final URI uri); public String getBaseDirectory(); public String getCurrentBaseDirectory(); public String getVersion(); public String getBuildDate(); public String getBuildTime(); public String getCopyright(); }
[ 337 ]
Geronimo Internals
We will now look at the APIs in ServerInfo, and their uses: •
resolve(): Resolves a specified relative path name to a file relative to the server installation directory. For example, "foo" resolves to /foo.
•
resolveServer(): Resolves a specified relative path name to a file relative
to the server instance directory. For the default instance, the server instance directory is the same as the server installation directory. For an instance started by specifying the org.apache.geronimo.server.name system property, this resolves to a path under the / directory. For example, for a server instance with a name of instance2, "foo" resolves to /instance2/foo.
•
resolvePath(): Returns an absolute path relative to the server
•
resolveServerPath(): Returns an absolute path relative to the server
•
resolve(URI): Resolves the specified URI relative to the server
•
resolveServer(URI): Resolves the specified URI relative to the server
•
getBaseDirectory(): Returns the server base directory. By default, this
•
getCurrentBaseDirectory(): Returns the absolute path name of the server
•
getVersion(): Returns the server version information.
•
getBuildDate(): Returns the server build date.
•
getBuildTime(): Returns the server build time.
•
getCopyright(): Returns the server copyright information.
installation directory. instance directory.
installation directory. instance directory.
is the server installation directory. The base directory can be overridden by using the org.apache.geronimo.home.dir system property.
base directory.
You can obtain a ServerInfo object by calling the Kernel API getGBean() with ServerInfo.class as a parameter.
Configurations and deployment
In this section, we will investigate some of the classes that provide the deployment and configuration management functionality of Apache Geronimo.
[ 338 ]
Chapter 14
ConfigurationManager
A ConfigurationManager encapsulates the logic for dealing with configurations. Configurations have a lifecycle with three states: installed, loaded, and running. Installed means that the configuration is present in the server's repository. Loaded means that the configuration Gbean, including the configuration's ClassLoader, is running. Running means that all of the GBeans in the configuration are running. When a configuration is not loaded, only its ConfigurationData is available for inspection. It's normally not possible to inspect the GBeans in the configuration because there's no ClassLoader that could be used to load the classes needed by the instances of GBeanData in the configuration. Once the configuration has been loaded, its ClassLoader is available so that the instances of GBeanData can be loaded and inspected. But the GBean instances are not instantiated and started until the configuration is started. We will now look at some of the APIs in the ConfigurationManager interface: • •
isInstalled(): Returns true if a specified configuration is installed on
the server.
isLoaded(): Returns true if a specified configuration is loaded into
the kernel.
•
isRunning(): Returns true if a specified configuration is running.
•
getInstalled(): Returns a list of installed configurations, g����������������� iven an artifact that's not fully resolved (for example, some parts are missing), that is, any of the matching configurations in the configuration store, regardless of whether they're loaded or running.
•
getLoaded(): Returns a list of configurations, g����������������������������� iven an artifact that is not
•
getRunning(): Returns a list of configurations, g����������������������������� iven an artifact that is not
•
fully resolved (for example, some parts are missing), and check whether there are any instances loaded.
fully resolved (for example, some parts are missing), and check whether there are any instances running.
listConfigurations(): Returns a list of all of the configurations installed
on the server.
•
listStores(): Returns a list of abstract names of the configuration stores
•
getStores(): Returns an array containing all of the configuration stores
•
isConfiguration(): Returns true if a specified artifact is a configuration in
controlled by this configuration manager. known to this configuration manager. the server.
[ 339 ]
Geronimo Internals
•
loadConfiguration(): Loads a specified configuration.
•
getConfiguration(): Returns the configuration for a given artifact ID.
•
unloadConfiguration(): Unloads a specified configuration.
•
startConfiguration(): Starts a specified configuration and the contained
GBeans. It will also start any parent configurations.
•
stopConfiguration(): Stops a specified configuration and the containing
•
restartConfiguration(): Restarts a specified configuration and the containing GBeans. It will also restart any child configurations.
•
reloadConfiguration(): Reloads a specified configuration and the containing GBeans. It will also reload any child configurations.
•
GBeans. It will also stop any child configurations.
uninstallConfiguration(): Uninstalls a specified configuration from
the server.
•
isOnline(): Returns true if the ConfigurationManager is fully functional.
•
getRepositories(): Returns a collection of repositories known to this
•
getArtifactResolver(): Returns the ArtifactResolver ������������������� configured for all of the repositories known to this ConfigurationManager.
ConfigurationManager.
Configurations are identified by their artifact IDs.
You can obtain a ConfigurationManager by calling the API ConfigurationUtil. getConfigurationManager(), with the kernel passed as a parameter.
EditableConfigurationManager
EditableConfigurationManager enables you to dynamically change the set of
GBeans included in the configuration at runtime. The interface definition is as follows: public interface EditableConfigurationManager extends ConfigurationManager { void addGBeanToConfiguration(Artifact configID, GBeanData gbean, boolean start) throws InvalidConfigException; void addGBeanToConfiguration(Artifact configID, String name, GBeanData gbean, boolean start) throws InvalidConfigException; void removeGBeanFromConfiguration(Artifact configID, AbstractName gbean) throws InvalidConfigException, GBeanNotFoundException; } [ 340 ]
Chapter 14
•
•
addGBeanToConfiguration: Adds a new GBean defined by GBeanData to an existing configuration identified by the configID. The start parameter determines whether the newly-added GBean should be started or not. removeGBeanFromConfiguration: Removes the GBean specified by its abstract name from the configuration identified by configID.
LocalAttributeManager
ConfigurationManager uses an AttributeManager service to manage the GBean attributes of the GBeans deployed on the server. The LocalAttributeManager is configured by two files, namely, config.xml and config-substitutions. properties, which are located under the var/config directory, in order to the enable editing of GBean attribute values. The properties defined in config-substitutions. properties can be used in composing expressions for attribute values defined in config.xml. The following is an excerpt from config.xml: ${SMTPHost} ${SMTPPort}
Here, the host attribute of the SMTPTransport GBean in the org.apache.geronimo. configs/javamail/2.1.4/car configuration are overridden by using an expression of ${SMTPHost}. The property SMTPHost is defined in config-substitutions. properties as follows: SMTPHost=localhost
Therefore, the attribute value will evaluate to localhost. If the SMTPHost is used in multiple places in config.xml, then config-substitutions.properties provides an easy way to effect a change by making a change in only one place.
ArtifactResolver
ConfigurationManager uses the ArtifactResolver service for artifact resolution while loading configurations. The ArtifactResolver GBean is configured by the artifact_aliases.properties file, which is located under the var/config
directory, in order to support the substitution of one artifact for another at runtime. This file contains entries in the format oldartifactid=newartifactId. The following is an excerpt from artifact_aliases.properties: org.apache.geronimo.plugins/mconsole-ds//car=org.apache.geronimo. plugins/mconsole-ds/2.1.4/car org.apache.geronimo.framework/geronimo-gbean-deployer/2.1/car=org. apache.geronimo.framework/geronimo-gbean-deployer/2.1.4/car [ 341 ]
Geronimo Internals
Here, all references to org.apache.geronimo.plugins/mconsole-ds//car, where the version is not specified, will be resolved to org.apache.geronimo.plugins/ mconsole-ds/2.1.4/car, and any reference to org.apache.geronimo.framework/ geronimo-gbean-deployer/2.1/car will be resolved to org.apache.geronimo. framework/geronimo-gbean-deployer/2.1.4/car. The artifact-aliases. properties file comes in handy when you have deployed configurations pointing to an explicit version of a JAR that you will want to upgrade to, without having to redeploy the configuration. Although overwriting the older JAR with a newer version could be a crude way of resolving the problem, artifact aliasing offers a cleaner way of achieving the same thing. Note that in the entries, the version number can be omitted from the left-hand side but not from the right-hand side.
Developing a new GBean
In this section, we will look at creating a new GBean and deploying the GBean to the server. Remember that a GBean is the basic unit in Geronimo that may provide a service or is used to wrap services deployed in the kernel. We will now develop a GBean, and in the process, we will look at various aspects of the GBean, such as the attributes, references, operations, constructor, interfaces, lifecycle management, dependencies, and so on. A GBean Java class typically implements a service interface and exposes the operations from the service interface or provides lifecycle operations such as start or stop to initialize and shutdown the service. A GBean can use lifecycle management by implementing the GBeanLifecycle interface. The GBean is configured by attributes and references to other GBeans. Irrespective of what the Java class defines, the GBean is only identified by the structure defined by the GBean's metadata GBeanInfo. The Java class defining a GBean should make the GBeanInfo available through a static method getGBeanInfo(). The following is a typical structure of a Java class that defines a GBean: public class MySampleGBean implements MySampleInterface, GBeanLifecycle { ... public MySampleGBean(...) { .... } ... /* Lifecycle methods */ public void doStart() throws Exception { ... } public void doStop() throws Exception { [ 342 ]
Chapter 14 ... } public void doFail() { ... } public static final GBeanInfo GBEAN_INFO; static { GBeanInfoBuilder infoFactory = GBeanInfoBuilder.createStatic ("GBean", MySampleGBean.class); // Initialize the GBean structure here ... GBEAN_INFO = infoFactory.getBeanInfo(); } public static GBeanInfo getGBeanInfo() { return GBEAN_INFO; } }
The static block at the bottom of the listing is used to initialize the GBeanInfo for the GBean. We use the GBeanInfoBuilder helper class to create the GBeanInfo.
GBean attributes
Attributes are used to configure the GBean. Each attribute must have a name and a type. Optionally, an attribute can be persistent, which means that the attribute's value will be saved and applied each time the GBean is loaded. Moreover, an attribute can be manageable, which means that the attribute's value can be overridden by using config.xml. Except for the four "magic" attributes (as we will see next), usually all attributes are persistent, and most attributes are manageable. The GBeanInfoBuilder. addAttribute() method can be used to add information about GBean attributes to the GBeanInfo. This method takes four parameters, as given below: •
name—String value specifying the name of the attribute.
•
type—Class specifying the type of the attribute.
•
Persistent—Optional Boolean value specifying whether the attribute
•
is persistent.
Manageable—Optional Boolean value specifying whether the attribute is manageable.
The following is an excerpt from the MySampleGBean class. infoFactory.addAttribute("name", String.class, true, true); infoFactory.addAttribute("name2", String.class, true, false); [ 343 ]
Geronimo Internals
This code defines a persistent and manageable attribute with name name of type String and a persistent but not manageable attribute with name name2 of type String. A GBean can have zero or more attributes defined for it.
Magic attributes
Geronimo provides four special attributes that cannot be configured by a user. These attributes, referred to as magic attributes, must be designated as not persistent and non-manageable. The attribute details are as follows: •
kernel: This attribute is of type Kernel. The value for this attribute is the
•
objectName: This attribute is of type String. The value of this attribute is the
•
abstractName: This attribute is of type AbstractName. The value of this
•
classLoader: This attribute is of type ClassLoader. The value of this
Geronimo kernel in which the GBean is running.
JMX ObjectName that can be used to refer to this GBean component.
attribute is the unique name identifying this GBean instance.
attribute is the class loader that is used for the current configuration.
The following is an excerpt from the MySampleGBean class: infoFactory.addAttribute("kernel", Kernel.class, false); infoFactory.addAttribute("objectName", String.class, false); infoFactory.addAttribute("abstractName", AbstractName.class, false); infoFactory.addAttribute("classLoader", ClassLoader.class, false);
This code defines the four magic attributes for the MySampleGBean class. The kernel attribute is used whenever you want to invoke certain kernel method implementations in your GBean. Geronimo will inject an instance of the currently-used kernel into that attribute. Similarly, usage of the abstractName and objectName attributes ensures that these are available to the GBean. The classLoader attribute is used when we need to gain access to the configuration's class loader.
GBean references
A GBean can reference other GBeans running in the kernel. A GBean reference has a name and a type. A reference can be either single valued or multiple valued. In the case of multiple valued references, the reference will be made to multiple GBeans of the same type. The GBeanInfoBuilder.addReference() method can be used to add GBean references to GBeanInfo. The parameters to this method are as follows: [ 344 ]
Chapter 14
•
name—A string value specifying the name of the reference.
•
type—A class representing the type of the reference. In the case of
•
namingType—A string representing the J2EE type of the reference.
multiple valued references, the corresponding argument in the constructor or getter/setter methods will have the type Collection, and the type of the element in the collection is specified by this type parameter.
The following is an excerpt from the MySampleGBean class: infoFactory.addReference("ServerInfo", ServerInfo.class);
This code defines a single valued GBean reference with name ServerInfo of type ServerInfo. A GBean can have zero or more references defined for it.
GBean operations
A GBean can make zero or more service operations available. The GBeanInfoBuilder.addOperation() method can be used to add GBean operations to GBeanInfo. The parameters for this method are as follows: •
name—A string value specifying the name of the operation.
•
parameterTypes—An optional array of class objects specifying the parameter types of the operation.
•
returnType—An optional string value specifying the return type of the operation.
The following is an excerpt from the MySampleGBean class: infoFactory.addOperation("myMethod1", "java.lang.String");
This code defines a GBean operation with the name myMethod1, with no arguments, and the return type String.
GBean constructor
A GBean can have a constructor configured by using the GBeanInfoBuilder. setConstructor() method. The parameter to this method is as follows: •
parameterNames—An array of strings containing the names of attributes����� ��������������� and
references that form the parameters of the constructor.
[ 345 ]
Geronimo Internals
The following is an excerpt from the MySampleGBean class: infoFactory.setConstructor(new String[] {"kernel", "objectName", "abstractName", "classLoader", "name"});
This code defines a GBean constructor with five parameters, which are all GBean attributes. If no GBean constructor is defined, then the Java class must have a public no-argument constructor defined.
GBean interface
A GBean can have zero or more service interfaces defined by using the GBeanInfoBuilder.addInterface() method. The parameters to this method are as follows: • • •
intf—The Java interface that should be added as the GBean interface. persistentAttributes—An optional array of strings specifying
persistent attributes.
manageableAttributes—An optional array of strings specifying
manageable attributes.
The following is an excerpt from MySampleGBean: infoFactory.addInterface(MySampleInterface.class);
This code adds MySampleInterface as a GBean interface in MySampleGBean. Adding an interface as the GBean interface allows the querying of the kernel for GBeans using the interface.
GBeanLifecycle
A GBean can use lifecycle management support by implementing the GBeanLifecycle interface. The methods in this interface are as follows: •
doStart()—This method is called when the GBean is started. Any module
dependencies, GBean dependencies, and any GBeans in the references will have been started already.
•
doStop()—This method is called when the GBean is stopped.
•
doFail()—This method is called when the GBean can not be started due to an exception in doStart().
[ 346 ]
Chapter 14
Sample GBean MySampleGBean Create a Maven project by using the following command:
This will create a directory gbean-sample with pom.xml. Change the pom.xml as given below, to add dependencies such as geronimo-kernel and geronimo-system JARs, as our GBean uses classes from these Geronimo modules: 4.0.0 packt-samples gbean-sample jar 1.0 gbean-sample http://maven.apache.org org.apache.geronimo.framework geronimo-kernel 2.1.4 provided org.apache.geronimo.framework geronimo-system 2.1.4 provided junit junit 3.8.1 test
[ 347 ]
Geronimo Internals
Run the following command to create Eclipse project artifacts: mvn –Peclipse eclipse:eclipse
Import the project into an Eclipse workspace by using the option File | Import | Import Existing Projects into Workspace. Create a Java interface named packtsamples.MySampleInterface. This interface definition is given below: package packtsamples; public interface MySampleInterface { String myMethod1(); }
Create a Java class named packtsamples.MySampleGBean. The class definition is given below: package packtsamples; ... public class MySampleGBean implements MySampleInterface, GBeanLifecycle { private Kernel kernel; private String objectName; private AbstractName abstractName; private ClassLoader classLoader; private String name; private String name2; private ServerInfo serverInfo; public MySampleGBean(Kernel kernel, String objectName, AbstractName abstractName, ClassLoader classLoader, String name) { this.kernel = kernel; this.objectName = objectName; this.abstractName = abstractName; this.classLoader = classLoader; this.name = name; System.out.println("kernel = "+kernel); System.out.println("objectName = "+objectName); System.out.println("abstractName = "+abstractName); System.out.println("classLoader = "+classLoader); System.out.println("name = "+name); } public void setServerInfo(ServerInfo serverInfo) { this.serverInfo = serverInfo; System.out.println("serverInfo = "+serverInfo); } [ 348 ]
Chapter 14 public String myMethod1() { StringBuffer out = new StringBuffer(this.getClass() .getSimpleName()+"["+name+"].myMethod1()\n"); out.append("server version = "+serverInfo.getVersion()+"\n"); out.append("server build date = "+serverInfo.getBuildDate() +"\n"); out.append("server build time = "+serverInfo.getBuildTime() +"\n"); out.append("server copyright = "+serverInfo.getCopyright()+"\n"); out.append("server base directory = "+serverInfo.getBaseDirectory()+"\n"); out.append("server current base directory = "+serverInfo.getCurrentBaseDirectory()); System.out.println(out.toString()); return out.toString(); } public void setName(String name) { this.name = name; } public void setName2(String name2) { this.name2 = name2; } public void doFail() { System.out.println(this.getClass().getSimpleName()+ "["+name+"] Failed............."); } public void doStart() throws Exception { System.out.println(this.getClass().getSimpleName()+ "["+name+"] Started............"); } public void doStop() throws Exception { System.out.println(this.getClass().getSimpleName()+ "["+name+"] Stopped............"); } public static final GBeanInfo GBEAN_INFO; static { GBeanInfoBuilder infoFactory = GBeanInfoBuilder.createStatic ("GBean", MySampleGBean.class); // Initialize the GBean structure here infoFactory.addAttribute("kernel", Kernel.class, false); infoFactory.addAttribute("objectName", String.class, false); infoFactory.addAttribute("abstractName", AbstractName.class, false); infoFactory.addAttribute("classLoader", ClassLoader.class, false); [ 349 ]
Build the module by using the following command: mvn install
This will create the module JAR file gbean-sample-1.0.jar under the target directory. This JAR contains the GBean definition class of MySampleGBean. In the next section, we will see how we can create instances of this GBean.
Deploying the GBean
The gbean-sample-1.0.jar can be packaged in a WAR file or EAR file, and the GBean declaration XML can be added to the deployment plan of those applications. We will deploy a service module with four instances of the MySampleGBean. Before deploying the service module, upload the gbean-sample-1.0.jar to the server repository by using the Repository portlet. Select the file for upload. This will populate the artifactId, version, and type fields. Enter packt-samples for the groupId, and click on Install to upload the JAR. Use the Deploy New portlet to deploy the service module with the plan file provided under the samples. The same deployment plan is given below: packt-samples mygbean 1.0 car [ 350 ]
Chapter 14 org.apache.geronimo.framework j2ee-system car packt-samples gbean-sample jar mysamplegbean ServerInfo mysamplegbean2 ServerInfo mysamplegbean3 ServerInfo mysamplegbean4 mysamplegbean4 ServerInfo
[ 351 ]
Geronimo Internals
Here we have created four instances of MySampleGBean with GBean names mysamplegbean, mysamplegbean2, mysamplegbean3, and mysamplegbean4. Notice that under the dependencies element, we have added a dependency on packtsamples/gbean-sample//jar, which contains our GBean definition. Also notice that the dependency on org.apache.geronimo.framework/j2ee-system//car contains the ServerInfo GBean that we are using as a reference. The console output upon deploying this plan is as shown in the screenshot below:
Usually, the GBeans in the module are started in the same order as they are defined in the deployment plan. When the instances of MySampleGBean are started, a message is displayed in the Geronimo console window, giving the name of the GBean. Note that even though we have not configured the magic attributes in our deployment plan, the Geronimo server has provided values for these attributes. These attribute values are displayed in the command window. Notice that even though mysamplegbean3 is defined before mysamplegbean4 in the deployment plan, mysamplegbean4 is started before mysamplegbean3. This is because of the dependency mysamplegbean3 has on mysamplegbean4, as declared in the deployment plan. [ 352 ]
Chapter 14
Testing the GBean with GBean web app sample In order to test the MySampleGBean, we have provided a gbean-webapp web which is application in the samples. This sample contains a GBeanServlet,���������� shown below:
public class GBeanServlet extends HttpServlet { private static final long serialVersionUID = 1L; private Kernel kernel; @Override public void init(ServletConfig config) { kernel = KernelRegistry.getSingleKernel(); } @Override protected void service(HttpServletRequest request, HttpServletResponse response) throws IOException { response.setContentType("text/plain"); PrintWriter out = response.getWriter(); out.println("GBeanServlet"); out.println("Query using interface name MySampleInterface..."); try { AbstractNameQuery query = new AbstractNameQuery (MySampleInterface.class.getName()); Set gbeanNames = kernel.listGBeans(query); out.println("number of gbeans = "+gbeanNames.size()); for(Iterator itr = gbeanNames.iterator(); itr.hasNext(); ) { out.println(itr.next()); } gbeanNames = kernel.listGBeans(query); AbstractName gbeanName = (AbstractName) gbeanNames.iterator() .next(); out.println("\nObtaining gbean instance using abstract name " +gbeanName); MySampleInterface gbean = (MySampleInterface) kernel.getGBean(gbeanName); out.println(gbean); out.println("\nInvoking gbean method via proxy object..."); out.println((String)gbean.myMethod1()); out.println("\nInvoking set attribute on gbean "+gbeanName); kernel.setAttribute(gbeanName, "name", ((String) kernel.getAttribute(gbeanName, "name")).toUpperCase()); kernel.setAttribute(gbeanName, "name2", ((String) kernel.getAttribute(gbeanName, "name2")).toUpperCase()); out.println("\nInvoking invoke on gbean "+gbeanName); out.println((String)kernel.invoke(gbeanName, "myMethod1")); [ 353 ]
This servlet obtains an instance of kernel by using KernelRegistry, queries the kernel for instances of MySampleGBean, and executes operations on the GBeans. Deploy the gbean-webapp-1.0.war by using the Deploy New portlet, and access the application at http://localhost:8080/gbean-webapp/. The output from the servlet is shown in the screenshot below:
Observe the following in this output: •
The query for GBeans using the interface MySampleInterface has yielded 4 results.
•
The servlet obtains the GBean MySampleGBean by using the getGBean API and invokes myMethod1() using the GBean object. Notice that myMethod1() has retrieved the server details using ServerInfo.
[ 354 ]
Chapter 14
•
The servlet has invoked the setAttribute kernel API on MySampleGBean to set the name attribute to MYSAMPLEGBEAN and name2 attribute to MYSMPLGBN. �������������������������������������������������������� Notice that the following XML fragment gets added under the packt-samples/mygbean/1.0/car module element in the config.xml file, as shown below: MYSAMPLEGBEAN
•
The attribute value change for name2 is not reflected in config.xml as name2 is not a manageable attribute.
•
The servlet then invokes the GBean operation myMethod1 on MySampleGBean. Notice that the value of name is now displayed in uppercase in the output.
Now launch the System Modules portlet and stop the configuration
packt-samples/mygbean/1.0/car. Notice the log messages displayed in the console by the doStop() lifecycle method.
Summary
In this chapter, we have taken a look at some of the important services provided by Geronimo, such as the kernel, ServerInfo, Configuration-Manager, AttributeStore, and ArtifactResolver. We have also looked at how low-level kernel services can be used to directly interact with GBeans and invoke services on GBeans. We have developed a new GBean to familiarize you with various aspects of GBeans, and demonstrated the newly-developed GBean by using a sample web application. This brings us to the end of this book on Apache Geronimo. You should now be familiar with most of the configuration aspects of the Apache Geronimo server, as well as being aware of the architecture that Geronimo is built on.
[ 355 ]
Deployment Plans A deployment descriptor is an XML file that describes a Java EE module. It lists the Java EE components that make up the module and defines the environment for these components. Java EE components have access to a naming service called JNDI, which is used to decouple the component from the resources and other components that it uses. The process of mapping the actual resources to the references in the application is done by means of the Java EE deployment descriptors and server-specific deployment plans. By deployment plans, we refer to the server-specific XML files that help in deployment. These files can be created by tooling or by hand. The different types of deployment descriptors, as specified in the Java EE specifications, are as follows: •
Web deployment descriptor: This file should be named web.xml, and should be present in the WEB-INF directory of your web module.
•
EJB deployment descriptor: This file should be named ejb-jar.xml, and should be present in the META-INF directory of the EJB module.
•
Application deployment descriptor: This file should be named
application.xml, and should be present in the META-INF directory
of the EAR file in which the application is packaged. •
Application Client deployment descriptor: This file should be named application-client.xml, and should be present in the META-INF directory of the application client module.
•
Resource Adapter deployment descriptor: This file should be named ra.xml, and should be present in the META-INF directory of the resource adapter module.
Deployment Plans
There are Geronimo-specific deployment plan counterparts for each of the Java EE 5 deployment descriptors. These are given below: •
Web deployment plan: This file should be named geronimo-web.xml, and should be present in the WEB-INF directory of your web module. This maps the resource references in the web.xml file to server resources.
•
EJB deployment plan: This file should be named openejb-jar.xml, and should be present in the META-INF directory of the EJB module. This maps the resource references in the ejb-jar.xml file to resources on the server.
•
Application deployment plan: This file should be named
geronimo-application.xml, and should be present in the META-INF
directory of the EAR file in which the application is packaged.
•
•
Application Client deployment plan: This file should be named
geronimo-application-client.xml, and should be present in the META-INF directory of the application client module.
Resource Adapter deployment plan: This file should be named geronimo-ra.xml, and should be present in the META-INF directory of the resource adapter module.
An external deployment plan can also be specified during deployment. In this case, the plan file can have any name, and will override any deployment plan packaged within the archives. Deployment plans are used to deploy services such as security realms into Geronimo. If the Service deployment plan is provided internally in the Java archive, it should be named geronimo-service.xml, and located under the META-INF directory. All deployment plans use some common elements, such as environment and gbean definitions. In this appendix, we will examine these common elements.
Environment
The environment element defines elements that are used to store information such as the Module ID, dependencies, and the class loader for the module. This element is used in all of the Services and application modules' deployment plans. This element is defined in the namespace http://geronimo.apache.org/xml/ns/ deployment-1.2. The schema representation is shown below:
[ 358 ]
Appendix A
The description of various elements under environment is as follows: •
moduleId: moduleId holds elements for the groupId, artifactId, version, and type of the module. Module IDs are normally specified with slashes between the four components, such as GroupID/ArtifactID/Version/Type. °
groupId: This ID is used to name the group containing this module. When groupId is not specified, by default,
it is considered 'default' for declaration and wildcard '*' for dependencies. °
artifactId: This ID is used to name the module in a specified group. If no articfactId is provided, it will be defaulted
to the file name of the module file. In case of dependencies, artifactId must be provided. °
version: This is used to specify the version number of the module, formatted by dot-separated numbers. If no version is provided, then it will be defaulted to a numeric timestamp generated by System.currentTimeMillis() at deploy time. In case of dependencies, the latest available version in the repository will be used.
[ 359 ]
Deployment Plans
°
•
type: This element defines the type of the module. The
type could be CAR, JAR, EAR, WAR, and so on. If no type is provided, then it will be defaulted appropriately by the deployer, depending upon the type of deployed module. In the case of dependencies, JAR will be used.
dependencies: The dependencies element defines all of the dependencies
of this module on other modules and repository artifacts. You can specify zero or more dependencies by using the dependency child element. Each dependency element may contain groupId, artifactId, version, type, and import elements. See moduleId above, for a description of groupId, artifactId, version, and type. °
import: The import element is a restrictive element used to
define the type of dependency. The default (when omitted) is to include the specified dependency in the class loader (as a parent or URL). If defined as "classes", it means that the classes must be included in the current module's class loader but the dependency does not need to be started. Specifying "services" means that the dependency (a module) must be started before the current module, but it is not included as a parent class loader.
•
hidden-classes: This element is used to specify a list of classes that will never be loaded from parent class loaders of this module. For example, if Log4J was listed here, the module would never see Geronimo's copy of Log4J. If the module provides its own Log4J JAR then it would use that. Otherwise, it would not be able to load Log4J at all. The classes are specified in zero or more child filter elements, where each filter element specifies a fully-qualified class name or prefix. Essentially, any class that starts with one of the prefixes listed in this element will be treated as hidden.
•
non-overridable-classes: This element is used to specify a list of classes that will only be loaded from parent class loaders of this module (never from the module's own class loader). For example, this is used to prevent a web application from redefining javax.servlet, so those classes will always be loaded from the server instead of the web application's own class-path. The classes are specified in zero or more child filter elements, where each filter element specifies a fully-qualified class name or prefix. Essentially, any class that starts with one of the prefixes listed here will be treated as non-overridable.
•
inverse-classloading: If this element is specified, the standard class loading delegation model is to be reversed for this module.
[ 360 ]
Appendix A
•
suppress-default-environment: If this element is specified, then any default environment built by a builder when deploying the plan will be suppressed. An example of where this is useful is when deploying a connector on an application client in a separate (standalone) module (not as part of a client plan). The connector builder default Environment includes some server modules that won't work on an application client, so you need to suppress the default environment and supply a complete environment including all parents for a non-application-client module that you want to run on an application client.
A typical environment element in a deployment plan looks like the block of code below: packt-samples helloworld 1.0 war log4j log4j 1.2.14 jar classes org.apache.log4j javax.servlet
Here the module will be deployed under the ID packt-samples/helloworld/1.0/ war. The module has a dependency on the log4j/log4j/1.2.14/jar repository artifact. All classes in the package org.apache.log4j and its sub-packages in the parent class loader are hidden and will be loaded in the module's class loader. All classes in the package javax.servlet and its sub-packages will be loaded from the parent class loader and will never be overridden in the module's class loader. The class loader uses inverse class loading. [ 361 ]
Deployment Plans
GBeans
The gbean element defines a GBean that will be deployed as part of the module. The schema diagram for this element is shown below:
The name attribute of the gbean element specifies a unique name for this GBean within this module. This name will be used as a name component in AbstractName, hence AbstractName will be unique, server-wide. The class attribute of the gbean element specifies the fully-qualified name of the Java class containing the GBeanInfo for this GBean. The description of the child elements of gbean is as follows: •
attribute: This element provides a value for the GBean attribute. The name of the GBean attribute is specified using the name attribute of the attribute element. The type of the GBean attribute is specified by using the type attribute of the attribute element. The value of the attribute is specified by the value of this element. [ 362 ]
Appendix A
•
xml-attribute: This element specifies the value of a particular GBean
•
reference: This element specifies the value of a particular reference for this
attribute in XML format, interpreted by a component running in the system, which converts it to a single value for this attribute. The name of the GBean attribute is specified by using the name attribute of the element.
GBean, in its simplest form. It holds the reference to the GBean that matches the single pattern specified here; if no value is specified it will refer to all the matching GBeans. The name of the GBean reference is specified by using the name attribute of this element. The child elements of this element are as follows: °
groupId: This element specifies the name of the group
containing the module to match. By default is it the wild card '*'.
°
artifactId: This element specifies the name of the module in a
°
version: This element specifies the version number of the module, formatted by dot-separated numbers. If no version is provided it will be defaulted to the latest available version that matches the other criteria.
°
module: The value specified for module should match the file name of the referenced module.
°
type: This element defines the type of the module to be
°
name: This element specifies the name to identify the referenced
specified group to be matched.
matched. The type could be CAR, JAR, EAR, WAR, and so on. If no type is provided, it will be defaulted to the wild card '*'. GBean by.
•
references: This element specifies the value of a particular reference for this GBean if it matches multiple pattern elements. Each pattern element may have groupId, artifactId, version, module, type, and name child elements.
•
xml-reference: This element specifies the value of a particular reference
•
dependency: This element is used to resolve dependencies at the GBean level.
in XML format, which will be interpreted by a component running in the system, which converts it to a single value for this reference. The name of the reference is specified by using the name attribute of this element.
This is normally used only if, for some reason, the GBeans within a module must be started in a certain order that is not reflected in the references between them. Dependencies are specified by using multiple pattern elements. Each pattern element may have groupId, artifactId, version, module, type, and name child elements. [ 363 ]
Deployment Plans
The following is an example of a GBean definition: packt-properties-realm ServerInfo packt-properties-realm org.apache.geronimo. security.realm.providers.PropertiesFileLoginModule var/security/packt-users.properties var/security/packt-groups.properties
Here, a security realm GBean with name of packt-properties-realm is created using XML. It configures one GBean attribute, with a name of realmName, using an attribute element and two references, namely, ServerInfo using a reference element and LoginModuleConfiguration using an xml-reference element.
[ 364 ]
Appendix A
Application Client
Application Client deployment plans use the client-environment and server-environment elements to define the environment. The description of these elements is as follows: •
client-environment: This element is used only by Application Client
•
server-environment: This element is used only by Application Client
modules to provide a client module environment setting. It defines elements for storing information , such as the Module ID, dependencies, and a class loader for the client-side application module. This information is used to identify the module in the client container only, and should not be directly used by deployment process. modules to define server-side module environment settings. It defines elements for storing information such as the Module ID, dependencies, and a class loader for the server-side of the client application module. This information is used to identify the module in the server environment only.
[ 365 ]
Troubleshooting In this Appendix, we will look at troubleshooting server startup, application/ configuration deployment and application/configuration startup problems.
Server startup errors
If any of the configurations fail to start during server startup, the server will automatically be shutdown. Most errors during startup are logged to the command window, as well as to the geronimo.log file under the /var/log directory (//var/log directory in the case of a non-default instance). Here are some common startup errors and ways to resolve these errors.
BindException
A BindException is thrown when a GBean attempts to bind to a port that is already in use by another process on the system. A typical log entry for this kind of error is shown below: 2009-07-14 00:02:14,642 ERROR [GBeanInstanceState] Error while starting; GBean is now in the FAILED state: abstractName="org.apache. geronimo.framework/rmi-naming/2.1.4/car? ServiceModule=org.apache.geronimo.framework/rmi-naming/2.1.4/car, j2eeType=GBean,name=RMIRegistry" java.rmi.server.ExportException: Port already in use: 1099; nested exception is: java.net.BindException: Address already in use: JVM_Bind at sun.rmi.transport.tcp.TCPTransport.listen(TCPTransport.java:249) ...
Troubleshooting
Some of the reasons due to which this error may occur, and the associated remedies are: •
The server instance is already running in a different server process. There is nothing to do in this case.
•
You are attempting to start a different server instance created using the multiple instances feature provided by Geronimo, and the org.apache. geronimo.server.name system property is not set. Make sure that you set the org.apache.geronimo.server.name system property correctly, by using the GERONIMO_OPTS environment variable.
•
You are attempting to start a different server instance created using the multiple instances feature provided by Geronimo, and the org.apache. geronimo.server.name system property is set correctly. The PortOffset property in the config-substitutions.properties file under //var/config may not have been set correctly. Set the PortOffset property so that the conflict is resolved. Remember that this property is used to offset the server ports when using multiple instances within the same installation.
IllegalArgumentException due to a wrong instance name
An IllegalArgumentException is thrown when you attempt to start a non-existent server instance. A message similar to the following is logged to the console: 11:49:26,439 ERROR [GBeanInstanceState] Error while starting; GBean is now in the FAILED state: abstractName="org.apache.geronimo.framework/j2ee-system/2.1.4/car? ServiceModule=org.apache.geronimo.framework/j2ee-system/2.1.4/car, j2eeType=GBean,name=ServerInfo" java.lang.IllegalArgumentException: Server directory is not a directory: C:\book\temp\geronimo-tomcat6-javaee5-2.1.4\wrong_inst at org.apache.geronimo.system.serverinfo.BasicServerInfo.deriv eBaseServer(BasicServerInfo.java:187) ...
To resolve this problem, specify the correct instance name in the org.apache. geronimo.server.name system property.
[ 368 ]
Appendix B
InvalidConfigurationException
An InvalidConfigurationException is thrown when a configuration that the server is attempting to start does not exist. One reason due to which this can happen is with the multiple server instances feature, when a configuration deployed through one server instance is undeployed through a different server instance, which results in entries corresponding to that configuration being left out of the config.xml files. A typical error message logged in this case looks like the following: org.apache.geronimo.kernel.config.InvalidConfigException: Could not locate configs to start: [packt-samples/helloworld/1.0/war] at org.apache.geronimo.system.main.EmbeddedDaemon. doStartup(EmbeddedDaemon.java:167)
To resolve this problem, edit the config.xml file and remove the problematic configuration entries.
Deployment errors
In this section, we will look at some common deployment errors and how these errors can be resolved.
MissingDependencyException
A MissingDependencyException is thrown when a configuration or repository artifact specified as a dependency in the application, or the configuration being deployed does not exist on the server. The following is a typical error message displayed during deployment: Error: Unable to deploy mywebapp-1.0.war: Unable to createconfiguration for deployment load of default/mywebapp-1.0/1.0/war failed Error starting configuration gbean default/mywebapp-1.0/1.0/war Missing dependency: default/non-existant/1.0/jar
[ 369 ]
Troubleshooting
The following is a typical message logged to Administration Console when deploying from Deploy New portlet: org.apache.geronimo.common.DeploymentException: Unable to create configuration for deployment at org.apache.geronimo.deployment.DeploymentContext. createTempConfiguration(DeploymentContext.java:150) Caused by: org.apache.geronimo.kernel.repository. MissingDependencyException: Missing dependency: default/non-existant/1.0/jar at org.apache.geronimo.kernel.config.ConfigurationResolver.resolve (ConfigurationResolver.java:113) ...
To resolve this error, make sure that the parent configurations declared in the dependencies exist on the server. You can use the Repository Viewer portlet to view a list of artifacts in the repository. Click on the artifact in the portlet to get help on how to use the artifact as a dependency.
XmlException—Invalid deployment descriptor An XmlException can occur due to an erratic deployment plan, or if the deployer is unable to recognize an element. The following is an example of a deployment exception due to an element in the deployment plan not being recognized:
Appendix B service@http://geronimo.apache.org/xml/ns/deployment-1.2 persistence@ http://java.sun.com/xml/ns/persistence' instead of 'tomcat-clusteringwadi@http://geronimo.apache.org/xml/ns/tomcat-clustering-wadi-1.2' here Descriptor: packt-samples helloworld-cluster 1.0 war /helloworld-cluster at org.apache.geronimo.deployment.xmlbeans.XmlBeansUtil. validateDD(XmlBeansUtil.java:187) ...
In this example, the error is due to the element not being recognized, as the org.apache.geronimo.configs/tomcat6-clusteringbuilder-wadi/2.1.4/car is not running when deployment was attempted. To resolve this kind of error, start the builder configuration and deploy the application again.
DuplicateDeploymentException
A DuplicateDeploymentException is thrown when an EJB module contains EJBs with the same names as the EJBs already running on the server. This is because the deployment-ids created for the EJBs are same as the running EJBs. A typical log message for this error is given below: 2009-07-17 01:03:17,421 ERROR [GBeanInstanceState] Error while starting; GBean is now in the FAILED state: abstractName="packtsamples/myejbapp/2.0/jar? J2EEApplication=null,j2eeType=EJBModule,name=packt-samples/ myejbapp/2.0/jar"
[ 371 ]
Troubleshooting org.apache.openejb.DuplicateDeploymentIdException: Application cannot be deployed as it contains deployment-ids which are in use: app: C:\book\geronimo-tomcat6-javaee5-2.1.4\var\temp\geronimodeployer5436850122084871803.tmpdir\myejbapp.jar myejbapp/MySessionBean myejbapp/MyEjb3ServiceBean myejbapp/MyEjb3ServiceBean2 myejbapp/MyEjb3ServiceBean3 at org.apache.openejb.assembler.classic.Assembler. createApplication(Assembler.java:438) ...
This error can be overcome by setting the openejb.deploymentId.format system variable, in order to override the default setting that is causing the conflict. See http://openejb.apache.org/3.0/system-properties.html and http://openejb.apache.org/3.0/jndi-names.html for more details.
Runtime errors
In this section, we will look at some runtime errors that can occur and how these errors can be resolved.
LoginException—No LoginModules configured
A LoginException occurs when the security realm configured in a web application is not running on the server. A warning message similar to the following will be logged to the geronimo.log file�. 2009-07-17 00:48:58,234 WARN [TomcatGeronimoRealm] Login exception authenticating username "system" javax.security.auth.login.LoginException: No LoginModules configured for test-realm ...
To resolve this error, make sure that the configured security realm is running. You can use the Security Realms portlet to view all of the security realms running on the server. To avoid running the application while the security realm is stopped, you should add a dependency on the security realm configuration to your application's deployment plan, so that the security realm is started automatically before starting your application.
client-environment element 132, 365 default-subject element 133 ejb-ref element 132 elements 131 gbean-ref element 132 message-destination element 133 realm-name element 133 resource-env-ref element 133 resource-ref element 132 resource element 133 server-environment element 365 server-environment, dependencies element 131 server-environment, hidden-classes element 131 server-environment, inverse-classloading element 132 server-environment, moduleId element 131 server-environment, non-overridable-classes element 131 server-environment, suppress-default-environment element 132 server-environment element 131 service-ref element 132 service element 134 application deployment descriptor 96, 357 application deployment plan 97, 358 Application EARs portlet 256 application local JNDI context about 219, 220 ejb-local-ref element 223 ejb-ref element 222, 223 gbean-ref element 228 message-destination-ref element 225, 226 persistence-context-ref element 226, 227 persistence-unit-ref element 227, 228 resource-env-ref element 222 resource-ref element 221 service-ref element 224, 225 ApplicationLog4jConfigurationGBean used, for logging 332, 333 application logging, configuring about 327 Java Logging API used 333 log4j used 327 SLF4j logging adapter used 333, 334
[ 375 ]
application security about 180 application-scoped security realm 196 EAR application security, configuring 196 EJB application security, configuring 185 run-as and default subjects 192 web application security, configuring 180, 181, 183, 184, 185 Applications portlets, Administration Console about 17, 255 App Clients portlet 257 Application EARs portlet 256 Deploy New portlet 255 EJB JARs portlet 256 J2EE connectors portlet 257 Plan Creator portlet 257 System Modules portlet 256 Web App WARs portlet 256 artifactId 31 ArtifactResolver 341, 342 ASF 8, 75 Assembler class 27 attribute element 362 attributes, GBean about 343 GBeanInfoBuilder.addAttribute() method 343 magic attributes 344 MySampleGBean class 343
B Bean-managed persistence 124 Bean-managed transactions 144 BindException, Server startup errors 367, 368 BIO HTTP connector, attributes address 269 port 269 uniqueName 269 blocking IO (BIO) 268 boot() 337 BootStrap class loader 35 brokerName attribute 76 brokerUri attribute 76 buildConfiguration() 44
C CA about 161 portlet 164 calculateTax method 26 car-maven-plugin 235 Certificate Signing Request. See CSR Certification Authority. See CA ciphers 165 class loader architecture, Apache Geronimo about 35, 36 BootStrap class loader 35 ClassLoader Viewer portlet 35 default class loading behavior, modifying 36, 37 j2ee-system class loader 35 modules 37 classLoader attribute 344 ClassLoader Viewer portlet 263, 264 client-scoped, database pool scopes 50 client-scoped pool creating 64-66 clientAuth 165 clientAuthRequired 166 Client Security Service. See CSS ClockGBean 235 Clock interface 235 Cluster 307 Clustered Helloworld-cluster application about 317 workers.properties, updating 317-320 clustering 307 CMP 9 command-line deployer used, for creating server-wide JMS resources 86 used, for deploying database pool 61 commit() method 146 Common Object Requesting Broker Architecture. See CORBA Common Secure Interoperability Version 2. See CSIv2 protocol Common Security Interoperability. See CSI compoundSecMech, child elements GSSUP 204 identityTokenTypes 204
E EAR sample application 137-140 EAR application security configuring 196 EARConfigBuilder 44 Eclipse about 290 downloading 290 EditableConfigurationManager about 340 addGBeanToConfiguration 341 removeGBeanFromConfiguration 341 EJB 8 ejb-local-ref element 223 ejb-ref element 222, 223 EJB annotation 107, 108 EJB applications about 112 annotations 113 EJB deployment plan 116 sample 118, 119 EJB applications, sample about 118-120 deploying 120 JMS resources, deploying 120 web application, deploying 120 EJB application security configuring 185 EJB sample application, running 190, 191
[ 379 ]
entity bean security, configuring 191, 192 method permissions, configuring 188 method permissions, declaring in deployment descriptor 185-187 principals, mapping to roles in EJB deployment plan 189 roles defining, annotations used 188 security roles, defining 188 security roles, defining in deployment descriptor 185 EJBContext.getUserTransaction() 144 EJB deployment descriptor 96, 357 EJB deployment plan 97, 358 EJB deployment plan, EJB applications about 116 environment element 116 jndiEnviromentRefsGroup 116 message-destination element 117 security element 117 web-service-binding element 117 EJB deployment plan, enterprise beans ejb-name element 118 jndi-name element 118 local-jndi-name element 118 tss-link element 118 tss element 118 EJB deployment plan, schema openejb-jar2.2.xsd db-syntax-factory element 117 ejb-ql-compiler-factory element 117 enforce-foreign-key-constraints element 117, 118 relationships element 118 EJB JARs portlet 256 EJBs, exposing through CORBA EJB, configuring to use TSS 205 sample application 205-209 sample EJB application, deploying 209 sample EJB application, running 209 Target Security Service (TSS), creating 200, 201 EJBs, referencing through CORBA Client Security Service (CSS), creating 209 EJB reference, configuring to use CSS 214 sample, deploying 217 sample, running 217 sample CSS 215-217
sample web application, CORBA EJBs accessing 214 EJB web service about 135 deploying 140, 141 Embedded DB portlets, Administration Console DB Info portlet 258 DB Manager portlet 258-260 embedded Derby database BUILTIN, authentication method 153 database pools, updating 153, 154 LDAP, authentication method 153 securing 152, 153 enterprise applications about 127 deployment plan 127 enterprise applications, deployment plan elements 128 environment element 128 ext-module element 128, 129 module element 128 security element 129 service element 129 Enterprise JavaBeans. See EJB environment element about 358 defining, in namespace 358 dependencies, import 360 dependencies element 360 hidden-classes element 360 in deployment plan 361 inverse-classloading element 360 moduleId, artifactId 359 moduleId, groupId 359 moduleId, type 360 moduleId, version 359 moduleId element 359 non-overridable-classes element 360 suppress-default-environment element 361 error-page element 105 external-path 63
F farm deployment about 321 sample application, running 322, 323 [ 380 ]
farming about 320 cluster member, configuring 320 farm deployment, using 321 sample application running, farm deployment used 322, 323 filter-class element 102 filter-name element 102 filters about 101 filter-class element 102 filter-name element 102 FilterConfig 102 param-name element 102 param-value element 102 servlet-name element 102 url-pattern element 102
groupId 359 type 360 version 359 MOM 75 Monitoring console about 276 graph, adding 279, 280 server, adding 277-279 view, creating 280, 281 Monitoring portlet 253 multiple server instances running, from single installation 315- 317
N name 60 name parameter, GBeanInfoBuilder.addAttribute() method 343 name parameter, GBeanInfoBuilder.addOperation() method 345 name parameter, GBeanInfoBuilder.addReference() method 345 NamingBuilder instances 46 namingType parameter, GBeanInfoBuilder. addReference() method 345 nodes 307 non-blocking IO (NIO) 268 non-overridable-classes 36 non-overridable-classes element 360
O Object Management Group. See OMG objectName attribute 344 Object Request Broker. See ORB OMG 199 openejb.jndiname.format system property 229 operations, GBean GBeanInfoBuilder.addOperation() method 345 GBeanInfoBuilder.addOperation() method, parameters 345 ORB 199
[ 387 ]
P PAM framework 150 param-name element 101 param-value element 101 parameterTypes parameter, GBeanInfoBuilder.addOperation() method 345 persistence-context-ref element 226 persistence-unit-ref element 227, 228 persistentAttributes parameter, GBeanInfoBuilder.addInterface() method 346 Plan Creator portlet, Geronimo Administration Console 17, 257 pluggable Administration Console about 237 architecture 238 extension, developing 238-242 Pluggable Authentication Module. See PAM framework plugin developing 231 installing 236, 237 list 237 project, creating 232-236 plugin, installing Administration Console used 236, 237 deploy.bat script used 236 deploy.sh script used 236 GShell used 236 install-plugin command used 236 list-plugins command used 237 plugin catalog 47 plugin repository 48 plugins about 47 catalog 47 customer server assemblies 48 extensible administration console 48 repository 47 Plugins portlet 243, 244 Plugins portlet, Geronimo Administration Console 17 POJO web services 135 pool editing 66, 67
importing, from another application server 67-69 PortalContainerServicesGBean 242 private-classes 36 PropertiesFile login module about 167 groups properties file, sample 167 options 168 users properties file, sample 167 PropertiesFile login module, options digest option 168 encoding option 168 groupsURI 168 usersURI 168
R reference element about 363 groupId 363 module 363 name 363 type 363 version 363 references, GBean about 344 GBeanInfoBuilder.addReference() method 344 GBeanInfoBuilder.addReference() method, parameters 345 MySampleGBean class, excerpt 345 references element 363 registerShutdownHook() 337 reloadConfiguration() 340 removeGBeanFromConfiguration, EditableConfigurationManager 341 RentCalculator class 25 Repository portlet, Geronimo Administration Console 16, 254 resolve() 338 resolve(URI) 338 resolvePath() 338 resolveServer() 338 resolveServer(URI) 338 resolveServerPath() 338 resource-env-ref element 222 resource-ref element 221
[ 388 ]
resource adapter deployment descriptor 96, 357 resource adapter deployment plan 97, 358 resource annotation env-entry value 107 name attribute 106 ResourceBindingsFormat, Global JNDI 229 ResourceBindingsNameInNamespace, Global JNDI 229 ResourceBindingsNamePattern, Global JNDI 229 ResourceBindingsQuery, Global JNDI 229 restartConfiguration() 340 returnType parameter, GBeanInfoBuilder. addOperation() method 345 rollback() method 146 run-as and default subjects, application security application configuring, to use credential store 193 configuring 194 credential store 192, 193 message-driven bean security, configuring 196 sample EJB application, running 195 runtime, errors LoginException 372
S sasMech about 204 schema diagram 213 secureProtocol 166 security-constraint 105 security-role 105 security realm about 174 creating, ways 174 deployment plan 179 principal, wrapping 180 Security Realms portlet, using 174-178 security services on client side 200 on server side 200 security standards CSIv2 protocol 150
JAAS 150 JACC 150 Java Authentication and Authorization Service (JAAS) 149 PAM framework 150 server-environment element 365 server-scoped database pool accessing 70-73 server-wide, JMS resources scope 78 server-wide database pool Administration Console Wizard, using 51-55 command-line deployer, using 61 creating 51 Deploy New portlet, using 56-61 GShell, using 62 Scopes 50 unlisted drivers, installing 56 server-wide JMS resources, creating Administration Console Wizard used 79-85 command-line deployer used 86 Deploy New portlet used 86 GShell used 86 server directory securing 150, 151 var/config 151 var/derby 151 var/repository 151 var/security 151 var/security/keystores 151 server directory structure bin directory 41 configuration files 41 etc directory 41 lib directory 41 schema directory 41 var|config directory 41 var|derby directory 41 var|log directory 41 var|security|keystores directory 41 var|security directory 41 server directory structure, configuration files artifact_aliases.properties 41 client-log4j.properties 42 client_artifact_aliases.properties 42 config-substitutions.properties 41 config.xml 41
[ 389 ]
deployer-log4j.properties 42 groups.properties 42 server-log4j.properties 42 users.properties 42 ServerInfo, APIs getBaseDirectory() 338 getBuildDate() 338 getBuildTime() 338 getCopyright() 338 getCurrentBaseDirectory() 338 getVersion() 338 resolve() 338 resolve(URI) 338 resolvePath() 338 resolveServer() 338 resolveServer(URI) 338 resolveServerPath() 338 Server Logs portlet, Geronimo Administration Console 15 Derby Log Viewer 252 Log Manager 252 Server Log Viewer 252 Web Access Log Viewer 252 Server Log Viewer 252 Server portlets, Administration Console about 251 Apache HTTP portlet 253 Information portlet 251, 252 Java System Info portlet 252 JMS Server portlet 253 Monitoring portlet 253 Server logs portlet 252 shutdown portlet 252 Thread Pools portlet 253 Web Server portlet 253 Server startup, errors about 367 BindException 367, 368 IllegalArgumentException 368 InvalidConfigurationException 369 service-ref element 224 service-ref element, elements port 137 service-completion 136 service-ref-name 136 ServiceConfigBuilder 43
Services portlets, Administration Console Database Pools portlet 254 JMS Resources portlet 255 Repository portlet 254 servlet-class element 101 servlet-mapping element 101 servlet-name element 101, 102 servlet context attribute listener 103 servlet context listener 102 servlet request attribute listener 103 servlet request listener 103 Servlets about 100 init() lifecycle method 101 init-param tag 101 param-name element 101 param-value element 101 servlet-class element 101 servlet-mapping 101 servlet-name element 101 session-config element 105 setAttribute() 336 setRollbackOnly() method 143 shutdown() 337 Shutdown portlet 252 Simple Logging Facade for Java. See SLF4J single-pool 60 Single sign-on. See SSO SLF4J about 326 using, over log4j 333, 334 SLF4j logging adapter used, for application logging configuring 333, 334 Spring 39 SQL login module database connectivity using JDBC, options 169 digested passwords using, options 169 digest option 169 encoding option 169 jdbcDriver option 169 jdbcPassword option 169 jdbcURL option 169 jdbcUser option 169
[ 390 ]
SQL login module, options groupSelect 168 userSelect 168 SSL element, attributes handshakeTimeout 202, 211 hostname 202 port 202 SSL element, child elements requires 202, 211 supports 202, 211 trustGroup 203, 211 sslProtocol 165 SSO 196, 197 startConfiguration() 340 startGBean() 336 startRecursiveGBean() 336 stopConfiguration() 340 stopGBean() 336 suppress-default-environment 37 suppress-default-environment element 361 System class loader 35 System Modules portlet 256
T Target Security Service. See TSS TaxCalculator class 25 Thread Pools portlet 253 Tomcat HTTPS connectors algorithm 165 ciphers 165 clientAuth 165 keyAlias 165 keyStore 165 keyStoreType 165 sslProtocol 165 trustStore 165 trustStorePass 165 trustStoreType 165 Tomcat specific configuration, web deployment plan cluster 111 cross-context element 110 disable-cookies element 111 host element 110 jndiEnviromentRefsGroup element 111 listener-chain element 111
manager element 111 tomcat-realm element 111 valve-chain element 111 TranQL 11 TranQL framework 49 TranQL RAR files 50 transaction about 142 annotations 143 Bean-managed transactions 144 container-managed transactions 142 in web applications 146, 147 session bean example, container-managed transactions used 142 support in Geronimo 145 timeout, setting 145 transaction, isolation levels read committed 145 read uncommitted 145 repeatable read 145 serializable 145 transaction, support in Geronimo transaction, isolation level 145, 146 transactions, in web applications 146, 147 transaction timeout, setting 145 transaction-caching 60 transaction attribute annotations 143 transaction attribute, values mandatory value 143 never value 143 NotSupported value 143 required value 142 RequiresNew value 142 supports value 143 transaction attribute, values 142 troubleshooting deployment, errors 369 runtime, errors 372 Server startup, errors 367 trustStore 165, 166 trustStorePass 165 TSS about 200 creating 200
[ 391 ]
TSS, creating authentication mechanism 203, 204 compoundSecMech, child elements 204 compundSecMech block 203 identityTokenTypes block 204, 205 SSL block 202 SSL element, attributes 202 SSL element, child elements 202 supports and requires elements, values 203 tssConfig element, child elements 201 tssConfig element, elements 201 tssConfig element, child elements compoundSecMech 201 compoundSecMechTypeList: 201 description 201 SECIOP 201 SSL 201 type 31 type parameter, GBeanInfoBuilder.addAttribute() method 343 type parameter, GBeanInfoBuilder.addReference() method 345
U uninstallConfiguration() 340 unlisted drivers installing 56 unloadConfiguration() 340 unloadGBean() 336 unregisterShutdownHook() 337 url-pattern element 102 Users and Groups portlet, Geronimo Administration Console 17 UserTransaction object 146 useShutdownHook attribute 76 useShutdownHook property 77
V var/config 151 var/derby 151 var/repository 151 var/security 151 var/security/keystores 151 version 31 vertical cluster 307
W WADI about 308 deployment descriptor, updating 308, 309 deployment plan, updating 308, 309 org.apache.geronimo.configs/clustering// car 308 org.apache.geronimo.configs/wadi-clustering//car 308 WADI integration of Tribes 308 Web Access Log Viewer 252 Web app in Geronimo 310 Web Application Distribution Infrastructure. See WADI web application security tag 182 configuring 181, 182 geronimo-web.xml file, points 184 sample web application, running 185 web.xml file, points 181 Web App WARs portlet 256 web deployment descriptor about 96, 357 context-param element 105 error-page element 105 jndiEnvironmentRefsGroup 106 jsp-config element 105 locale-encoding-mapping-list 106 login-config 105 message-destination 106 mime-mapping element 105 security-constraint 105 security-role 105 session-config element 105 welcome-file-list element 105 web deployment plan about 97, 108, 358 geronimo-web-2.0.1.xsd, graphical representation 108 Jetty specific configuration 111 Tomcat specific configuration 110 Tomcat specific configuration element 111
[ 392 ]
web deployment plan, schema geronimoweb-2.0.1.xsd container-config 109 context-root 109 environment 109 jndiEnvironmentRefsGroup 109 message-destination 109 persistence 109 security 109 security-realm-name 109 service 109 web-container 109 work-dir 109 web modules 100 Web Server administration about 268 AJP connectors 273 HTTP connectors 269-271 HTTPS connectors 271, 272 Web Server Logs 274, 275 Web Server Logs 274, 275 Web Server portlet, Geronimo Administration Console 16, 253 web services about 135 EAR, sample application 137-140 EJB web service, deploying 140, 141 EJB web services 135
POJO web services 135 port-completion Type element 135 port Type element 136 service-completion Type element 135 service-ref element, elements 136, 137 Web Tools Platform. See WTP welcome-file-list element 105 WorldClock plugin 246, 247 WTP 20, 289
X xa-transaction 60 XA pool creating 69, 70 xml-attribute element 363 xml-reference element 363 XmlException, deployment errors 370, 371
Y Yoko, Apache 11
Z ZIP file, Apache Geronimo downloading 12
[ 393 ]
Thank you for buying
Apache Geronimo 2.1 Quick Reference
Packt Open Source Project Royalties
When we sell a book written on an Open Source project, we pay a royalty directly to that project. Therefore by purchasing Apache Geronimo 2.1, Packt will have given some of the money received to the Apache Geronimo project. In the long term, we see ourselves and you—customers and readers of our books—as part of the Open Source ecosystem, providing sustainable revenue for the projects we publish on. Our aim at Packt is to establish publishing royalties as an essential part of the service and support a business model that sustains Open Source. If you're working with an Open Source project that you would like us to publish on, and subsequently pay royalties to, please get in touch with us.
Writing for Packt
We welcome all inquiries from people who are interested in authoring. Book proposals should be sent to [email protected]. If your book idea is still at an early stage and you would like to discuss it first before writing a formal book proposal, contact us; one of our commissioning editors will get in touch with you. We're not just looking for published authors; if you have strong technical skills but no writing experience, our experienced editors can help you develop a writing career, or simply get some additional reward for your expertise.
About Packt Publishing
Packt, pronounced 'packed', published its first book "Mastering phpMyAdmin for Effective MySQL Management" in April 2004 and subsequently continued to specialize in publishing highly focused books on specific technologies and solutions. Our books and publications share the experiences of your fellow IT professionals in adapting and customizing today's systems, applications, and frameworks. Our solution-based books give you the knowledge and power to customize the software and technologies you're using to get the job done. Packt books are more specific and less general than the IT books you have seen in the past. Our unique business model allows us to bring you more focused information, giving you more of what you need to know, and less of what you don't. Packt is a modern, yet unique publishing company, which focuses on producing quality, cutting-edge books for communities of developers, administrators, and newbies alike. For more information, please visit our website: www.PacktPub.com.
Apache Struts 2 Web Application Development ISBN: 978-1-847193-39-1
Paperback: 384 pages
A beginner’s guide for Java developers 1.
Design, develop, test, and deploy your web applications using Struts 2 framework
2.
No prior knowledge of JavaScript and CSS is required
3.
Apply the best of agile development techniques and TDD techniques
4.
# Step-by-step instructions and careful explanations with lots of code examples
Apache MyFaces Trinidad 1.2: A Practical Guide ISBN: 978-1-847196-08-8
Paperback: 300 pages
Develop JSF web applications with Trinidad and Seam 1.
Develop rich client web applications using the most powerful integration of modern web technologies
2.
Covers working with Seam security, internationalization using Seam, and more
3.
Get well-versed in developing key areas of web applications
4.
A step-by-step approach that will help you strengthen your understanding of all the major concepts