1: \documentclass[twocolumn,twoside,slac]{revtex4}
2: \usepackage{graphicx}
3: \usepackage{fancyhdr}
4: \pagestyle{fancy}
5: \fancyhead{}
6: \fancyhead[C]{\it {CHEP'03 in La Jolla, March 2003}}
7: \fancyhead[RO,LE]{\thepage}
8: \fancyfoot{}
9: \fancyfoot[LE,LO]{\bf TUKT005}
10: \renewcommand{\headrulewidth}{0pt}
11: \renewcommand{\footrulewidth}{0pt}
12: \renewcommand{\sfdefault}{phv}
13: \def\tablename{Listing}
14:
15: \setlength{\textheight}{235mm}
16: \setlength{\textwidth}{170mm}
17: \setlength{\topmargin}{-20mm}
18:
19: \bibliographystyle{apsrev}
20:
21: \begin{document}
22:
23: \title{Transparent Persistence with Java Data Objects}
24:
25: \author{Julius H\v{r}ivn\'{a}\v{c}}
26: \affiliation{LAL, Orsay, France}
27:
28: \begin{abstract}
29: Flexible and performant Persistency Service is a necessary component of any HEP
30: Software Framework. The building of a modular, non-intrusive and performant
31: persistency component have been shown to be very difficult task. In the past,
32: it was very often necessary to sacrifice modularity to achieve acceptable
33: performance. This resulted in the strong dependency of the overall Frameworks
34: on their Persistency subsystems.
35:
36: Recent development in software technology has made possible to build a
37: Persistency Service which can be transparently used from other Frameworks.
38: Such Service doesn't force a strong architectural constraints on the overall
39: Framework Architecture, while satisfying high performance requirements. Java
40: Data Object standard (JDO) has been already implemented for almost all major
41: databases. It provides truly transparent persistency for any Java object
42: (both internal and external). Objects in other languages can be handled
43: via transparent proxies. Being only a thin layer on top of a used database,
44: JDO doesn't introduce any significant performance degradation. Also
45: Aspect-Oriented Programming (AOP) makes possible to treat persistency as
46: an orthogonal Aspect of the Application Framework, without polluting it
47: with persistence-specific concepts.
48:
49: All these techniques have been developed primarily (or only) for the Java
50: environment. It is, however, possible to interface them transparently to
51: Frameworks built in other languages, like for example C++.
52:
53: Fully functional prototypes of flexible and
54: non-intrusive persistency modules have been build for several
55: other packages, as for example FreeHEP AIDA and LCG Pool AttributeSet
56: (package Indicium).
57: \end{abstract}
58:
59: \maketitle
60:
61: \thispagestyle{fancy}
62:
63: \section{JDO}
64:
65: \subsection{Requirements on Transparent Persistence}
66:
67: The Java Data Object (JDO)~\cite{JDO1},\cite{JDO2},\cite{Standard},\cite{Portal}
68: standard has been created to satisfy several requirements on
69: the object persistence in Java:
70: \begin{itemize}
71: \item {\bf Object Model independence on persistency}:
72: \begin{itemize}
73: \item Java types are automatically mapped to native storage types.
74: \item 3rd party objects can be persistified (even when their source is not
75: available).
76: \item The source of the persistent class is the same as the source of the transient
77: class. No additional code is needed to make a class persistent.
78: \item All classes can be made persistent (if it has a sense).
79: \end{itemize}
80: \item {\bf Illusion of in-memory access to data}:
81: \begin{itemize}
82: \item Dirty instances (i.e. objects which have been changed after they have
83: been read) are implicitly updated in the database.
84: \item Catching, synchronization, retrieval and lazy loading are done
85: automatically.
86: \item All objects, referenced from a persistent object, are automatically
87: persistent ({\em Persistence by reachability}).
88: \end{itemize}
89: \item {\bf Portability across technologies}:
90: \begin{itemize}
91: \item A wide range of storage technologies (relational databases, object-oriented
92: databases, files,\dots) can be transparently used.
93: \item All JDO implementations are exchangeable.
94: \end{itemize}
95: \item {\bf Portability across platforms} is automatically available in
96: Java.
97: \item {\bf No need for a different language} (DDL, SQL,\dots) to handle
98: persistency (incl. queries).
99: \item {\bf Interoperability with Application Servers} (EJB~\cite{EJB},\dots).
100: \end{itemize}
101:
102: \subsection{Architecture of Java Data Objects}
103:
104: The Java Data Objects standard (Java Community Process Open Standard JSR-12)~\cite{Standard} has
105: been created to satisfy the requirements listed in the previous paragraph.
106:
107: \begin{figure*}[!]
108: \centering
109: \includegraphics[width=135mm]{Enhancement.eps}
110: \caption{JDO Enhancement.}
111: \label{Enhancement}
112: \end{figure*}
113:
114: The persistence capability is added to a class by the Enhancer
115: (as shown in Figure~\ref{Enhancement}):
116: \begin{itemize}
117: \item Enhancer makes a transient class PersistenceCapable by adding it all data and
118: methods needed to provide the persistence functionality. After enhancement,
119: the class implements PersistenceCapable interface (as shown in Figure~\ref{PersistenceCapable}).
120: \item Enhancer is generally applied to a class-file, but it can be also part
121: of a compiler or a loader.
122: \item Enhancing effects can be modified via Persistence Descriptor (XML file).
123: \item All enhancers are compatible. Classes enhanced with one JDO
124: implementation will work automatically with all other implementations.
125: \end{itemize}
126:
127: \begin{figure}[!]
128: \centering
129: \includegraphics[width=80mm]{PersistenceCapable.eps}
130: \caption{Enhancer makes any class PersistenceCapable.}
131: \label{PersistenceCapable}
132: \end{figure}
133:
134: The main object, a user interacts with, is the PersistenceManager. It mediates
135: all interactions with the database,
136: it manages instances lifecycle and it serves as a factory for Transactions,
137: Queries and Extents (as described in Figure~\ref{PersistenceManager}).
138:
139: \begin{figure}[!]
140: \centering
141: \includegraphics[width=80mm]{PersistenceManager.eps}
142: \caption{All interactions with JDO are mediated by PersistenceManager.}
143: \label{PersistenceManager}
144: \end{figure}
145:
146: \subsection{Available Implementations}
147:
148: After about a year since the JDO standardization, there are already many
149: implementations available supporting all existing storage technologies.
150:
151: \subsection{JDO Implementations}
152:
153: \subsubsection{Commercial JDO Implementations}
154:
155: Following commercial implementations of JDO standard exist:
156:
157: enJin(Versant), FastObjects(Poet), FrontierSuit(ObjectFrontier),
158: IntelliBO (Signsoft), JDOGenie(Hemisphere), JRelay(Object Industries),
159: KODO(SolarMetric), LiDO(LIBeLIS), OpenFusion(Prism), Orient(Orient),
160: PE:J(HYWY), \dots
161:
162: These implementation often have a free community license available.
163:
164: \subsubsection{Open JDO Implementations}
165:
166: There are already several open JDO implementations available:
167: \begin{itemize}
168: \item {\bf JDORI}~\cite{JDORI} (Sun) is the reference and standard implementation. It
169: currently only works with the FOStore files. Support for a relational database
170: via JDBC implementation is under
171: development. It is the most standard, but not the most performant implementation.
172: \item {\bf TJDO}~\cite{TJDO} (SourceForge) is a high quality implementation originally written
173: by the TreeActive company, later put on the GPL license. It supports all important
174: relational databases. It supports an automatic creation of the database schema. It
175: implements full JDO standard.
176: \item {\bf XORM}~\cite{XORM} (SourceForge) does not yet support full JDO standard. It
177: does not automatically generate a database schema, on the other hand, it allows
178: a reuse of existing schemas.
179: \item {\bf JORM}~\cite{JORM} (JOnAS/ObjectWeb) has a fully functional object-relational
180: mapping, the full JDO implementation is under development.
181: \item {\bf OJB}~\cite{OJB} (Apache) has a mature object-relational engine. Full JDO interface
182: is not yet provided.
183: \end{itemize}
184:
185: \subsection{Supported Databases}
186:
187: All widely used databases are already supported either by their provider or by
188: a third party:
189: \begin{itemize}
190: \item {\bf RDBS and ODBS}: Oracle, MS SQL Server, DB2, PointBase, Cloudscape,
191: MS Access, JDBC/ODBC Bridge, Sybase, Interbase, InstantDB, Informix, SAPDB,
192: Postgress, MySQL, Hypersonic SQL, Versant,\dots
193: \item {\bf Files}: XML, FOSTORE, flat, C-ISAM,\dots
194: \end{itemize}
195: The performance of JDO implementations is determined by the native performance of
196: a database. JDO itself introduces a very small overhead.
197:
198: \section{HEP Applications using JDO}
199:
200: \subsection{Trivial Application}
201:
202: A simple application using JDO to write and read data is shown in Listing~\ref{Trivial}.
203:
204: \begin{table*}[!]
205: \begin{center}
206: \begin{tabular}{|l|}
207: \hline
208: $//\ Initialization$ \\
209: $PersistenceManagerFactory\ pmf = JDOHelper.getPersistenceManagerFactory(properties);$ \\
210: $PersistenceManager\ pm = pmf.getPersistenceManager();$ \\
211: $Transaction\ tx = pm.currentTransaction();$ \\
212: \\
213: $//\ Writing$ \\
214: $tx.begin();$ \\
215: $\dots$ \\
216: $Event\ event = \dots;$ \\
217: $pm.makePersistent(event);$ \\
218: $\dots$ \\
219: $tx.commit();$ \\
220: \\
221: $//\ Searching\ using\ Java-like\ query\ language\ translated\ internally\ to\ DB\ native\ query\ language$ \\
222: $//\ (SQL\ available\ too\ for\ RDBS)$ \\
223: $tx.begin();$ \\
224: $Extent\ extent = pm.getExtent(Track.class, true);$ \\
225: $String\ filter = "pt > 20.0";$ \\
226: $Query\ query = pm.newQuery(extent, filter);$ \\
227: $Collection\ results = query.execute();$ \\
228: $\dots$ \\
229: $tx.commit();$ \\
230: \hline
231: \end{tabular}
232: \caption{Trivial example of using JDO.}
233: \label{Trivial}
234: \end{center}
235: \end{table*}
236:
237: \subsection{Indicium}
238:
239: Indicium~\cite{Indicium} has been created to satisfy the LCG~\cite{LCG}
240: Pool~\cite{Pool} requirements on the Metadata management:
241: ``To define, accumulate, search, filter and manage Attributes (Metadata)
242: external/additional to existing (Event) data.'' Those metadata are a generalization
243: of the traditional Paw ntuple concept. They are used in the first phase of the analysis
244: process to make a pre-selection of Event for further processing. They should be
245: efficient. They are apparently closely related to Collections (of Events).
246:
247: The Indicium package provides an implementation of the AttributeSet (Event
248: Metadata, Tags) for the LCG/Pool project in Java and C++ (with the same API).
249: The core of Indicium is implemented in Java.
250:
251: All expressed requirements can only be
252: well satisfied by the system which allows in principle any object to act
253: as an AttributeSet. Such system can be easily built when we realize that
254: mentioned requirements are satisfied by JDO:
255: \begin{itemize}
256: \item {\bf AttributeSet} is simply any Object with a reference to another
257: (Event) Object.
258: \item {\bf Explicit Collection} is just any standard Java Collection.
259: \item {\bf Implicit Collection} (i.e. all objects of some type T within a
260: Database) is directly the JDO Extent.
261: \end{itemize}
262:
263: Indicium works with any JDO/DB implementation. As all the requirements are
264: directly satisfied by the JDO itself, the Indicium only implements a simple
265: wrapper and a code for database management (database creation, opening, \dots).
266: That is in fact the only database-specific code.
267:
268: It is easy to switch between various JDO/DB implementations via a simple
269: properties file. The default Indicium implementation contains configuration for
270: JDORI with FOStore file format and TJDO with Cloudscape or MySQL
271: databases, others are simple to add.
272:
273: The data stored by Indicium are accessible also via native database protocols
274: (like JDBC or SQL) and tools using them.
275:
276: As it has been already mentioned, Indicium provides just a simple convenience
277: layer on top of JDO trying to capture standard AttributeSet usage
278: patterns. There are four ways how AttributeSet can be defined:
279: \begin{itemize}
280: \item {\bf Assembled} AttributeSet is fully constructed at run-time in a way
281: similar to classical Paw ntuples.
282: \item {\bf Generated} AttributeSet class is generated from a simple XML
283: specification.
284: \item {\bf Implementing} AttributeSet can be written by hand to implement
285: the standard AttributeSet Interface.
286: \item {\bf FreeStyle} AttributeSet can be just about any class. It can be managed
287: by the Indicium infrastructure, only some convenience functionality may be
288: lost.
289: \end{itemize}
290:
291: To satisfy also the requirements of C++ users, the C++ interface of Indicium has been
292: created in the form of JACE~\cite{JACE} proxies. This way, C++ users can directly use Indicium
293: Java classes from a C++ program. CIndicium Architecture is shown in Figure~\ref{AttributeSet},
294: an example of its use is shown in Listing~\ref{CIndicium}.
295:
296: \begin{figure*}[!]
297: \centering
298: \includegraphics[width=135mm]{AttributeList.eps}
299: \caption{CIndicium - C++ interface to Indicium.}
300: \label{AttributeSet}
301: \end{figure*}
302:
303: \begin{table*}[!]
304: \begin{center}
305: \begin{tabular}{|l|}
306: \hline
307: $//\ Construct\ Signature$ \\
308: $Signature\ signature("AssembledClass");$ \\
309: $signature.add("j", "int", "Some Integer Number");$ \\
310: $signature.add("y", "double", "Some Double Number");$ \\
311: $signature.add("s", "String", "Some String");$ \\
312: \\
313: $//\ Obtain\ Accessor\ to\ database$ \\
314: $Accessor\ accessor = AccessorFactory::createAccessor("MyDB.properties");$ \\
315: \\
316: $//\ Create\ Collection$ \\
317: $accessor.createCollection("MyCollection", signature, true);$ \\
318: \\
319: $//\ Write\ AttributeSets\ into\ database$ \\
320: $AssembledAttributeSet*\ as;$ \\
321: $for (int\ i = 0; i < 100; i++) \{$ \\
322: $\ \ as = new\ AssembledAttributeSet(signature);$ \\
323: $\ \ as->set("j", ...);$ \\
324: $\ \ as->set("y", ...);$ \\
325: $\ \ as->set("s", ...);$ \\
326: $\ \ accessor.write(*as);$ \\
327: $\ \ \}$ \\
328: \\
329: $//\ Search\ database$ \\
330: $std::string\ filter = "y > 0.5";$ \\
331: $Query\ query = accessor.newQuery(filter);$ \\
332: $Collection\ collection = query.execute();$ \\
333: $std::cout << "First: " << collection.toArray()[0].toString() << std::endl;$ \\
334: \hline
335: \end{tabular}
336: \caption{Example of CIndicium use.}
337: \label{CIndicium}
338: \end{center}
339: \end{table*}
340:
341: \subsection{AIDA Persistence}
342:
343: JDO has been used to provide a basic persistency service for the FreeHEP~\cite{FreeHEP} reference
344: implementation of AIDA~\cite{AIDA}. Three kinds of extension to the existing implementation
345: have been required:
346: \begin{itemize}
347: \item Implementation of the IStore interface as AidaJDOStore.
348: \item Creation of the XML description for each AIDA class (for example see Listing~\ref{AIDA}).
349: \item Several small changes to exiting classes, like creation of wrappers around
350: arrays of primitive types, etc.
351: \end{itemize}
352:
353: \begin{table*}[!]
354: \begin{center}
355: \begin{tabular}{|l|}
356: \hline
357: $<jdo>$ \\
358: $\ \ <package\ name="hep.aida.ref.histogram">$ \\
359: $\ \ \ \ <class\ name="Histogram2D"$ \\
360: $\ \ \ \ \ \ \ persistence-capable-superclass="hep.aida.ref.histogram.Histogram">$ \\
361: $\ \ \ \ \ \ \ </class>$ \\
362: $\ \ \ \ </package>$ \\
363: $\ \ </jdo>$ \\
364: \hline
365: \end{tabular}
366: \caption{Example of JDO descriptor for AIDA class.}
367: \label{AIDA}
368: \end{center}
369: \end{table*}
370:
371: It has become clear, that the AIDA persistence API is not sufficient and it has to
372: be made richer to allow more control over persistent objects, better searching
373: capabilities, etc.
374:
375: \subsection{Minerva}
376:
377: Minerva~\cite{Minerva} is a lightweight Java Framework which implements main Architectural
378: principles of the ATLAS C++ Framework Athena~\cite{Athena}:
379: \begin{itemize}
380: \item {\bf Algorithm - Data Separation}: Algorithmic code is separated from
381: the data on which it operates. Algorithms can be explicitly called and
382: don't a have persistent state (except for parameters). Data are potentially
383: persistent and processed by Algorithms.
384: \item {\bf Persistent - Transient Separation}: The Persistency mechanism is
385: implemented by specified components and have no impact on the
386: definition of the transient Interfaces. Low-level Persistence technologies
387: can be replaced without changing the other Framework components (except
388: for possible configuration). A specific definition of Transient-Persistent
389: mapping is possible, but is not required.
390: \item {\bf Implementation Independence}: There are no implementation-specific
391: constructs in the definition of the interfaces. In particular, all
392: Interfaces are defined in an implementation independent way. Also all
393: public objects (i.e. all objects which are exchanged between components
394: and which subsequently appear in the Interface' definitions) are
395: identifiable by implementation independent Identifiers.
396: \item {\bf Modularity}: All components are explicitly designed with
397: interchangeability in mind. This implies that the main deliverables are
398: simple and precisely defined general interfaces and existing implementation
399: of various modules serves mainly as a Reference implementation.
400: \end{itemize}
401:
402: Minerva scheduling is based on InfoBus~\ref{InfoBus} Architecture:
403: \begin{itemize}
404: \item Algorithms are {\em Data Producers} or {\em Data Consumers} (or both).
405: \item Algorithm declare their supported I/O types.
406: \item Scheduling is done implicitly. An Algorithm runs when it has all its
407: inputs ready.
408: \item Both Algorithms and Services run as (static or dynamic) Servers.
409: \item The environment is naturally multi-threaded.
410: \end{itemize}
411:
412: Overview of the Minerva Architecture is shown in Figure~\ref{InfoBus}.
413:
414: \begin{figure*}[!]
415: \centering
416: \includegraphics[width=135mm]{InfoBus.eps}
417: \caption{Minerva is based on the InfoBus scheduling and the JDO persistency.}
418: \label{InfoBus}
419: \end{figure*}
420:
421: It is very easy to configure and run Minerva. For example, one can create
422: a Minerva run with 5 parallel Servers. Two of them are reading Events from
423: two independent databases, one is processing each Event and two last write
424: new processed Events on two new databases depending on the Event characteristics.
425: (See Figure~\ref{Minerva} for a schema of such run and Listing~\ref{MinervaScript}
426: for its steering script.)
427:
428: \begin{figure}[!]
429: \centering
430: \includegraphics[width=80mm]{Minerva.eps}
431: \caption{Example of a Minerva run.}
432: \label{Minerva}
433: \end{figure}
434:
435: \begin{table}[!]
436: \begin{center}
437: \begin{tabular}{|l|}
438: \hline
439: $new\ Algorithm(<Algorithm\ properties>);$ \\
440: $new\ ObjectOutput(<db3>, <Event\ properties1>);$ \\
441: $new\ ObjectOutput(<db4>, <Event\ properties2>);$ \\
442: $new\ ObjectInput(<db1>);$ \\
443: $new\ ObjectInput(<db2>);$ \\
444: \hline
445: \end{tabular}
446: \caption{Example of steering script for a Minerva run.}
447: \label{MinervaScript}
448: \end{center}
449: \end{table}
450:
451: Minerva has also simple but powerful modular Graphical User Interface which
452: allows to plug in easily other components as the BeanShell~\cite{BeanShell} command-line interface,
453: the JAS~\cite{JAS} histogramming, the ObjectBrowser~\cite{ObjectBrowser}, etc.
454: Figure~\ref{GUI} and Figure~\ref{ObjectBrowser} show examples of running Minerva with various
455: interactive plugins loaded.
456:
457: \begin{figure*}[!]
458: \centering
459: \includegraphics[width=135mm]{GUI.eps}
460: \caption{Running set of Producers and Consumers created from a script inside
461: Minerva.}
462: \label{GUI}
463: \end{figure*}
464:
465: \begin{figure*}[!]
466: \centering
467: \includegraphics[width=135mm]{ObjectBrowser.eps}
468: \caption{Using ObjectBrowser to inspect Algorithm inside Minerva.}
469: \label{ObjectBrowser}
470: \end{figure*}
471:
472: \section{Prototypes using JDO}
473:
474: \subsection{Object Evolution}
475:
476: It is often necessary to change object' shape while keeping its content and
477: identity. This functionality is especially needed in the persistency
478: domain to satisfy {\em Schema Evolution} (Versioning) or {\em Object Mapping}
479: (DB Projection), i.e. retrieving an Object of type A dressed as an Object of
480: another type B. This functionality is not addressed by JDO. In practice, it is
481: handled either on the lower lever (in a database) or on the higher level (in
482: the overall framework, for example EJB).
483:
484: It is, however, possible to implement an Object Evolution for JDO with the
485: help of Dynamic Proxies and Aspects.
486:
487: Let's suppose that a user wants to read an Object of a type A (of an
488: Interface IA) dressed as an Object of another Interface IB. To enable that,
489: four components should co-operate (as shown in Fig~\ref{Evolution}):
490: \begin{itemize}
491: \item JDO Enhancer enhances class A so it is PersistenceCapable and it is
492: managed by JDO PersistenceManager.
493: \item AspectJ~\cite{AspectJ} adds read-callback with the mapping A $\rightarrow$ IB. This is called
494: automatically when JDO reads an object A.
495: \item A simple database of mappers provides a suitable mapping between A
496: and IB.
497: \item DynamicProxy delivers the content of the Object A with the interfaces IB:\\
498: $IB\ b = (IB)DynamicProxy.newInstance(A, IB);$.
499: \end{itemize}
500: All those manipulations are of course hidden from the End User.
501:
502: \begin{figure}[!]
503: \centering
504: \includegraphics[width=80mm]{Evolution.eps}
505: \caption{Support for Object Evolution.}
506: \label{Evolution}
507: \end{figure}
508:
509: \subsection{Foreign References}
510:
511: HEP data are often stored in sets of independent databases, each one managed
512: independently. This architectures do not directly support references between
513: objects from different databases (while references inside one database are
514: managed directly by the JDO support for Persistence by Reachability). As in the case
515: of the Object Evolution, foreign references are usually resolved either on
516: the lower level (i.e. all databases are managed by one storage manager and
517: JDO operates on top) or on the higher level (for example by the EJB framework).
518:
519: Another possibility is to use a similar Architecture as in the case of Object
520: Evolution with Dynamic Proxy delivering foreign Objects.
521:
522: Let's suppose, that a User reads an object A, which contains a reference
523: to another object B, which is actually stored in a different database (and
524: thus managed by a different PersistenceManager). The database with the object A
525: doesn't in fact in this case contain an object B, but a DynamicProxy object.
526: The object B can be transparently retrieved using three co-operating components
527: (as shown on Fig~\ref{References}):
528: \begin{itemize}
529: \item When reference from an object A to an object B is requested, JDO delivers
530: DynamicProxy instead.
531: \item The DynamicProxy asks PersistenceManagerFactory for a PersistenceManager
532: which handles the object B. It then uses that PersistenceManager to get the
533: object B and casts itself into it.
534: \item PersistenceManagerFactory gives this information by interrogating
535: DBcatalog (possibly a Grid Service).
536: \end{itemize}
537: All those manipulations are of course hidden from the End User.
538:
539: \begin{figure}[!]
540: \centering
541: \includegraphics[width=80mm]{References.eps}
542: \caption{Support for Foreign References.}
543: \label{References}
544: \end{figure}
545:
546: \section{Summary}
547:
548: It has been shown that JDO standard provides suitable foundation of the
549: persistence service for HEP applications.
550:
551: Two major characteristics of persistence solutions based on JDO are:
552: \begin{itemize}
553: \item Not intrusiveness.
554: \item Wide range of available JDO implementations, both commercial and free,
555: giving access to all major databases.
556: \end{itemize}
557: JDO profits from the native databases functionality and performance (SQL
558: queries,...), but presents it to users in a native Java API.
559:
560: \newpage
561: \onecolumngrid
562:
563: \begin{thebibliography}{99}
564:
565: \bibitem{JDO1}
566: More details talk about JDO: \\
567: {\small http://hrivnac.home.cern.ch/hrivnac/Activities/2002/June/JDO}
568:
569: \bibitem{JDO2}
570: More details talk about JDO: \\
571: {\small http://hrivnac.home.cern.ch/hrivnac/Activities/2002/November/Indicium}
572:
573: \bibitem{Standard}
574: Java Data Objects Standard: \\
575: {\small http://java.sun.com/products/jdo}
576:
577: \bibitem{Portal}
578: Java Data Objects Portal: \\
579: {\small http://www.jdocentral.com}
580:
581: \bibitem{JDORI}
582: JDO Reference Implementation (JDORI): \\
583: {\small http://access1.sun.com/jdo}
584:
585: \bibitem{TJDO}
586: TJDO: \\
587: {\small http://tjdo.sourceforge.net}
588:
589: \bibitem{XORM}
590: XORM: \\
591: {\small http://xorm.sourceforge.net}
592:
593: \bibitem{JORM}
594: JORM: \\
595: {\small http://jorm.objectweb.org}
596:
597: \bibitem{OJB}
598: OJB: \\
599: {\small http://db.apache.org/ojb/}
600:
601: \bibitem{Indicium}
602: Indicium: \\
603: {\small http://hrivnac.home.cern.ch/hrivnac/Activities/Packages/Indicium}
604:
605: \bibitem{AIDA}
606: AIDA: \\
607: {\small http://aida.freehep.org}
608:
609: \bibitem{FreeHEP}
610: FreeHEP Library: \\
611: {\small http://java.freehep.org}
612:
613: \bibitem{Minerva}
614: Minerva: \\
615: {\small http://hrivnac.home.cern.ch/hrivnac/Activities/Packages/Minerva}
616:
617: \bibitem{JACE}
618: JACE: \\
619: {\small http://reyelts.dyndns.org:8080/jace/release/docs/index.html}
620:
621: \bibitem{BeanShell}
622: Lightweight Scripting for Java (BeanShell): \\
623: {\small http://www.beanshell.org}
624:
625: \bibitem{InfoBus}
626: InfoBus: \\
627: {\small http://java.sun.com/products/javabeans/infobus/}
628:
629: \bibitem{JAS}
630: Java Analysis Studio (JAS): \\
631: {\small http://jas.freehep.org}
632:
633: \bibitem{ObjectBrowser}
634: Object Browser: \\
635: {\small http://hrivnac.home.cern.ch/hrivnac/Activities/Packages/ObjectBrowser/}
636:
637: \bibitem{AspectJ}
638: AspectJ: \\
639: {\small http://www.eclipse.org/aspectj/}
640:
641: \bibitem{EJB}
642: Enterprise Java Beans (EJB): \\
643: {\small http://java.sun.com/products/ejb}
644:
645: \bibitem{Athena}
646: ATLAS C++ Framework (Athena): \\
647: {\small http://atlas.web.cern.ch/ATLAS/GROUPS/SOFTWARE/OO/architecture/General/index.html}
648:
649: \bibitem{LCG}
650: LCG Computing Grid Project (LCG): \\
651: {\small http://wenaus.home.cern.ch/wenaus/peb-app}
652:
653: \bibitem{Pool}
654: LCG Persistency Framework (Pool): \\
655: {\small http://lcgapp.cern.ch/project/persist}
656:
657: \end{thebibliography}
658:
659: \end{document}
660: