tag:blogger.com,1999:blog-230781132024-03-13T17:02:47.189-07:00Make IT Simplemake it simplehttp://www.blogger.com/profile/03356377809939814997noreply@blogger.comBlogger198125tag:blogger.com,1999:blog-23078113.post-12896713354419560832008-03-10T22:26:00.000-07:002008-03-10T22:30:59.510-07:00Open Source Software in Java(tm) LinksOpen Source Ajax Frameworks<br /><br /> * ThinWire - ThinWire is an development framework that allows you to easily build applications for the web that have responsive, expressive and interactive user interfaces without the complexity of the alternatives. While virtually any web application can be built with ThinWire, when it comes to enterprise applications, the framework excels with its highly interactive and rich user interface components.<br /><br /> * See all Open Source Ajax Frameworks<br /><br />Open Source Aspect-Oriented Frameworks in Java<br /><br /> * AspectJ - AspectJ is a seamless aspect-oriented extension to the Java programming language, Java platform compatible and easy to learn and use. AspectJ enables the clean modularization of crosscutting concerns such as: error checking and handling, synchronization, context-sensitive behavior, performance optimizations, monitoring and logging, debugging support, multi-object protocols.<br /><br /> * See all Open Source Aspect-Oriented Frameworks in Java<br /><br />Open Source Bloggers in Java<br /><br /> * The Roller Weblogger - A server-based weblogging software & a web application that is designed to support multiple simultaneous weblog users and visitors. Roller supports all of the latest-and-greatest weblogging features such as comments, WYSIWYG HTML editing, page templates, RSS syndication, trackback, blogroll management, and provides an XML-RPC interface for blogging clients such as w:bloggar and nntp//rss.<br /><br /> * See all Open Source Bloggers in Java<br /><br />Open Source Build Systems in Java<br /><br /> * Maven - Maven is a Java project management and project comprehension tool. Maven is based on the concept of a project object model (POM) in that all the artifacts produced by Maven are a result of consulting a well defined model for your project. Builds, documentation, source metrics, and source cross-references are all controlled by your POM. Look here to see the full list of Maven's features.<br /><br /> * See all Open Source Build Systems in Java<br /><br />Open Source ByteCode Libraries in Java<br /><br /> * BCEL - The Byte Code Engineering Library is intended to give users a convenient possibility to analyze, create, and manipulate (binary) Java class files (those ending with .class). Classes are represented by objects which contain all the symbolic information of the given class: methods, fields and byte code instructions, in particular.<br /><br /> * See all Open Source ByteCode Libraries in Java<br /><br />Open Source Content Management Systems (CMS) in Java<br /><br /> * Apache Lenya - Apache Lenya is a Java-based Open-Source Content Management System. It is based on open standards such as XML and XSLT. One of its core components is Cocoon from the Apache Software Foundation.<br /><br /> * See all Open Source Content Management Systems (CMS) in Java<br /><br />Open Source Cache Solutions in Java<br /><br /> * EHCache - EHCache is a pure Java, in-process cache with the following features: Fast,Simple, Acts as a pluggable cache for Hibernate 2.1., with Small foot print, Minimal dependencies, Fully documented and Production tested.<br /><br /> * See all Open Source Cache Solutions in Java<br /><br />Open Source Charting & Reporting Tools in Java<br /><br /> * JFreeChart - JFreeChart is a free Java class library for generating charts, including:<br /><br /> * pie charts (2D and 3D)<br /> * bar charts (regular and stacked, with an optional 3D effect)<br /> * line and area charts<br /> * scatter plots and bubble charts<br /> * time series, high/low/open/close charts and candle stick charts<br /> * combination charts<br /> * Pareto charts<br /> * Gantt charts<br /> * wind plots, meter charts and symbol charts<br /> * wafer map charts<br /><br /> * See all Open Source Charting & Reporting Tools in Java<br /><br />Open Source Chat Servers in Java<br /><br /> * GujChat - GujChat is a new Chat System capable of managing multiple chat servers, each one serving different rooms and options for its users. One single installation delivers webmasters different templates, rooms, languages and configurations<br /><br /> * See all Open Source Chat Servers in Java<br /><br />Open Source Code Analyzers in Java<br /><br /> * PMD - PMD scans Java source code and looks for potential problems like:<br /><br /> * Unused local variables<br /> * Empty catch blocks<br /> * Unused parameters<br /> * Empty 'if' statements<br /> * Duplicate import statements<br /> * Unused private methods<br /> * Classes which could be Singletons<br /> * Short/long variable and method names<br /><br /> * See all Open Source Code Analyzers in Java<br /><br />Open Source Code Beautifiers<br /><br /> * Jalopy - Jalopy is a source code formatter for the Sun Java programming language. It layouts any valid Java source code according to some widely configurable rules; to meet a certain coding style without putting a formatting burden on individual developers.<br /><br /> * See all Open Source Code Beautifiers<br /><br />Open Source Code Coverage Tools in Java<br /><br /> * Cobertura - Cobertura is a free Java tool that calculates the percentage of code accessed by tests. It can be used to identify which parts of your Java program are lacking test coverage. It is based on jcoverage. Features of Cobertura:<br /><br /> * Can be executed from ant or from the command line.<br /> * Instruments Java bytecode after it has been compiled.<br /> * Can generate reports in HTML or XML.<br /> * Shows the percentage of lines and branches covered for each class, each package, and for the overall project.<br /> * Shows the McCabe cyclomatic code complexity of each class, and the average cyclomatic code complexity for each package, and for the overall product.<br /> * Can sort HTML results by class name, percent of lines covered, percent of branches covered, etc. And can sort in ascending or decending order.<br /><br /> * See all Open Source Code Coverage Tools in Java<br /><br />Open Source Collections Libraries in Java<br /><br /> * Commons Collections - Commons-Collections seek to build upon the JDK classes by providing new interfaces, implementations and utilities. There are many features, including:<br /><br /> * Bag interface for collections that have a number of copies of each object<br /> * Buffer interface for collections that have a well defined removal order, like FIFOs<br /> * BidiMap interface for maps that can be looked up from value to key as well and key to value<br /> * MapIterator interface to provide simple and quick iteration over maps<br /> * Type checking decorators to ensure that only instances of a certain type can be added<br /> * Transforming decorators that alter each object as it is added to the collection<br /> * Composite collections that make multiple collections look like one<br /> * Ordered maps and sets that retain the order elements are added in, including an LRU based map<br /> * Identity map that compares objects based on their identity (==) instead of the equals method<br /> * Reference map that allows keys and/or values to be garbage collected under close control<br /> * Many comparator implementations<br /> * Many iterator implementations<br /> * Adapter classes from array and enumerations to collections<br /> * Utilities to test or create typical set-theory properties of collections such as union, intersection, and closure<br /><br /> * See all Open Source Collections Libraries in Java<br /><br />Open Source Command Line Interpreters in Java<br /><br /> * Jakarta Commons CLI - The Apache Commons CLI library provides an API for processing command line interfaces. There are three stages to command line processing. They are the definition, parsing and interrogation stages.<br /><br /> * See all Open Source Command Line Interpreters in Java<br /><br />Open Source Database Connection Pools<br /><br /> * Jakarta DBCP - DBCP is a database connection pool that relies on code in the Jakarta commons-pool package to provide the underlying object pool mechanisms that it utilizes. Applications can use the DBCP component directly or through the existing interface of their container / supporting framework.<br /><br /> * See all Open Source Database Connection Pools<br /><br />Open Source Crawlers in Java<br /><br /> * Heritrix - Heritrix is the Internet Archive's open-source, extensible, web-scale, archival-quality web crawler project.<br /><br /> * See all Open Source Crawlers in Java<br /><br />Open Source Database Engines in Java<br /><br /> * Apache Derby - Derby is a Java RDBMS undergoing incubation at Apache Software Foundation. It is a fully functioned standards based JDBC & SQL RDBMS with tables, indexes, views, triggers, sub-queries, procedures, functions, transactions, isolation levels, encryption, etc. Derby is the open sourcing of the IBM Cloudscape technology.<br /><br /> * See all Open Source Database Engines in Java<br /><br />Open Source EJB Servers<br /><br /> * JBoss - JBoss is advanced middleware with a full J2EE based personality that IT departments look for. But that is not all, the OEM and ISV community embraced JBoss as a highly flexible service oriented architecture on which to build their own products.<br /><br /> * See all Open Source EJB Servers<br /><br />Open Source ERP & CRM Software<br /><br /> * Apache OFBiz (Apache Open For Business Project) - The Apache Open For Business Project is an open source enterprise automation software project. By open source enterprise automation we mean: Open Source ERP, Open Source CRM, Open Source E-Business / E-Commerce, Open Source SCM, Open Source MRP, Open Source CMMS/EAM, and so on.<br /><br /> * See all Open Source ERP & CRM Software<br /><br />Open Source Enterprise Service Bus in Java<br /><br /> * Mule - Mule is a light-weight messaging framework. It is a highly distributable object broker that can seamlessly handle interactions with other applications using disparate technologies, transports and protocols. The Mule framework provides a highly scalable environment in which you can deploy your business components. Mule manages all the interactions between components transparently whether they exist in the same VM or over the internet and regardless of the underlying transport used. Mule was designed around the Enterprise Service Bus architecture, which stipulates that different components or applications communicate through a common messaging bus, usually implemented using Jms or some other messaging server. Mule goes a lot further by abstracting Jms and any other transport technology away from the business objects used to receive messages from the bus.<br /><br /> * See all Open Source Enterprise Service Bus in Java<br /><br />Open Source Eclipse Plugins<br /><br /> * Spring IDE - Spring IDE is a graphical user interface for the configuration files used by the Spring Framework. Spring IDE provides the following features:<br /><br /> * Project nature which supports a list of Spring bean config files and sets of bean config files (aka beans config sets)<br /> * Incremental builder which validates all modified Spring bean config files defined in a Spring project<br /> * View which displays a tree with all Spring projects and their Spring bean config files<br /> * Image decorator which decorates all Spring projects, their bean config files and all Java classes which are used as bean classes<br /> * Graph which shows all beans (and their relationships) defined in a single config file or a config set<br /> * XML editor for Spring beans configuration files<br /> * Extension of Eclipse's search facility to search for beans defined in the BeansCoreModel<br /> * Wizard for creating a new Spring project<br /> * Content contribution to Eclipse's ProjectExplorer with Spring artefacts<br /><br /> * See all Open Source Eclipse Plugins<br /><br />Open Source Expression Languages in Java<br /><br /> * Jakarta JXPath - JXPath defines a simple interpreter of an expression language called XPath. JXPath applies XPath expressions to graphs of objects of all kinds: JavaBeans, Maps, Servlet contexts, DOM etc, including mixtures thereof.<br /><br /> * See all Open Source Expression Languages in Java<br /><br />Open Source Financial Software in Java<br /><br /> * JMoney - JMoney is a personal finance manager. It supports multiple accounts in different currencies, double entry banking, income/expense categories, various reports and Quicken file (QIF) exchange. It is built using the Eclipse RCP and can be extended using plug-ins.<br /><br /> * See all Open Source Financial Software in Java<br /><br />Open Source Forum Software in Java<br /><br /> * JForum - JForum is a powerful and robust discussion board system implemented in Javatm. It provides an attractive interface, an efficient forum engine, an easy to use administrative panel, an advanced permission control system and much more.<br /><br /> * See all Open Source Forum Software in Java<br /><br />Open Source General Purpose Libraries in Java<br /><br /> * Ostermiller Utils - Libraries for common tasks such as CSV, Base64, Circular Buffers, MD5, and Significant Figures.<br /><br /> * See all Open Source General Purpose Libraries in Java<br /><br />Open Source Geospacial Software in Java<br /><br /> * deegree - deegree is a Java Framework offering the main building blocks for Spatial Data Infrastructures. Its entire architecture is developed using standards of the Open Geospatial Consortium (OGC) and ISO/TC 211 (ISO Technical Committee 211 -- Geographic Information/Geomatics). deegree encompasses OGC Web Services as well as Clients and security components.<br /><br /> * See all Open Source Geospacial Software in Java<br /><br />Open Source Groupware Software in Java<br /><br /> * CHEF - The CompreHensive collaborativE Framework (CHEF) initiative has as its goal, the development of a flexible environment for supporting distance learning and collaborative work.<br /><br /> * See all Open Source Groupware Software in Java<br /><br />Open Source HTML Parsers in Java<br /><br /> * JTidy - JTidy is a Java port of HTML Tidy , a HTML syntax checker and pretty printer. Like its non-Java cousin, JTidy can be used as a tool for cleaning up malformed and faulty HTML. In addition, JTidy provides a DOM interface to the document that is being processed, which effectively makes you able to use JTidy as a DOM parser for real-world HTML.<br /><br /> * See all Open Source HTML Parsers in Java<br /><br />Open Source IDEs in Java<br /><br /> * Eclipse - Eclipse is a kind of universal tool platform - an open extensible IDE for anything and nothing in particular.<br /><br /> * See all Open Source IDEs in Java<br /><br />Open Source Installers Generators in Java<br /><br /> * JSmooth - JSmooth is a Java Executable Wrapper that makes a standard Windows executable binary (.exe) from a jar file. It makes java deployment much smoother and user-friendly, as it is able to find a Java VM by itself. When no VM is available, it provides feed-back to the users, and can launch the default web browser to an URL that explains how to download a Java VM. Note: NOT COMPLETELY WRITTEN IN JAVA<br /><br /> * See all Open Source Installers Generators in Java<br /><br />Open Source Inversion of Control Containers<br /><br /> * Excalibur - Excalibur is an open source software project of The Apache Software Foundation that contains a lightweight, embeddable Inversion of Control container named Fortress that is written in java.<br /><br /> * See all Open Source Inversion of Control Containers<br /><br />Open Source Issue Tracking Software in Java<br /><br /> * Scarab - The goal of the Scarab project is to build an Artifact tracking system that has the following features:<br /><br /> * A full feature set similar to those found in other Artifact tracking systems: data entry, queries, reports, notifications to interested parties, collaborative accumulation of comments, dependency tracking<br /> * In addition to the standard features, Scarab has fully customizable and unlimited numbers of Modules (your various projects), Artifact types (Defect, Enhancement, Requirement, etc), Attributes (Operating System, Status, Priority, etc), Attribute options (P1, P2, P3) which can all be defined on a per Module basis so that each of your modules is configured for your specific tracking requirements.<br /> * Built using Java Servlet technology for speed, scalability, maintainability, and ease of installation.<br /> * Import/Export ability via XML allowing for easy migration from other systems (e.g. Bugzilla).<br /> * Modular code design that allows manageable modifications of existing and new features over time.<br /> * Fully customizable through a set of administrative pages.<br /> * Easily modified UI look and feel.<br /> * Can be integrated into larger systems by re-implementing key interfaces.<br /> * Is a ready to use issue management system<br /><br /> * See all Open Source Issue Tracking Software in Java<br /><br />Open Source J2EE Frameworks<br /><br /> * Spring - Spring is a layered Java/J2EE application framework, based on code published in Expert One-on-One J2EE Design and Development<br /><br /> * See all Open Source J2EE Frameworks<br /><br />Open Source JDBC Drivers<br /><br /> * jTDS - jTDS is an open source 100% pure Java (type 4) JDBC 3.0 driver for Microsoft SQL Server (6.5, 7, 2000 and 2005) and Sybase (10, 11, 12). jTDS is based on the work of the FreeTDS project and is currently the fastest complete JDBC driver for SQL Server and Sybase. Starting with release 0.7.1 jTDS is 100% JDBC 2.1 compatible, supporting forward-only and scrollable/updateable ResultSets, multiple concurrent (completely independent) Statements per Connection and implementing all of the DatabaseMetaData and ResultSetMetaData methods. As of version 0.9 most of the JDBC 3.0 features are also implemented. Quite a few of the commercial JDBC drivers out there are based on jTDS (or FreeTDS), even if they no longer acknowledge this. jTDS has been tested with virtually all of the available JDBC-based database management tools and is the driver of choice for most of these (DataDino and Aqua Data Studio even contain it). jTDS is also becoming a common choice for enterprise-level applications: starting with release 0.8-rc1 jTDS passes the Hibernate test suite, making it the driver of choice for SQL Server.<br /><br /> * See all Open Source JDBC Drivers<br /><br />Open Source JMS<br /><br /> * OpenJMS - OpenJMS is an open source implementation of Sun Microsystems's Java Message Service API 1.0.2 Specification. Features include:<br /><br /> * Point-to-Point and publish-subscribe messaging models<br /> * Guaranteed delivery of messages<br /> * Synchronous and asynchronous message delivery<br /> * Persistence using JDBC<br /> * Local transactions<br /> * Message filtering using SQL92-like selectors<br /> * Authentication<br /> * Administration GUI<br /> * XML-based configuration files<br /> * In-memory and database garbage collection<br /> * Automatic client disconnection detection<br /> * Applet support<br /> * Integrates with Servlet containers such as Jakarta Tomcat<br /> * Support for RMI, TCP, HTTP and SSL protocol stacks<br /> * Support for large numbers of destinations and subscribers<br /><br /> * See all Open Source JMS<br /><br />Open Source JMX Tools<br /><br /> * MX4J - MX4J is a project to build an Open Source implementation of the Java(TM) Management Extensions (JMX) and of the JMX Remote API (JSR 160) specifications, and to build tools relating to JMX.<br /><br /> * See all Open Source JMX Tools<br /><br />Open Source JSP Tag Libraries<br /><br /> * pack:tag - pack:tag is a JSP Taglib that compresses static resources like JavaScript or Cascading Style Sheets. The Taglib caches the resources, once they are compressed, in memory or to file. When caching to memory, the output is additionally gzipped. Compressing-algorithms could be exchanged per resourcetype, and are extendable by usage of the strategy-pattern. Resources can also be combined to reduce requests.<br /><br /> * See all Open Source JSP Tag Libraries<br /><br />Open Source Job Schedulers in Java<br /><br /> * Quartz - Quartz is an open source job scheduling system that can be integrated with, or used along side virtually any J2EE or J2SE application. Quartz can be used to create simple or complex schedules for executing tens, hundreds, or even tens-of-thousands of jobs; jobs whose tasks are defined as standard Java components or EJBs.<br /><br /> * See all Open Source Job Schedulers in Java<br /><br />Open Source Localization & Internationalization Tools<br /><br /> * ICU4J - ICU4J is a java libraries providing Unicode and Globalization support for software applications. Here are a few highlights of the services provided by ICU:<br /><br /> * Code Page Conversion: Convert text data to or from Unicode and nearly any other character set or encoding. ICU's conversion tables are based on charset data collected by IBM over the course of many decades, and is the most complete available anywhere.<br /> * Collation: Compare strings according to the conventions and standards of a particular language, region or country. ICU's collation is based on the Unicode Collation Algorithm plus locale-specific comparison rules from the Common Locale Data Repository, a comprehensive source for this sort of data.<br /> * Formatting: Format numbers, dates, times and currency amounts according the conventions of a chosen locale. This includes translating month and day names into the selected language, choosing appropriate abbreviations, ordering fields correctly, etc. Again, ICU uses data from the Common Locale Data Repository.<br /> * Unicode Support: ICU closely tracks the Unicode standard, providing easy access to all of the many Unicode character properties, Unicode Normalization, Case Folding and other fundamental operations as specified by the Unicode Standard.<br /> * Regular Expression: ICU's regular expressions fully support Unicode while providing very competitive performance.<br /> * Bidi: support for handling text containing a mixture of left to right (English) and right to left (Arabic or Hebrew) data.<br /> * Text Boundaries: Locate the positions of words, sentences, paragraphs within a range of text, or identify locations that would be suitable for line wrapping when displaying the text.<br /><br /> * See all Open Source Localization & Internationalization Tools<br /><br />Open Source Logging Tools in Java<br /><br /> * Log4j - Log4j is a logging tool that allows you to log at runtime without modifying the application binary. The log4j package is designed so that logging statements can remain in shipped code without incurring a heavy performance cost. Logging behavior can be controlled by editing a configuration file, without touching the application binary.<br /><br /> * See all Open Source Logging Tools in Java<br /><br />Open Source Mail Clients in Java<br /><br /> * Grendel - Grendel is a mail/news reader entirely written in Java. Its goal is to be a true cross-platform application with a feature set that satisfies the poweruser.<br /><br /> * See all Open Source Mail Clients in Java<br /><br />Open Source Network Clients in Java<br /><br /> * Jakarta Commons HttpClient - HttpClient provides an efficient, up-to-date, and feature-rich package implementing the client side of the most recent HTTP standards and recommendations.<br /><br /> * See all Open Source Network Clients in Java<br /><br />Open Source Network Servers in Java<br /><br /> * Apache James - The Apache JAMES Project delivers a rich set of open source solutions, written in Java, related to internet mail and news. JAMES is organized into subprojects with JAMES Server and the Mailet API as their core. Apache JAMES is a project of The Apache Software Foundation (ASF) which encourages a collaborative, consensus-based development process under an open software license. The ASF maintains other Java projects which may also be of interest. These are detailed on the ASF Projects page. We recommended that users of JAMES products subscribe to the JAMES users mailing list.<br /><br /> * See all Open Source Network Servers in Java<br /><br />Open Source Obfuscators in Java<br /><br /> * ProGuard - ProGuard is a free Java class file shrinker and obfuscator. It can detect and remove unused classes, fields, methods, and attributes. It can then rename the remaining classes, fields, and methods using short meaningless names. The resulting jars are smaller and harder to reverse-engineer.<br /><br /> * See all Open Source Obfuscators in Java<br /><br />Open Source PDF Libraries in Java<br /><br /> * FOP - FOP is an XSL formatter written in Java. It is used in conjunction with an XSLT transformation engine to format XML documents into PDF.<br /><br /> * See all Open Source PDF Libraries in Java<br /><br />Open Source Parser Generators in Java<br /><br /> * ANTLR - ANother Tool for Language Recognition, (formerly PCCTS) is a language tool that provides a framework for constructing recognizers, compilers, and translators from grammatical descriptions containing Java, C#, or C++ actions. ANTLR provides excellent support for tree construction, tree walking, and translation.<br /><br /> * See all Open Source Parser Generators in Java<br /><br />Open Source Persistence Frameworks in Java<br /><br /> * Hibernate - Hibernate is a powerful, ultra-high performance object/relational persistence and query service for Java. Hibernate lets you develop persistent objects following common Java idiom - including association, inheritance, polymorphism, composition and the Java collections framework. Extremely fine-grained, richly typed object models are possible. The Hibernate Query Language, designed as a "minimal" object-oriented extension to SQL, provides an elegant bridge between the object and relational worlds. Hibernate is now the most popular ORM solution for Java.<br /><br /> * See all Open Source Persistence Frameworks in Java<br /><br />Open Source Portals in Java<br /><br /> * Liferay - Liferay is a portal designed to deploy portlets that adhere to the Portlet API (JSR 168). Many useful portlets are bundled with the portal (Mail, Document Library, Calendar, Message Boards, etc)<br /><br /> * See all Open Source Portals in Java<br /><br />Open Source Profilers in Java<br /><br /> * NetBeans Profiler - NetBeans Profiler is a project to integrate the JFluid profiling technology, which is being developed by Sun, into the NetBeans IDE. The aim of this project is to provide a powerful and flexible profiling solution that is tightly integrated into the IDE workflow. As the size and complexity of Java applications grow, keeping their performance at the required level becomes progressively difficult. That is why we believe profiling should become a natural part of the development work cycle. To achieve that, we would like to make profiling easy-to-use and as unobtrusive as possible - and the JFluid technology that we use, with dynamic bytecode instrumentation at its heart, suits this goal perfectly.<br /><br /> * See all Open Source Profilers in Java<br /><br />Open Source Project Management Tools in Java<br /><br /> * XPlanner - XPlanner is a web-based project planning and tracking tool for agile development teams<br /><br /> * See all Open Source Project Management Tools in Java<br /><br />Open Source RSS & RDF Tools in Java<br /><br /> * Jena - Jena is a Java framework for building Semantic Web applications. It provides a programmatic environment for RDF, RDFS and OWL, including a rule-based inference engine.<br /><br /> * See all Open Source RSS & RDF Tools in Java<br /><br />Open Source Rule Engines in Java<br /><br /> * SweetRules - SweetRules is a uniquely powerful integrated set of tools for semantic web rules and ontologies, revolving around the RuleML (Rule Markup/Modeling Language) emerging standard for semantic web rules, and supporting also the closely related SWRL (Semantic Web Rule Language), along with the OWL standard for semantic web ontologies, which in turn use XML and, optionally, RDF. (SWRL rules are essentially an expressive subset of RuleML rules.) SweetRules supports the powerful Situated Courteous Logic Programs extension of RuleML, including prioritized conflict handling and procedural attachments for actions and tests. SweetRules' capabilities include semantics-preserving translation and interoperability between a variety of rule and ontology languages (including XSB Prolog, Jess production rules, HP Jena-2, and IBM CommonRules), highly scaleable backward and forward inferencing, and merging of rulebases/ontologies. Procedural attachments can even be WSDL Web Services. SweetRules' pluggability and composition capabilities enable new components to be added relatively quickly. Implemented in Java, SweetRules has a compact codebase (~40K lines of code total for several dozen tools). The SweetRules project is an international, multi-institutional effort, originated and coordinated by the SweetRules group at MIT Sloan led by Benjamin Grosof, and its creation was funded largely by the DAML (DARPA Agent Markup Language) research program which co-pioneered the Semantic Web. SWEET ("Semantic WEb Enabling Technology") is an overall set of tools that Benjamin Grosof's group (with collaborators) has been developing since 2001. Other components in it include the SweetDeal e-contracting system approach and prototype, and the SweetPH system for business process ontologies drawn from the Process Handbook. Hundreds of users have already downloaded SweetRules, inspired in part by its well-received demonstrations in detailed presentations at the DAML Principal Investigators Meeting and the International Semantic Web Conference tutorial program.<br /><br /> * See all Open Source Rule Engines in Java<br /><br />Open Source SQL Clients in Java<br /><br /> * SQuirreL SQL Client - SQuirreL SQL Client is a graphical Java program that will allow you to view the structure of a JDBC compliant database, browse the data in tables, issue SQL commands etc. The minimum version of Java supported is 1.3<br /><br /> * See all Open Source SQL Clients in Java<br /><br />Open Source Scripting Languages in Java<br /><br /> * Groovy - Groovy is a new agile dynamic language for the JVM combining lots of great features from languages like Python, Ruby and Smalltalk and making them available to the Java developers using a Java-like syntax. Groovy is designed to help you get things done on the Java platform in a quicker, more concise and fun way - bringing the power of Python and Ruby inside the Java platform. Groovy can be used as an alternative compiler to javac to generate standard Java bytecode to be used by any Java project or it can be used dynamically as an alternative language such as for scripting Java objects, templating or writing unit test cases.<br /><br /> * See all Open Source Scripting Languages in Java<br /><br />Open Source Search Engines in Java<br /><br /> * Lucene - Jakarta Lucene is a high-performance, full-featured text search engine library written entirely in Java. It is a technology suitable for nearly any application that requires full-text search, especially cross-platform.<br /><br /> * See all Open Source Search Engines in Java<br /><br />Open Source Security & Cryptography Tools in Java<br /><br /> * Bouncy Castle Crypto - The Bouncy Castle Crypto APIs is a lightweight cryptography API in Java with a provider for the JCE and JCA, a clean room implementation of the JCE 1.2.1, a library for reading and writing encoded ASN.1 objects and generator for:<br /><br /> * Version 1 and Version 3 X.509 certificates and PKCS12 files.<br /> * Version 2 X.509 attribute certificates.<br /> * S/MIME and CMS (PKCS7).<br /> * OCSP (RFC 2560).<br /> * TSP (RFC 3161).<br /> * OpenPGP (RFC 2440). The lightweight API works with everything from the J2ME to the JDK 1.5<br /><br /> * See all Open Source Security & Cryptography Tools in Java<br /><br />Source Control Tools in Java<br /><br /> * jCVS - JCVS is a CVS client package written entirely in Java. JCVS provides a complete CVS client/server protocol package that allows any Java program to implement the complete suite of CVS operations. JCVS also provides a Swing based client that provides a commercial quality GUI client for CVS. Finally, jCVS provides a Servlet that allows any Servlet enabled web server to present any CVS repository on the internet for browsing and download.<br /><br /> * See all Source Control Tools in Java<br /><br />Open Source Swing Frameworks & Components<br /><br /> * JGoodies Binding - The JGoodies Binding synchronizes object properties with Swing components. And it helps you represent the state and behavior of a presentation independently of the GUI components used in the interface.<br /><br /> * See all Open Source Swing Frameworks & Components<br /><br />Open Source Template Engines in Java<br /><br /> * Velocity - Velocity is a Java-based template engine. It permits web page designers to reference methods defined in Java code. Velocity can be used to generate web pages, SQL, PostScript and other output from templates. It can be used either as a standalone utility for generating source code and reports, or as an integrated component of other systems<br /><br /> * See all Open Source Template Engines in Java<br /><br />Open Source Testing Tools in Java<br /><br /> * JUnit - JUnit is a regression testing framework written by Erich Gamma and Kent Beck. It is used by the developer who implements unit tests in Java.<br /><br /> * See all Open Source Testing Tools in Java<br /><br />Open Source Text Processing Tools<br /><br /> * Jakarta ORO - The Jakarta-ORO Java classes are a set of text-processing Java classes that provide Perl5 compatible regular expressions, AWK-like regular expressions, glob expressions, and utility classes for performing substitutions, splits, filtering filenames, etc. This library is the successor to the OROMatcher, AwkTools, PerlTools, and TextTools libraries originally from ORO, Inc. Despite little activity in the form of new development initiatives, issue reports, questions, and suggestions are responded to quickly.<br /><br /> * See all Open Source Text Processing Tools<br /><br />Open Source UML & Modeling in Java<br /><br /> * ArgoUML - ArgoUML is a powerful yet easy-to-use interactive, graphical software design environment that supports the design, development and documentation of object-oriented software applications.<br /><br /> * See all Open Source UML & Modeling in Java<br /><br />Open Source Validation Frameworks<br /><br /> * Commons Validator - Commons Validator provides the building blocks for both client side validation and server side data validation. It may be used standalone or with a framework like Struts.<br /><br /> * See all Open Source Validation Frameworks<br /><br />Open Source Web Frameworks in Java<br /><br /> * Struts - The core of the Struts framework is a flexible control layer based on standard technologies like Java Servlets, JavaBeans, ResourceBundles, and XML, as well as various Jakarta Commons packages. Struts encourages application architectures based on the Model 2 approach, a variation of the classic Model-View-Controller (MVC) design paradigm.<br /><br /> * See all Open Source Web Frameworks in Java<br /><br />Open Source Web Mail Clients in Java<br /><br /> * GatorMail - GatorMail is a servlet-based Webmail built on the Struts framework. It was originally developed to meet the needs of the University of Florida. Efficient interaction with the mail store along with a low support overhead are the goals of the project.<br /><br /> * See all Open Source Web Mail Clients in Java<br /><br />Open Source Web Servers in Java<br /><br /> * Jigsaw - Jigsaw is W3C's leading-edge Web server platform, providing a sample HTTP 1.1 implementation and a variety of other features on top of an advanced architecture implemented in Java.<br /><br /> * See all Open Source Web Servers in Java<br /><br />Open Source Web Services Tools in Java<br /><br /> * Axis - Axis is the third generation of Apache SOAP (which began at IBM as "SOAP4J"). It also includes:<br /><br /> * a simple stand-alone server,<br /> * a server which plugs into servlet engines such as Tomcat,<br /> * extensive support for the Web Service Description Language (WSDL),<br /> * emitter tooling that generates Java classes from WSDL.<br /> * some sample programs, and<br /> * a tool for monitoring TCP/IP packets.<br /><br /> * See all Open Source Web Services Tools in Java<br /><br />Open Source Web Testing Tools in Java<br /><br /> * MaxQ - MaxQ is a free web functional testing tool. It includes an HTTP proxy that records your test script, and a command line utility that can be used to playback tests. The proxy recorder automatically stores variables posted to forms, so you don't have to write that stuff by hand.<br /><br /> * See all Open Source Web Testing Tools in Java<br /><br />Open Source Wiki Engines in Java<br /><br /> * JSPWiki - A WikiWiki web clone written using JSPs and Servlets<br /><br /> * See all Open Source Wiki Engines in Java<br /><br />Open Source Workflow Engines in Java<br /><br /> * Apache ODE - Apache ODE (Orchestration Director Engine) executes business processes written following the WS-BPEL standard. It talks to web services, sending and receiving messages, handling data manipulation and error recovery as described by your process definition. It supports both long and short living process executions to orchestrate all the services that are part of your application.<br /><br /> * See all Open Source Workflow Engines in Java<br /><br />Open Source XML Parsers in Java<br /><br /> * Xerces - The Xerces Java Parser 1.4.4 supports the XML 1.0 recommendation and contains advanced parser functionality, such as support for the W3C's XML Schema recommendation version 1.0, DOM Level 2 version 1.0, and SAX Version 2, in addition to supporting the industry-standard DOM Level 1 and SAX version 1 APIs.<br /><br /> * See all Open Source XML Parsers in Java<br /><br />Open Source XML UI Toolkits in Java<br /><br /> * Laszlo - Laszlo is an open source platform for the development and delivery of rich Internet applications on the World Wide Web. It is released under the OSI-certified Common Public License. The Laszlo platform consists of the LZX language and the Laszlo Presentation Server. LZX is an XML and JavaScript description language similar in spirit to XUL and XAML. LZX enables a declarative, text-based development process that supports rapid prototyping and software development best practices. The Laszlo Presentation Server (LPS) is a Java servlet that compiles LZX applications into executable binaries for targeted run-time environments. Laszlo currently targets the Flash Player. The LPS compiles LZX applications into SWF bytecode for the Flash Player, serves and caches these compiled applications to any Web browser enabled with Flash 5 or later, and proxies application requests for back-end XML data sources and web services.<br /><br /><span style="font-weight:bold;">Link : http://java-source.net/</span>make it simplehttp://www.blogger.com/profile/03356377809939814997noreply@blogger.com0tag:blogger.com,1999:blog-23078113.post-87523000937968037082008-03-10T22:25:00.000-07:002008-03-10T22:26:15.138-07:00PaperClipsWelcome to PaperClips: a simple, light weight, extensible Java printing plug-in for SWT. PaperClips hides the complexity of laying out and rendering documents on the printer, helping you focus on what to print instead of how to print it.<br /><br />In a nutshell, PaperClips provides an assortment of document "building blocks," which you can tweak and combine to form a custom document. The assembled document is then sent toPaperClips for printing. PaperClips includes support for printing text, images, borders, headers and footers, column layouts and grid layouts, to name a few. It can also be extended with your own printable classes.<br /><br />With PaperClips you do not have to track cursors, calculate line breaking, fool around with font metrics, or manage system resources--it's all handled internally. And unlike report-generation tools, you are not constrained to a predefined document structure (like report bands). Every document is custom and the layout is up to you.<br /><br />Requirements:<br /><br /> * Java 1.4 or later.<br /> * SWT 3.2 or later. SWT may be downloaded at http://www.eclipse.org/swt/.<br /><br />PaperClips can be used as an Eclipse plug-in or as a regular Jar (provided the SWT libraries are on the classpath).<br />closeclose otherseditpermalinkreferencesjump<br />News<br />MatthewHall, 3 November 2007 (created 4 April 2006)<br />2 November 2007 -- PaperClips 1.0.2 released<br /><br /> * Bugs fixed:<br /> o Clipping problems on Mac OS X.<br /> o PrintPreview.getPageCount() returns 0 before pages are first drawn.<br /> o PrintPreview spits out a blank page on Linux when the window is closed.<br /> o Changed ImageCaptureExample.java to capture JPG since PNG was not fully supported until SWT version 3.3 (PaperClips is developed against 3.2).<br /> o BorderPrint sometimes showed an open bottom border even though the target was completely shown.<br /> o PrintViewer performance improvements when print document is vertically greedy.<br /> * New Features:<br /> o GridPrint.setCellClippingEnabled() controls whether grid cells may be broken across pages. See GridPrintCellClippingExample.java.<br /> o DefaultGridLook.setCellPadding()<br /> o PrintPreview.setHorizontalPageCount() and setVerticalPageCount() controls how many pages are shown on screen.<br /> o Experimental PaperClips.setDebug() API helps troubleshoot documents that won't lay out properly ("Unable to layout on page X" errors).<br /> o BasicGridLookPainter simplifies implementing custom GridLooks.<br /> o StyledTextPrint for mixing text with different font sizes, styles, colors and decorations. Other printable objects such as ImagePrint may be embedded inline with the text.<br /> o TextPrint and StyledTextPrint support underline and strikeout text.<br /> o TextPrint.setWordSplitting() controls whether words may be split between rows. This feature only applies when space is very limited.<br /> o Unified error reporting to PaperClips.error() methods. Custom Print implementations should use these methods to act uniformly with the rest of the library. <br /> * Enhanced print preview snippet (Snippet7):<br /> o Support scrolling with the mouse wheel (horizontally with Shift+Wheel)<br /> o Support zooming with Ctrl+Wheel<br /><br />8 March 2007 -- PaperClips 1.0.1 released<br />This is a maintenance release to address printing issues on Mac OS X. Many thanks to the all the Mac users at EclipseCon who graciously provided assistance in fixing this problem.<br /><br /> * Resolved printing problems on Mac OS X.<br /> * Added public accessor APIs for all Print classes.<br /><br />Download PaperClips 1.0.1make it simplehttp://www.blogger.com/profile/03356377809939814997noreply@blogger.com0tag:blogger.com,1999:blog-23078113.post-57241928912883193432008-03-10T22:23:00.000-07:002008-03-10T22:24:56.209-07:00MOZILLA FIREFOX CHEAT SHEETBASIC<br />Home:<br />http://www.mozilla.com/firefox/<br />Extensions & Themes:<br />https://addons.mozilla.org/<br />Support Forum:<br />http://forums.mozillazine.org/<br />GENERAL KEYBOARD SHORTCUTS<br />Add Bookmarks Ctrl + D<br />Bookmarks Ctrl + B<br />DOM Inspector Ctrl + Shift + I<br />Downloads Ctrl + J<br />Full Screen View F11<br />Help F1<br />History Ctrl + H<br />Page Source Ctrl + U<br />Print Ctrl + P<br />Refresh Page F5<br />Refresh Page & Cache Ctrl + F5<br />Save Page As Ctrl + S<br />NAVIGATION KEYBOARD SHORTCUTS<br />Back Alt + Left Arrow<br />Down One Line Down<br />Down One Page PageDown<br />File Open Ctrl + O<br />Forward Alt + Right Arrow<br />Frame Next F6<br />Frame Previous Shift + F6<br />Home Page Alt + Home<br />Jump to Address Bar Ctrl + L<br />Jump to Search Bar Ctrl + K<br />Page Bottom End<br />Page Top Home<br />Stop Esc<br />Tab Close Ctrl + W<br />Tab New Ctrl + T<br />Tab Next Ctrl + Tab<br />Tab Previous Ctrl + Shift + Tab<br />Tab Select Ctrl + [1 - 9]<br />Up One Line Up<br />Up One Page PageUp<br />Window Close Alt + F4<br />Window New Ctrl + N<br />TEXT KEYBOARD SHORTCUTS<br />Copy Ctrl + C<br />Cut Ctrl + X<br />Delete Del<br />Text Size Decrease Ctrl + -<br />Text Size Increase Ctrl + +<br />Text Size Default Ctrl + 0<br />Undo Ctrl + Z<br />SEARCH KEYBOARD SHORTCUTS<br />Find Again F3<br />Find as You Type Link '<br />Find as You Type Text /<br />Find in This Page Ctrl + F<br />Find Previous Shift + F3<br />MOUSE SHORTCUTS<br />Back Shift + Scroll Down<br />Forward Shift + Scroll Up<br />Open Link in Background Tab Ctrl + Left Click or Middle Click<br />Open Link in Foreground Tab Ctrl + Shift + Left Click<br />Open Link in New Window Shift + Left Click<br />Scroll Line by Line Alt + Scroll<br />Tab Close Middle Click on Tab<br />Tab New Double Click on Tab Bar<br />Text Size Decrease Ctrl + Scroll UP<br />Text Size Increase Ctrl + Scroll Down<br />LOCATIONS<br />Cached Elements<br />C:\Documents and Settings\[username]\Local Settings\Application Data\Mozilla\Firefox\Profiles\[profilename]\Cache\<br />Profile Manager<br />Close Firefox. From the "Start" menu, select "Run", type "firefox.exe -p"<br />User Profile Folder<br />C:\Documents and Settings\[username]\Application Data\Mozilla\Firefox\Profiles\xxxxxxxx.default\<br />Advanced Configuration<br />Address Bar: about:config<br />Cache Info<br />Address Bar: about:cache<br />Plugin Info<br />Address Bar: about:plugins<br />TIPS/TRICKS<br />Block Popup Windows<br />Tools -> Options -> Web Features<br />Customize Toolbars<br />Right click on a toolbar and chose customize toolbar. To add icons drag and drop them on the toolbar. To subtract icons drag them from the toolbar to the "Customize Toolbar" window.<br />Desktop Shortcut to Current Page<br />Drag the icon in the address bar to the desktop<br />Make Firefox Default Browser<br />Tools -> Options -> General -> Set Firefox As Default Browser<br />Manage Cache, Cookies, History and Passwords<br />Tools -> Options -> Privacy<br />Set Home Page<br />Tools -> Options -> General -> Home Page<br />Tabbed Browsing Options<br />Tools -> Options -> Advanced -> Tabbed Browsingmake it simplehttp://www.blogger.com/profile/03356377809939814997noreply@blogger.com0tag:blogger.com,1999:blog-23078113.post-37474821836674448282008-03-05T21:14:00.000-08:002008-03-05T21:27:18.857-08:00Don't Use Mobile Phone During Storms, Warn DoctorsThey describe the case of a 15 year old girl who was witnessed being struck by lightning while using her mobile phone in a large park in London during stormy weather. She was successfully resuscitated, but one year later she suffered complex physical, cognitive, and emotional problems.<br /><br />If someone is struck by lightning, the high resistance of human skin results in lightning being conducted over the skin without entering the body, explain the authors. This is known as flashover and has a low death rate. Conductive materials such as liquids or metallic objects disrupt the flashover and result in internal injury with greater death rates.<br /><br />To their knowledge, no similar cases have been reported in the medical literature. They found three cases reported in newspapers in China, Korea, and Malaysia, all resulting in death.<br /><br />"This rare phenomenon is a public health issue, and education is necessary to highlight the risk of using mobile phones outdoors during stormy weather to prevent future fatal consequences from lightning strike injuries related to mobile phones," say the authors.<br /><br />"The Australian Lightning Protection Standard recommends that metallic objects, including cordless or mobile phones, should not be used (or carried) outdoors during a thunderstorm," they add. "We could not find any advice from British telecommunication companies."make it simplehttp://www.blogger.com/profile/03356377809939814997noreply@blogger.com0tag:blogger.com,1999:blog-23078113.post-85037690471077491812008-03-05T21:13:00.001-08:002008-03-05T21:13:53.524-08:00Secrets Of The Masters: Core Java Job Interview QuestionsJDJ's Enterprise Editor, Yakov Fain (pictured) writes: If you are planning to hit the job market, you may need to refresh some of the Java basic terms and techniques to prepare yourself for a technical interview. Let me offer you some of the core Java questions that you might expect during the interviews. <br /><br />For most questions I’ve provided only short answers to encourage further research. I have included only questions for mid (*) and senior level (**) Java developers. These sample questions could also become handy for people who need to interview Java developers (see also the article "Interviewing Enterprise Java Developers").<br />30 Java Interview Questions<br />* Q1. How could Java classes direct program messages to the system console, but error messages, say to a file?<br /><br />A. The class System has a variable out that represents the standard output, and the variable err that represents the standard error device. By default, they both point at the system console. This how the standard output could be re-directed:<br /><br />Stream st = new Stream(new FileOutputStream("output.txt")); System.setErr(st); System.setOut(st); <br /><br />* Q2. What's the difference between an interface and an abstract class?<br /><br />A. An abstract class may contain code in method bodies, which is not allowed in an interface. With abstract classes, you have to inherit your class from it and Java does not allow multiple inheritance. On the other hand, you can implement multiple interfaces in your class.<br /><br />* Q3. Why would you use a synchronized block vs. synchronized method?<br /><br />A. Synchronized blocks place locks for shorter periods than synchronized methods.<br /><br />* Q4. Explain the usage of the keyword transient?<br /><br />A. This keyword indicates that the value of this member variable does not have to be serialized with the object. When the class will be de-serialized, this variable will be initialized with a default value of its data type (i.e. zero for integers).<br /><br />* Q5. How can you force garbage collection?<br /><br />A. You can't force GC, but could request it by calling System.gc(). JVM does not guarantee that GC will be started immediately.<br /><br />* Q6. How do you know if an explicit object casting is needed?<br /><br />A. If you assign a superclass object to a variable of a subclass's data type, you need to do explicit casting. For example:<br /><br />Object a; Customer b; b = (Customer) a;<br /><br />When you assign a subclass to a variable having a supeclass type, the casting is performed automatically. <br /><br />* Q7. What's the difference between the methods sleep() and wait()<br /><br />A. The code sleep(1000); puts thread aside for exactly one second. The code wait(1000), causes a wait of up to one second. A thread could stop waiting earlier if it receives the notify() or notifyAll() call. The method wait() is defined in the class Object and the method sleep() is defined in the class Thread.<br /><br />* Q8. Can you write a Java class that could be used both as an applet as well as an application?<br /><br />A. Yes. Add a main() method to the applet.<br /><br />* Q9. What's the difference between constructors and other methods?<br /><br />A. Constructors must have the same name as the class and can not return a value. They are only called once while regular methods could be called many times.<br /><br />* Q10. Can you call one constructor from another if a class has multiple constructors<br /><br />A. Yes. Use this() syntax.<br /><br />* Q11. Explain the usage of Java packages.<br /><br />A. This is a way to organize files when a project consists of multiple modules. It also helps resolve naming conflicts when different packages have classes with the same names. Packages access level also allows you to protect data from being used by the non-authorized classes.<br /><br />* Q12. If a class is located in a package, what do you need to change in the OS environment to be able to use it?<br /><br />A. You need to add a directory or a jar file that contains the package directories to the CLASSPATH environment variable. Let's say a class Employee belongs to a package com.xyz.hr; and is located in the file c:\dev\com\xyz\hr\Employee.java. In this case, you'd need to add c:\dev to the variable CLASSPATH. If this class contains the method main(), you could test it from a command prompt window as follows:<br /><br />c:\>java com.xyz.hr.Employee<br /> <br />* Q13. What's the difference between J2SDK 1.5 and J2SDK 5.0?<br /><br />A.There's no difference, Sun Microsystems just re-branded this version.<br /><br />* Q14. What would you use to compare two String variables - the operator == or the method equals()?<br /><br />A. I'd use the method equals() to compare the values of the Strings and the == to check if two variables point at the same instance of a String object.<br /><br />* Q15. Does it matter in what order catch statements for FileNotFoundException and IOExceptipon are written?<br /><br />A. Yes, it does. The FileNoFoundException is inherited from the IOException. Exception's subclasses have to be caught first.<br /><br />* Q16. Can an inner class declared inside of a method access local variables of this method?<br /><br />A. It's possible if these variables are final.<br /><br />* Q17. What can go wrong if you replace && with & in the following code:<br /><br />String a=null; if (a!=null && a.length()>10) {...}<br /><br />A. A single ampersand here would lead to a NullPointerException.<br /><br />* Q18. What's the main difference between a Vector and an ArrayList<br /><br />A. Java Vector class is internally synchronized and ArrayList is not.<br /><br />* Q19. When should the method invokeLater()be used?<br /><br />A. This method is used to ensure that Swing components are updated through the event-dispatching thread.<br /><br />* Q20. How can a subclass call a method or a constructor defined in a superclass?<br /><br />A. Use the following syntax: super.myMethod(); To call a constructor of the superclass, just write super(); in the first line of the subclass's constructor.make it simplehttp://www.blogger.com/profile/03356377809939814997noreply@blogger.com0tag:blogger.com,1999:blog-23078113.post-7641153553753414482008-03-05T21:10:00.000-08:002008-03-05T21:11:49.217-08:00Creating a common lexicon for software development in your organizationWhile at lunch with a buddy of mine the other day he shared that he came to a startling revelation. He was listening to a presentation on Services Oriented Architecture (SOA) the day before and realized that much of his job was terms definition. Simple things like, what does the word "Enable" mean to you. What is an Enterprise Network Bus?<br /><br />In software development we often use terms with one another which are poorly defined and have different meanings to different members of the team. We assume that when we say "factory pattern" the person on the other end understands us the same way they understand us when we say "cat." This is, however, rarely the case.<br /><br />In this article, we'll explore the need for a common lexicon (see the dictionary.com definition for details) for your software development team and look at what you need to do to create it.<br /><br />The Tower of Babel<br />"The LORD said, 'If as one people speaking the same language they have begun to do this, then nothing they plan to do will be impossible for them. Come, let us go down and confuse their language so they will not understand each other.'" The Holy Bible, New International Version, Genesis Chapter 11, verses 5-7<br /><br />When people speak with one language, one understanding of each other, they are able to accomplish almost anything. The more that we are able to speak, hear, and understand each other the less time is wasted on stupid mistakes and misunderstandings.<br /><br />Most people have had situations where we've given direction to someone and come back only to find that the direction we gave wasn't clear to the recipient. Or at the very least we've taken some direction from someone and when we demonstrated what we had done they indicated they were expecting something different. (This still happens when my wife asks me to do something.)<br /><br />It's annoying but in software development it's costly. Estimates vary but the general consensus is that over 40 percent of a project's budget may be consumed by rework. If you consider that most of this rework isn't because of poor understanding of how the technology works, but in because of poor communication, you can see a great potential for improvement in the performance of your team by communicating better and reducing rework.<br /><br />The foundation for creating less rework is in developing a common language that you can use to communicate as clearly as possible. It will never be perfect, but having the same understanding of a word will radically improve your chances of fully understanding what someone else is communicating.<br /><br />Relearning existing vocabulary<br />One of the challenges with meeting the call to develop your own lexicon, your own language, with your developers is building common experience and common understanding of the things that you already believe that you know. You may believe that you know what the other person means but in reality you probably believe something slightly different.<br /><br />Take for instance, when I said "cat" above. You may have thought I was talking about "Fluffy" the white haired Persian cat that you had as a child. Or perhaps you were thinking of the Calico cat you have today. I was, however, actually, referring to one of the Bengal tigers that I recently saw. Should I have pointed out that I was speaking of a "big cat"? Probably, and if I was giving direction I would have. However, even big cat isn't specific. Would I be referring to a leopard, a lion, or a tiger?<br /><br />The point of all of this is that we all share a vocabulary but we each define the words slightly differently. The trick is to pull the definitions of a group of people together as much as possible so that you can use words and know what they will mean to your team members.<br /><br />One technique for doing this is finding examples of articles, white papers, etc. that defines the term and expands upon it's meaning. For instance, Services Oriented Architecture is a difficult thing for most people to define. However, you can bring folks to a common understanding by asking or encouraging them to read the same article on SOA as the rest of the team. While everyone may not agree on every specific point about SOA raised in the article it creates a reference point that can be used to anchor a definition that everyone on the team agrees upon.<br /><br />That anchored definition allows you to define other terms in relationship to it, and to other terms, and helps to strengthen the continuity of understanding between team members. However, even well understood, anchored terms may not be enough.<br /><br />Creating new vocabulary<br />Your existing vocabulary is a good start. With seasoned practitioners there's a wide variety of words and phrases that have – or can have – a specific meaning. However, there are times when the existing vocabulary just won't cut it. When you're trying to describe your own techniques, processes, or methodologies, you may find that the existing vocabulary just doesn't cover it.<br /><br />A former coworker of mine, David Feinberg, has a dream. He wants to get a new word added to the dictionary. It's a great dream, and I wish him luck. Of course, whether he does or doesn't succeed in his goals, he's good at introducing new words into his organization. The beauty of these words is that they mean a specific thing to everyone in the organization – and there is little chance of anyone outside the organization having a different definition.<br /><br />Although it may seem like having others not know the word would not be a good thing – it can be. It's good because there's a low chance that the word will be misinterpreted. Because there are no other context clues as to the meaning of the word, it's likely that the only definition that the team will develop is the one that is intended.<br /><br />The most difficult problems to troubleshoot, diagnose, and fix are those which are not clear and repeatable. The same goes with communications. If you can't see that it's a problem, and if it's not a problem all the time, you will probably have a hard time getting people on the same page. A new vocabulary item has the benefit of being understood or not understood, but with a very low probability of being understood incorrectly.<br /><br />Culture of precision<br />One of the great benefits that I get out of having different professional editors looking at more than 80 percent of everything that I write is that they have encouraged me to be more specific in my writing. I can't just say things happen – I have to be more specific about what, when, for how long, etc. We all speak in somewhat general terms when we are speaking. It's less formal and we're thinking on our feet, however, the general way that we approach speaking leads to a certain amount of ambiguity and imprecision. The most frequent situation that illuminates the lack of precision is when we ask someone a question via email. We indicate the question but rarely do we actually indicate a deadline for the response. We leave ambiguity in how long the person has to respond to our inquiry.<br /><br />The impact of a culture of precision in speaking and writing is subtle. It is subtle because you can develop your own lexicon for developers without it; however, it's like a catalyst. It can accelerate the process. By making the team hunger for precision in their communications they will seek out the most precise words they can find to express their ideas. Instead of just being satisfied with the idea that a data entry screen is necessary, they'll begin to explore which of the standard operations they need. Instead of data entry screens you'll get something like. "We need an edit screen for the customer list capable of adding, reading, editing, and disabling a customer. We never delete customers so that isn't necessary."<br /><br />Perhaps it takes a few more words to communicate like this, perhaps even a minute's worth of time is "wasted" by this precise way of communicating, but that certainly takes less time than coding a delete feature into a screen that will never be used because the business process doesn't allow customers to be deleted.<br /><br />Culture of refinement<br />A culture of precision is not only about speaking and writing in precise terms but is also about learning how to hear with precision. In other words, communicating in precise terms also requires that the listener verify the meaning that they attribute to the words that the speaker used. A culture of refinement is one where listeners are encouraged to challenge their understanding of what the speaker said by echoing back the understanding – and not the words. This leads to an automatic refinement of the message which makes it even more precise.<br /><br />The Humanist approach to psychology is based upon the idea that you tell the person what you just heard. The technique is both validating to the patient and illuminating to the counselor. The patient feels like they're being truly heard and has an opportunity to expand upon the details of the situation or how they feel. The counselor verifies their understanding of the patient and in return understands better.<br /><br />The basic format is the speaker saying something like "I believe we need a SOA-based approach to this problem." The recipient (or one of the recipients in a group setting) says something like "I understand that you believe Web services are the right way to go with this project." The response doesn't use the same words that the speaker used. It uses a slightly different construction and in this case with a slightly different meaning. The result should be the speaker responding with "Yes, but I believe we need to address queuing and the transactional nature of what we're doing. I also believe that we have to focus on maintaining loose coupling." This interchange has illuminated that the speaker believes that queuing (asynchronous operation), transactional processing, and loose coupling are important components of the solution. Without this reflection of meaning back to the speaker this information would have never been shared.<br /><br />This culture of refinement, where everyone is trying to refine their understanding of what is being said can be a bit overwhelming at first as it initially increases communications, however, it has the potential to substantially reduce rework.<br /><br />The world at large<br />One of the challenges that occur when you create your own lexicon for communication is that the world creeps in around you. You're overwhelmed by messages from the rest of the world which may have a different definition of your terms than the group defines. That's one of the reasons why it's important to find your own vocabulary so that you don't have to battle a different meaning in the world at large. Prefixing terms with 'OurCo' such as in OurCo-SOA can help to keep the distinction even when the world has a slightly different or less refined meaning.<br /><br />Ultimately there is one major caution with your lexicon. That is not to make it conflict with the meaning of the world at large. So you wouldn't, for instance, want to define a Web service as a Web site that users use on top of existing mainframe applications. The definition would be substantially inconsistent with the definition used by the rest of the world and would simply lead to problems of misunderstandings when you try to bring in new people, communicate with your peers, or even get consultants "up to speed" as they come in.<br /><br />The best way to view your lexicon is a dialect. Something that resembles the way the outside world communicates, but has special and unique meaning to the team – a meaning that makes it easier and more productive to communicate.<br /><br />The mind<br />You may not need to create a whole new language or learn some obscure language like Klingon but you should consider how you communicate with your team and how you can create your own lexicon for communicating back and forth with one another.<br /><br />Learn to anchor your key terms and apply your own definitions to new words to form a stronger bond between the meaning behind the communication in the mind of the speaker and the meaning behind the communication in the mind of the listener.make it simplehttp://www.blogger.com/profile/03356377809939814997noreply@blogger.com0tag:blogger.com,1999:blog-23078113.post-57494725188331692022008-03-05T21:04:00.000-08:002008-03-05T21:10:08.139-08:00Ten things every Java developer should know about UNIXOne of the great things about Java is how multi-platform it really is. While cross platform glitches do occur, they are not really all that common. But since the law of unintended consequences is all pervasive, we now have the common sight of teams of developers building Java programs meant to run on Unix boxes on Windows.Developing code meant for Unix on Windows does work reasonably well. The trouble is, many those coders slaving away in front of XP have a very limited understanding of their target platform. If that describes you, this following list is meant for you. Without further ado, here are the ten things you really need to know about Unix, in reverse David Letterman order:<br /><br />10) You need to be special to use some ports<br /><br />On Unix machines, programs run by ordinary mortals cannot use network ports less than 1024. Only the special root user can use these ports. If you do decide that you need to run your server as root, be very careful since a program running as root is all powerful on a Unix machine.<br /><br />9) There is no magic file locking<br /><br />Windows has this magic file locking mechanism that prevents people from removing a file while it is open. Thus, on a Windows box the call to delete() in the following code is pretty much sure to fail:InputStream is = new FileInputStream(”foo.txt”);(new File(”foo.txt”)).delete();int ch;while( (ch = is.read()) > 0 )System.out.println( “char: ” + (char)ch );is.close();The delete will fail because someone (our program in fact) has the file open. After we get done printing out its contents, foo.txt will still be there. The kicker is, the delete() will work just fine on any Unix box. Under Unix, the call to delete() will delete the entry for foo.txt out from the file system, but since someone (our program) still has the file open, the bytes will live on, to be read and printed out. Only when we close the stream will the contents of foo.txt follow its name into oblivion.In exactly the same way, on a Unix box, someone can delete a program’s current directory right out from underneath it.<br /><br />8 ) Sometimes there is no GUI<br /><br />People who are used to Windows are sometimes surprised to find their programs running on a Unix box that has no GUI at all. None. Zilch. Nada. In Unix, the GUI is an add on component and it is completely optional. The machine will run fine without it and servers commonly do. Be very careful making calls to those handy java.awt methods — some of them will fail on a machine with no GUI.While you are at it, you may want to rethink what you are writing out with System.out. Many severs not only lack a GUI, they are completely headless: no keyboard, no mouse, no screen. If you are deploying into this kind of environment, the log file is your friend, because your program’s cries for help are unlikely to be heard anywhere else.<br /><br />7) In Unix, there is no registry……<br /><br />but if there was, it would be a plain text file. Unix systems have no central place like the Windows registry for storing configuration information. Instead, Unix configuration is spread over a fair number of different files. Many of these files live in a directory called /etc : the list of users is in a file called /etc/passwd, while the name of the machine is typically found in /etc/host.I guess if you are a Windows user that is the bad news. Here is the good news: most, if not all of the configuration files are plain text files. You can look at them with any old text editor. A further bit of good news is that all modern Unix like systems come with GUIs to edit the configuration files.<br /><br />6) Forward slashes are your friend<br /><br />This one is really more about Java on Windows than it is about Unix, but useful anyway. Just about everyone knows that Unix uses forward slashes to separate the bits of a path: /etc/passwd, while Windows uses backslashes: c:\Program Files\Windows. What a disturbing number of folks don’t realize is that forward slashes work just fine on in Java on Windows too. On a Windows box, Java is smart enough to translate /a/b/c/foo.txt to something like C:\a\b\c\foo.txt.Should you rely on this for production? No. If you are really coding cross platform Java, you need know about File.pathSeparator and the various File constructors. But if you are coding stuff that is only meant for Unix, and you just want to test it on your windows box, knowing that the forward slashes work in both places can save a lot of agony.<br /><br />5) Our services are just programs<br /><br />In Windows, system services are special programs, written to a particular service API. On Unix, services are provided by pretty ordinary programs that do service like things.Typically, a Unix service consists of the useful program and a script which starts the program in the background when the system starts up and may shut it down again when the system is halting. Many Unix systems keep these scripts in the /etc/init.d directory.<br /><br />4) Environment variables are hard to change<br /><br />Windows programmers sometimes cook up little batch files that set the environment variables they want. Perhaps you need to roll back to an old version of Java and Ant. You might write a batch file that looks something like:set JAVA_HOME=C:\java1.4.1_05set ANT_HOME=C:\apache-ant-1.6.1They can then run the batch file:c:\> setenv.batand have the environment that you need. If you try to translate this directly into Unix-land, you get a script that looks not too different:#!/bin/shJAVA_HOME=/usr/java1.4.1_05export JAVA_HOMEANT_HOME=/usr/apache-ant-1.6.1export ANT_HOMESo you try out your new script…$ setenv.sh…and it does nothing. The trouble is that the Unix shell runs scripts by creating a copy of itself and running the script in the new shell. This new shell will read in the script, set all the environment variables and then exit, leaving the original shell and its environment unchanged. I hate when that happens. Changing directories works pretty much the same way: if you do a cd in an ordinary shell script, it will change the directory for that second shell, which may or may not be what you want.If what you want is to change things in your current shell, you need to have the current shell read in the script directly, without starting a new shell to do the job. You can do this with by using the dot command:. setenv.shLife will be good as your environment variables change.I should mention that there are several different shells available in Unix. Which one you use is mostly a matter of taste, either yours or the person who set up your account. The commands above will work with many of the common Unix shells, but if you happen to be running the C shell (note the pun), then your little script will need to look something like:setenv JAVA_HOME /usr/java1.4.1_05setenv ANT_HOME /usr/apache-ant-1.6.1You also need a different command to read the script in:source setenv.csh<br /><br />3) We don’t like spaces in our file names<br /><br />Okay, this one probably has more to do with Unix users and sys admins than the OS itself, but the fact is, we don’t like spaces in our paths. Oh it is perfectly possibly to have spaces in Unix file names. In fact you can put darn near anything in a Unix file name: /tmp/:a,*b%c is actually the name of a directory on the system that I am using to write this.But can and should are two different things. Unix users spend much of their time using the command line and Unix command line utilities are not crazy about paths with stars, question marks and especially spaces. The Unix guy can always find a way, but if you insist on putting strange characters like spaces in your file names, you are just finding a way to annoy your local Unix guy.<br /><br />2) There is no carriage to return<br /><br />If I had just one magic lighting bolt to hurl at one person, I think I would pick the guy who decided to use different line terminating characters on the two major OS’s. I suspect we would have hyper intelligent computers by now were it not for all the time wasted trying to figure out why my file looks funny on your OS.In a plain text file, Windows typically uses a carriage return followed by a newline character to mark the end of a line. Unix dispenses with the carriage return and makes due with the single newline character. Although the tools are getting better, Unix style files may show up as one long line in Windows — not a single carriage return/newline pair in that file, must be a single line. Likewise, Windows style files will sometimes show up on Unix with garbage characters at the end of a line — that extra carriage return is meaningless under the Unix convention.This doesn’t matter much for Java files — it’s all white space to the Java compiler. But some native Unix programs care passionately about those funny characters at the end of a line. In particular if you use a Windows based tool to edit a Unix script and your tool adds carriage returns to the script file, you have screwed it up. The script will no longer run. Worse, since many Unix editors do now handle the carriage returns, you could look at the broken script and see nothing wrong.<br /><br />1) You need a Linux box<br /><br />If you are doing significant development for Unix, you owe it to yourself and your customers to know something about Unix. If all else fails, get yourself an old PC and some of that free Linux. Or get yourself one of the many bootable Linux-on-a-CD distributions and try it out on any machine. Java is nearly platform independent, but not quite. It is up to you to make up the difference.make it simplehttp://www.blogger.com/profile/03356377809939814997noreply@blogger.com1tag:blogger.com,1999:blog-23078113.post-74576532631235068162008-02-29T03:30:00.000-08:002008-02-29T03:44:26.142-08:00Open Source Java Reporting with JasperReports and iReportasperReports, a powerful, flexible open-source reporting engine, is easy to integrate into Java enterprise applications, but it lacks an integrated visual report editor. So, if you want to use JasperReports directly, you need to manipulate its XML report structure—a relatively technical activity with a high learning curve, to say the least. <br /><br />In fact, writing a full JasperReport from scratch using only the XML format is a long, painful, and unrewarding task. <br />Luckily, some available alternatives are much easier. The first and foremost of which is to use a visual editor to design, compile, and test your reports. <br /><br />One of the most useful visual editors you can use is iReport. This article demonstrates how to use iReport to leverage the full power of JasperReports without getting entangled in complexities of the JasperReports native XML format. <br /><br />Getting Started<br /><br />The first thing to do is download and install iReport. It is a Java application, so you will need a JDK on your machine (JDK 1.4 or higher). This tutorial uses JDK 1.5.0: <br /><br />Download iReport from ireport.sourceforge.net. <br />Decompress the iReport archive. <br />Run the startup script (bin\startup.bat or ./bin/startup.sh).<br /> <br />The iReport download comes with its own JasperReports package (the latest version to date, 0.5.1, supports the recently released JasperReports 1.0.1). <br /><br /><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhztHmg4B-IDg0QnPj-Yo6T6bOAmuThdSmUEc89CJgqLAgjntlnkgj0OS0QhI8Knbt_xCP7QzqWkDdJOjpwG8YINT3S5VcBVY0JRpQehWwIJ-01bNbKAfDfoAqwwpe2qsylCHEm/s1600-h/13888.png"><img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhztHmg4B-IDg0QnPj-Yo6T6bOAmuThdSmUEc89CJgqLAgjntlnkgj0OS0QhI8Knbt_xCP7QzqWkDdJOjpwG8YINT3S5VcBVY0JRpQehWwIJ-01bNbKAfDfoAqwwpe2qsylCHEm/s400/13888.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5172366439744176194" /></a><br /> <br />Figure 1. The Tutorial's Employee Database Schema <br /><br />Once you have iReport running, you can start designing your reports! <br /><br /><br />The Example Database<br />This tutorial uses a very simple database (see Figure 1) for demonstration. To follow along step-by-step, either download the scripts for setting up this database with MySQL and set it up on your machine, or use a similar database and translate the techniques to your situation. <br /><br /><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjT14yg-3pOnYmuDyKLkdzE1OCHn3qbzIf_Nrbow5R1PlV6GzT2laQBbhl6r7a172xBtPzSLuB1I8B7HDppuR4vG-7-AojdP1tTfFNb1U1DWBAbK-hqkVJ60435HSlr3QiCTFeJ/s1600-h/13889.png"><img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjT14yg-3pOnYmuDyKLkdzE1OCHn3qbzIf_Nrbow5R1PlV6GzT2laQBbhl6r7a172xBtPzSLuB1I8B7HDppuR4vG-7-AojdP1tTfFNb1U1DWBAbK-hqkVJ60435HSlr3QiCTFeJ/s400/13889.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5172365963002806322" /></a><br /> <br />Figure 2. Adding a New Database Connection <br /><br /><br />Adding a New Database Connection<br />First, add a new connection to your database. Use the "Datasource -> Connections/Datasources" menu to set up a new database connection (see Figure 2). If you chose the JDBC driver in the list (the example chooses MySQL), enter the server address and the database name, and then click on the 'Wizard' button. iReport should provide you with a correct JDBC URL for your particular database. <br />Now that you have a datasource, it's time to do something with it.make it simplehttp://www.blogger.com/profile/03356377809939814997noreply@blogger.com0tag:blogger.com,1999:blog-23078113.post-62231662221188048992008-02-29T03:04:00.000-08:002008-02-29T03:19:14.851-08:00Generating Huge reports in JasperReportsThere are certain things to care while implementing the Jasper Reports for huge dataset to handle the memory efficiently, so that the appliacation does not go out of memory. <br /><br />They are: <br /><br />1) Pagination of the data and use of JRDataSource, <br /><br />2) Viruatization of the report. <br /><br />When there is a huge dataset, it is not a good idea to retrieve all the data at one time.The application will hog up the memory and you're application will go out of memory even before coming to the jasper report engine to fill up the data.To avoid that, the service layer/Db layer should return the data in pages and you gather the data in chunks and return the records in the chunks using JRDataSource interface, when the records are over in the current chunk, get the next chunk untilall the chunks gets over.When I meant JRDataSource, do not go for the Collection datasources, you implement the JRDataSource interface and provide the data through next() and getFieldValue()To provide an example, I just took the "virtualizer" example from the jasperReports sampleand modified a bit to demonstrate for this article.To know how to implement the JRDataSource, Have a look at the inner class "InnerDS" in the example. <br /><br /> <br /><br />Even after returning the data in chunks, finally the report has to be a single file.Jasper engine build the JasperPrint object for this. To avoid the piling up of memory at this stage, JasperReports provided a really cool feature called Virtualizer. Virtualizer basically serializes and writes the pages into file system to avoid the out of memory condition. There are 3 types of Virtualizer out there as of now. They are JRFileVirtualizer, JRSwapFileVirtualizer, and JRGzipVirtualizer.JRFileVirtualizer is a really simple virtualizer, where you need to mention the number of pages to keep in memory and the directory in which the Jasper Engine can swap the excess pages into files. Disadvantage with this Virtualizer is file handling overhead. This Virtualizer creates so many files during the process of virtualization and finally produces the required report file from those files.If the dataset is not that large, then you can go far JRFileVirtualizer.The second Virtualizer is JRSwapFileVirtualizer, which overcomes the disadvantage of JRFileVirtualizer. JRSwapFileVirtualizer creates only one swap file,which can be extended based on the size you specify. You have to specify the directory to swap, initial file size in number of blocks and the extension size for the JRSwapFile. Then while creating the JRSwapFileVirtualizer, provide the JRSwapFile as a parameter, and the number of pages to keep in memory. This Virtualizer is the best fit for the huge dataset.The Third Virtualizer is a special virtualizer which does not write the data into files, instead it compresses the jasper print object using the Gzip algorithm and reduces the memory consumption in the heap memory.The Ultimate Guide of JasperReports says that JRGzipVirtualizer can reduce the memory consumption by 1/10th. If you are dataset is not that big for sure and if you want to avoid the file I/O, you can go for JRGzipVirtualizer. <br /><br />Check the sample to know more about the coding part. To keep it simple, I have reused the "virtualizer" sample and added the JRDataSource implementation with paging.I ran the sample that I have attached here for four scenarios. To tighten the limits to get the real effects, I ran the application with 10 MB as the max heap size (-Xmx10M). <br /><br />1a) No Virtualizer, which ended up in out of memory with 10MB max heap size limit. <br /><br />export:<br /> [java] Exception in thread "main" java.lang.OutOfMemoryError: Java heap space<br /> [java] Java Result: 1 <br /><br /> <a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh4-AF8lNY0DXGYZl4xIkv9rnG-BYW0Wz2FFSprz4nISygnWpe5WYMpKY50S8JuXHkAOSXwgV_YCC4sxDyLpYTG5NXJ2EUfESHjEl_HTALKgaoQfiz_cpxoa1db-LYbfsE_eocL/s1600-h/225288186.jpg"><img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh4-AF8lNY0DXGYZl4xIkv9rnG-BYW0Wz2FFSprz4nISygnWpe5WYMpKY50S8JuXHkAOSXwgV_YCC4sxDyLpYTG5NXJ2EUfESHjEl_HTALKgaoQfiz_cpxoa1db-LYbfsE_eocL/s400/225288186.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5172357961478733778" /></a><br /> <br />1b) No Virtualizer with default heap size limit (64M) <br /><br />export2:<br /> [java] null<br /> [java] Filling time : 44547<br /> [java] PDF creation time : 22109<br /> [java] XML creation time : 10157<br /> [java] HTML creation time : 12281<br /> [java] CSV creation time : 2078<br /><br /><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiczfuyGhMF7HnCCpxUYLFibg5AnFE_mxOMk_tZahH8CZnFiaCdsoLx82l_MdPa0TBdTk5QC51ZwkX7DBfEUzRfnQtLv9JMd15m6WZajd-R4uYtchCCmJSzBEoyns0qjw3lHvAo/s1600-h/225288187.jpg"><img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiczfuyGhMF7HnCCpxUYLFibg5AnFE_mxOMk_tZahH8CZnFiaCdsoLx82l_MdPa0TBdTk5QC51ZwkX7DBfEUzRfnQtLv9JMd15m6WZajd-R4uYtchCCmJSzBEoyns0qjw3lHvAo/s400/225288187.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5172358438220103650" /></a><br /> <br /><br />2) 2) With JRFileVirtualizer <br />exportFV:<br /> [java] Filling time : 161170<br /> [java] PDF creation time : 38355<br /> [java] XML creation time : 14483<br /> [java] HTML creation time : 17935<br /> [java] CSV creation time : 5812 <br /><br /> <br /><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjUf42ND0Nh5jgqzjEYO8l7SBVl3AA3kurZ8JMVlTD64Q6IoGkynsZ3Wxjg24EQur45-Za9RnQ5KKK9cea8ozmaUjoDF0J-oOeEFMafKc33qPdbvho0hnJ1BtqjvMksTsBqv4yw/s1600-h/225288189.jpg"><img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjUf42ND0Nh5jgqzjEYO8l7SBVl3AA3kurZ8JMVlTD64Q6IoGkynsZ3Wxjg24EQur45-Za9RnQ5KKK9cea8ozmaUjoDF0J-oOeEFMafKc33qPdbvho0hnJ1BtqjvMksTsBqv4yw/s400/225288189.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5172358781817487346" /></a><br /> <br />3) With JRSwapFileVirtualizer<br />exportSFV:<br /> [java] Filling time : 51879<br /> [java] PDF creation time : 32501<br /> [java] XML creation time : 14405<br /> [java] HTML creation time : 16579<br /> [java] CSV creation time : 5365<br /><br /><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgKzieDswQRyZQgKlxRTc-lE5i4tNwQBTQlP5grhLT8s93cckBdAY3WK0mUgkvAi_r3RPmipAE8Z8PY9mjH2mXLtbPl-T9E4xsCOd3qYYBCmOJX8RZDnH-8V5VAVys5Hv3SNIzr/s1600-h/225288190.jpg"><img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgKzieDswQRyZQgKlxRTc-lE5i4tNwQBTQlP5grhLT8s93cckBdAY3WK0mUgkvAi_r3RPmipAE8Z8PY9mjH2mXLtbPl-T9E4xsCOd3qYYBCmOJX8RZDnH-8V5VAVys5Hv3SNIzr/s400/225288190.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5172359185544413186" /></a><br /> <br />4a) With GZipVirtualizer with lots of GC<br />exportGZV:<br /> [java] Filling time : 84062<br /> [java] Exception in thread "RMI TCP Connection(22)-127.0.0.1" java.lang.OutOfMemoryError: Java heap space<br /> [java] Exception in thread "RMI TCP Connection(24)-127.0.0.1" java.lang.OutOfMemoryError: Java heap space<br /> [java] Exception in thread "main" java.lang.OutOfMemoryError: Java heap space<br /> [java] Exception in thread "RMI TCP Connection(25)-127.0.0.1" java.lang.OutOfMemoryError: Java heap space<br /> [java] Exception in thread "RMI TCP Connection(27)-127.0.0.1" java.lang.OutOfMemoryError: Java heap space<br /> [java] Java Result: 1<br /><br /><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhEJMfGbFC_T6C6idHSNtVg0pJzf_wE3Q9XPQJnU2wnWHjP9Bomis3_uzqo4s2OLOeqUKaKKDfEJVS8H3TQ-PEtpqVWykXC24IfR6a_cyeQMy_bOHjExs5PeEAB55wtzrlKoTcb/s1600-h/225288191.jpg"><img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhEJMfGbFC_T6C6idHSNtVg0pJzf_wE3Q9XPQJnU2wnWHjP9Bomis3_uzqo4s2OLOeqUKaKKDfEJVS8H3TQ-PEtpqVWykXC24IfR6a_cyeQMy_bOHjExs5PeEAB55wtzrlKoTcb/s400/225288191.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5172359456127352850" /></a><br /> <br />4b) With GZipVirtualizer (max: 13MB)<br />exportGZV2:<br /> [java] Filling time : 59297<br /> [java] PDF creation time : 35594<br /> [java] XML creation time : 16969<br /> [java] HTML creation time : 19468<br /> [java] CSV creation time : 10313 <br /><br /><br /> <a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjwhofzJktgbrNqvgC1VErRs2K5l2pYot7hhhJLv4ybfsMgkiVgimJ_KDI0i5A2jpEPxC9T6E9_VWVqNMBkez-jVkDRJQr10vhHlgGs4eGVeVjR-TGcRTtxEIZ5H2-Pnr370-fq/s1600-h/225288191.jpg"><img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjwhofzJktgbrNqvgC1VErRs2K5l2pYot7hhhJLv4ybfsMgkiVgimJ_KDI0i5A2jpEPxC9T6E9_VWVqNMBkez-jVkDRJQr10vhHlgGs4eGVeVjR-TGcRTtxEIZ5H2-Pnr370-fq/s400/225288191.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5172359700940488738" /></a><br /><br />I have shared the updated virtualizer sample files at Updated Virtualizer Sample filesmake it simplehttp://www.blogger.com/profile/03356377809939814997noreply@blogger.com1tag:blogger.com,1999:blog-23078113.post-25472683527866188672008-02-29T02:54:00.000-08:002008-02-29T02:55:35.182-08:00Using Jasper Reports with Visual Web PackThis tutorial illustrates the use of Jasper Reports with a Visual Web Pack application.<br />Register Jasper Reports library<br />Use the NetBeans Library Manager to create a library for the Jasper Reports class libraries. You need at least the following files from the distribution:<br />• dist/jasperreports-<version>.jar<br />• lib/commons-beanutils-1.7.jar<br />• lib/commons-collections-2.1.jar<br />• lib/commons-digester-1.7.jar<br />• lib/commons-logging-1.0.2.jar<br />• lib/itext-1.3.1.jar<br />Register Jasper Reports image servlet<br />The image servlet is needed if you want html rendered reports (also without any graphical elements, because report placeholders uses images from this servlet). So you must register it in the web.xml configuration file. You can use the NetBeans web.xml editor to do so.<br />Servlet name : ImageServlet<br />Servlet class : net.sf.jasperreports.j2ee.servlets.ImageServlet<br />URL : /image<br />Insert methods for report output to application bean<br />The following methods in the application bean can be used to output a precompiled report as html or pdf. In this sample a collection of java objects is used as data source. For other data sources see the Jasper Reports documentation.<br />/**<br /> * Output Jasper Report<br /> *<br /> * @param filename Precompiled report filename<br /> * @param type Content type of report ("application/pdf" or "text/html")<br /> * @param data Collection of value objects<br /> */<br />public void jasperReport( String filename, String type, Collection data ) {<br /> jasperReport( filename, type, data, new HashMap() );<br />}<br /> <br />/**<br /> * Output Jasper Report<br /> *<br /> * @param filename Precompiled report filename<br /> * @param type Type of report ("application/pdf" or "text/html")<br /> * @param data Collection of value objects<br /> * @param params Map with parameters<br /> */<br />public void jasperReport( String filename, String type, Collection data, Map params ) {<br /> final String[] VALID_TYPES = { "text/html", "application/pdf" };<br /> // First check if type is supported<br /> boolean found = false;<br /> for ( int i = 0; i < VALID_TYPES.length; i++ ) {<br /> if ( VALID_TYPES[i].equals( type ) ) {<br /> found = true;<br /> break;<br /> }<br /> }<br /> <br /> if ( !found ) {<br /> throw new IllegalArgumentException( "Report type '" + type + "' not supported." );<br /> }<br /> <br /> // InputStream for compiled report<br /> ExternalContext econtext = getExternalContext();<br /> InputStream stream = econtext.getResourceAsStream( filename );<br /> <br /> if ( stream == null ) {<br /> throw new IllegalArgumentException( "Report '" + filename + "' could not be opened." );<br /> }<br /> <br /> // Use collection as data source<br /> JRBeanCollectionDataSource ds = new JRBeanCollectionDataSource( data );<br /> JasperPrint jasperPrint = null;<br /> <br /> try {<br /> jasperPrint = JasperFillManager.fillReport( stream, params, ds );<br /> } catch ( RuntimeException e ) {<br /> throw e;<br /> } catch ( Exception e ) {<br /> throw new FacesException( e );<br /> } finally {<br /> try {<br /> stream.close();<br /> } catch ( IOException e ) {<br /> }<br /> }<br /> <br /> // Configure exporter and set parameters<br /> JRExporter exporter = null;<br /> HttpServletResponse response = (HttpServletResponse) econtext.getResponse();<br /> FacesContext fcontext = FacesContext.getCurrentInstance();<br /> <br /> try {<br /> response.setContentType( type );<br /> <br /> if ( "application/pdf".equals( type ) ) {<br /> exporter = new JRPdfExporter();<br /> exporter.setParameter( JRExporterParameter.JASPER_PRINT, jasperPrint );<br /> exporter.setParameter( JRExporterParameter.OUTPUT_STREAM,<br /> response.getOutputStream() );<br /> } else if ( "text/html".equals( type ) ) {<br /> exporter = new JRHtmlExporter();<br /> exporter.setParameter( JRExporterParameter.JASPER_PRINT, jasperPrint );<br /> exporter.setParameter( JRExporterParameter.OUTPUT_WRITER, response.getWriter() );<br /> HttpServletRequest request = (HttpServletRequest)<br /> fcontext.getExternalContext().getRequest();<br /> request.getSession().setAttribute(<br /> ImageServlet.DEFAULT_JASPER_PRINT_SESSION_ATTRIBUTE, jasperPrint );<br /> exporter.setParameter( JRHtmlExporterParameter.IMAGES_MAP, new HashMap() );<br /> exporter.setParameter(<br /> JRHtmlExporterParameter.IMAGES_URI,<br /> request.getContextPath() + "/image?image=" );<br /> }<br /> } catch ( RuntimeException e ) {<br /> throw e;<br /> } catch ( Exception e ) {<br /> throw new FacesException( e );<br /> }<br /> <br /> // Export report<br /> try {<br /> exporter.exportReport();<br /> } catch ( RuntimeException e ) {<br /> throw e;<br /> } catch ( Exception e ) {<br /> throw new FacesException( e );<br /> }<br /> <br /> // Tell JavaServer faces that no more processing is necessary<br /> fcontext.responseComplete();<br />}<br />Start report output from page bean<br />The output of a report can initiated from a ActionEvent with the following code:<br />try {<br /> getApplicationBean().jasperReport(<br /> "/reports/report.jasper",<br /> "application/pdf",<br /> getSessionBean().getSuchergebnisDataProvider().getList() );<br />} catch ( Exception e ) {<br /> Logger.getLogger(getClass().getName()).severe( e.getMessage() );make it simplehttp://www.blogger.com/profile/03356377809939814997noreply@blogger.com0tag:blogger.com,1999:blog-23078113.post-26440331258223337852008-02-29T02:45:00.000-08:002008-02-29T02:48:36.513-08:00Using Hibernate queries with JasperReportsIntroduction<br />In the article, we examine a performance-optimised approach for using Hibernate queries to generate reports with JasperReports. <br /><br />JasperReports is a powerful and flexible Open Source reporting tool. Combined with the graphical design tool iReport, for example, you get a complete Java Open Source reporting solution. In this article, we will investigate how you can integrate JasperReports reporting with Hibernate data sources in an optimal manner, without sacrificing ease-of-use or performance. <br /><br />Basic Hibernate/JasperReports integration<br />To integrate Hibernate and JasperReports, you have to define a JasperReports data source. One simple and intuitive approach is to use the JRBeanCollectionDataSource data source (This approach is presented here) : <br /><br /> List results = session.find("from com.acme.Sale");<br /><br /> Map parameters = new HashMap();<br /> parameters.put("Title", "Sales Report");<br /><br /> InputStream reportStream<br /> = this.class.getResourceAsStream("/sales-report.xml");<br /> JasperDesign jasperDesign = JasperManager.loadXmlDesign(reportStream);<br /> JasperReport jasperReport = JasperManager.compileReport(jasperDesign);<br /><br /> JRBeanCollectionDataSource ds = new JRBeanCollectionDataSource(results);<br /> JasperPrint jasperPrint = JasperManager.fillReport(jasperReport,<br /> parameters,<br /> ds);<br /><br /> JasperExportManager.exportReportToPdfFile(jasperPrint, "sales-report.pdf");<br /><br /><br />This approach will work well for small lists. However, for reports involving tens or hundreds of thousands of lines, it is inefficiant, memory-consuming, and slow. Indeed, experience shows that, when running on a standard Tomcat configuration, a list returning as few as 10000 business objects can cause OutOfMemory exceptions. It also wastes time building a bulky list of objects before processing them, and pollutes the Hibernate session (and possibly second-level caches with temporary objects. <br /><br />Optimised Hibernate/JasperReports integration<br />We need a way to efficiently read and process Hibernate queries, without creating too many unnecessary temporary objects in memory. One possible way to do this is the following :<br /><br />Define an optimised layer for executing Hibernate queries efficiently <br />Define an abstraction layer for these classes which is compatible with JasperReports <br />Wrap this data access layer in a JasperReports class that can be directly plugged into JasperReports <br />The Hibernate Data Access Layer : The QueryProvider interface and its implementations<br />We start with the optimised Hibernate data access. (you may note that this layer is not actually Hibernate-specific, so other implementations could implement other types of data access without impacting the design). <br /><br />This layer contains two principal classes :<br /><br />The CriteriaSet class <br />The QueryProvider interface <br />A CriteriaSet is simply a JavaBean which contains parameters which may be passed to the Hibernate query. It is simply a generic way of encapsulating a set of parameters. A QueryProvider provides a generic way of returning an arbitrary subset of the query results set. The essential point is that query results are read in small chunks, not all at once. This allows more efficient memory handling and better performance.<br /><br /> /**<br /> * A QueryProvidor provides a generic way of fetching a set of objects.<br /> */<br /> public interface QueryProvider {<br /><br /> /**<br /> * Return a set of objects based on a given criteria set.<br /> * @param firstResult the first result to be returned<br /> * @param maxResults the maximum number of results to be returned<br /> * @return a list of objects<br /> */<br /> List getObjects(CriteriaSet criteria,<br /> int firstResult,<br /> int maxResults) throws HibernateException;<br /> }<br /><br />A typical implementation of this class simply builds a Hibernate query using the specified criteria set and returns the requested subset of results. For example : <br /><br /> public class ProductQueryProvider implements QueryProvider {<br /><br /> public List getObjects(CriteriaSet criteria,<br /> int firstResult,<br /> int maxResults)<br /> throws HibernateException {<br /> //<br /> // Build query criteria<br /> //<br /> Session sess = SessionManager.currentSession();<br /> ProductCriteriaSet productCriteria<br /> = (ProductCriteriaSet) criteria;<br /> Query query = session.find("from com.acme.Product p "<br /> + "where p.categoryCode = :categoryCode ");<br /><br /> query.setParameter("categoryCode",<br /> productCriteria.getCategoryCode();<br /> return query.setCacheable(true)<br /> .setFirstResult(firstResult)<br /> .setMaxResults(maxResults)<br /> .setFetchSize(100)<br /> .list();<br /> }<br /> }<br /><br /><br />A more sophisticated implementation is helpful for dynamic queries. We define an abstract BaseQueryProvider class which can be used for dynamic query generation. This is typically useful when the report has to be generated using several parameters, some of which are optionnal.. Each derived class overrides the buildCriteria() method. This method builds a Hibernate Criteria object using the specified Criteria set as appropriate : <br /><br /> public abstract class BaseQueryProvider implements QueryProvider {<br /><br /> public List getObjects(CriteriaSet criteria, int firstResult, int maxResults)<br /> throws HibernateException {<br /><br /> Session sess = SessionManager.currentSession();<br /> Criteria queryCriteria = buildCriteria(criteria, sess);<br /> return queryCriteria.setCacheable(true)<br /> .setFirstResult(firstResult)<br /> .setMaxResults(maxResults)<br /> .setFetchSize(100)<br /> .list();<br /><br /> }<br /><br /> protected abstract Criteria buildCriteria(CriteriaSet criteria, Session sess);<br /> }<br /><br />A typical implementation is shown here : <br /><br /> public class SalesQueryProvider extends BaseQueryProvider {<br /><br /> protected Criteria buildCriteria(CriteriaSet criteria,<br /> Session sess) {<br /> //<br /> // Build query criteria<br /> //<br /> SalesCriteriaSet salesCriteria<br /> = (SalesCriteriaSet) criteria;<br /><br /> Criteria queryCriteria<br /> = sess.createCriteria(Sale.class);<br /><br /> if (salesCriteria.getStartDate() != null) {<br /> queryCriteria.add(<br /> Expression.eq("getStartDate",<br /> salesCriteria.getStartDate()));<br /> }<br /> // etc...<br /><br /> return queryCriteria;<br /> }<br /> }<br /><br /><br /><br />Note that a QueryProvider does not need to return Hibernate-persisted objects. Large-volume queries can sometimes be more efficiently implemented by returning custom-made JavaBeans containing just the required columns. HQL allows you to to this quite easily : <br /><br /> public class CityQueryProvider implements QueryProvider {<br /><br /> public List getObjects(CriteriaSet criteria,<br /> int firstResult,<br /> int maxResults)<br /> throws HibernateException {<br /> //<br /> // Build query criteria<br /> //<br /> Session sess = SessionManager.currentSession();<br /> Query query<br /> = session.find(<br /> "select new CityItem(city.id, "<br /> + " city.name, "<br /> + " city.electrityCompany.name) "<br /> + " from City city "<br /> + " left join city.electrityCompany");<br /><br /> return query.setCacheable(true)<br /> .setFirstResult(firstResult)<br /> .setMaxResults(maxResults)<br /> .setFetchSize(100)<br /> .list();<br /> }<br /> }<br /><br /><br />Hibernate data access abstraction : the ReportDataSource interface<br />Next, we define a level of abstraction between the Hibernate querying and the JasperReport classes. The ReportDataSource does this :<br /><br /> public interface ReportDataSource extends Serializable {<br /> Object getObject(int index);<br /> }<br /><br />The standard implementation of this interface reads Hibernate objects using a given QueryProvider and returns them to JasperReports one by one. Here is the source code of this class (getters, setters, logging code and error-handling code have been removed for clarty) : <br /><br /> public class ReportDataSourceImpl implements ReportDataSource {<br /><br /> private CriteriaSet criteriaSet;<br /> private QueryProvider queryProvider;<br /> private List resultPage;<br /> private int pageStart = Integer.MAX_VALUE;<br /> private int pageEnd = Integer.MIN_VALUE;<br /> private static final int PAGE_SIZE = 50;<br /><br /> //<br /> // Getters and setters for criteriaSet and queryProvider<br /> //<br /> ...<br /><br /> public List getObjects(int firstResult,<br /> int maxResults) {<br /><br /> List queryResults = getQueryProvider()<br /> .getObjects(getCriteriaSet(),<br /> firstResult,<br /> maxResults);<br /> if (resultPage == null) {<br /> resultPage = new ArrayList(queryResults.size());<br /> }<br /> resultPage.clear();<br /> for(int i = 0; i < queryResults.size(); i++) {<br /> resultPage.add(queryResults.get(i));<br /> }<br /> pageStart = firstResult;<br /> pageEnd = firstResult + queryResults.size() - 1;<br /> return resultPage;<br /> }<br /><br /> public final Object getObject(int index) {<br /> if ((resultPage == null)<br /> || (index < pageStart)<br /> || (index > pageEnd)) {<br /> resultPage = getObjects(index, PAGE_SIZE);<br /> }<br /> Object result = null;<br /> int pos = index - pageStart;<br /> if ((resultPage != null)<br /> && (resultPage.size() > pos)) {<br /> result = resultPage.get(pos);<br /> }<br /> return result;<br /> }<br /> }<br /><br /><br />Finally, we have to be able to call the Hibernate data source from JasperReports. To do so, we start by looking at the JasperManager fillReport() method, which takes a JRDataSource object as its third parameter and uses it to generate the report : <br /><br /> JasperPrint jasperPrint = JasperManager.fillReport(jasperReport, parameters, ds);<br /><br />To implement our own optimised JRDataSource, we extended the JRAbstractBeanDataSource class. This class is presented here (logging and error-handling code has been removed for clarty). <br /><br /> public class ReportSource extends JRAbstractBeanDataSource {<br /><br /> private ReportDataSource dataSource;<br /> protected int index = 0;<br /> protected Object bean;<br /> private static Map fieldNameMap = new HashMap();<br /><br /> public ReportSource(ReportDataSource dataSource) {<br /> super(true);<br /> this.dataSource = dataSource;<br /> index = 0;<br /> }<br /><br /> public boolean next() throws JRException {<br /> bean = dataSource.getObject(index++);<br /> return (bean != null);<br /> }<br /><br /> public void moveFirst() throws JRException {<br /> index = 0;<br /> bean = dataSource.getObject(index);<br /> }<br /><br /> public Object getFieldValue(JRField field) throws JRException {<br /> String nameField = getFieldName(field.getName());<br /> return PropertyUtils.getProperty(bean, nameField);<br /> }<br /><br /> /**<br /> * Replace the character "_" by a ".".<br /> *<br /> * @param fieldName the name of the field<br /> * @return the value in the cache or make<br /> * the replacement and return this value<br /> */<br /> private String getFieldName(String fieldName) {<br /> String filteredFieldName<br /> = (String) fieldNameMap.get(fieldName);<br /> if (filteredFieldName == null) {<br /> filteredFieldName = fieldName.replace('_','.');<br /> fieldNameMap.put(fieldName,filteredFieldName);<br /> }<br /> return filteredFieldName;<br /> }<br /> }<br /><br /><br />This class is basically just a proxy between JasperReports and the Hibernate data source object. The only tricky bit is field name handling. For some reason, JasperReports does not accept field names containing dots (ex. "product.code"). However, when you retrieve a set of Hibernate-persisted business objects, you often need to access object attributes. To get around this, we replace the "." by a "_" in the JasperReport template (ex. "product_code" instead of "product.code"), and convert back to a conventional JavaBean format in the getFieldName() method. <br /><br />Putting it all together<br />So, when you put it all together, you get something like this : <br /><br /> List results = session.find("from com.acme.Sale");<br /><br /> Map parameters = new HashMap();<br /> parameters.put("Title", "Sales Report");<br /><br /> InputStream reportStream<br /> = this.class.getResourceAsStream("/sales-report.xml");<br /> JasperDesign jasperDesign<br /> = JasperManager.loadXmlDesign(reportStream);<br /> JasperReport jasperReport<br /> = JasperManager.compileReport(jasperDesign);<br /> <br /> ReportDataSource hibernateDataSource<br /> = new ReportDataSourceImpl();<br /> hibernateDataSource.setQueryProvider(new SalesQueryProvider());<br /> hibernateDataSource.setCriteriaSet(salesCriteria);<br /> ReportSource rs = new ReportSource(hibernateDataSource);<br /> <br /> JasperPrint jasperPrint<br /> = JasperManager.fillReport(jasperReport,<br /> parameters,<br /> rs);<br /> JasperExportManager.exportReportTsoPdfFile(jasperPrint,<br /> "sales-report.pdf");<br /><br /><br />Further JasperReports optimisations<br /><br />Compiled Report caching<br />In the previous code, the JasperReport is loaded and compiled before it is run. In a serverside application, for optimal performance, the reports should be loaded and compiled once and then cached. This will save several seconds on each query generation. <br /><br />Optimising Hibernate Queries<br />The first cause of slow report generation is sub-optimal querying. Hibernate is a high-performance persistence library which gives excellent results when correctly used. So you should treate any report which takes an excessive time to generate as suspicious. Common Hibernate optimisation strategies include :<br /><br />Correct use of joins <br />Correct use of lazy associations <br />Reading a subset of columns rather than whole Hibernate-persisted objects <br />Some Hibernate query optimisation techniques are discussed here.make it simplehttp://www.blogger.com/profile/03356377809939814997noreply@blogger.com1tag:blogger.com,1999:blog-23078113.post-37152203392506680142008-02-29T02:28:00.000-08:002008-02-29T02:44:36.499-08:00Reporting Made Easy with JasperReports and HibernateJasperReports and Hibernate in Web applications<br /><br />JasperReports is a valuable and viable reporting solution for Java Web applications. It simplifies report generation through the use of XML report templates that are then compiled using the JasperReports engine for use in reporting modules. These compiled report templates can be filled by data received from a variety of sources including relational databases. JasperReports can be integrated into Web applications and create reports in several file formats including PDF and XLS. <br /><br /> Reporting in Java Applications<br />Often reporting modules increase in complexity and size during the course of application development. Clients tend to demand more information from report modules when they become aware of the benefits reports offer. The reporting module developed as something of an afterthought in such environments suddenly becomes a much more integral part of the application. Reporting modules often seem to be tacked on to developed applications, rather than being considered and implemented during initial application development.<br /><br />Recently while working on some applications that made extensive use of report extraction to XLS files using the Apache POI library, it became apparent that these report modules tied up lots of valuable development resources for extended periods of time. When the client requested PDF extraction, initial iText API research led me to discover JasperReports. JasperReports was to change our team approach to report development dramatically.<br /><br />Prior to implementing JasperReports each report creation required the development of a custom report class using the Apache POI library. This approach expended valuable development time creating aspects of the report such as cell specific formats, styles, and population methods. JasperReports offered our team the ability to get back this valuable development time, while producing the same report because of its embedded use of the Apache POI library.<br /><br />One of the benefits offered by the introduction of JasperReports is that a single report template implementation can produce reports in a number of formats. This means that templates created for XLS format extraction can also be used to produce PDF files and even CSV, HTML or XML. <br /><br />How Can JasperReports Help Developers?<br />JasperReports gives developers the ability to create reports quickly and easily that can be extracted to numerous formats. Developers can also use the JasperReports engine to compile report templates at design or runtime - allowing dynamic report formats. Developers can also inject data into these reports from a number of data sources. Developer time no longer has to be spent creating custom report classes using the Apache POI or iText libraries for formatting and stylizing reports, allowing the code writers to focus on the data retrieval aspect of the report. As a result developers gain valuable flexibility and time savings using JasperReports in application development.<br /><br />The XML report templates used by JasperReports provide the layout and presentation information required to format the resulting report as well as field, variable, and parameter references. Non-development staff can create these templates using a third-party GUI such as iReport with minimal developer collaboration, so developers don't have to involve themselves in the layout and presentation aspect of report generation.<br /><br />JasperReports enables developers to concentrate their efforts on the parts of the reporting module where they are required, while relieving them of having to write custom report generation code. A developer's role in the report module can be reduced to template compilation, data source implementation, and actual report creation. <br /><br />Creating and Compiling an XML Report Template<br />JasperReports requires a report design defining the layout, presentation, and data fields. This design can be built using the net.sf.jasperreports.engine.design.JasperDesign object, so developers can create report designs dynamically, or by creating a net.sf.jasperreports.engine.design.JasperDesign instance from an XML report template. Unless an application specifically requires a dynamic layout a compiled XML report template is the recommended method. This XML template is usually saved with a .jrxml file extension and compiled using the net.sf.jasperreports.engine.JasperCompileManager.<br /><br />The JasperReports XML template includes elements for title, pageHeader, columnHeader, pageFooter, columnFooter, and the main data <detail> element. Each of these elements has a variety of sub-elements as can be seen in sampleReport.jrxml (see Listing 1).<br /><br />You can download the code samples used in this article at jdj.sys-con.com. As can be seen in sampleReport.jrxml some elements such as <band> and <reportElement> contain layout information, while others such as <textElement> and font contain presentation information. The XML templates also contain <parameter>, <field>, and <variable> elements used to include data in the report.<br /><br />The <parameter> elements allow non-data source information to be passed into a report, such as a dynamic title; <field> elements are the only way to map report fields to the data source fields, while variables are values generated at runtime for use in the report. The complete Document Type Definition (DTD) for the JasperReports XML report template can be found in the JasperReports Ultimate Guide.<br /><br />Compilation of the XML template can be done either at runtime or build time as part of an Ant build using the JasperReports Ant task.<br /><br />Compiling the report at runtime entails loading the report into a JasperDesign object and using the created instance as the parameter to the JasperCompileManager.compileReport(JasperDesign design) method, which returns a JasperReport instance. Alternatively the XML template can be passed into the JasperCompileManager.compileToFileReport(String sourceFileName, which creates a compiled report file (.jasper) available throughout the application.<br /><br />Compiling the report at build time using the JasperReports Ant task requires the addition of the task definition to the build.xml file and a target making use of this task as seen in Listing 2, which is an extract from the source code build.xml. Using the Ant task results in the creation of a compiled (.jasper) file in the destdir task and offers the opportunity to save the Java source file by passing the keepjava attribute of the target a true value. A more thorough example of how to use the Ant task is included in the sample applications provided in the JasperReports download bundle. <br /><br />Using Data Sources to Fill JasperReports<br />Most reports use a database as the data source, but JasperReports can use any available data source. These data sources are passed to a net.sf.jasperreports.engine.JasperFillManager fillReportXXX() method. Two types of data source are provided for by these methods - net.sf.jasperreports.engine.JRDataSource and java.sql.Connection. The source code for this article contains examples of both a static data source that extends the JRDataSource and a JDBC connection data source implementation.<br /><br />The StaticDataSource class implementation provided implements the net.sf.jasperreports.engine.JRDataSource interface enabling it to fill the report data by calling the JasperFillManager.fillReport(JaperReport report, Map parameters, JRDataSource dataSource) method. The two required methods getFieldValue(JRField jrField) and next() of the JRDataSource interface present in StaticDataSource handle the data passing from the data source into the JasperReport. The data source used by StaticDataSource is a static simple two-dimensional array of bowlers containing their names and scores over three games (see Listing 3). When the fillReport() method containing this data source is processed and a detail section is encountered in the report a call will be made to the next() method. The implementation of this method in StaticDataSource (see Listing 4) returns true if there's another element in the data array, or false if there is no more data. If this method returns true then field elements encountered in the detail section will result in a call to the getFieldValue(JRField jrField) method in StaticDataSource. The implementation of this method in StaticDataSource (see Listing 5) returns the value of the mapped data field name for the current index of the data array. When the end of the detail section is encountered, the next() method is called again and the process repeats until the next() method returns false.<br /><br />The JDBCDataSourceExample (see Listing 6) implements a fillReport() method that accepts a java.sql.Connection parameter. Through the addition of a <queryString> element into the XML report template (jdbcSampleReport.jrxml) this fillReport() method enables data to be extracted from a relational database. The <queryString> element returns the data fields for use in the report data mapping. In this case the query simply returns all records in the sample_data table. A java.sql.ResultSet can be used instead of implementing the <queryString> element in the report template, allowing dynamic query implementation. <br /><br />Using Hibernate with JasperReports<br />Hibernate is one of the most popular ORM tools in use at the moment. Using Hibernate as a data source for JasperReports can be very simple when a collection of objects is returned from a Hibernate query, but when a tuple of objects is returned then a custom JRDataSource implementation is required.<br /><br />When a Hibernate query returns a collection of objects, a net.sf.jasperreports.engine.data.JRBeanCollection-DataSource can be used to map the Hibernate POJO instance fields to the report fields. All that's required for this simple solution is to use the JRBeanCollectionDataSource(java.util.Collection beanCollection) constructor, passing it the Hibernate Query result set as implemented in SimpleHibernateExample (see Listing 7). In this example the simple Hibernate query used (session.createQuery("from SampleData").list()) is equivalent to that found in the JDBCDataSourceExample. JRBeanCollectionDataSource implements JRDataSource like StaticDataSource but its getFieldValue(JRField jrField) method implementation maps the report template field names to the query result bean properties.<br /><br />When a Hibernate query returns a tuple of objects it's necessary to write a custom implementation of the JRDataSource similar to HibernateDataSource (see Listing 8). The implementation of the required next() method in this class returns true if there is another list item in the Hibernate query result set, while putting the current list item in a currentValue holder for use in the getFieldValue(JRField jrField) method. The getFieldValue() method implementation gets the field index in the currentValue object via a call to the getFieldIndex(String field) method. This method iterates through the mapped field names passed to the HibernateDataSource constructor until it finds the field name it was passed and then returns the index of this field in the currentValue information. The getFieldValue() method then returns the value at this index in the currentValue result object.<br /><br />More extensive solutions to using Hibernate with JasperReports, including the use of reflection instead of the name mapping method used in HibernateDataSource, can be found on the Hibernate Web site www.hibernate.org/79.html. Also of interest in this area is the report optimization implementation advocated by John Ferguson Smart in his article "Hibernate Querying 103: Using Hibernate Queries with JasperReports" (see Resources). <br /><br />Exporting Reports to PDF and XLS Formats in Web Applications<br />After compiling and filling a JasperReport report exporting it is a fairly simple and straightforward process using the net.sf.jasperreports.engine.JRExporter interface implementations provided. JasperReports can export data to PDF, XLS, CSV, RTF, HTML, and XML from the same report design using the appropriate implementation of the JRExporter interface. The PDF and XLS formats are two of the most common export formats and examples of exporting to these formats from within a Web application can be found in the source code for this article. PrintServlet exports to PDF, while DataExtractServlet exports the same data to an XLS format file.<br /><br />PrintServlet (see Listing 9) is a an example servlet implementation class using JasperReports to export a report to PDF format. JasperReports makes use of the Open Source iText PDF creation library (see Resources) to generate PDF format files. Once the report is compiled in PrintServlet, the PDF is created and streamed to the Web browser ready for printing using the runReportToPdfStream(InputStream inputStream, OutputStream outputStream, Parameters params, Connection connection) method implemented by the JasperRunManager facade class.<br /><br />DataExtractServlet (see Listing 10) is an example servlet implementation class using JasperReports to export a report to the XLS format. JasperReports makes use of the Apache POI library (see Resources) to generate XLS format files. Once the report is compiled in DataExtractServlet the XLS file is created in memory and a save dialog is displayed to the user. The servlet uses net.sf.jasperReports.engine.export.JRXlsExporter, one of the concrete implementations of the JRExporter interface provided by JasperReports to export the report. The parameters for exporting the report are initialized using JRXlsExporterParameter variables to set the filled report (JRXlsExporterParameter.JASPER_PRINT) and the output stream (JRXlsExporterParameter.OUTPUT_STREAM) - which is the response object that has had its content type and header set so that the file will be made available to the user for saving rather than displayed as in the PrintServlet example when exportReport() is called.<br /><br />Useful Hint: By default JasperReport puts page headings at the top of every 'page' of data. When exporting to an XLS format this breaks up the continuous data in a worksheet that contains more than a single 'page' of data. Data continuity can be maintained by passing the type of output format as a parameter to a report template combined with a <printExpression> element based on the passed parameter placed in the <pageHeader> element. The <printExpression> below will result in only the page headings being output to a 'page' if the report is processing the first page when the output format isn't PDF and on every 'page' for PDF output formats. <br /><br /><printWhenExpression><br /><![CDATA[$V{PAGE_NUMBER}.intValue() == 1<br />|| $P{REPORT_TYPE}.equals("PDF")<br />? Boolean.TRUE : Boolean.FALSE]]><br /></printWhenExpression> <br /><br />Creating Reports Is Easy and Fun with JasperReports<br />Hopefully this article has whetted your appetite for exploring the world of report generation using JasperReports, or if you've already discovered JasperReports, that it's provided some ideas on how to delve into creating custom data sources or using new export formats. Understanding and mastering the implementation of the required JRDataSource methods next() and getFieldValue(JRField jrField) opens up any data source for use in generating reports with JasperReports.<br /><br />Creating reports with JasperReports is made even simpler by some useful tools. iReport (see Resources), an excellent JasperReports template creation tool that allows visual report designs in a GUI application can be used by non-developers to create the JasperReport designs. It also offers substantial developer-focused functionality such as data source connectivity to create report previews outside of an application. JasperAssistant (see Resources), while not Open Source has the advantage of being an Eclipse plug-in for developing JasperReport templates in a similar GUI manner, albeit more developer-oriented. Both offer the benefit of being able to prepare a report design, which can then be provided to a developer for filling, relieving him of the tedious presentation aspect of report generation.<br /><br />This article has barely scratched the surface of JasperReports' extensive use and functionality but hopefully it's introduced some developers to an extremely useful tool in any Java developer's arsenal. JasperReports can even produce charts and graphs, as well as including images in reports that increase the richness and presentation of an applications reporting system. JasperReports is a powerful API that can take a reporting system to the next level.make it simplehttp://www.blogger.com/profile/03356377809939814997noreply@blogger.com0tag:blogger.com,1999:blog-23078113.post-53182690210927588062008-02-29T02:26:00.000-08:002008-02-29T02:28:48.410-08:00HowTo: JasperReports framework. Deployment to TomcatJasperReports framework does not ship report engine WAR file - you have to build it yourself. <br /><br />Building JasperReports report engine WAR file<br /><br />1. Download jasperreports-1.2.6-project.zip, unzip it to directory jasper. <br /><br />2. Create Eclipse project: New->Project->General->Project. Location should point to jasper directory. <br /><br />3. In the Eclipse Navigatior, select jasperreports-1.2.6\demo\samples\webapp\build.xml, open it, select war target, right-click->RunAs->Ant Build. The jasper-webapp.war file is built in jasperreports-1.2.6\demo\samples\webapp\ directory. <br /><br />Deploying JasperReports report engine WAR file to Tomcat<br /><br />1. Copy jasper-webapp.war file to tomcat\webapps directory. Start Tomcat, it will unzip the WAR file. <br /><br />Deploying JasperReports report to Tomcat<br /><br />For each report, you should have one file with .jasper extension (compiled report definition). <br />1. Copy the report file to jasper-webapp\reports directory. <br /><br />2. Copy JDBC driver, required by your report, to jasper-webapp\WEB-INF\lib directory. <br /><br />3. Modify jasper-webapp\jsp\html.jsp JSP file to load .jasper file, open database connection and render the report as HTML: <br /><br /><br /><%@ page errorPage="error.jsp" %><br /><%@ page import="datasource.*" %><br /><%@ page import="net.sf.jasperreports.engine.*" %><br /><%@ page import="net.sf.jasperreports.engine.util.*" %><br /><%@ page import="net.sf.jasperreports.engine.export.*" %><br /><%@ page import="net.sf.jasperreports.j2ee.servlets.*" %><br /><%@ page import="java.util.*" %><br /><%@ page import="java.io.*" %><br /><%@ page import="java.sql.*" %><br /><br /><%<br /> File reportFile = new File(application.getRealPath("/reports/MyReport.jasper"));<br /> if (!reportFile.exists())<br /> throw new JRRuntimeException("File WebappReport.jasper not found. The report design must be compiled first.");<br /><br /> JasperReport jasperReport = (JasperReport)JRLoader.loadObject(reportFile.getPath());<br /><br /> Map parameters = new HashMap();<br /> parameters.put("ReportTitle", "Address Report");<br /> parameters.put("BaseDir", reportFile.getParentFile());<br /> <br /> Class.forName ("com.mysql.jdbc.Driver");<br /> Connection connection = DriverManager.getConnection ("jdbc:mysql://XX.XX.XX.XX/world", "userId", "password"); <br /> <br /> JasperPrint jasperPrint = <br /> JasperFillManager.fillReport(<br /> jasperReport, <br /> parameters, <br /> connection<br /> );<br /><br /> connection.close();<br /> <br /> JRHtmlExporter exporter = new JRHtmlExporter();<br /><br /> exporter.setParameter(JRExporterParameter.JASPER_PRINT, jasperPrint);<br /> exporter.setParameter(JRExporterParameter.OUTPUT_WRITER, out);<br /> exporter.setParameter(JRHtmlExporterParameter.IMAGES_URI, "../servlets/image?image=");<br /> <br /> exporter.exportReport();<br />%><br />4. Restart Tomcat. <br /><br />5. Invoke your report, using URL like: "http://localhost:8080/jasper-webapp/jsp/html.jsp".make it simplehttp://www.blogger.com/profile/03356377809939814997noreply@blogger.com0tag:blogger.com,1999:blog-23078113.post-67424654465540519152008-02-29T02:20:00.000-08:002008-02-29T02:26:36.101-08:00How to call Stored Procedures from JasperReportsJasper Reports is unable to call Oracle stored procedures directly, because procedures do not return standard result sets. As a solution, in Oracle, you can use a stored function to retrieve the results of a stored procedure. There are a few more steps to do this than if you were able to use a stored procedure, but it currently is the only option, if the query you need to do can’t be done with a standard SQL query.<br /><br />In order to to use stored functions to retrieve the result set of a stored procedure, you will need to use a temp table to hold the results, and then return the results using types and tables of types.<br /><br />Note: In this example, I have kept the function very limited. This particular query would not need to be done with a stored procedure and function, as a standard select query would be best, but is only used to demonstrated how to do it, should the need arise.<br /><br />I have provided all the sql used in this demo, in this file.<br /><br />Setup<br />For this example, the table Presidents will be used. Sample data will also need to be loaded into the table. You can use the file I provided above, with all the example’s sql to create the table and load it with sample data.<br /><br />Now that there is a base table and data to work with, creation of the objects needed for the stored function can begin.<br /><br />Step 1: Create a Temp Table<br />First, create a temp table to temporarily hold the results from the stored procedure, so the Jasper Report can query it via the stored function, with a standard select query. To create the temp table, use this sql:<br /><br />CREATE GLOBAL TEMPORARY TABLE “TEMP_PRESIDENTS” (<br /> ID NUMBER(10) not null,<br /> NAME VARCHAR(32) not null,<br /> BIRTHDATE DATE not null,<br /> PARTY char(1) not null<br />) ON COMMIT PRESERVE ROWSStep 2: Create the Stored Procedure<br />Next, create the stored procedure which will perform the needed data gathering. In this simple example, the query will select all rows based on the party passed (R for republican, D for democrat).<br /><br />CREATE PROCEDURE “LOAD_TEMP_PRESIDENTS” (<br />partyParam CHAR )<br />as<br />begin<br /> EXECUTE IMMEDIATE ‘TRUNCATE TABLE TEMP_PRESIDENTS’;<br /> COMMIT;<br /><br /> INSERT INTO TEMP_PRESIDENTS<br /> SELECT ID, NAME, BIRTHDATE, PARTY FROM PRESIDENTS WHERE PARTY = partyParam;<br /> COMMIT;<br />end;Step 3: Test the Stored Procedure<br />Before proceeding any further, call the stored procedure and then check the temp table to be sure it behaves properly (sql below). You should get a result of all the Democrat Presidents, four of them. If not, you will need to retrace your steps.<br /><br />call LOAD_TEMP_PRESIDENTS(‘D’);<br />select * from TEMP_PRESIDENTS;Step 4: Create the Return Type<br />This step creates the type that will be used to return the results from the temp table. This type should describe the result set you are expecting in the Jasper Report.<br /><br />CREATE OR REPLACE TYPE “PRESIDENT_TYPE” AS OBJECT (<br /> ID NUMBER(10),<br /> NAME VARCHAR2(32),<br /> BIRTHDATE DATE,<br /> PARTY CHAR(1)<br />)Step 5: Create a Table of the Type<br />In this step we create a table of the type we created in the previous step. This “table” is what we will be selecting from in the Jasper Report. It is not a real table, but instead a type or object representing the structure of the table that we will funnel the stored procedures results through.<br /><br />CREATE OR REPLACE TYPE “PRESIDENT_TYPE_TABLE” AS TABLE OF “PRESIDENT_TYPE”Step 6: Create the Stored Function<br />The next step is to create the stored function with the following code, to retrieve all the presidents for the party you select (R or D).<br /><br />CREATE OR REPLACE FUNCTION “PRESIDENTS_FUNC” (<br />partyParam CHAR<br />)<br />return PRESIDENT_TYPE_TABLE pipelined<br />is<br />PRAGMA AUTONOMOUS_TRANSACTION;<br /><br />TYPE ref0 is REF CURSOR;<br />myCursor ref0;<br />out_rec PRESIDENT_TYPE := PRESIDENT_TYPE(0, null, null, null);<br /><br />BEGIN<br />LOAD_TEMP_PRESIDENTS(partyParam);<br /><br />open myCursor for<br />select id,<br />name,<br />birthdate,<br />party<br />from TEMP_PRESIDENTS;<br /><br />LOOP FETCH myCursor into<br />out_rec.ID,<br />out_rec.NAME,<br />out_rec.BIRTHDATE,<br />out_rec.PARTY;<br /><br />EXIT WHEN myCursor%NOTFOUND;<br />PIPE ROW(out_rec);<br />END LOOP;<br />CLOSE myCursor;<br /><br />RETURN;<br />END;Step 7: Testing and Using the Stored Function<br />In order to use the stored function you execute the code below:<br /><br />select * from table(PRESIDENTS_FUNC(‘D’))This code can now be used within a Jasper Report, as you have turned a stored procedure into a stored function accessible with a standard select. To the Jasper Report you are merely issuing a standard query.make it simplehttp://www.blogger.com/profile/03356377809939814997noreply@blogger.com1tag:blogger.com,1999:blog-23078113.post-64235506117664069732008-02-29T02:16:00.000-08:002008-02-29T02:20:06.519-08:00Flexible reporting with JasperReports and iBATISIntegrate JasperReports with your existing iBATIS implementation <br /><br />The core task of many Java applications is to retrieve data and display it, sometimes in sophisticated print- or Web-based reports. Luckily for Java developers, two popular open source solutions work especially well together to help you accomplish this task. The iBATIS Data Mapper framework provides a simple XML-based mechanism for linking Java objects to a data repository. JasperReports is a full featured Java reporting library that you can embed in your applications. Put the two together and you have a winning combination for producing scalable, easy-to-maintain reports. <br /><br />JasperReports is an open source Java reporting library that is quickly gaining popularity as a viable alternative to costly proprietary reporting solutions. With any reporting solution, getting the data to the reporting engine is the most basic implementation concern. Unfortunately, Jasper poses a small problem in this area. <br /><br />Most Java applications use some type of data-fetching framework for data mapping and dynamic SQL generation, such as the iBatis Data Mapper Framework. Jasper's default mechanism for retrieving and managing data isn't flexible enough to leverage existing data mapping frameworks, however. Instead, you pass the Jasper engine a connection to your database, and it uses SQL queries embedded in an XML-based report template to populate the report. <br /><br />Although simple to implement, this mechanism ties you to the Jasper template's embedded SQL. Besides, who wants to add yet another moving piece to an already complex application? You would be better off leveraging the existing data framework and just letting Jasper handle report generation. <br /><br />In this article you'll learn how to integrate JasperReports and the iBATIS Data Mapper Framework for just such a solution. I'll walk through two simple scenarios where the goal is to integrate Jasper and iBATIS for report generation. The first scenario applies to iBATIS implementations that use iBATIS's data capabilities to return a list of Java beans. This scenario doesn't require you to write any custom code. The Jasper framework contains supporting classes that allow the data returned from iBATIS to fill a Jasper report. <br /><br />For the second scenario -- a more basic uses of iBATIS that returns a list of java.util.Map objects -- you'll create a custom Jasper data source to feed a Jasper report. In addition to working with the Jasper framework classes, for both exercises you'll use the iReport report designer, which eases and accelerates the process of creating template files in Jasper. <br /><br />Running the examples<br />This article's example code generates a simple monthly sales report for each type of implementation I cover. The data for the reports is retrieved from an embedded Apache Derby database via the iBATIS Data Mapper framework. The examples are built into a JSF/Spring-based Web application that runs in the same JVM as Derby. I've provided an Ant script for building that WAR file -- just execute the buildWar task to compile content and build it. You'll need Tomcat 5.5x to deploy and run the examples. You'll also need the Abode Acrobat Reader Web browser plug-in to view the report output. <br /><br />Getting the iBATIS data into Jasper<br />Using iBATIS to return a list of a specific type of Java beans (I'll call this a return list) is much tidier than using the framework to return a list of java.util.Map objects. Most developers using iBATIS take this approach to data mapping, and it happens to make integration with Jasper a snap. <br /><br />The Jasper framework provides a JRDataSource implementation that your application can use to fill a report template with data from an iBATIS return list. The JRBeanCollectionDataSource class is constructed from a collection of Java beans and knows how to loop through the collection and access the beans' properties. Listing 1 shows how you can pass an instance of a JRBeanCollectionDataSource when calling on the Jasper engine to populate a report. <br /><br />Listing 1. Populating a report with JRBeanCollectionDataSource<br /> /* Helper method to create a fully populated JasperPrint object from an list of Java beans */<br />private JasperPrint fillReport (List dataList) throws JRException {<br /> <br /> // this map could be filled with parameters defined in the report<br /> Map parameters = new HashMap();<br /> <br /> // make sure the .jasper file (a compiled version of the .jrxml template file) exists<br /> String localPath = this.servlet.getServletContext().getRealPath("/");<br /> <br /> File reportFile = new File(localPath + "WEB-INF" + File.separator + "monthySales.jasper");<br /> <br /> if (!reportFile.exists()) {<br /> throw new JRRuntimeException("monthySales.jasper file not found.");<br /> }<br /> <br /> // load up the report<br /> JasperReport jasperReport = (JasperReport)JRLoader.loadObject(reportFile);<br /> <br /> // pass JRBeanCollectionDataSource (which is populated with iBATIS list) to fillReport method<br /> return JasperFillManager.fillReport (jasperReport, parameters,<br /> new JRBeanCollectionDataSource (dataList));<br />}<br /><br /> <br />In Listing 1, you first define the parameters map, which is the mechanism for passing parameter values to the report at runtime. For example, you could define a parameter named REPORT_TITLE in the report template and pass the value for this parameter to the report by simply adding the key/value pair to the map (e.g., Key=REPORT_TITLE, Value=Sale Report). The parameters map is passed to the fillReport method. The next portion of code loads a compiled Jasper template (.jasper) file. Finally, the static fillReport method is called. It does the actual work of building the report and returns a JasperPrint object, which is passed to a specific type of Jasper exporter to write out the report. The example code for this article uses a JRPdfExporter to write the report to PDF format (see the PdfServlet.java class). <br /><br />Although this mechanism lets the Jasper framework link with iBATIS, you might need to modify the Java beans that iBATIS populates, depending on your report's requirements. Jasper's field objects know how to work with the common JDBC mapping types. For example, Jasper stores an Oracle numeric field type as a java.math.BigDecimal object. Any of the iBATIS bean properties that you plan to use in a report must map to one of Jasper's defined field types. You should select your report field types carefully, because the formatting and expression capabilities are better in some types than in others. For example, a BigDecimal type is more convenient to work with than a String when you're trying to apply a currency format.make it simplehttp://www.blogger.com/profile/03356377809939814997noreply@blogger.com0tag:blogger.com,1999:blog-23078113.post-80475756265602643462008-02-29T02:13:00.000-08:002008-02-29T02:16:17.117-08:00Export Swing components to PDFUse JFreeChart and iText to draw charts<br /><br />Suppose you've written an application with a GUI using Swing components such as JTable or JTextPane. All these components are derived from the abstract class javax.swing.JComponent, which includes the print(Graphics g) method: You can use this method to let the Swing component print itself to iText's PdfGraphics2D object. <br /><br />(Note: This article excerpts Chapter 12, "Drawing to Java Graphics2D," from iText in Action, Bruno Lowagie (Manning Publications, December 2006; ISBN: 1932394796): http://www.manning.com/lowagie.) <br /><br />Figure 1 shows a simple Java application with a JFrame. It contains a JTable found in Sun's Java tutorial on Swing components. If you click the first button, the contents of the table are added to a PDF using createGraphicsShapes() (the upper PDF in the screenshot). If you click the second button, the table is added using createGraphics() (the lower PDF, using the standard Type 1 font Helvetica). Notice the subtle differences between the fonts used for both variants. <br /><br /><br /><br />Figure 1. A Swing application with a JTable that is printed to PDF two different ways. Click on thumbnail to view full-sized image.<br /><br />If you run this example, try changing the content of the JTable; the changes are reflected in the PDF. If you select a row, the background of the row is shown in a different color in the Java applications as well as in the PDF. <br /><br />The code to achieve this is amazingly simple:<br /><br /> /* chapter12/MyJTable.java */<br />public void createPdf(boolean shapes) {<br /> Document document = new Document();<br /> try {<br /> PdfWriter writer;<br /> if (shapes)<br /> writer = PdfWriter.getInstance(document,<br /> new FileOutputStream("my_jtable_shapes.pdf"));<br /> else<br /> writer = PdfWriter.getInstance(document,<br /> new FileOutputStream("my_jtable_fonts.pdf"));<br /> document.open();<br /> PdfContentByte cb = writer.getDirectContent();<br /> PdfTemplate tp = cb.createTemplate(500, 500);<br /> Graphics2D g2;<br /> if (shapes)<br /> g2 = tp.createGraphicsShapes(500, 500);<br /> else<br /> g2 = tp.createGraphics(500, 500);<br /> table.print(g2);<br /> g2.dispose();<br /> cb.addTemplate(tp, 30, 300);<br /> } catch (Exception e) {<br /> System.err.println(e.getMessage());<br /> }<br /> document.close();<br />}<br /><br /> <br />The next example was posted to the iText mailing list by Bill Ensley (bearprinting.com), one of the more experienced iText users on the mailing list. It's a simple text editor that allows you to write text in a JTextPane and print it to PDF. <br /><br />Figure 2 shows this application in action.<br /><br /><br /><br />Figure 2. A simple editor with a JTextPane that is drawn onto a PDF file. Click on thumbnail to view full-sized image.<br /><br />The code is a bit more complex than the JTable example. This example performs an affine transformation before the content of the JTextPane is painted: <br /><br /> /* chapter12/JTextPaneToPdf.java */<br />Graphics2D g2 = cb.createGraphics(612, 792, mapper, true, .95f);<br />AffineTransform at = new AffineTransform();<br />at.translate(convertToPixels(20), convertToPixels(20));<br />at.scale(pixelToPoint, pixelToPoint);<br />g2.transform(at);<br />g2.setColor(Color.WHITE);<br />g2.fill(ta.getBounds());<br />Rectangle alloc = getVisibleEditorRect(ta);<br />ta.getUI().getRootView(ta).paint(g2, alloc);<br />g2.setColor(Color.BLACK);<br />g2.draw(ta.getBounds());<br />g2.dispose();<br /><br /> <br />Numerous applications use iText this way. Let me pick two examples; one free/open source software (FOSS) product and one proprietary product: <br /><br />JasperReports, a free Java reporting tool from JasperSoft, allows you to deliver content onto the screen; to the printer; or into PDF, HTML, XLS, CSV, and XML files. If you choose to generate PDF, iText's PdfGraphics2D object is used behind the scenes. <br />ICEbrowser is a product from ICEsoft. ICEbrowser parses and lays out advanced Web content (XML/HTML/CSS/JS); PDF is generated by rendering the parsed documents to the PdfGraphics2D object. <br />It's not my intention to make a complete list of products that use iText. The main purpose of these two examples is to answer the following question: Can I build iText into my commercial product? Lots of people think open source is the opposite of commercial, but that's a misunderstanding. It's not because iText is FOSS that it can only be used in other free products. It's not because iText is free that it isn't a "commercial" product. As long as you respect the license, you can use iText in your closed-source or proprietary software. <br /><br />Another useful aspect of iText's Graphics2D functionality is that it opens the door to using iText in combination with other libraries with graphical output—for instance, Apache Batik, a library that is able to parse SVG; or JFreeChart, a library that will be introduced in the next section. <br /><br />Drawing charts with JFreeChart<br />Suppose you need to make charts showing demographic information. You take the student population of the Technological University of Foobar and graph the number of students per continent. <br /><br />To make these charts, you'll combine iText with JFreeChart, an interesting library developed by David Gilbert and Thomas Morgner. The Website jfree.org explains that JFreeChart is "a free Java class library for generating charts, including pie charts (2D and 3D), bar charts (regular and stacked, with an optional 3D effect), line and area charts, scatter plots and bubble charts, time series, high/low/open/close charts and candle stick charts, combination charts, Pareto charts, Gantt charts, wind plots, meter charts and symbol charts, and wafer map charts." <br /><br />These charts can be rendered on an AWT (Abstract Window Toolkit) or Swing component, they can be exported to JPEG or PNG, and you can combine JFreeChart with Apache Batik to produce SVG or with iText to produce PDF. <br /><br />Figure 3 shows PDFs with a pie chart and a bar chart created using JFreeChart and iText. In JFreeChart, you construct a JFreeChart object using the ChartFactory. One of the parameters passed to one of the methods to create the chart is a dataset object. <br /><br /><br /><br />Figure 3. Foobar statistics represented in a pie chart and a bar chart. Click on thumbnail to view full-sized image.<br /><br />The code to create the charts shown in Figure 3 is simple:<br /><br /> /* chapter12/FoobarCharts.java */<br />public static JFreeChart getBarChart() {<br /> DefaultCategoryDataset dataset = new DefaultCategoryDataset();<br /> dataset.setValue(57, "students", "Asia");<br /> dataset.setValue(36, "students", "Africa");<br /> dataset.setValue(29, "students", "S-America");<br /> dataset.setValue(17, "students", "N-America");<br /> dataset.setValue(12, "students", "Australia");<br /> return ChartFactory.createBarChart("T.U.F. Students",<br /> "continent", "number of students", dataset,<br /> PlotOrientation.VERTICAL, false, true, false);<br />}<br />public static JFreeChart getPieChart() {<br /> DefaultPieDataset dataset = new DefaultPieDataset();<br /> dataset.setValue("Europe", 302);<br /> dataset.setValue("Asia", 57);<br /> dataset.setValue("Africa", 17);<br /> dataset.setValue("S-America", 29);<br /> dataset.setValue("N-America", 17);<br /> dataset.setValue("Australia", 12);<br /> return ChartFactory.createPieChart("Students per continent",<br /> dataset, true, true, false);<br />}<br /><br /> <br />The previous code snippet creates two JFreeChart objects. The following code snippet shows how to create a PDF file per chart: <br /><br /> /* chapter12/FoobarCharts.java */<br />public static void convertToPdf(JFreeChart chart,<br /> int width, int height, String filename) {<br /> Document document = new Document(new Rectangle(width, height));<br /> try {<br /> PdfWriter writer;<br /> writer = PdfWriter.getInstance(document, new FileOutputStream(filename));<br /> document.open();<br /> PdfContentByte cb = writer.getDirectContent();<br /> PdfTemplate tp = cb.createTemplate(width, height);<br /> Graphics2D g2d = tp.createGraphics(width, height, new DefaultFontMapper());<br /> Rectangle2D r2d = new Rectangle2D.Double(0, 0, width, height);<br /> chart.draw(g2d, r2d);<br /> g2d.dispose();<br /> cb.addTemplate(tp, 0, 0);<br /> }<br /> catch(Exception e) {<br /> e.printStackTrace();<br /> }<br /> document.close();<br />}<br /><br /> <br />The chart is drawn on a PdfTemplate. This object can easily be wrapped in an iText Image object if you want to add it to the PDF with document.add().make it simplehttp://www.blogger.com/profile/03356377809939814997noreply@blogger.com0tag:blogger.com,1999:blog-23078113.post-7249371722944087272008-02-29T02:08:00.000-08:002008-02-29T02:13:02.321-08:00Dynamic PDF generation with JasperReports, Struts and a databaseA requirement appeared recently as part of a Purchase Ordering application to allow a user to dynamically generate a PDF copy of the final Purchase Order to send to the supplier. Taking a look around I stumbled rather fortunately upon an API called JasperReports (JR). JasperReports is a powerful open source Java reporting tool that has the ability to deliver rich content onto the screen, to the printer or into PDF, HTML, XLS, CSV and XML files. This tutorial is aimed at the beginner JR user who is happy with J2EE web application development. It will show you how JR was used to deliver the requirement described and should convince you that it is a truly fantastic piece of kit.<br /><br />What we will be doing in 1 sentence<br /><br />You will define a report template using JR’s XML syntax and then bind data from a database into it and get a PDF sent back to a web browser.<br /><br />What will I need<br /><br />OK, you need a few bits of kit. Firstly, I hate to break it to you but I kind of cheated with defining the report template. See, thing is, you can write this manually, but I didn’t have time to learn the ins and outs of JR’s XML syntax, so I got hold of JasperAssistant, a brilliant Eclipse IDE plugin that allows a developer to visually draw their report for JR. If like me you use Eclipse, or indeed you just want to use this method for creating your report template, grab Eclipse and JasperAssistant. There is also another tool called iReport that does a similar thing without Eclipse but you’ll need to look at that yourself. So, you will need<br /><br />JasperReports - head to the Download section <br />Either JasperAssistant, iReports OR a willingness to learn the JR XML syntax for which there are many examples with the JR distribution. Whichever method you chose, I leave it to you to configure the environment - full instructions are available on each site. <br />A knowledge of J2EE web application development. In this tutorial I shall be using Struts but only in the slightest way to illustrate how to send the PDF back to the web user. You can do the same stuff with a plain old Servlet. <br />Creating the report template<br /><br />First of all, you need to think about what data your report needs to show. In my scenario, we are talking about a Purchase Ordering application. In this application is the master object called PurchaseOrder. A PurchaseOrder has at least one or more LineItem stored in a list collection. Each of these 2 objects have other attributes that reveal information, e.g the PuchaseOrder has a createdDate and orderId whereas a LineItem has a description and unitCost. These objects are persisted to a database. It is not really important how, it may be via a series of SQL statements or it may be via some Object Relational Mapping API such as Hibernate (which for the record, is how I have done it), but what matters is that you have code in place to save and fetch your particular application objects/data. Now, my report layout requires that the header contain master detail such as the created date and order id and then to list all the line items in a table below. Finally, some more master detail such as delivery address is required at the foot. JR divides up a report into a series of stacked bands from top to bottom, e.g title, header, detail and footer are names of some bands. In my case, I chose to use the header, detail and footer bands for the areas I have just mentioned.<br /><br />Parameters, fields and static text<br /><br />Using JasperAssistant, I was able to draw my report layout using guides and properties boxes. You may do the same or do it manually, but the main elements that I had to use were parameters, fields and static text. JR has a mechanism for binding a Map of data to a report. This is referred to as a parameter map. The idea being that the map element’s key is used for binding the map element’s value to the parameter defined in the report. For example, if I have an empty report with a parameter declaration orderId as follows:<br /><br />l version="1.0" encoding="UTF-8–>http://jasperreports.sourceforge.net/dtds/jasperreport.dtd"<br /> <br /><br />then I would need a corresponding Map<br /><br />Map map = new HashMap(); map.put(orderId, “12345″);<br />I will show how you can bind this to the report later. In addition to the parameter map mechanism, you can also use something called a DataSource. You musn’t think a DataSource is a database necessarily like it is with an application server. A DataSource is an object that provides methods that can be called by the report in obtaining rows of data. For my purposes if you remember, I have a collection of LineItem elements inside my PurchaseOrder and I need to loop through them outputting to a table in my report. The way I achieved this was by implementing JR’s DataSource interface JRDataSource. This interface requires an implementation provide methods;<br /><br />public boolean next() throws JRException;<br />public Object getFieldValue(JRField field) throws JRException;<br />In your report, you must define fields in the detail band. When the report is run together with the custom implementation, JR will automatically keep calling next and then attempt to bind each field in the detail band to a call to getFieldValue(JRField field).<br /><br />Since my implementation of JRDataSource will return operation on a collection of LineItem I have named my DataSource LineItemDataSource. It has 2 class variables; private List data; private int index; Which is an internal data List to use (which I will populate with LineItem objects later), and the index allows us to know at which position we are in iteration of the List. That’s why you need to use List, because it is indexed and has methods for getting elements at certain indexes.<br /><br />I also have an add(LineItem lineItem) for adding LineItem objects. Now, the implementation of next is quite simple:<br /><br />public boolean next() throws JRException {<br /> index++;<br /> return (index < data.size());<br />}<br />I increase the index by 1, and then return a boolean as to whether the index is still within the List’s bounds. JR will use this to determine if any more binding to fields in the detail band is required. Finally, the implementation of getFieldValue. First, let’s show you how to define iterating fields in your report template. You need to define fields in your detail band like this:<br /><br />< ![CDATA[$F{getItemName}]]> < ![CDATA[$F{getItemCost}]]><br />The detail band is iterated over using the custom DataSource implementation which I will show you in a moment. What is important is that you declare your textField elements along with their child textFieldExpression elements. The textFieldExpression tells the JR binding process what fields (by name) to look for in the DataSource. You can call these whatever you like, but as you can see in my case, I have decided to call them getXXX like a traditional bean accessor. Why have I done this? Well, because my LineItem object has matching accessor methods. So now let’s return to the custom DataSource implementation of getFieldValue. Here is the full listing:<br /><br />public Object getFieldValue(JRField field) throws JRException {<br /> LineItem lineItem = (LineItem) data.get(index);<br /> Object value = null;<br /> try {<br /> Object[] args = {};<br /> Class[] paramTypes = {};<br /> Class lineItemClass = lineItem.getClass();<br /> Method getMethod = lineItemClass.getDeclaredMethod(field.getName(), paramTypes);<br /> value = “” + getMethod.invoke(lineItem, args);<br /> } catch (Exception e) {<br /> throw new JRException(e.getMessage());<br /> }<br /> return value;<br />}<br />Clever huh? You don’t have to do it like this, but I have decided to use Java Reflection in order to dynamically call the appropriate LineItem method for the JRField parameter. That is why I named my textFieldExpression elements with getXXX. So, now if I were ever to add a new attribute to LineItem that I wanted in my report, I only need add it to LineItem with the accessors, and then into the report. I can leave my custom DataSource alone. One last note, I have defined all my fields as String even through my LineItem has attributes of float, int, Calendar. I am not really bothered that the report uses correct data types, but you can do that if you want, just set it up with your fields.<br /><br />Putting it all together<br /><br />So, you have hopefully got an idea about how JR works, particularly for my Purchase Order scenario. You should understand that a report template is defined by you either manually or using an editor like JasperAssistant. You will also appreciate 2 ways in which you can bind data to this report through parameters and fields. Furthermore, you have seen a clever way to use both methods in binding a master object with internal collection of elements to a report template. So now you probably want to see how to get the PDF back to the user. Well, remember that I am using a web application here but you don’t necessarily need to. First of all, I need to load my PurchaseOrder with it’s collection. You can do this however you like. In my case, I use Hibernate to load the object out of the database. PurchaseOrder po = poDAO.load(id); Now, I need to setup a parameter map for the master details<br /><br />Map parameterMap = new HashMap();<br />parameterMap.put(“orderId”, po.getOrderId());<br />parameterMap.put(“createdDate”, convertToDateString(po.getCreated()));<br />parameterMap.put(“deliveryAddress”, po.getDeliveryAddress());<br />There are a lot more! But this will do. Finally, I need to add my LineItem collection to my custom DataSource LineItemDataSource<br /><br />LineItemDataSource lineItemDataSource = new LineItemDataSource(po.getLineItems());<br />And last of all, let’s setup the response to the browser, and bind the parameter map and custom DataSource.<br /><br />response.setContentType(“application/pdf”);<br />response.addHeader(<br /> “Content-Disposition”,<br /> “attachment; filename=PO - “ + po.getReference() + “.pdf”); <br />try {<br /> JasperRunManager.runReportToPdfStream( getClass().getClassLoader().getResourceAsStream( “com/mycomp/po/pof.jasper”), response.getOutputStream(), parameters, lineItemDataSource );<br />} catch (Exception e) {<br /> e.printStackTrace(System.out);<br /> logger.error(e);<br />}<br /><br />Right, so I have used just one of the many ways in which you can bind to the report. You will of course need to find out how to compile your report template. When you author your template it is in .jrxml format and this needs to be compiled into a .jasper file which you can do either automatically with JasperAssistant, or manually with bundled tools with JR. In my example here, the compiled report is located in the class struture and I dynamically load it as an InputStream as required by the runReportToPdfStream method.<br /><br />You should examine the JR API for all the other alternatives including running PDFs to file and even doing HTML output rather than PDF. In an application you would need to use slightly different calls that can be found in the JR API also. Some of you have asked how to send the result direct to the browser. Well, that’s easy - the code above forces a Save to Disk for the PDF by using the content-disposition header, so just comment out the response.addHeader call<br /><br />/* comment the save to disk feature out so that the pdf goes straight to the browser response.addHeader("Content-Disposition", "attachment; filename=PO - " + po.getReference() + ".pdf"); */<br /><br />Conclusion<br /><br />This tutorial has covered some specific aspects of the fantastic JasperReports API that may or may not be suitable for your own projects. I hope if nothing else, it provides an insight into one way of using the API or grounds you in the basics. There is so much more to JR that I have not used myself so take time once you get the idea to look at the bundled examples and API to make sure you are making the right choices.<br /><br />JasperAssistant was an invaluable piece of kit for this job. It is quite tough getting to grips with the report template XML syntax, especially when your report needs pixel perfect alignment and so fourth. I did not go into a great deal of depth with layout elements like boxes and lines, but I have used them to draw the table boundaries around my detail LineItem band. Good luck, and if this article was helpful or not, leave a comment.make it simplehttp://www.blogger.com/profile/03356377809939814997noreply@blogger.com0tag:blogger.com,1999:blog-23078113.post-56485175029774515222008-02-29T02:07:00.000-08:002008-02-29T02:08:54.758-08:00Comparing FOP and JasperReportsAnybody looking for OSS reporting solutions in Java usually has to make a choice between Apache FOP and Jasper Reports*. While having somewhat different feature sets and addressing distinct reporting solutions, the two APIs boil down to the same basic thing : generate a report from an XML file (or stream/string/whatever). FOP has a clear advantage of standardization (based on XSL-Formatting Objects) while Jasper plays more in the pragmatic field of obtaining those 80% results with a minimum of effort and uses a proprietary XML format.<br /><br />But FOP is not a standalone reporting solution : it's just a way of transforming XSL-FO files into a report. In order to fill the report with the necessary data, the obvious choice is a templating engine such as Jakarta Velocity. Thus a FOP report creation is a two-step operation :<br /><br />create the XML report via Velocity <br />feed the XML stream to FOP <br />Jasper alleviates this problem by including its own binding engine, the only restriction being that input data should support some constraints (such as putting your 'rows' inside a JRDataSource).<br /><br />Both Jasper and FOP allow inclusion of graphic files inside, usual formats (GIF, JPEG) are supported, however FOP has a nice bonus of rendering SVG inside reports. Unfortunately, this comes with the price of using Batik SVG Toolkit, which is a bulky (close to 2MB) and rather slow API. While processing your dynamic charts as XML files (Velocity again) is a seducing idea, the abysmal performance of SVG rendering will make you give up in no time. Unfortunately, I speak from experience. <br /><br />At first sight, FOP has a lot more options for output format, compared to Jasper Reports. Of course there's PDF and direct printing via AWT, but also Postscript, PCL, MIF as well as SVG. These choices are quite intriguing, since Postscript and PCL are printing formats (easily obtained by redirecting the specific printer queue into a file), MIF is a rather obscure Adobe format (for Framemaker) and SVG … well, a SVG report is too darn slow to be useable (yes, I was foolish enough to try this, too). Jasper makes again a pragmatic choice by allowing really useful output formats such as HTML, CSV and XSL (never underestimate the power of Excel); and of course: direct printing via AWT and PDF.<br />While FOP's latest version (0.20.5) was released almost a year ago (summer 2003), Jasper Reports is bubbling with activity - Teodor releases a minor version each one or two months (latest being 0.5.3 at 18.05.2004).<br /><br />I've decided to use as a 'lab rat' one of the apps developed during my 'startup days': the client GUI is written in Swing and features a few mildly complex reports generated using Velocity+FOP. FOP version is 0.20.4 (the current version back in Q1-2003, when we had to quit dreaming about the 'next financing round' and development halted) but as I already told you FOP has evolved little since then. Though, it's perfectly reasonable to use this implementation as a witness for comparison with Jasper (on the opposite, Jasper has evolved a great deal since Q1-2003).<br /><br />Back then, the report development cycle was quite simplistic. In fact, the XSL-FO templates were written by hand inside a text editor and the application code was run (via a Junit testcase and some necessary configuration and business data mocking) in order to generate a PDF report. In the case of errors, we had feedback by examining the error traces. Visual feedback was given by the PDF output. While simple to perform, this cycle was extremely tiresome after a while as there was an important overhead : start a new JVM, initialize FOP, fire Acrobat Reader (plus we were using some crappy - even by the standards of 2003 - 1GHz machines w 256/512MB RAM). A WYSIWYG editor would have been nice, so one of my coworkers has made some research and the only solution he found was XMLSpy (Stylevision not available back then) - but, at 800USD/seat this was 'a bit' pricey** for us (only the Enterprise flavor covers FO WYSIWYG editing !?). Another interesting idea was to use one of the conversion tools (from RTF to FOP) such as Jfor, XMLMind or rtf2fo (of these products, only Jfor is free, but feature-poor). What stopped us from doing it was that the generated FO was overly complex : we needed comprehensible cut_the_crap files because we were going to integrate inside Velocity templates. And when you have tens of tags and blocks inside blocks and not the slightest idea which one is a row, which one is a column and which one is a transparent dumbass artefact, it's a gruesome trial-and-error task to integrate even simple VTL loops. And you'd have to do this each time you change something in the report : yikes ! Conclusion : the report development cycle was primitive for FOP and there was no way we could change it.<br /><br />Things are quite different for Jasper Report : there are a lot of available report designers, and some of them are free. While the complete list is on Jasper Report site, I'd like to note at least three of them :<br /><br />iReport is a Swing editor and very interesting because it's not only covering the basic Jasper functionality but also supplementary features such as barcode support (which is admittedly as easy as embedding a barcode font in Jasper with two lines of XML, but much easier to make it via a mouse click). iReport is free, which is excellent, but is a standalone app without IDE integration, and as any complex Swing app is quite slow and a memory hog. <br />if you are a developer using Eclipse, you'd appreciate two graphical editors based on Eclipse GEF, available as Eclipse plugins : JasperAssistant and SunshineReports. None of them is free and, at least on paper, the functionality seem identical, but SunshineReports has only the older 1.1 version downloadable, which is free but does NOT work with recent builds of Eclipse 3. How the heck am I supposed to test it ? On the contrary, Assistant has a much more relaxed attitude allowing the download of a free trial for the latest version of their product. Maybe too relaxed, though, because - even if (theoretically) limited in number of usages - you can use the trial as much as you want to***. But if you are serious about doing Jasper in Eclipse you should probably buy Assistant, available for a rather decent 59USD price tag. I am currently using it and it's a good tool. <br />So much for the tools, let's get the job done. The bad part : if you're experienced with FO templates, don't expect to be immediately proficient with Jasper, even with a GUI editor. The structure of an FO document has powerful analogies with HTML : you have tables, rows, cells, stuff like that, inside special constructs called blocks. It's relatively easy to use a language such as VTL in order to create nested tables, alternating colors and other data layout tricks. You can even render a tree-organized data via a recursive VTL macro, and everything is smooth and easy to understand. Jasper is completely different and at first sight you'll be shocked by its apparent lack of functionality : only rectangles, lines, ellipses, images, boilerplate text and fields (variable text). Each one of this elements has an extensive set of properties about when the element should be displayed, stretch type, associated expression for value and so on. Basically, you'd have to write Java code instead of Velocity macros and call this code from the corresponding properties of various report elements. If at the beginning it feels a little awkward, after a while it comes quite natural and simple. As for nesting and other advanced layouts, there is a powerful concept of 'subreport'. And yes I've managed to render a tree using a recursive subreport, but given the poor performance the final choice was to flatten the data into a vector then feed it into a simple Jasper report. So pay attention to the depth of 'subreporting'. <br /><br />Once the reports were completely migrated, I've benchmarked a simple one (without SVG, charts, barcodes or other 'exotic' characteristics). The test machine is a 2.4GHz P4 w 512MB Toshiba Satellite laptop. In the case of FOP, the compiled velocity template and the FOP Driver are cached between successive runs. In the case of Jasper, the report is precompiled and loaded only on first run, then refilled with new data before each generation. The lazy loading and caching of reporting engines is the cause of important time differences between the generation of the first report and the subsequent reports. Delta memory is measured after garbage collection. The values presented are median for 10 runs of the 'benchmark report'.<br /><br /> First run Subsequent runs Delta memory <br />Velocity + FOP 10365ms 381ms 850KB <br />Jasper Reports 1322ms 82ms 1012KB <br /><br />While I am totally pro-Jasper after this short experiment, it is important to note that commercial and well-maintained FO rendering engines such as RenderX XEP claim improved performance upon FOP. Depending on your requirements, environment and reporting legacy apps, an FO-based solution might be better, especially when report generation is only on server-side.make it simplehttp://www.blogger.com/profile/03356377809939814997noreply@blogger.com0tag:blogger.com,1999:blog-23078113.post-87477132628118958732008-02-29T00:51:00.000-08:002008-02-29T00:55:11.687-08:00Good advice for creating XMLThe use of XML has become widespread, but much of it is not well formed. When it is well formed, it's often of poor design, which makes processing and maintenance very difficult. And much of the infrastructure for serving XML can compound these problems. In response, there has been some public discussion of XML best practices, such as Henri Sivonen's document, "HOWTO Avoid Being Called a Bozo When Producing XML." Uche Ogbuji frequently discusses XML best practices on IBM developerWorks, and in this column, he gives you his opinion about the main points discussed in such articles.<br /><br />I have been discussing XML best practices in this column and in other series for years. Others, such as fellow columnist Elliotte Rusty Harold, have covered it as well. The more XML experts that join the discussion of XML design principles, the better, so the community can converge on solid advice for developers at all levels of XML adoption. In this article, using a recent document and a classic one, you learn more details about XML best practices.<br /><br />Enter the no bozo zone<br /><br />Henri Sivonen wrote a useful article, "HOWTO Avoid Being Called a Bozo When Producing XML" (see Resources). Adopting the perspective of XML-based Web feed formats, such as RSS and Atom, he goes over his Dos and Don'ts for producing well-formed XML with namespaces. As he says in his introduction:<br /><br /> There seem to be developers who think that well-formedness is awfully hard -- if not impossible -- to get right when producing XML programmatically and developers who can get it right and wonder why the others are so incompetent. I assume no one wants to appear incompetent or to be called names. Therefore, I hope the following list of Dos and Don'ts helps developers to move from the first group to the latter. <br /><br />The first bit of advice Henri gives is, "Don't think of XML as a text format." I think this is dangerous advice. Certainly his main point is valid -- you cannot be as careless in producing or editing XML as you would a simple text document, but this applies to all text formats with any structure. However, saying that XML is not text is denying one of the most important characteristics of XML, one that is enshrined in the very definition of XML in the specification. ("A textual object is a well-formed XML document [if it conforms to this specification.]") Henri's statement is also confusing because there is a technical definition of text in XML that is essentially the sequence of characters interpreted as XML. Text is not merely what goes within leaf elements or within attributes -- technically called character data. Text is the fundamental fabric of all XML entities, so to say that XML is not text is a contradiction. I think it's more useful to highlight the specific ways in which XML differs from text formats with which developers might already be familiar.<br /><br />This comment is an example of how Henri's advice is colored by his interest in the problem of generating well-formed Web feeds. He is right to warn people that carelessly slapping strings together and hoping they are well formed is a dangerous course. I too have written articles advising people to use mature XML toolkits rather than simple text tools when generating XML (see Resources). My concern is that the way in which Henri couches this advice is a bit confusing and could be misconstrued in the broader context of XML processing. He reiterates his advice in the sections, "Don't use text-based templates" and "Don't print". I think this should be summarized as: "Do not use mechanisms that you're not sure will result in well-formed XML." That's very important advice indeed. One approach to safe XML generation is sending SAX events, as Henri suggests in, "Use a tree or a stack (or an XML parser)." If you do so, however, do not assume you are home free. The SAX tools you use might not do all the necessary well-formedness checking. For example, some Unicode characters are not allowed in XML. You may need an additional level of checking to account for such issues.<br /><br />Henri rightly suggests that users not try to manage namespaces by hand. As I've discussed on developerWorks, XML namespaces require a great deal of care. His suggestion that developers only think in terms of universal name [namespace Uniform Resource Identifier (URI) plus local name] is generally sound, but sometimes a developer cannot avoid dealing with prefixes or XML declarations. In specifications, such as XSLT, a QName (prefix/local name combination) can be used within attribute values, and the prefix is supposed to be interpreted according to in-scope namespace declarations. This kind of pattern is called a QName in context. In this case, the developer must have control over the declared prefix or the resulting XML processing will fail. When developers do manage their own namespace declarations, the result is often messy because of the complexities of XML namespaces.<br /><br />One way to clean up namespace syntax that might become messy while passing through a pipeline of XML processing is to insert a canonicalization step to the end of the pipeline. XML canonicalization eliminates the syntactic variations permitted by XML 1.0 and XML namespaces, including different namespace declaration patterns. Canonicalization will not eliminate all the issues that make namespace declarations treacherous to developers. Canonicalization does not help with QNames in context problems since it does not change the prefixes used in a document, but it does reduce the mess of namespace declarations to the point where you can easily spot problems or even write code to automatically fix them. The GenX library, which is one of the XML generation options Henri suggests, automatically generates canonical XML, and many other toolkits provide canonicalization as an option.<br /><br />Henri's advice about Unicode and character handling is almost completely sound. However, in "Avoid adding pretty-printing white space in character data," I think the case is a bit overstated. Pretty-printing XML is safe in most cases between elements, rather than within elements with character data. As Henri says, if you have the XML in Listing 1, it is usually not safe to render it as in Listing 2.<br /><br />Listing 1. XML sample<br /><br /><foo>bar</foo><br /><br /><br /><br />Listing 2. XML sample with white space added to character data<br /><br /><foo><br /> bar<br /></foo><br /><br /><br />But it is usually safe to pretty-print the XML in Listing 3, so that the output is as in Listing 4.<br /><br />Listing 3. Another XML sample<br /><br /><doc><foo>bar</foo></doc><br /><br /><br /><br />Listing 4. XML sample in Listing 3 with white space added to character data<br /><br /><doc><br /> <foo>bar</foo><br /></doc><br /><br /><br />Many XML serializer tools understand this distinction between relatively safe and relatively unsafe pretty-printing. It is important to understand that the form of pretty-printing shown in Listings 3 and 4 can cause distortion if white space is added to mixed content. Such problems can be avoided if the serialization is guided by a schema. In practice, though, most vocabularies that use mixed content are not so sensitive to white space normalization, so don't worry too much about pretty-printing. You should be knowledgeable of the issues, and be sure there is an option to turn pretty-printing off (preferably the default should be to not pretty-print). Henri recommends a pretty-printing practice as in Listing 5, but I disagree because I think it makes for ugly markup that's not friendly to manipulation by people.<br /><br />Listing 5. Pretty-printing convention suggested by Henri Sivonen but not recommended by this author<br /><br /><foo<br /> >bar</foo<br />><br /><br /><br />From the monastery<br /><br />Switching to a very different speed, the second resource I shall explore in this article is Simon St. Laurent's "Monastic XML" (see Resources). This is a collection of brief essays with advice on how to process and even think about XML for maximum effect. Simon uses the metaphors of monasticism and asceticism to suggest that it is dangerous to load XML too heavily with baggage that does not suit its simple, textual roots. In "Marking-up at the foundation," he discusses the fundamental roles of character data and markup (elements and attributes). In "Naming things and reading names," he explains why the generic identifier (also called the element type name) is an important concept and how it should be the sole primary key to the structure of the marked-up information. Realistically, if you're using XML namespaces, the primary key is the universal name (namespace URI plus local name), and this complication is one of the reasons Simon urges caution in "Namespaces as opportunity." "Accepting the discipline of trees" calls out one of XML's dirty secrets: Even though it seems that XML's hierarchical structure could be easily extended to graph structure, in practice, the modeling of graphs in XML has proven a bit difficult. But by far the most important lesson on the "Monastic XML" site is found in "Optimizing markup for processing is always premature." XML is a declarative technology, and therein lies its strengths, as well as its frustrations, for many developers. Developers who try to pull XML design too close to the details of processing generally end up making that processing more difficult in the long term. The key to success with XML is to focus on the nature of the information that needs to be represented in the abstract separately from the technical design of the systems that need to process that information.make it simplehttp://www.blogger.com/profile/03356377809939814997noreply@blogger.com0tag:blogger.com,1999:blog-23078113.post-45708285761001158772008-02-29T00:50:00.000-08:002008-02-29T00:51:20.915-08:00Top 10 Eclipse HotkeysEclipse has lots and lots of hotkeys, but for daily work you need only a small subset. This are the hotkeys I consider to be the most important time savers:<br /><br />Moving around<br /><br /> * Ctrl+J — Incremental Search<br /> * Ctrl+Shift+T — Search a type, with search on typing. You can use only the upcase letters (e.g. type “MIL” to find MouseInputListener)<br /> * Ctrl+F6 — Switch between last used files<br /> * F3 — Open declaration<br /> * Ctrl+Alt+H — Open Call Hierarchy<br /><br />Editing<br /><br /> * Ctrl+1 — Quick Fix: press while cursor is positioned at member variable, parameter, selection, warnings, errors, …<br /> * Ctrl+Space — Context Assist: press after a ., or to use macros (for, while, sysout, …). Press in class-scope to automatically create method declarations.<br /> * Ctrl+Shift+O — Organize Imports<br /> * Ctrl+Shift+F — Reformat source<br /> * Alt+Shift+T — Show Refactor Quick Menu<br /><br />In case these hotkeys are not enough or you have forgotten which hotkey does what, you can always press Ctrl+Shift+L to get a nice list of all the hotkeys.make it simplehttp://www.blogger.com/profile/03356377809939814997noreply@blogger.com0tag:blogger.com,1999:blog-23078113.post-88319146681780285622008-02-29T00:38:00.000-08:002008-02-29T00:49:09.817-08:00Useful windows RUN Commands ...<a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhAXbGpIUE7bZPMf89bLj8kG6dd-FQkHVOe8jTv7euHZjnLsU1MDNnMALV-eAbJFUOogOrZVYGgElq9jzssnYPDima3dL4Yn5XkFA02bmgk6Z6coRpE9N-SJmxeqOahJh_1a-Ls/s1600-h/282kcv9.gif"><img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhAXbGpIUE7bZPMf89bLj8kG6dd-FQkHVOe8jTv7euHZjnLsU1MDNnMALV-eAbJFUOogOrZVYGgElq9jzssnYPDima3dL4Yn5XkFA02bmgk6Z6coRpE9N-SJmxeqOahJh_1a-Ls/s400/282kcv9.gif" border="0" alt=""id="BLOGGER_PHOTO_ID_5172321407012077506" /></a><br /> <br />To Access…. - Run Command<br />Accessibility Controls - access.cpl <br />Add Hardware Wizard - hdwwiz.cpl <br />Add/Remove Programs - appwiz.cpl <br />Administrative Tools - control admintools <br />Automatic Updates - wuaucpl.cpl <br />Bluetooth Transfer Wizard - fsquirt <br />Calculator - calc <br />Certificate Manager - certmgr.msc <br />Character Map - charmap <br />Check Disk Utility - chkdsk <br />Clipboard Viewer - clipbrd <br />Command Prompt - cmd <br />Component Services - dcomcnfg <br />Computer Management - compmgmt.msc <br />Date and Time Properties - timedate.cpl <br />DDE Shares - ddeshare <br />Device Manager - devmgmt.msc <br />Direct X Control Panel (If Installed)* - directx.cpl <br />Direct X Troubleshooter - dxdiag <br />Disk Cleanup Utility - cleanmgr <br />Disk Defragment - dfrg.msc <br />Disk Management - diskmgmt.msc <br />Disk Partition Manager - diskpart <br />Display Properties - control desktop <br />Display Properties - desk.cpl <br />Display Properties (w/Appearance Tab Preselected) - control color <br />Dr. Watson System Troubleshooting Utility - drwtsn32 <br />Driver Verifier Utility - verifier <br />Event Viewer - eventvwr.msc <br />File Signature Verification Tool - sigverif <br />Findfast - findfast.cpl <br />Folders Properties - control folders <br />Fonts - control fonts <br />Fonts Folder - fonts <br />Free Cell Card Game - freecell <br />Game Controllers - joy.cpl <br />Group Policy Editor (XP Prof) - gpedit.msc <br />Hearts Card Game - mshearts <br />Iexpress Wizard - iexpress <br />Indexing Service - ciadv.msc <br />Internet Properties - inetcpl.cpl <br />IP Configuration (Display Connection Configuration) - ipconfig /all <br />IP Configuration (Display DNS Cache Contents) - ipconfig /displaydns <br />IP Configuration (Delete DNS Cache Contents) - ipconfig /flushdns <br />IP Configuration (Release All Connections) - ipconfig /release <br />IP Configuration (Renew All Connections) - ipconfig /renew <br />IP Configuration (Refreshes DHCP & Re - Registers DNS) - ipconfig /registerdns <br />IP Configuration (Display DHCP Class ID) - ipconfig /showclassid <br />IP Configuration (Modifies DHCP Class ID) - ipconfig /setclassid <br />Java Control Panel (If Installed) - jpicpl32.cpl <br />Java Control Panel (If Installed) - javaws <br />Keyboard Properties - control keyboard <br />Local Security Settings - secpol.msc <br />Local Users and Groups - lusrmgr.msc <br />Logs You Out Of Windows - logoff <br />Microsoft Chat - winchat <br />Minesweeper Game - winmine <br />Mouse Properties - control mouse <br />Mouse Properties - main.cpl <br />Network Connections - control netconnections <br />Network Connections - ncpa.cpl <br />Network Setup Wizard - netsetup.cpl <br />Notepad - notepad <br />Nview Desktop Manager (If Installed) - nvtuicpl.cpl <br />Object Packager - packager <br />ODBC Data Source Administrator - odbccp32.cpl <br />On Screen Keyboard - osk <br />Opens AC3 Filter (If Installed) - ac3filter.cpl <br />Password Properties - password.cpl <br />Performance Monitor - perfmon.msc <br />Performance Monitor - perfmon <br />Phone and Modem Options - telephon.cpl <br />Power Configuration - powercfg.cpl <br />Printers and Faxes - control printers <br />Printers Folder - printers <br />Private Character Editor - eudcedit <br />Quicktime (If Installed) - QuickTime.cpl <br />Regional Settings - intl.cpl <br />Registry Editor - regedit <br />Registry Editor - regedit32 <br />Remote Desktop - mstsc <br />Removable Storage - ntmsmgr.msc <br />Removable Storage Operator Requests - ntmsoprq.msc <br />Resultant Set of Policy (XP Prof) - rsop.msc <br />Scanners and Cameras - sticpl.cpl <br />Scheduled Tasks - control schedtasks <br />Security Center - wscui.cpl <br />Services - services.msc <br />Shared Folders - fsmgmt.msc <br />Shuts Down Windows - shutdown <br />Sounds and Audio - mmsys.cpl <br />Spider Solitare Card Game - spider <br />SQL Client Configuration - cliconfg <br />System Configuration Editor - sysedit <br />System Configuration Utility - msconfig <br />System File Checker Utility (Scan Immediately) - sfc /scannow <br />System File Checker Utility (Scan Once At Next Boot) - sfc /scanonce <br />System File Checker Utility (Scan On Every Boot) - sfc /scanboot <br />System File Checker Utility (Return to Default Setting) - sfc /revert <br />System File Checker Utility (Purge File Cache) - sfc /purgecache <br />System File Checker Utility (Set Cache Size to size x) - sfc /cachesize=x <br />System Properties - sysdm.cpl <br />Task Manager - taskmgr <br />Telnet Client - telnet <br />User Account Management - nusrmgr.cpl <br />Utility Manager - utilman <br />Windows Firewall - firewall.cpl <br />Windows Magnifier - magnify <br />Windows Management Infrastructure - wmimgmt.msc<br />Windows System Security Tool - syskey <br />Windows Update Launches - wupdmgr <br />Windows XP Tour Wizard - tourstart <br />Wordpad - writemake it simplehttp://www.blogger.com/profile/03356377809939814997noreply@blogger.com0tag:blogger.com,1999:blog-23078113.post-50851439079465154482008-02-29T00:36:00.000-08:002008-02-29T00:37:47.064-08:00Java Performance TuningI Love Binary Search (Page last updated June 2006, Added 2006-06-29, Author Tim Bray, Publisher Tim Bray). Tips:<br /><br /> * Binary search is O(log2(N)). This means that a 1 ms search of a million items, will take 1.05ms to search 2 million, 1.10ms to search 4 million, and a whole 1.301ms when you get up to 64 million!<br /> * In absolute terms, a simple O(log2(N)) routine is often faster than a more complex O(1) routine up to any usable size of structure.<br /> * With tree structures you can potentially search really large data sets, too large to fit into memory, using persistent on-disk structures.<br /> * Binary search has minimal memory requirements.<br /> * Binary search is simple enough that you can implement specialized searches that directly reference internal structures (which can avoid unecessary access overheads, though a JIT might eliminate those anyway)<br /> * Memory is cheap, virtual memory mapping is efficient and pages in data, so memory mapping a file could be an efficient way to access a huge data structure.<br /> * You can write a bunch of complicated code to manage the on-disk vs. in-memory parts of your data, or you can pretend it's all in memory and use memory mapped files to take care of the details - and any increase in RAM transparently improves performance. <br /><br />http://weblogs.java.net/blog/jfarcand/archive/2006/05/tricks_and_tips_1.html<br />Why you must handle NIO OP_WRITE (Page last updated May 2006, Added 2006-06-29, Author Jean-Francois Arcand, Publisher java.net). Tips:<br /><br /> * When the write buffer is full, SocketChannel.write will return 0, and this needs to be handled in such a way that avoids CPU cycling.<br /> * Obtaining a globally pooled object seems to be quicker than getting a thread local one.<br /> * Checking select to see if a channel is writable in a separate thread can be more efficient than merging the select to the main select call then spinning off to a write thread (and maintaining the writable data accessible across threads) when it is writable - assuming clients are not normally slow consumers.<br /> * Check for 0 (slow client) and -1 (disconnected client) from Selector.select() calls to handle slow/bad clients.<br /> * Time 0 returns (slow client) and check for -1 (disconnected client) from Channel.read - if too many 0's, then maybe explicitly close the client as it is too slow producing data, and is consuming resources. <br /><br />http://weblogs.java.net/blog/jfarcand/archive/2006/06/tricks_and_tips.html<br />Why SelectionKey.attach() is evil (Page last updated June 2006, Added 2006-06-29, Author Jean-Francois Arcand, Publisher java.net). Tips:<br /><br /> * Under load you might end up with 10 000 connections, so 10 000 active SelectionKeys. If they all have a ByteBuffer or other attachment, then a lot of memory will be consumed, reducing your scalability and having fun eating all your memory.<br /> * Use SelectionKey.channel() to retrieve the SocketChannel, rather than having separate support in your framework.<br /> * Leave a socket read on its own thread for a configurable length of time, assuming (optimistically) that the read will complete soon enough and allow you to avoid moving the data across to the generic selector thread.<br /> * If a socket read is taking too long to get all the data, you can move the data (ByteBuffer) across to the generic selector thread (e.g. attached to the selector). In tests with Grizzly, on slow a network, with broken clients, etc., blocking read Threads scale better than moving a dormant ByteBuffer to the main selector thread.<br /> * Aim to have one ByteBuffer per Thread, not per selector - this significantly improves scalability by not overloading the VM with dormant ByteBuffers. <br /><br />http://www.ddj.com/dept/java/188700760<br />Java 5 & 6 features (Page last updated June 2006, Added 2006-06-29, Author Matt Love, Publisher DrDobbs). Tips:<br /><br /> * The String concatenator operator (+, +=) should be avoided.<br /> * StringBuilder is faster than StringBuffer, but not synchronized.<br /> * Autoboxing imposes an order of magnitude overhead.<br /> * Java 6 provides useful speedups, especially if escape analysis optimizes away object creation. <br /><br />http://www.javaworld.com/javaworld/jw-06-2006/jw-0619-tuning.html<br />Common Java EE performance problems (Page last updated June 2006, Added 2006-06-29, Author Steven Haines, Publisher Javaworld). Tips:<br /><br /> * If the garbage collector cannot free enough memory to hold the new object, then it throws an OutOfMemoryError.<br /> * Out-of-memory errors are associated with: application server crashes; Degraded performance; or seemingly endless repeated garbage collections that nearly halts processing and usually leads to an application server crash.<br /> * A Java memory leak is the result of maintaining a lingering reference to an unused object: you are finished using an object, but because one or more other objects still reference that object, so the garbage collector cannot reclaim its memory.<br /> * The following settings are recommended for monitoring garbage collection in a Sun JVM: -verbose:gc -xloggc:gc.log -XX:+PrintGCDetails -XX:+PrintGCTimeStamps. Sun reports the overhead for this level of logging at approximately 5 percent.<br /> * To determine the cause of a memory leak, run your application in a memory profiler and: Execute the use-case; Take a snapshot of the heap; Execute the use-case again; Take another snapshot of the heap; Compare the two heap snapshots and look for objects that should not remain in the heap after executing the use-case<br /> * Wait until your application reaches this steady state prior to performing any trend analysis on the heap.<br /> * Memory leaks from Web requests usually come from sessions. Look at: Page scope; Request scope; Session scope; Application scope; Static variables; Long-lived class variables; the HttpServletRequest object; the servlet init() method.<br /> * Page- or request-scoped variables are automatically cleaned up before a web request completes.<br /> * A workaround for large sessions is to increase the heap or decrease the session time-out.<br /> * Store the minimum information in session-scoped variables.<br /> * Explicitly invalidate sessions when users log out.<br /> * Tune session time-out.<br /> * Classes are loaded into Perm Space, and if this fills up, a full GC is triggered. With -noclassgc, no classes will be deleted from Perm space. This can lead to continual full GCs for no apparent reason.<br /> * Perm space of 128m is reasonable, 256m reasonable if you have a particularly large number of (generated) classes. 512m suggests an architectural problem.<br /> * After tuning memory, the tuning option with the biggest impact in an application server is the size of the execution thread pool.<br /> * Too small a thread pool will leave requests waiting in the queue for processing; too large and the CPU could spend too much time context switching.<br /> * Tune the thread pool size by looking at CPU utilization, the thread pool utilization and the number of pending requests (queue depth).<br /> * The recommendation for a starting point when tuning thread pool size is between 50 and 75 threads per CPU.<br /> * Garbage collection causes CPU spikes, while saturated thread pools (thread pool size too large) cause consistently high CPU utilization.<br /> * A saturated CPU results in abysmal performance across the board, and performance is better if a request arrives, waits in a queue, and then is processed optimally. Aim for CPU between 75 and 85 percent utilized during normal user load.<br /> * If an application is using too much CPU after thread pool tuning, you need to either tune the application code with a code profiler, or add additional hardware.<br /> * Tune database connection pool so that utilization is running at 70 to 80 percent during average load and threads are rarely observed waiting for a connection. But avoid overloading the database.<br /> * Make sure the prepared statement cache in the database is sufficiently large to cache all plans.<br /> * Tune your cache sizes to optimize successful cache hits. Avoid cache thrashing - a low ratio of hits to miss on the cache.<br /> * Minimize the number of transaction rollbacks. <br /><br />http://www.developer.com/java/other/article.php/3609776<br />Using the Full-Screen Exclusive Mode API in Java (Page last updated May 2006, Added 2006-06-29, Author Richard G. Baldwin, Publisher developer.com). Tips:<br /><br /> * The Full-Screen Exclusive Mode API allows you to write Java programs that take over the entire screen.<br /> * Active rendering is more responsive than passive rendering, and is usually used with full screen mode applications.make it simplehttp://www.blogger.com/profile/03356377809939814997noreply@blogger.com0tag:blogger.com,1999:blog-23078113.post-10037089921491702672008-02-29T00:31:00.000-08:002008-02-29T00:36:07.281-08:00Native file locks in javaJava 1.4 introduced the native io layer into the JDK. One of the nice things you can do with it is to execute a native file lock that gets acknowledged by both “fcntl”- and “flock”-style locking. This is tremendously helpful if you need to share resources with native programs. So what is in C<br /><br /><br /> int fd = open("/path/to/file", O_RDWR);<br /><br /> if (flock(fd,LOCK_EX) != 0 ) { ... }<br /><br /> printf("locked file\\npress return");<br /> char c = getchar();<br /><br /> if (flock(fd,LOCK_UN) != 0 ) { ... }<br /><br /> printf("released file\\n");<br /> close(fd);<br /><br /><br /> int fd = open("/path/to/file", O_RDWR);<br /><br /> struct flock lock;<br /> lock.l_type = F_WRLCK;<br /> lock.l_whence = SEEK_SET;<br /> lock.l_start = 0;<br /> lock.l_len = 0;<br /> lock.l_pid = 0;<br /><br /> if (fcntl(fd, F_SETLK, &lock) == -1) { ... }<br /><br /> printf("locked file\\npress return");<br /> char c = getchar();<br /><br /> lock.l_type = F_UNLCK;<br /><br /> if (fcntl(fd, F_SETLK, &lock) == -1) { ... }<br /><br /> printf("released file\\n");<br /> close(fd);<br /><br />becomes this in java<br /><br /><br />File file = new File("/path/to/file");<br />FileChannel channel = new RandomAccessFile(file, "rw").getChannel();<br />FileLock lock = channel.lock();<br /><br />System.out.println("locked file\\npress return");<br />System.in.read();<br /><br />lock.release();<br />System.out.println("released file\\n");make it simplehttp://www.blogger.com/profile/03356377809939814997noreply@blogger.com0tag:blogger.com,1999:blog-23078113.post-12748185841588235412008-02-29T00:25:00.000-08:002008-02-29T00:30:39.785-08:00World's fastest supercomputers (Blue gene/L)<a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg2qS1fAYxkFHK6_2flvUxucvJ1NvnMUoLksfLEwQ915rlltWfXcI3sUDqxb_LnFU5gzpV9YleA0GoHME-01Tjde-uTOLFFCgNlChTOqgrdjHra8QGbzREPvAesYMisrgaerCWy/s1600-h/!cid_000701c87770$2476d830$4e64a8c0@gehan.jpg"><img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg2qS1fAYxkFHK6_2flvUxucvJ1NvnMUoLksfLEwQ915rlltWfXcI3sUDqxb_LnFU5gzpV9YleA0GoHME-01Tjde-uTOLFFCgNlChTOqgrdjHra8QGbzREPvAesYMisrgaerCWy/s400/!cid_000701c87770$2476d830$4e64a8c0@gehan.jpg" alt="" id="BLOGGER_PHOTO_ID_5172316321770799010" border="0" /></a><br /><br /><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi6Fo0KrI-ywf69r2Nu_etmpZUO-M7O1t6maJUQivSWVoSD40gjjCFPv1O2IRr5b1aS0A5hKl1y97NlbUGFR-66RRI1D4UawZ2o5eZX3LgIBEflxqheF6XSSoWnBWIEExMEhNz9/s1600-h/!cid_000401c87770$24746730$4e64a8c0@gehan.jpg"><img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi6Fo0KrI-ywf69r2Nu_etmpZUO-M7O1t6maJUQivSWVoSD40gjjCFPv1O2IRr5b1aS0A5hKl1y97NlbUGFR-66RRI1D4UawZ2o5eZX3LgIBEflxqheF6XSSoWnBWIEExMEhNz9/s400/!cid_000401c87770$24746730$4e64a8c0@gehan.jpg" alt="" id="BLOGGER_PHOTO_ID_5172315780604919666" border="0" /></a><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgDNoL6joMXyz7lJCLDDdXeEudp_2KnoIxQQ6bM14-iXbbEiKiHFvOoNBqqBrQyXgV3jqoJEmkMUfz2X519khSD916r20Ly_dh4b3xTflNtec8qRYt-LSbrsY8W1jK87hG1NKpU/s1600-h/!cid_000601c87770$2476d830$4e64a8c0@gehan.jpg"><img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgDNoL6joMXyz7lJCLDDdXeEudp_2KnoIxQQ6bM14-iXbbEiKiHFvOoNBqqBrQyXgV3jqoJEmkMUfz2X519khSD916r20Ly_dh4b3xTflNtec8qRYt-LSbrsY8W1jK87hG1NKpU/s400/!cid_000601c87770$2476d830$4e64a8c0@gehan.jpg" alt="" id="BLOGGER_PHOTO_ID_5172316188626812818" border="0" /></a><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgHKO6JZWZuce9FZZ0qo8ppYDSL7SfcBYjaqHR96S9qBSCrGksQI4VKeU3tJF9nP8IKki7GNxB1LktOQgbw-HhLjEdbCc4Xn6YTbMzvIgpak-5UYCtW-9nprEms_B0XqWjh4pj5/s1600-h/!cid_000501c87770$2476d830$4e64a8c0@gehan.jpg"><img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgHKO6JZWZuce9FZZ0qo8ppYDSL7SfcBYjaqHR96S9qBSCrGksQI4VKeU3tJF9nP8IKki7GNxB1LktOQgbw-HhLjEdbCc4Xn6YTbMzvIgpak-5UYCtW-9nprEms_B0XqWjh4pj5/s400/!cid_000501c87770$2476d830$4e64a8c0@gehan.jpg" alt="" id="BLOGGER_PHOTO_ID_5172315905158971266" border="0" /></a><br /><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg5IkaWCKfYH-HX-ROKJ8rnbAxNDCe8BqjerC2svTBCDEEe-6tR5n437ug9Ff-OQAwUpVwZMf3zTMQM1mpwIPdK0dxL5QcIePujAJBWTQeLjwqNGgC1Z_rDnfZX54VKAJ7FgoUh/s1600-h/!cid_000801c87770$2476d830$4e64a8c0@gehan.jpg"><img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg5IkaWCKfYH-HX-ROKJ8rnbAxNDCe8BqjerC2svTBCDEEe-6tR5n437ug9Ff-OQAwUpVwZMf3zTMQM1mpwIPdK0dxL5QcIePujAJBWTQeLjwqNGgC1Z_rDnfZX54VKAJ7FgoUh/s400/!cid_000801c87770$2476d830$4e64a8c0@gehan.jpg" alt="" id="BLOGGER_PHOTO_ID_5172316446324850610" border="0" /></a>make it simplehttp://www.blogger.com/profile/03356377809939814997noreply@blogger.com0tag:blogger.com,1999:blog-23078113.post-33196376294902678252008-02-29T00:22:00.000-08:002008-02-29T00:25:11.329-08:00Secuirty problem casts doubt on E-passports<table align="center" border="0" cellpadding="0" cellspacing="0" width="50%"><tbody><tr><td height="10"><br /></td> </tr> </tbody></table> <p><span id="Zoom"> </span></p><p> <table style="width: 223px; height: 202px;" align="left" border="0" cellpadding="0" cellspacing="0" height="202" width="223"> <tbody> <tr> <td><img style="width: 283px; height: 213px;" alt="A recent demonstration shows that the hi-tech biometric E-passports could be hacked and information embedded could be copied and transferred to another device, which threw in doubt the passport-upgrading scheme used by the U.S., UK and other countries." src="http://news.xinhuanet.com/english/2006-08/07/xinsrc_2720803071026312245952.jpg" border="0" hspace="0" /></td></tr> <tr> <td><span style="color: rgb(0, 0, 128);font-size:85%;" >A sample of E-passport reader. (File Photo)</span></td></tr></tbody></table></p> <p><span id="Zoom"> BEIJING, Aug. 7 (Xinhuanet) -- A demonstration showed the hi-tech biometric E-passports could be hacked and information embedded could be copied and transferred to another device.</span></p> <p><span id="Zoom"> This threw in doubt the passport-upgrading scheme used by the U.S., UK and other countries.</span></p> <p><span id="Zoom"> Speaking Sunday at the Defcon security conference in Las Vegas, Lukas Grunwald, a consultant with a German security company, said he had discovered a method for cloning the information stored in the new passports.</span></p> <p><span id="Zoom"> Data can be transferred onto blank chips, which could then be implanted in fake passports, a flaw which he said undermined the project.</span></p> <p><span id="Zoom"> But the findings do not mean that all biometric information could be faked or altered by criminals. Although the data held on a passport chip is not encrypted, it is not yet possible to change the cloned data without alerting the authorities.</span></p> <p><span id="Zoom"> Grunwald said his discovery was made within two weeks of first attempting to copy the data, and the equipment used cost 200 U.S. dollors. It is believed the hacking principle could be applied to any new passport issued in Britain, the US and other countries. </span></p> <p><span id="Zoom"> It is the latest research to raise concerns about the growing use of RFID, short for radio-frequency identification, a technology that allows everyday objects such as store merchandise, livestock and security documents to beam electronic data to computers equipped with special antennas.</span></p> <p><span id="Zoom"> Germany already used RFID in passports to help border officials guard against forgeries and automate the processing of international visitors. U.S. officials plan to start embedding RFID in passports in October. Since March anyone applying for a UK passport has been issued with a biometric version, which contains physical identification information. Enditem </span></p>make it simplehttp://www.blogger.com/profile/03356377809939814997noreply@blogger.com0