Java Developer's Guide
Java Developer's Guide
Release 2 (9.2)
Oracle9i Java Developers Guide, Release 2 (9.2) Part No. A96656-01 Copyright 2000, 2002 Oracle Corporation. All rights reserved. Primary Author: Sheryl Maring
Contributors: Steve Harris, Ellen Barnes, Peter Benson, Greg Colvin, Bill Courington, Matthieu Devin, Jim Haungs, Hal Hildebrand, Mark Jungerman, Susan Kraft, Thomas Kurian, Scott Meyer, Tom Portfolio, Dave Rosenberg, Jerry Schwarz, Harlan Sexton, Tim Smith, David Unietis, Brian Wright. The Programs (which include both the software and documentation) contain proprietary information of Oracle Corporation; they are provided under a license agreement containing restrictions on use and disclosure and are also protected by copyright, patent and other intellectual and industrial property laws. Reverse engineering, disassembly or decompilation of the Programs, except to the extent required to obtain interoperability with other independently created software or as specied by law, is prohibited. The information contained in this document is subject to change without notice. If you nd any problems in the documentation, please report them to us in writing. Oracle Corporation does not warrant that this document is error-free. Except as may be expressly permitted in your license agreement for these Programs, no part of these Programs may be reproduced or transmitted in any form or by any means, electronic or mechanical, for any purpose, without the express written permission of Oracle Corporation. If the Programs are delivered to the U.S. Government or anyone licensing or using the programs on behalf of the U.S. Government, the following notice is applicable: Restricted Rights Notice Programs delivered subject to the DOD FAR Supplement are "commercial computer software" and use, duplication, and disclosure of the Programs, including documentation, shall be subject to the licensing restrictions set forth in the applicable Oracle license agreement. Otherwise, Programs delivered subject to the Federal Acquisition Regulations are "restricted computer software" and use, duplication, and disclosure of the Programs shall be subject to the restrictions in FAR 52.227-19, Commercial Computer Software - Restricted Rights (June, 1987). Oracle Corporation, 500 Oracle Parkway, Redwood City, CA 94065. The Programs are not intended for use in any nuclear, aviation, mass transit, medical, or other inherently dangerous applications. It shall be the licensee's responsibility to take all appropriate fail-safe, backup, redundancy, and other measures to ensure the safe use of such applications if the Programs are used for such purposes, and Oracle Corporation disclaims liability for any damages caused by such use of the Programs. Oracle is a registered trademark, and Oracle9i, Oracle8i, PL/SQL, and SQL*Plus are trademarks or registered trademarks of Oracle Corporation. Other names may be trademarks of their respective owners.
Contents
Send Us Your Comments ................................................................................................................... xi Preface.......................................................................................................................................................... xiii
Who Should Read This Book?............................................................................................................ xiii Java API Programming Models......................................................................................................... xiv Java Information Resources................................................................................................................ xiv Documentation Accessibility .............................................................................................................. xv
iii
The Java Virtual Machine (JVM)............................................................................................... Key Features of the Java Language .......................................................................................... Why Use Java in Oracle9i? .............................................................................................................. Multithreading ............................................................................................................................ Automated Storage Management ............................................................................................ Footprint....................................................................................................................................... Performance................................................................................................................................. How Native Compilers Improve Performance ............................................................... Dynamic Class Loading ............................................................................................................. Oracles Java Application Strategy ................................................................................................ Java Stored Procedures .............................................................................................................. PL/SQL Integration and Oracle RDBMS Functionality........................................................ JDBC Drivers ........................................................................................................................ SQLJ Embedded SQL in Java .......................................................................................... Development Tools..................................................................................................................... Overview of Oracle9i Java Documentation .................................................................................
1-10 1-13 1-14 1-14 1-15 1-16 1-17 1-17 1-18 1-19 1-19 1-20 1-20 1-21 1-22 1-22
iv
Defining the Same Class Twice ......................................................................................... Designating Database Privileges and JVM Permissions................................................ Loading JAR or ZIP Files.................................................................................................... How to Grant Execute Rights ................................................................................................... Controlling the Current User.................................................................................................... Checking Java Uploads.............................................................................................................. Object Name and Type ....................................................................................................... Status ..................................................................................................................................... Publishing .................................................................................................................................... User Interfaces on the Server.......................................................................................................... Shortened Class Names ................................................................................................................... Class.forName() in Oracle9i............................................................................................................ Supply the ClassLoader in Class.forName ............................................................................. Supply Class and Schema Names to classForNameAndSchema ........................................ Supply Class and Schema Names to lookupClass................................................................. Supply Class and Schema Names when Serializing ............................................................. Class.forName Example ............................................................................................................ Managing Your Operating System Resources............................................................................. Overview of Operating System Resources ............................................................................. Operating System Resource Access .................................................................................. Operating System Resource Lifetime ............................................................................... Referencing Files with Relative Path Names.......................................................................... Garbage Collection and Operating System Resources.......................................................... Operating System Resources Affected Across Calls ............................................................. Sockets................................................................................................................................... Threading in Oracle9i ...................................................................................................................... Thread Lifecycle ..................................................................................................................
2-18 2-19 2-19 2-19 2-21 2-23 2-23 2-24 2-25 2-25 2-26 2-27 2-28 2-29 2-30 2-30 2-31 2-32 2-32 2-33 2-33 2-34 2-34 2-35 2-37 2-38 2-39
JDBC ........................................................................................................................................ SQLJ ......................................................................................................................................... An Example Comparing JDBC and SQLJ.................................................................................. Complete SQLJ Example.............................................................................................................. SQLJ Strong Typing Paradigm .......................................................................................... Translating a SQLJ Program .............................................................................................. Running a SQLJ Program in the Server............................................................................ Converting a Client Application to Run in the Server ................................................... Interacting with PL/SQL.................................................................................................... Debugging Server Applications..................................................................................................... The Debug Agent Protocol ........................................................................................................ 1. Prepare the Code for Debugging .................................................................................. 2. Start the Debug Proxy ..................................................................................................... 3. Starting, Stopping, and Restarting the Debug Agent................................................. OracleAgent Class ............................................................................................................... 4. Connecting a Debugger .................................................................................................. How To Tell You Are Executing in the Server ............................................................................. Redirecting Output on the Server..................................................................................................
3-6 3-7 3-7 3-9 3-10 3-11 3-11 3-12 3-12 3-13 3-13 3-14 3-15 3-16 3-17 3-18 3-20 3-20
vi
vii
deploync....................................................................................................................................... Syntax .................................................................................................................................... Argument Summary ........................................................................................................... statusnc......................................................................................................................................... Syntax .................................................................................................................................... Argument Summary ........................................................................................................... Java Memory Usage .......................................................................................................................... Configuring Memory Initialization Parameters..................................................................... Initializing Pool Sizes within Database Templates......................................................... Java Pool Memory....................................................................................................................... Displaying Used Amounts of Java Pool Memory.................................................................. Correcting Out of Memory Errors............................................................................................ Running out of memory while compiling ....................................................................... Running out of memory while loading............................................................................ End-of-Call Migration...................................................................................................................... Oracle-Specific Support for End-of-Call Optimization ......................................................... Memory Proling Utility ................................................................................................................. How MemStat Works................................................................................................................. Using MemStat............................................................................................................................ MemStat Permissions ................................................................................................................. The MemStat Report Format.....................................................................................................
6-16 6-16 6-16 6-17 6-18 6-18 6-19 6-19 6-20 6-21 6-22 6-24 6-24 6-24 6-25 6-26 6-30 6-31 6-31 6-33 6-34
Glossary Index
viii
Oracle Corporation welcomes your comments and suggestions on the quality and usefulness of this document. Your input is an important part of the information used for revision.
s s s s s
Did you nd any errors? Is the information clearly presented? Do you need more information? If so, where? Are the examples correct? Do you need more examples? What features did you like most?
If you nd any errors or have any other suggestions for improvement, please indicate the document title and part number, and the chapter, section, and page number (if available). You can send comments to us in the following ways:
s s s
Electronic mail: jpgcomment_us@oracle.com FAX: (650) 506-7225 Attn: Java Platform Group, Information Development Manager Postal service: Oracle Corporation Java Platform Group, Information Development Manager 500 Oracle Parkway, Mailstop 4op9 Redwood Shores, CA 94065 USA
If you would like a reply, please give your name, address, telephone number, and (optionally) electronic mail address. If you have problems with the software, please contact your local Oracle Support Services.
xi
xii
Preface
Who Should Read This Book?
This book has been written for the following audiences:
s
ManagementYou may have purchased Oracle9i for reasons other than Java development within the database. However, if you want to know more about Oracle9i Java features, see "Overview of Oracle9i Java Documentation" on page 1-22 for a management perspective. Non-Java DevelopersOracle database programming consists of PL/SQL and other non-Java programming. For experienced PL/SQL developers who are not familiar with Java, a brief overview of Java and object-oriented concepts is discussed in the rst part of Chapter 1, "Introduction to Java in Oracle9i". For more detailed information on Java, see "Java Information Resources" at the end of this Preface. Java DevelopersPure Java developers are used to a Java environment that follows the Sun Microsystems specication. However, when Java is combined in the database, both Java and database concepts merge. Thus, the Java environment within Oracle9i is expanded to include database concerns. The bulk of this book discusses how to execute Java in the database. The following outlines the two viewpoints that arise from this merge: * Java environmentNote that Oracle9i delivers a compliant Java implementationany 100% pure Java code will work. Oracle9i JVM affects your Java development in the way you manage your classes, and the environment in which your classes exist. For example, the classes must be loaded into the database. In addition, there is a clearer separation of client and server in the Oracle9i model.
xiii
Database environmentYou need to be aware of database concepts for managing your Java objects. This book gives you a comprehensive view of how the two well-dened realmsthe Oracle9i database and the Java environmentt together. For example, when deciding on your security policies, you must consider both database security and Java security for a comprehensive security policy.
Java stored proceduresYou can develop Java applications that are stored in the database. Once loaded, these procedures can be invoked from SQL, PL/SQL, or as triggers. See the Oracle9i Java Stored Procedures Developers Guide. for more information. JDBC and SQLJYou can write a Java application that accesses SQL data from the client, or directly on the server.
Each of these models is briey discussed in Chapter 1, "Introduction to Java in Oracle9i" and examples are given in Chapter 3, "Invoking Java in the Database". Both of these chapters should help you decide which model to use for your particular application. Once you decide on the appropriate model, examine the appropriate developers guide for in-depth information on each model. For example, if you decide to use Java stored procedures, examine Oracle9i Java Stored Procedures Developers Guide.
http://java.sun.com/docs/books/jls http://java.sun.com/docs/books/vmspec
xiv
Description Internet newsgroups can be a valuable source of information on Java from other Java developers. We recommend that you monitor these two newsgroups. Note: Oracle monitors activity on some of these newsgroups and posts responses to Oracle-specic issues.
Documentation Accessibility
Our goal is to make Oracle products, services, and supporting documentation accessible, with good usability, to the disabled community. To that end, our documentation includes features that make information available to users of assistive technology. This documentation is available in HTML format, and contains markup to facilitate access by the disabled community. Standards will continue to evolve over time, and Oracle Corporation is actively engaged with other market-leading technology vendors to address technical obstacles so that our documentation can be accessible to all of our customers. For additional information, visit the Oracle Accessibility Program Web site at
http://www.oracle.com/accessibility/
JAWS, a Windows screen reader, may not always correctly read the code examples in this document. The conventions for writing code require that closing braces should appear on an otherwise empty line; however, JAWS may not always read a line of text that consists solely of a bracket or brace.
Accessibility of Code Examples in Documentation
This documentation may contain links to Web sites of other companies or organizations that Oracle Corporation does not own or control. Oracle Corporation neither evaluates nor makes any representations regarding the accessibility of these Web sites.
Accessibility of Links to External Web Sites in Documentation
xv
xvi
1
Introduction to Java in Oracle9i
This book provides a general overview on how to develop, load, and execute your Java applications in the database. This chapter contains the following information:
s
Chapter Contents Whats New in this Release? Overview of Java Why Use Java in Oracle9i? Oracles Java Application Strategy Overview of Oracle9i Java Documentation
Chapter Contents
Chapter Contents
This chapter covers the following three missions:
s
Introduces the Java language for Oracle database programmers. Oracle PL/SQL developers are accustomed to developing server-side applications that have tight integration with SQL data. You can develop Java server-side applications that take advantage of the scalability and performance of the Oracle database. If you are not familiar with Java, see "Overview of Java" on page 1-5. Examines why you should consider using Java within an Oracle9i database. See "Why Use Java in Oracle9i?" on page 1-14. In addition, a brief description is given for each of the Java APIs supported within Oracle9i. The list of APIs include SQLJ, JDBC, and Java stored procedures. See "Oracles Java Application Strategy" on page 1-19. Provides a roadmap to the Oracle9i Java documentation. Several Java APIs are supported within Oracle9i. Each API is described generally in this book, and more intimately in their own books. "Overview of Oracle9i Java Documentation" on page 1-22 shows you which books cover each Java application type in detail.
Upgrading to JDK 1.3 Desupport of J2EE Technologies in the Oracle Database Additions to the loadjava Tool Replacement of the sess_sh tool with ojvmjava Debugger Modications
1-2
the J2EE stack, consisting of: Enterprise Beans (EJB) container JavaServer Pages (JSP) container Oracle9i Servlet Engine (OSE)
the embedded Common Object Request Broker Architecture (CORBA) framework, based on Visibroker for Java
Customers will no longer be able to deploy servlets, JSP pages, EJBs, and CORBA objects in Oracle databases. Oracle9i database release 1 (9.0.1) will be the last database release to support the J2EE and CORBA stack. Oracle is encouraging customers to migrate existing J2EE applications running in the database to OC4J now.
The schema in which the missing classes are loaded will be the one specied by the -user command-line option, even when referring classes are created in some other schema. The created classes will be agged as such so that tools can recognize them. In particular, this is needed, so that the verier can recognize generated classes. See "loadjava" on page 1-2 for more information.
Debugger Modications
Oracle9i furnishes a debugging capability that is useful for developers who use the JDKs jdb debugger. Two interfaces are supported.
s
The debug Agent protocol that was introduced in Oracle8i, and is supported by JDK 1.2 and later versions of JDB. The class DebugProxy makes remote Java programs appear to be local. It lets any debugger that supports the sun.tools.debug.Agent protocol connect to a program as if the program were local. The proxy forwards requests to the server and returns results to the debugger. For detailed instructions, see the Oracle9i Java Developers Guide.
The Java Debug Wire Protocol supported by JDK 1.3 and later versions of the Sun Microsystems JDB debugger (http://java.sun.com/j2se/1.3/docs/guide/jpda/, http://java.sun.com/j2se/1.4/docs/guide/jpda/.) The use of this interface is documented on OTN. The JDWP protocol supports many new features, including the ability to listen for connections (no more DebugProxy), change the values of variables while debugging, and evaluate arbitrary Java expressions, including method evaluation. Oracle's JDeveloper provides a user-friendly integration with these debugging features. See the JDeveloper documentation for more information on how to debug your Java application through JDeveloper. Other independent IDE vendors will be able to integrate their own debuggers with Oracle9i.
1-4
Overview of Java
Overview of Java
Java has emerged as the object-oriented programming language of choice. It includes the following concepts:
s
a Java virtual machine (JVM), which provides the fundamental basis for platform independence automated storage management techniques, the most visible of which is garbage collection language syntax that borrows from C and enforces strong typing
The result is a language that is object-oriented and efcient for application-level programs.
Classes
All object-oriented programming languages support the concept of a class. As with a table denition, a class provides a template for objects that share common characteristics. Each class can contain the following:
s
Attributesstatic or instance variables that each object of a particular class possesses. Methodsyou can invoke methods dened by the class or inherited by any classes extended from the class.
When you create an object from a class, you are creating an instance of that class. The instance contains the elds of an object, which are known as its data, or state. Figure 11 shows an example of an Employee class dened with two attributes: last name (lastName) and employee identier (ID).
Overview of Java
When you create an instance, the attributes store individual and private information relevant only to the employee. That is, the information contained within an employee instance is known only for that single employee. The example in Figure 11 shows two instances of employeeSmith and Jones. Each instance contains information relevant to the individual employee.
Attributes
Attributes within an instance are known as elds. Instance elds are analogous to the elds of a relational table row. The class denes the elds, as well as the type of each eld. You can declare elds in Java to be static, public, private, protected, or default access.
1-6
Overview of Java
Public, private, protected, or default access elds are created within each instance. Static elds are like global variables in that the information is available to all instances of the employee class.
The language specication denes the rules of visibility of data for all elds. Rules of visibility dene under what circumstances you can access the data in these elds.
Methods
The class also denes the methods you can invoke on an instance of that class. Methods are written in Java and dene the behavior of an object. This bundling of state and behavior is the essence of encapsulation, which is a feature of all object-oriented programming languages. If you dene an Employee class, declaring that each employees id is a private eld, other objects can access that private eld only if a method returns the eld. In this example, an object could retrieve the employees identier by invoking the Employee.getId() method. In addition, with encapsulation, you can declare that the Employee.getId() method is private, or you can decide not to write an Employee.getId() method. Encapsulation helps you write programs that are reusable and not misused. Encapsulation makes public only those features of an object that are declared public; all other elds and methods are private. Private fields and methods can be used for internal object processing.
Class Hierarchy
Java denes classes within a large hierarchy of classes. At the top of the hierarchy is the Object class. All classes in Java inherit from the Object class at some level, as you walk up through the inheritance chain of superclasses. When we say Class B inherits from Class A, each instance of Class B contains all the elds dened in class B, as well as all the elds dened in Class A. For example, in Figure 12, the FullTimeEmployee class contains the id and lastName elds dened in the Employee class, because it inherits from the Employee class. In addition, the FullTimeEmployee class adds another eld, bonus, which is contained only within FullTimeEmployee. You can invoke any method on an instance of Class B that was dened in either Class A or B. In our employee example, the FullTimeEmployee instance can invoke methods dened only within its own class, or methods dened within the Employee class.
Overview of Java
Instances of Class B are substitutable for instances of Class A, which makes inheritance another powerful construct of object-oriented languages for improving code reuse. You can create new classes that dene behavior and state where it makes sense in the hierarchy, yet make use of pre-existing functionality in class libraries.
Interfaces
Java supports only single inheritance; that is, each class has one and only one class from which it inherits. If you must inherit from more than one source, Java provides the equivalent of multiple inheritance, without the complications and confusion that usually accompany it, through interfaces. Interfaces are similar to classes; however, interfaces dene method signatures, not implementations. The methods
1-8
Overview of Java
are implemented in classes declared to implement an interface. Multiple inheritance occurs when a single class simultaneously supports many interfaces.
Polymorphism
Assume in our Employee example that the different types of employees must be able to respond with their compensation to date. Compensation is computed differently for different kinds of employees.
s
In traditional procedural languages, you would write a long switch statement, with the different possible cases dened.
switch: (employee.type) { case: Employee return employee.salaryToDate; case: FullTimeEmployee return employee.salaryToDate + employee.bonusToDate ...
If you add a new kind of Employee, you must update your switch statement. If you modify your data structure, you must modify all switch statements that use it. In an object-oriented language such as Java, you implement a method, compensationToDate(), for each subclass of Employee class that requires any special treatment beyond what is already dened in Employee class. For example, you could implement the compensationToDate() method of NonExemptEmployee, as follows:
private float compensationToDate() { return super.compensationToDate() + this.overtimeToDate(); }
The common usage of the method name compensationToDate() allows you to invoke the identical method on different classes and receive different results, without knowing the type of employee you are using. You do not have to write a special method to handle FullTimeEmployees and PartTimeEmployees. This
Overview of Java
ability for the different objects to respond to the identical message in different ways is known as polymorphism. In addition, you could create an entirely new class that does not inherit from Employee at allContractorand implement a compensationToDate() method in it. A program that calculates total payroll to date would iterate over all people on payroll, regardless of whether they were full-time, part-time, or contractors, and add up the values returned from invoking the compensationToDate() method on each. You can safely make changes to the individual compensationToDate() methods with the knowledge that callers of the methods will work correctly. For example, you can safely add new elds to existing classes.
1-10
Overview of Java
When you develop a Java program, you use predened core class libraries written in the Java language. The Java core class libraries are logically divided into packages that provide commonly-used functionality, such as basic language support (java.lang), input/output (java.io), and network access (java.net). Together, the JVM and core class libraries provide a platform on which Java programmers can develop with the condence that any hardware and operating system that supports Java will execute their program. This concept is what drives the write once, run anywhere idea of Java. Figure 14 illustrates how Oracles Java applications sit on top of the Java core class libraries, which in turn sit on top of the JVM. Because Oracles Java support system is located within the database, the JVM interacts with the Oracle database libraries, instead of directly with the operating system.
Overview of Java
Operating System
Sun Microsystems furnishes publicly available specications for both the Java language and the JVM. The Java Language Specication (JLS) denes things such as syntax and semantics; the JVM specication denes the necessary low-level behavior for the machine that executes the bytecodes. In addition, Sun Microsystems provides a compatibility test suite for JVM implementors to determine if they have complied with the specications. This test suite is known as the Java Compatibility Kit (JCK). Oracles JVM implementation complies fully with JCK. Part of the overall Java strategy is that an openly specied standard, together
1-12
Overview of Java
with a simple way to verify compliance with that standard, allows vendors to offer uniform support for Java across all platforms.
SimplicityJava is a simpler language than most others used in server applications because of its consistent enforcement of the object model. The large, standard set of class libraries brings powerful tools to Java developers on all platforms. PortabilityJava is portable across platforms. It is possible to write platform-dependent code in Java, but it is also simple to write programs that move seamlessly across machines. Oracle server applications, which do not support graphical user interfaces directly on the platform that hosts them, also tend to avoid the few platform portability issues that Java has. Automatic Storage ManagementThe Java virtual machine automatically performs all memory allocation and deallocation during program execution. Java programmers can neither allocate nor free memory explicitly. Instead, they depend on the JVM to perform these bookkeeping operations, allocating memory as they create new objects and deallocating memory when the objects are no longer referenced. The latter operation is known as garbage collection. Strong TypingBefore you use a Java variable, you must declare the class of the object it will hold. Javas strong typing makes it possible to provide a reasonable and safe solution to inter-language calls between Java and PL/SQL applications, and to integrate Java and SQL calls within the same application. No PointersAlthough Java retains much of the avor of C in its syntax, it does not support direct pointers or pointer manipulation. You pass all parameters, except primitive types, by reference (that is, object identity is preserved), not by value. Java does not provide Cs low level, direct access to pointers, which eliminates memory corruption and leaks. Exception HandlingJava exceptions are objects. Java requires developers to declare which exceptions can be thrown by methods in any particular class. Flexible NamespaceJava denes classes and holds them within a hierarchical structure that mirrors the Internets domain namespace. You can distribute Java applications and avoid name collisions. Java extensions such as the Java Naming and Directory Interface (JNDI) provide a framework for multiple name services to be federated. Javas namespace approach is exible enough for
Oracle to incorporate the concept of a schema for resolving class names, while fully complying with the language specication.
s
SecurityThe design of Java bytecodes and the JVM allow for built-in mechanisms to verify that the Java binary code was not tampered with. Oracle9i is installed with an instance of SecurityManager, which, when combined with Oracle database security, determines who can invoke any Java methods. Standards for Connectivity to Relational DatabasesJDBC and SQLJ enable Java code to access and manipulate data resident in relational databases. Oracle provides drivers that allow vendor-independent, portable Java code to access the relational database.
Multithreading
Multithreading support is often cited as one of the key scalability features of the Java language. Certainly, the Java language and class libraries make it simpler to write multithreaded applications in Java than many other languages, but it is still a daunting task in any language to write reliable, scalable multithreaded code. As a database server, Oracle9i efciently schedules work for thousands of users. The Oracle9i JVM uses the facilities of the RDBMS server to concurrently schedule Java execution for thousands of users. Although Oracle9i supports Java language
1-14
level threads required by the JLS and JCK, using threads within the scope of the database will not increase your scalability. Using the embedded scalability of the database eliminates the need for writing multithreaded Java servers. You should use the databases facilities for scheduling users by writing single-threaded Java applications. The database will take care of the scheduling between each application; thus, you achieve scalability without having to manage threads. You can still write multithreaded Java applications, but multiple Java threads will not increase your servers performance. One difculty multithreading imposes on Java is the interaction of threads and automated storage management, or garbage collection. The garbage collector executing in a generic JVM has no knowledge of which Java language threads are executing or how the underlying operating system schedules them.
s
Non-Oracle9i modelA single user maps to a single Java language level thread; the same single garbage collector manages all garbage from all users. Different techniques typically deal with allocation and collection of objects of varying lifetimes and sizes. The result in a heavily multithreaded application is, at best, dependent upon operating system support for native threads, which can be unreliable and limited in scalability. High levels of scalability for such implementations have not been convincingly demonstrated. Oracle9i JVM modelEven when thousands of users connect to the server and execute the same Java code, each user experiences it as if he is executing his own Java code on his own Java virtual machine. The responsibility of the Oracle9i JVM is to make use of operating system processes and threads, using the scalable approach of the Oracle RDBMS. As a result of this approach, the JVMs garbage collector is more reliable and efcient because it never collects garbage from more than one user at any time. Refer to "Threading in Oracle9i" on page 2-38 for more information on the thread model implementation in Oracle9i JVM.
Garbage collection imposes a challenge to the JVM developer seeking to supply a highly scalable and fast Java platform. The Oracle9i JVM meets these challenges in the following ways:
s
The Oracle9i JVM uses the Oracle9i scheduling facilities, which can manage multiple users efciently. Garbage collection is performs consistently for multiple users because garbage collection is focused on a single user within a single session. The Oracle9i JVM enjoys a huge advantage because the burden and complexity of the memory managers job does not increase as the number of users increases. The memory manager performs the allocation and collection of objects within a single sessionwhich typically translates to the activity of a single user. The Oracle9i JVM uses different garbage collection techniques depending on the type of memory used. These techniques provide high efciency and low overhead.
Footprint
The footprint of an executing Java program is affected by many factors:
s
Size of the program itselfhow many classes and methods and how much code they contain. Complexity of the programthe amount of core class libraries that the Oracle9i JVM uses as the program executes, as opposed to the program itself. Amount of state the JVM useshow many objects the JVM allocates, how large they are, and how many must be retained across calls. Ability of the garbage collector and memory manager to deal with the demands of the executing program, which is often non-deterministic. The speed with which objects are allocated and the way they are held on to by other objects inuences the importance of this factor.
From a scalability perspective, the key to supporting many concurrent clients is a minimum per-user session footprint. The Oracle9i JVM keeps the per-user session footprint to a minimum by placing all read-only data for users, such as Java bytecodes, in shared memory. Appropriate garbage collection algorithms are applied against call and session memories to maintain a small footprint for the users session. The Oracle9i JVM uses three types of garbage collection algorithms to maintain the users session memory:
s
1-16
mark and lazy sweep collection for objects that exist for the life of a single call copying collector for long-lived objectsobjects that live across calls within a session
Performance
Oracle9i JVM performance is enhanced by implementing a native compiler.
Ahead-of-Time Compilation
Oracle9i uses Ahead-of-Time compilation to deliver its core Java class libraries: JDBC code in natively compiled form. It is applicable across all the platforms Oracle supports, whereas a JIT approach requires low-level, processor-dependent code to be written and maintained for each platform. You can use this native compilation
technology with your own Java code. Refer to "Natively Compiled Code" on page 6-2 for more information.
Reliability
A benet of dynamic class loading is that it supports program updating. For example, you would update classes on a server, and clients who download the program and load it dynamically see the update whenever they next use the program. Server programs tend to emphasize reliability. As a developer, you must know that every client executes a specic program conguration. You do not want clients to inadvertently load some classes that you did not intend them to load.
1-18
Java stored procedures as the Java equivalent and companion for PL/SQL. Java stored procedures are tightly integrated with PL/SQL. You can call a Java stored procedure from a PL/SQL package; you can call PL/SQL procedures from a Java stored procedure. SQL data can be accessed through JDBC and SQLJ programming interfaces. Tools and scripts used in assisting in development, class loading, and class management.
To help you decide which Java APIs to use, examine the following table:
Type of functionality you need Java API to use
To have a Java procedure invoked from SQL, such as a Java Stored Procedures trigger. To invoke a static, simple SQL statement from a known table with known column names from a Java object. To invoke dynamic, complex SQL statements from a Java object. SQLJ
JDBC
In addition, you can use Java to develop powerful programs independently of PL/SQL. Oracle9i provides a fully-compliant implementation of the Java programming language and JVM.
JDBC DriversUsed to build client/server 2-tier applications. SQLJ Embedded SQL in JavaUsed to access static SQL. You must know the name of the columns.
JDBC Drivers
JDBC is a database access protocol that enables you to connect to a database and then prepare and execute SQL statements against the database. Core Java class libraries provide only one JDBC API. JDBC is designed, however, to allow vendors to supply drivers that offer the necessary specialization for a particular database. Oracle delivers the following three distinct JDBC drivers.
Driver JDBC Thin Driver Description You can use the JDBC Thin driver to write 100% pure Java applications and applets that access Oracle SQL data. The JDBC Thin driver is especially well-suited to Web browser-based applications and applets, because you can dynamically download it from a Web page just like any other Java applet. The JDBC Oracle Call Interface (OCI) driver accesses Oracle-specic native code (that is, non-Java) libraries on the client or middle tier, providing a richer set of functionality and some performance boost compared to the JDBC Thin driver, at the cost of signicantly larger size and client-side installation.
1-20
Description Oracle9i uses the server-side internal driver when Java code executes on the server. It allows Java applications executing in the servers Java virtual machine to access locally dened data (that is, on the same machine and in the same process) with JDBC. It provides a further performance boost because of its ability to use underlying Oracle RDBMS libraries directly, without the overhead of an intervening network connection between your Java code and SQL data. By supporting the same Java-SQL interface on the server, Oracle9i does not require you to rework code when deploying it.
For more information on JDBC, see "Utilizing SQLJ and JDBC for Querying the Database" on page 3-6. Or for a complete detailed description, see the Oracle9i JDBC Developers Guide and Reference.
Development Tools
The introduction of Java to the Oracle9i server allows you to use several Java Integrated Development Environments. The adherence of Oracle9i to Java compatibility and open Internet standards and protocols ensures that your 100% pure Java programs work when you deploy them on Oracle9i. Oracle delivers many tools or utilities, all written in Java, that make development and deployment of Java server applications easier. Oracles JDeveloper has many features designed specically to make deployment of Java stored procedures and Enterprise JavaBeans easier.
Oracle9i Java developers should become familiar with Oracle9i JDBC Oracle's Java Database Connectivity (JDBC) product Developers Guide and because it provides the basis for accessing SQL data Reference from Java programs, as well as Oracle-specic extensions to this Java standard. JDBC is an industry standard. You may nd it easier to develop Java programs that access SQL data using embedded SQL in Java (SQLJ). SQLJ uses a preprocessor, written in Java, to translate embedded SQL statements to standard JDBC-style programs. SQLJ is an industry standard. JPublisher provides a simple and convenient tool to create Java programs that access existing Oracle relational database tables. Oracle9i SQLJ Developers Guide and Reference
SQLJ
JPublisher
1-22
Description (Cont.)
Book Title
If you are a PL/SQL programmer exploring Java, you Oracle9i Java Stored will be interested in Java stored procedures. A Java Procedures stored procedure is a program you write in Java to Developers Guide execute in the server, exactly as a PL/SQL stored procedure. You invoke it directly with products like SQL*Plus or indirectly with a trigger and can access it from any Oracle Net clientOCI, PRO*, JDBC or SQLJ. The Oracle9i Java Stored Procedures Developers Guide explains how to write stored procedures in Java, how to access them from PL/SQL, and how to access PL/SQL functionality from Java. In addition, you can use Java to develop powerful programs independently of PL/SQL. Oracle9i provides a fully compliant implementation of the Java programming language and JVM.
1-24
2
Writing Java Applications on Oracle9i
Oracle9i executes standard Java applications. However, by integrating Java classes within the database server, your environment is different from a typical Java development environment. This chapter describes the basic differences for writing, installing, and deploying Java applications within Oracle9i.
s
Overview Database Sessions Imposed on Java Applications Execution Control Java Code, Binaries, and Resources Storage Preparing Java Class Methods for Execution User Interfaces on the Server Shortened Class Names Class.forName() in Oracle9i Managing Your Operating System Resources Threading in Oracle9i
Note: To fully explore the usage for each API, refer to the
documentation for each API. The intent of this chapter is to place the Java APIs in an overall context, with enough detail for you to see how they t together and how you use them in the Oracle9i environment.
Overview
Overview
As discussed in Chapter 1, the Oracle9i JVM platform is a standard, compatible Java environment, which will execute any 100% pure Java application. It has been implemented by Oracle to be compatible with the Java Language Specication and the Java virtual machine specication. It supports the standard Java binary format and the standard Java APIs. In addition, Oracle9i adheres to standard Java language semantics, including dynamic class loading at runtime. However, unlike other Java environments, the JVM is embedded within the Oracle9i RDBMS and, therefore, introduces a number of new concepts. This section gives an overview of the differences between the Sun Microsystems JDK environment and the environment that occurs when you combine Java with the Oracle9i database.
Terminology
Term Oracle9i JVM Session Denition Java-enabled Oracle9i database server with JVM. As a user who executes Java code, you must establish a session in the server. The word session as we employ it here is identical to the standard Oracle (or any other database server) usage. A session is typically, although not necessarily, bounded by the time a single user connects to the server. When a user causes Java code to execute within a session, we refer to it as a call. You can initiate a call in different ways.
s s s
Call
A SQL client program executes a Java stored procedure. A trigger can execute a Java stored procedure. A PL/SQL program calls some Java code.
In all cases, a call begins, some combination of Java, SQL, or PL/SQL code is executed to completion, and the call ends.
In your standard Java environment, you run a Java application through the interpreter by executing java <classname>. This causes the application to execute within a process on your operating system. With the Oracle9i JVM, you must load the application into the database, publish the interface, and then run the application within a database session. This book discusses how to run your Java applications within the database. Specically, see the following sections for instructions on executing Java in the database:
2-2
Load and publish your Java applications before executionSee "Java Code, Binaries, and Resources Storage" and "Preparing Java Class Methods for Execution", starting on page 2-6. Running within a database sessionSee "Database Sessions Imposed on Java Applications" on page 2-3.
In addition, certain features, included within standard Java, change when you run your application within a database session. These are covered in the following sections:
s
Execution Control User Interfaces on the Server Shortened Class Names Class.forName() in Oracle9i Managing Your Operating System Resources Threading in Oracle9i
Once you are familiar with this chapter, see Chapter 3, "Invoking Java in the Database" for directions on how to set up your client, and examples for invoking different types of Java applications.
Connects to the database and opens a session. Executes Java within the database. This is referred to as a call. Continues to work within the session, performing as many calls as necessary. Ends the session.
Within a single session, the client has its own Java environment, which is separate from every other clients environment. It appears to the client as if a separate, individual JVM was invoked for each session, although the implementation is vastly more efcient than this seems to imply. Within a session, the Oracle9i JVM manages the scalability for you within the database. Every call executed from a single client is managed within its own sessionseparately from other clients. The Oracle9i JVM maximizes sharing read-only data between clients and emphasizes a minimum amount of per-session incremental footprint to maximize performance for multiple clients.
2-4
The underlying server environment hides the details associated with session, network, state, and other shared resource management issues from Java server code. Static variables are all local to the client. No client can access another clients static variables, because the memory is not available across session boundaries. Because each client executes its calls within its own session, each clients activities are separate from any other client. During a call, you can store objects in static elds of different classes, and you can expect this state to be available for your next call. The entire state of your Java program is private to you and exists for your entire session. The Oracle9i JVM manages the following within the session:
s
all the objects referenced by Java static variables, all the objects referred to by these objects, and so on (their transitive closure) garbage collection for the single client session memory for static variables and across call memory needs call memory for variables that exist within a single call
JNDIStore objects in a JNDI namespace. JDBC and SQLJYou can access SQL data through SQLJ or JDBC. See Chapter 3, "Invoking Java in the Database", for examples of each Java API. Java stored proceduresThe lifetime of a Java stored procedure session is identical to the SQL session in which it is embedded. This concept is familiar to PL/SQL users. Any state represented in Java transparently persists for the lifetime of the RDBMS session, simplifying the process of writing stored procedures, triggers, and methods for Oracle Abstract Data Types. Individual invocations of Java code within a session are known as calls. For example, a call may be initiated by a SQL call.
Note:
The concepts of call and session apply across all uses of Oracle9i.
Execution Control
Execution Control
In the Sun Microsystems JDK environment, you develop Java applications with a main() method, which is called by the interpreter when the class is run. The main() method is invoked when you execute java <classname> on the command-line. This command starts the java interpreter and passes the desired classname to be executed to the interpreter. The interpreter loads the class and starts the execution by invoking main(). However, Java applications within the database do not start their execution from a main() method. After loading your Java application within the database (see "Loading Classes" on page 2-16), you can execute your Java code by invoking any static method within the loaded class. The class or methods must be published for you to execute them (see "Publishing" on page 2-25). Your only entry point is no longer always assumed to be main(). Instead, when you execute your Java application, you specify a method name within the loaded class as your entry point. For example, in a normal Java environment, you would start up the Java object on the server by executing the following:
java myprogram
where myprogram is the name of a class that contains a main() method. In myprogram, main() immediately calls mymethod for processing incoming information. In Oracle9i, you load the myprogram.class le into the database and publish mymethod as an entry-point. Then, the client or trigger can invoke mymethod explicitly.
Source code les are known as .java les. Compiled Java binary les are known as .class les. Resources are any data les, such as .properties or .ser les that are held within the le system hierarchy, which are loaded or used at runtime.
In addition, when you execute Java, you specify a CLASSPATH, which is a set of a le system tree roots containing your les. Java also provides a way to group these les into a single archive forma ZIP or JAR le.
2-6
Both of these concepts are different within the database. The following describes how Oracle9i handles Java classes and locates dependent classes: Java code, binaries, and resources In the Oracle9i JVM environment, source, classes, and resources reside within the Oracle9i database. Because they reside in the database, they are known as Java schema objects, where a schema corresponds to a database user. There are three types of Java objects: source, class, and resource. There are no .java, .class, .sqlj, .properties, or .ser les on the server; instead, these les map to source, class, and resource Java schema objects. Instead of a CLASSPATH, you use a resolver to specify one or more schemas to search for source, class, and resource Java schema objects.
The call and session terms, used during our discussions, are not Java terms; but are server terms that apply to the Oracle9i JVM platform. The Oracle9i memory manager preserves Java program state throughout your session (that is, between calls). The JVM uses the Oracle database to hold Java source, classes, and resources within a schemaJava schema objects. You can use a resolver to specify how Java, when executed in the server, locates source code, classes, and resources.
Decide when your source is going to be compiled. Decide if you are going to use the default resolver or another resolver for locating supporting Java classes within the database. Load the classes into the database. If you do not wish to use the default resolver for your classes, you should specify a separate resolver on the load command. Publish your class or method.
You can compile the source explicitly on your client machine, before loading it into the database, through a Java compiler, such as javac. You can ask the database to compile the source during the loading process managed within the loadjava tool. You can force the compilation to occur dynamically at runtime.
Note: If you decide to compile through loadjava, you can
specify compiler options. See "Specifying Compiler Options" on page 2-9 for more information.
2-8
3. 4.
Class schema objects are created for each class dened in the compiled .java le. The compiled code is stored in the class schema objects.
Oracle9i logs all compilation errors both to loadjavas logle and the USER_ ERRORS view.
Specify compiler options on the loadjava command line. You can specify the encoding option on the loadjava command line. Specify persistent compiler options in a per-schema database table called JAVA$OPTIONS. Every time you compile, the compiler uses these options. However, any specied compiler options on the loadjava command override the options dened in this table. You must create this table yourself if you wish to specify compiler options this way. See "Compiler Options Specied in a Database Table" on page 2-10 for instructions on how to create the JAVA$OPTIONS table.
Default Compiler Options Compiler Options on the Command Line Compiler Options Specied in a Database Table
Default Compiler Options When compiling a source schema object for which there is neither a JAVA$OPTIONS entry nor a command line value for an option, the compiler assumes a default value as follows:
s
encoding = System.getProperty("file.encoding");
online = true: See the Oracle9i SQLJ Developers Guide and Reference for a description of this option, which applies only to Java sources that contain SQLJ constructs. debug = true: This option is equivalent to javac -g.
Compiler Options on the Command Line The loadjava compiler option, encoding, identies the encoding of the .java le. This option overrides any matching value in the JAVA$OPTIONS table. The values are identical to the javac -encoding option. This option is relevant only when loading a source le. Compiler Options Specied in a Database Table Each JAVA$OPTIONS row contains the names of source schema objects to which an option setting applies; you can use multiple rows to set the options differently for different source schema objects. You can set JAVA$OPTIONS entries by means of the following functions and procedures, which are dened in the database package DBMS_JAVA:
s
PROCEDURE set_compiler_option(name VARCHAR2, option VARCHAR2, value VARCHAR2); FUNCTION get_compiler_option(name VARCHAR2, option VARCHAR2) RETURNS VARCHAR2; PROCEDURE reset_compiler_option(name VARCHAR2, option VARCHAR2);
option
A schema does not initially have a JAVA$OPTIONS table. To create a JAVA$OPTIONS table, use the DBMS_JAVA packages java.set_compiler_ option procedure to set a value. The procedure will create the table if it does not exist. Specify parameters in single quotes. For example:
2-10
Table 21 represents a hypothetical JAVA$OPTIONS database table. The pattern match rule is to match as much of the schema name against the table entry as possible. The schema name with a higher resolution for the pattern match is the entry that applies. Because the table has no entry for the encoding option, the compiler uses the default or the value specied on the command line. The online option shown in the table matches schema object names as follows:
s
The name a.b.c.d matches class and package names beginning with a.b.c.d; the packages and classes are compiled with online = true. The name a.b matches class and package names beginning with a.b. The name a.b does not match a.b.c.d; therefore, the packages and classes are compiled with online = false. All other packages and classes match the empty string entry and are compiled with online = true.
a.b.c.dmatches the pattern exactly. a.b.c.d.erst part matches the pattern exactly; no other rule matches full name. a.bmatches the pattern exactly a.b.c.xrst part matches the pattern exactly; no other rule matches beyond specied rule name. a.cno pattern match with any dened name; defaults to (empty string) rule x.yno pattern match with any dened name; defaults to (empty string) rule
a.b
online
false
s s
(empty string)
online
true
Automatic Recompilation
Oracle9i provides a dependency management and automatic build facility that will transparently recompile source programs when you make changes to the source or binary programs upon which they depend. Consider the following cases:
public class A
{ B b; public void assignB () {b = new B()} } public class { C c; public } public class { A a; public } B
The system tracks dependencies at a class level of granularity. In the preceding example, you can see that classes A, B, and C depend on one another, because A holds an instance of B, B holds an instance of C, and C holds an instance of A. If you change the denition of class A by adding a new eld to it, the dependency mechanism in Oracle9i ags classes B and C as invalid. Before you use any of these classes again, Oracle9i attempts to resolve them again and recompile, if necessary. Note that classes can be recompiled only if source is present on the server. The dependency system enables you to rely on Oracle9i to manage dependencies between classes, to recompile, and to resolve automatically. You must force compilation and resolution yourself only if you are developing and you want to nd problems early. The loadjava utility also provides the facilities for forcing compilation and resolution if you do not want to allow the dependency management facilities to perform this for you.
2-12
schema is SCOTT, the database resolver (the database replacement for CLASSPATH) searches the SCOTT schema before PUBLIC. The listing of schemas to search is known as a resolver spec. Resolver specs are per-class, whereas in a classic Java virtual machine, CLASSPATH is global to all classes. When locating and resolving the interclass dependencies for classes, the resolver marks each class as valid or invalid, depending on whether all interdependent classes are located. If the class that you load contains a reference to a class that is not found within the appropriate schemas, the class is listed as invalid. Unsuccessful resolution at runtime produces a class not found exception. Furthermore, runtime resolution can fail for lack of database resources if the tree of classes is very large.
Note: As with the Java compiler, loadjava resolves references to
classes, but not to resources. Be sure to correctly load the resource les that your classes need. For each interclass reference in a class, the resolver searches the schemas specied by the resolver spec for a valid class schema object that satises the reference. If all references are resolved, the resolver marks the class valid. A class that has never been resolved, or has been resolved unsuccessfully, is marked invalid. A class that depends on a schema object that becomes invalid is also marked invalid. To make searching for dependent classes easier, Oracle9i provides a default resolver and resolver spec that searches rst the deners schema and then PUBLIC. This covers most of the classes loaded within the database. However, if you are accessing classes within a schema other than your own or PUBLIC, you must dene your own resolver spec.
s
loading using Oracles default resolver, which searches the deners schema and PUBLIC: loadjava -resolve
loading using your own resolver spec denition containing the SCOTT schema, OTHER schema, and PUBLIC: loadjava -resolve -resolver "((* SCOTT)(* OTHER)(* PUBLIC))"
The -resolver option species the objects to search within the schemas dened. In the example above, all class schema objects are searched within SCOTT, OTHER, and PUBLIC. However, if you wanted to search for only a certain class or group of classes within the schema, you could narrow the scope for the search. For example,
to search only for the classes "my/gui/*" within the OTHER schema, you would dene the resolver spec as follows:
loadjava -resolve -resolver ((* SCOTT) ("my/gui/*" OTHER) (* PUBLIC))
The rst parameter within the resolver spec is for the class schema object; the second parameter denes the schema within which to search for these class schema objects.
In addition, you can dene that all classes not found are to be ignored. Without the wildcard, if a dependent class is not found within one of the schemas, your class is listed as invalid and cannot be run. However, this is also dangerous, because if there is a dependent class on a used class, you mark a class as valid that can never run without the dependent class. In this case, you will receive an exception at runtime. To ignore all classes not found within SCOTT or PUBLIC, specify the following resolver spec:
loadjava -resolve -resolver "((* SCOTT) (* PUBLIC) (* -))"
classes is with the -gemissing option of loadjava. This option causes loadjava to create and load denitions of classes that are referenced, but not dened. For more details, see "loadjava" on page 2-2.
2-14
ByteCode Verifier
According to the JVM specication, .class les are subject to verication before the class they dene is available in a JVM. In Oracle9i JVM, the verication process occurs at class resolution. The resolver might nd one of the following problems and issue the appropriate Oracle error code: ORA-29545 If the resolver determines that the class is malformed, the resolver does not mark it valid. When the resolver rejects a class, it issues an ORA-29545 error (badly formed class). The loadjava tool reports the error. For example, this error is thrown if the contents of a .class le are not the result of a Java compilation or if the le has been corrupted. In some situations, the resolver allows a class to be marked valid, but will replace bytecodes in the class to throw an exception at runtime. In these cases, the resolver issues an ORA-29552 (verication warning), which loadjava will report. The loadjava tool issues this warning when the Java Language Specication would require an IncompatibleClassChangeError be thrown. Oracle9i JVM relies on the resolver to detect these situations, supporting the proper runtime behavior that the JLS requires.
ORA-29552
Resolvers containing - This type of resolver marks your class valid regardless of whether classes it references are present. Because of inheritance and interfaces, you may want to write valid Java methods that use an instance of a class as if it were an instance of a superclass or of a specic interface. When the method being veried uses a reference to class A as if it were a reference to class B, the resolver must check that A either extends or implements B. For example, consider the potentially valid method below, whose signature implies a return of an instance of B, but whose body returns an instance of A:
B myMethod(A a) { return a; }
The method is valid only if A extends B, or A implements the interface B. If A or B have been resolved using a - term, the resolver does not know that this method is safe. It will replace the bytecodes of myMethod with bytecodes that throw an Exception if myMethod is ever called.
s
The resolver ensures that the class denitions of A and B are found and resolved properly if they are present in the schemas they specically identify. The only time you might consider using the alternative resolver is if you must load an existing JAR le containing classes that reference other non-system classes that are not included in the JAR le. For more information on class resolution and loading your classes within the database, see Chapter 7, "Schema Object Tools".
Loading Classes
This section gives an overview of loading your classes into the database using the loadjava tool. You can also execute loadjava within your SQL. See Chapter 7, "Schema Object Tools" for complete information on loadjava. Unlike a conventional Java virtual machine, which compiles and loads from les, the Oracle9i Java virtual machine compiles and loads from database schema objects.
.java source les or .sqlj source les .class compiled Java les .properties Java resource les, .ser SQLJ prole les, or data les correspond to Java source schema objects correspond to Java class schema objects correspond to Java resource schema objects
You must load all classes or resources into the database to be used by other classes within the database. In addition, at loadtime, you dene who can execute your classes within the database.
2-16
The loadjava tool performs the following for each type of le:
Table 22 loadjava Operatoins on Schema Objects
Schema Object .java source les loadjava Operations on Objects
1. 2. 3. 4.
It creates a source schema object within the deners schema unless another schema is specied. It loads the contents of the source le into a schema object. It creates a class schema object for all classes dened in the source le. If -resolve is requested, it does the following: a. It compiles the source schema object. b. It resolves the class and its dependencies. c. It stores the compiled class into a class schema object.
1. 2. 3. 4.
It creates a source schema object within the deners schema unless another schema is specied. It loads contents of the source le into the schema object. It creates a class schema object for all classes and resources dened in the source le. If -resolve is requested, it does the following: a. It translates and compiles the source schema object. b. It stores the compiled class into a class schema object. c. It stores the prole into a .ser resource schema object and customizes it.
1. 2. 3.
It creates a class schema object within the deners schema unless another schema is specied. It loads the class le into the schema object. It resolves and veries the class and its dependencies if -resolve is specied. It creates a resource schema object within the deners schema unless another schema is specied. It loads a resource le into a schema object. It creates a resource schema object within the deners schema unless another schema is specied. It loads the .ser resource le into a schema object and customizes it.
1. 2.
1. 2.
The dropjava tool performs the reverse of the loadjava tool: it deletes schema objects that correspond to Java les. Always use dropjava to delete a Java schema object created with loadjava. Dropping with SQL DDL commands will not update auxiliary data maintained by loadjava and dropjava. You can also execute dropjava from within SQL commands.
Note: More options for loadjava are available. However, this section discusses only the major options. See Chapter 7, "Schema Object Tools" for complete information on loadjava and dropjava.
You must abide by certain rules, which are detailed in the following sections, when loading classes into the database:
s
Dening the Same Class Twice Designating Database Privileges and JVM Permissions Loading JAR or ZIP Files
After loading, you can access the USER_OBJECTS view in your database schema to verify that your classes and resources loaded properly. For more information, see "Checking Java Uploads" on page 2-23.
You can load either a particular Java .class le or its .java le, but not both. Oracle9i tracks whether you loaded a class le or a source le. If you wish to update the class, you must load the same type of le that you originally loaded. If you wish to update the other type, you must drop the rst before loading the second. For example, if you loaded x.java as the source for class y, to load x.class, you must rst drop x.java.
You cannot dene the same class within two different schema objects within the same schema. For example, suppose x.java denes class y and you want to move the denition of y to z.java. If x.java has already been loaded, loadjava rejects any attempt to load z.java (which also denes y). Instead, do either of the following:
2-18
Drop x.java, load z.java (which denes y), then load the new x.java (which does not dene y). Load the new x.java (which does not dene y), then load z.java (which denes y).
CREATE PROCEDURE and CREATE TABLE privileges to load into your schema. CREATE ANY PROCEDURE and CREATE ANY TABLE privileges to load into another schema. oracle.aurora.security.JServerPermission.loadLibraryInClass. <classname>. See "Permission for Loading Classes" on page 5-25 for more information.
allow other users (schemas) the right to execute your class through the loadjava -grant option. You can grant execution rights to a certain user or schema. You cannot grant execution rights to a role, which includes the super-user DBA role. The setting of execution rights is the same as used to grant or revoke privileges in SQL DDL statements.
Figure 22 Execution Rights
Class A
Class B
Class C
Method invocation: Class A invokes class B; class B invokes class C. Execution rights for classes: * Class A needs execution rights for B. * Class A does not need execution rights for C. * Class B needs execution rights for C. For information on JVM security permissions, see Chapter 6, "Oracle9i Java Application Performance".
2-20
analyze
(IR)
sales
sales
Occasionally, you might want to override the default invoker-rights behavior. Suppose headquarters would like the procedure analyze to calculate sales commissions and update a central payroll table. That presents a problem because invokers of analyze should not have direct access to the payroll table, which stores employee salaries and other sensitive data. As Figure 24 shows, the solution is to have procedure analyze call the dener-rights (DR) procedure calcComm, which, in turn, updates the payroll table.
Figure 24 Indirect Access
Schema WEST Schema HQ analyze
(IR)
Schema EAST
calc_comm
(DR)
sales payroll
sales
To override the default invoker-rights behavior, specify the loadjava option -definer, which is similar to the UNIX facility setuid, except that -definer
2-22
applies to individual classes, not whole programs. Alternatively, you can execute the SQL DDL that changes the AUTHID of the current user. Different deners can have different privileges, and applications can consist of many classes. So, use the option -definer carefully, making sure that classes have only the privileges they need.
This routine shows you the Java source schema objects in full name format. Where no short name is used, no conversion occurs, because the short name and full name are identical.
You can use the SHORTNAME() routine of the DBMS_JAVA package to use a full name as a query criterion, without having to know whether it was converted to a short name in the database.
SQL*Plus> SELECT object_type FROM user_objects WHERE object_name=dbms_java.shortname(known_fullname);
This routine shows you the OBJECT_TYPE of the schema object of the specied full name. This presumes that the full name is representable in the database character set.
SVRMGR> select * from javasnm; SHORT LONGNAME ---------------------------------------------------------------------/78e6d350_BinaryExceptionHandl sun/tools/java/BinaryExceptionHandler /b6c774bb_ClassDeclaration sun/tools/java/ClassDeclaration /af5a8ef3_JarVerifierStream1 sun/tools/jar/JarVerifierStream$1
Status
STATUS is a character string that indicates the validity of a Java schema object. A source schema object is VALID if it compiled successfully; a class schema object is VALID if it was resolved successfully. A resource schema object is always VALID, because resources are not resolved. Example: Accessing USER_OBJECTS The following SQL*Plus script accesses the USER_OBJECTS view to display information about uploaded Java sources, classes, and resources.
COL object_name format a30 COL object_type format a15 SELECT object_name, object_type, status FROM user_objects WHERE object_type IN (JAVA SOURCE, JAVA CLASS, JAVA RESOURCE) ORDER BY object_type, object_name;
You can optionally use wildcards in querying USER_OBJECTS, as in the following example.
SELECT object_name, object_type, status FROM user_objects WHERE object_name LIKE %Alerter;
This routine nds any OBJECT_NAME entries that end with the characters: Alerter.
2-24
For more information about USER_OBJECTS, see the Oracle9i Java Stored Procedures Developers Guide.
Publishing
Oracle9i enables clients and SQL to invoke Java methods that are loaded within the database, once published. You publish either the object itself or individual methods. If you write a Java stored procedure that you intend to invoke with a trigger, directly or indirectly in SQL DML or in PL/SQL, you must publish individual methods within the class. Specify how to access it through a call specication. Java programs consist of many methods in many classes; however, only a few static methods are typically exposed with call specications. See the Oracle9i Java Stored Procedures Developers Guide for more details.
A similar issue exists for vendors of Java-powered embedded devices and in handheld devices (known as Personal Java). Future releases of Java and the Java Compatibility Kit will provide improved factorization of user interface support so that vendors of Java server platforms can better address this issue.
This function returns the longname from a Java schema object. An example is to print the fully qualied name of classes that are invalid for some reason.
select dbms_java.longname (object_name) from user_objects where object_type = 'JAVA CLASS' and status = 'INVALID';
In addition, you can specify a full name to the database by using the shortname() routine of the DBMS_JAVA package, which takes a full name as input and returns the corresponding short name. This is useful when verifying that your classes loaded by querying the USER_OBJECTS view.
FUNCTION shortname (longname VARCHAR2) RETURN VARCHAR2
2-26
Class.forName() in Oracle9i
Refer to the Oracle9i Java Stored Procedures Developers Guide for a detailed example of the use of this function and ways to determine which Java schema objects are present on the server.
Class.forName() in Oracle9i
The Java Language Specication provides the following description of Class.forName(): Given the fully-qualied name of a class, this method attempts to locate, load, and link the class. If it succeeds, a reference to the Class object for the class is returned. If it fails, a ClassNotFoundException is thrown. Class lookup is always on behalf of a referencing class through a ClassLoader. The difference between the JDK implementation and the Oracle9i JVM implementation is the method on which the class is found:
s
The JDK uses one ClassLoader that searches the set of directory tree roots specied by the environment variable CLASSPATH. Oracle9i JVM denes several resolvers, which dene how to locate classes. Every class has a resolver associated with it, and each class can, potentially, have a different resolver. When you execute a method that calls Class.forName(), the resolver of the currently executing class (this) is used to locate the class. See "Resolving Class Dependencies" on page 2-12 for more information on resolvers.
You can receive unexpected results if you try to locate a class with an unexpected resolver. For example, if a class X in schema X requests a class Y in schema Y to look up class Z, you can experience an error if you expected class Xs resolver to be used. Because class Y is performing the lookup, the resolver associated with class Y is used to locate class Z. In summary, if the class exists in another schema and you specied different resolvers for different classesas would happen by default if they are in different schemas you might not nd the class. You can solve this resolver problem as follows:
s
Avoid any class name lookup by passing the Class object itself. Supply the ClassLoader in the Class.forName method. Supply the class and the schema it resides into classForNameAndSchema method. Supply the schema and class name to ClassForName.lookupClass.
Class.forName() in Oracle9i
Serialize your objects with the schema name with the class name.
Note: Another unexpected behavior can occur if system classes
invoke Class.forName(). The desired class is found only if it resides in SYS or in PUBLIC. If your class does not exist in either SYS or PUBLIC, you can declare a PUBLIC synonym for the class.
The following examples show how to supply the class loader of either the current class instance or the calling class instance.
Example 21 Retrieve Resolver from Current Class
You can retrieve the class loader of any instance through the Class.getClassLoader method. The following example retrieves the class loader of the class represented by instance x.
Class c1 = Class.forName (x.whatClass(), true, x.getClass().getClassLoader());
You can retrieve the class of the instance that invoked the executing method through the oracle.aurora.vm.OracleRuntime.getCallerClass method. Once you retrieve the class, invoke the Class.getClassLoader method on the returned class. The following example retrieves the class of the instance that invoked the workForCaller method. Then, its class loader is retrieved and supplied to the Class.forName method. Thus, the resolver used for looking up the class is the resolver of the calling class.
void workForCaller() { ClassLoader c1 = oracle.aurora.vm.OracleRuntime.getCallerClass().getClassLoader();
2-28
Class.forName() in Oracle9i
The following example shows how you can save the schema and class names in the save method. Both names are retrieved, and the class is located using the DbmsJava.classForNameAndSchema method.
import oracle.aurora.rdbms.ClassHandle; import oracle.aurora.rdbms.Schema; import oracle.aurora.rdbms.DbmsJava; void save (Class c1) { ClassHandle handle = ClassHandle.lookup(c1); Schema schema = handle.schema(); writeNmae (schema.getName()); writeName (c1.getName()); } Class restore() { String schemaName = readName(); String className = readName(); return DbmsJava.classForNameAndSchema (schemaName, className); }
Class.forName() in Oracle9i
Note: You must use uppercase characters for the schema name. In
oracle.aurora.rdbms.DbmsObjectOutputStream
This class extends java.io.ObjectOutputStream and adds schema names in the appropriate places.
s
oracle.aurora.rdbms.DbmsObjectInputStream
This class extends java.io.ObjectInputStream and reads streams written by DbmsObjectOutputStream. You can use this class in any environment. If used within Oracle9i, the schema names are read out and used when performing the class lookup. If used on a client, the schema names are ignored.
2-30
Class.forName() in Oracle9i
Class.forName Example
The following example shows several methods for looking up a class.
s
To use the resolver of this instances class, invoke lookupWithClassLoader. This method supplies a class loader to the Class.forName method in the from variable. The class loader specied in the from variable defaults to this class. To use the resolver from a specic class, call ForName with the designated class name, followed by lookupWithClassLoader. The ForName method sets the from variable to the specied class. The lookupWithClassLoader method uses the class loader from the specied class. To use the resolver from the calling class, rst invoke the ForName method without any parameters. It sets the from variable to the calling class. Then, invoke the lookupWithClassLoader to locate the class using the resolver of the calling class. To lookup a class in a specied schema, invoke the lookupWithSchema method. This provides the class and schema name to the classForNameAndSchema method.
import oracle.aurora.vm.OracleRuntime; import oracle.aurora.rdbms.Schema; import oracle.aurora.rdbms.DbmsJava; public class ForName { private Class from; /* Supply an explicit class to the constructor */ public ForName(Class from) { this.from = from; } /* Use the class of the code containing the "new ForName()" */ public ForName() { from = OracleRuntime.getCallerClass(); } /* lookup relative to Class supplied to constructor */ public Class lookupWithClassLoader(String name) throws ClassNotFoundException { /* A ClassLoader uses the resolver associated with the class*/ return Class.forName(name, true, from.getClassLoader()); }
/* In case the schema containing the class is known */ static Class lookupWithSchema(String name, String schema) { Schema s = Schema.lookup(schema); return DbmsJava.classForNameAndSchema(name, s); } }
Overview of Operating System Resources Garbage Collection and Operating System Resources Operating System Resources Affected Across Calls
les
2-32
sockets
Java contains classes that represent socket resources. Instances of these classes hold on to socket constructs, some of which can become invalid between calls in a session. See "Sockets" on page 2-37 for information specic to maintaining sockets across calls. Threads are discouraged within the Oracle9i JVM because of scalability issues. However, you can have a multi-threaded application within the database. "Threading in Oracle9i" on page 2-38 discusses in detail the Oracle9i JVM threading model.
threads
If an attempt is made to read from a java.io.FileInputStream that was closed at the end of a previous call, a java.io.IOException is thrown. java.lang.Thread.isAlive() is false for any Thread object running in a previous call and still accessible in a subsequent call.
Resource Sockets
Lifetime
s s s
Sockets can exist across calls. ServerSockets on a shared server terminate when the call ends. ServerSockets on a dedicated server can exist across calls.
2-34
If you do not close the in le, eventually the File object will be garbage collected. However, even if the File object is garbage collected, the operating system still believes that the le is in use, because it was not closed.
Note: You might want to use Java nalizers to close resources.
However, nalizers are not guaranteed to run in a timely manner. Instead, nalizers are put on a queue to execute when the garbage collector has time. If you close your resources within your nalizer, it might not be freed up until the JVM exits. The best approach is to close your resources within the method.
There is a workaround: to make sure that your handles stay valid, close your les, buffers, and so on, at the end of every call; reopen the resource at the beginning of the next call. Another option is to use the database rather than using operating system resources. For example, try to use database tables rather than a le. Or do not store operating system resources within static objects expected to live across calls; use operating system resources only within objects local to the call. Example 26 shows how you can perform concatenation, as in Example 25, without compromising your operating system resources. The addFile method opens the outme.txt le within each call, making sure that anything written into the le is appended to the end. At the end of each call, the le is closed. Two things occur:
1. 2.
The File object no longer exists outside of a call. The operating system resource, the outme.txt le, is reopened for each call. If you had made the File object a static variable, the closing of outme.txt within each call would ensure that the operating system resource is not compromised.
2-36
FileReader in = new FileReader(inFile); int i; while ((i = in.read()) != -1) out.write(i); in.close(); /*close the output file between calls*/ out.close(); } }
Sockets
Sockets are used in setting up a connection between a client and a server. For each database connection, sockets are used at either end of the connection. Your application does not set up the connection; the connection is set up by the underlying networking protocol: Oracle Nets TTC or IIOP. See "Conguring Oracle JVM" on page 4-2 for information on how to congure your connection. You might also wish to set up another connectionfor example, connecting to a specied URL from within one of the classes stored within the database. To do so, instantiate sockets for servicing the client and server sides of the connection.
s
The java.net.Socket() constructor creates a client socket. The java.net.ServerSocket() constructor creates a server socket.
A socket exists at each end of the connection. The server-side of the connection that listens for incoming calls is serviced by a ServerSocket. The client-side of the connection that sends requests is serviced through a Socket. You can use sockets as dened within the JVM with the following restriction: a ServerSocket instance within a shared server cannot exist across calls. Socket Because the client-side of the connection is outbound, the Socket instance can be serviced across calls within either a shared or dedicated server.
Threading in Oracle9i
Dedicated serverYour ServerSocket can listen across calls only within a dedicated server; the dedicated server exists solely for servicing the single client. Shared serverThe ServerSocket is closed at the end of a call within a shared server; the shared servers move on to another client at the end of every call. You will receive an I/O exception stating that the socket was closed if you try to use the ServerSocket outside of the call it was created in.
Threading in Oracle9i
The Oracle9i JVM implements a non-preemptive threading model. With this model, the JVM runs all Java threads on a single operating system thread. It schedules them in a round-robin fashion and switches between them only when they block. Blocking occurs when you, for example, invoke the Thread.yield() method or wait on a network socket by invoking mySocket.read().
Advantages of Oracle9is Threading Model
s s
Disadvantages
s s s
simple to program efcient to implement in the Java virtual machine, because a thread switch does not require any system calls safer, because the JVM can detect a deadlock that would hang a preemptive JVM and can then raise a runtime exception
does not exhibit any concurrency lack of portability performance considerations, because of the system calls required for locking when blocking the thread memory scalability, because efcient multi-threaded memory allocation requires a larger pool of memory
Oracle chose this model because any Java application written on a single-processor system works identical to one written on a multi-processor system. Also, the lack of concurrency among Java threads is not an issue, because Oracle9i JVM is embedded in the database, which provides a higher degree of concurrency than any conventional JVM. There is no need to use threads within the application logic because the Oracle server preemptively schedules the session JVMs. If you must support hundreds or thousands of simultaneous transactions, start each one in its own JVM. This is exactly what happens when you create a session in the Oracle9i JVM. The normal transactional capabilities of the Oracle database server accomplish coordination and
2-38
Threading in Oracle9i
data transfer between the JVMs. This is not a scalability issue, because in contrast to the 6 MB-8 MB memory footprint of the typical Java virtual machine, the Oracle server can create thousands of JVMs, with each one taking less than 40 KB. Threading is managed within the Oracle9i JVM by servicing a single thread until it completes or blocks. If the thread blocks, by yielding or waiting on a network socket, the JVM will service another thread. However, if the thread never blocks, it is serviced until completed. The Oracle9i JVM has added the following features for better performance and thread management:
s
System calls are at a minimum. Oracle9i JVM has exchanged some of the normal system calls with non-system solutions. For example, entering a monitor-synchronized block or method does not require a system call. Deadlocks are detected. * The Oracle9i JVM monitors for deadlocks between threads. If a deadlock occurs, the Oracle9i JVM terminates one of the threads and throws the oracle.aurora.vm.DeadlockError exception. Single-threaded applications cannot suspend. If the application has only a single thread and you try to suspend it, the oracle.aurora.vm.LimboError exception is thrown.
Thread Lifecycle
In the single-threaded execution case, the call ends when one of the following events occurs:
1. 2. 3.
The thread returns to its caller. An exception is thrown and is not caught in Java code. The System.exit(), oracle.aurora.vm.OracleRuntime.exitCall() method is invoked.
If the initial thread creates and starts other Java threads, the rules about when a call ends are slightly more complicated. In this case, the call ends in one of the following two ways:
1.
The main thread returns to its caller, or an exception is thrown and not caught in this thread, and all other non-daemon threads complete execution. Non-daemon threads complete either by returning from their initial method or because an exception is thrown and not caught in the thread.
Threading in Oracle9i
2.
When a call ends because of a return and/or uncaught exceptions, the Oracle9i JVM throws a ThreadDeathException in all daemon threads. The ThreadDeathException essentially forces threads to stop execution. When a call ends because of a call to System.exit() or oracle.aurora.vm.OracleRuntime.exitCall(), the Oracle9i JVM ends the call abruptly and terminates all threads, but does not throw ThreadDeathException. During the execution of a single call, a Java program can recursively cause more Java code to be executed. For example, your program can issue a SQL query using JDBC or SQLJ that in turn causes a trigger written in Java to be invoked. All the preceding remarks regarding call lifetime apply to the top-most call to Java code, not to the recursive call. For example, a call to System.exit() from within a recursive call will exit the entire top-most call to Java, not just the recursive call.
2-40
3
Invoking Java in the Database
This chapter gives you an overview and examples of how to invoke Java within the database.
s
Overview Invoking Java Methods Utilizing SQLJ and JDBC for Querying the Database Debugging Server Applications How To Tell You Are Executing in the Server Redirecting Output on the Server
3-1
Overview
Overview
In Oracle9i, you utilize Java in one of the following ways:
s
Invoking Java MethodsInvoke Java methods in classes that are loaded within the database, such as Java stored procedures. Utilizing SQLJ and JDBC for Querying the DatabaseYou can query the database from a Java client through utilizing JDBC or SQLJ.
We recommend that you approach Java development in Oracle9i incrementally, building on what you learn at each step.
1.
You should master the process of writing simple Java stored procedures, as explained in "Preparing Java Class Methods for Execution" on page 2-8. This includes writing the Java class, deciding on a resolver, loading the class into the database, and publishing the class. You should understand how to access and manipulate SQL data from Java. Most Java server programs, and certainly Java programs executing on Oracle9i, interact with database-resident data. The two standard APIs for accomplishing this are JDBC and SQLJ. Because JDBC forms the foundation for SQLJ, you should understand how the two work together, even though you might be using only SQLJ in your code.
2.
Java is a simple, general purpose language for writing stored procedures. JDBC and SQLJ allow Java to access SQL data. They support SQL operations and concepts, variable bindings between Java and SQL types, and classes that map Java classes to SQL types. You can write portable Java code that can execute on a client or a server without change. With JDBC and SQLJ, the dividing line between client and server is usually obviousSQL operations happen in the server, and application program logic resides in the client. As you write more complex Java programs, you can gain performance and scalability by controlling the location where the program logic executes. You can minimize network trafc and maximize locality of reference to SQL data. JDBC and SQLJ furnish ways to accomplish these goals. However, as you tend to leverage the object model in your Java application, a more signicant portion of time is spent in Java execution, as opposed to SQL data access and manipulation. It becomes more important to understand and specify where Java objects reside and execute in an Internet application.
3-2
Utilizing Java Stored Procedures Utilizing Remote Method Invocation (RMI) Utilizing Java Native Interface (JNI) Support Utilizing SQLJ and JDBC for Querying the Database
Write the Java class. Dene a class, Hello, with one method, Hello.world(), that returns the string Hello world.
public class Hello { public static String world () { return "Hello world"; } }
2.
Compile the class on your client system. Using the Sun Microsystems JDK, for example, invoke the Java compiler, javac, as follows:
javac Hello.java
Normally, it is a good idea to specify your CLASSPATH on the javac command line, especially when writing shell scripts or make les. The Java compiler produces a Java binary lein this case, Hello.class.
3-3
Keep in mind where this Java code will execute. If you execute Hello.class on your client system, it searches the CLASSPATH for all supporting core classes it must execute. This search should result in locating the dependent class in one of the following:
s
as an individual le in a directory, where the directory is specied in the CLASSPATH within a .jar or .zip le, where the directory is specied in the CLASSPATH
3.
Decide on the resolver for your class. In this case, you load Hello.class in the server, where it is stored in the database as a Java schema object. When you execute the world() method of the Hello.class on the server, it nds the necessary supporting classes, such as String, using a resolverin this case, the default resolver. The default resolver looks for classes in the current schema rst and then in PUBLIC. All core class libraries, including the java.lang package, are found in PUBLIC. You may need to specify different resolvers, and you can force resolution to occur when you use loadjava, to determine if there are any problems earlier, rather than at runtime. Refer to "Resolving Class Dependencies" on page 2-12 or Chapter 7, "Schema Object Tools" for more details on resolvers and loadjava.
4.
Load the class on the Oracle9i server using loadjava. You must specify the username and password.
loadjava -user scott/tiger Hello.class
5.
Publish the stored procedure through a call specication. To invoke a Java static method with a SQL CALL, you must publish it with a call specication. A call specication denes for SQL which arguments the method takes and the SQL types it returns. In SQL*Plus, connect to the database and dene a top-level call specication for Hello.world():
SQL> connect scott/tiger connected SQL> create or replace function HELLOWORLD return VARCHAR2 as 2 language java name 'Hello.world () return java.lang.String'; 3 / Function created.
6.
3-4
variable myString varchar2[20]; call HELLOWORLD() into :myString; completed. print myString;
The call HELLOWORLD() into :myString statement performs a top-level call in Oracle9i. The Oracle-specic select HELLOWORLD from DUAL also works. Note that SQL and PL/SQL see no difference between a stored procedure that is written in Java, PL/SQL, or any other language. The call specication provides a means to tie inter-language calls together in a consistent manner. Call specications are necessary only for entry points invoked with triggers or SQL and PL/SQL calls. Furthermore, JDeveloper can automate the task of writing call specications. For more information on Java stored procedures, using Java in triggers, call specications, rights models, and inter-language calls, refer to the Oracle9i Java Stored Procedures Developers Guide.
3-5
Oracle does not support the use of JNI in Oracle9i Java applications. If you use JNI, your application is not 100% pure Java, and the native methods require porting between platforms. Native methods have the potential for crashing the server, violating security, and corrupting data.
JDBC
JDBC is an industry-standard API developed by Sun Microsystems that allows you to embed SQL statements as Java method arguments. JDBC is based on the X/Open SQL Call Level Interface and complies with the SQL92 Entry Level standard. Each vendor, such as Oracle, creates its JDBC implementation by implementing the interfaces of the Sun Microsystems java.sql package. Oracle offers three JDBC drivers that implement these standard interfaces:
1. 2. 3.
The JDBC Thin driver, a 100% pure Java solution you can use for either client-side applications or applets and requires no Oracle client installation. The JDBC OCI drivers, which you use for client-side applications and requires an Oracle client installation. The server-side JDBC driver embedded in the Oracle9i server.
For the developer, using JDBC is a step-by-step process of creating a statement object of some type for your desired SQL operation, assigning any local variables that you want to bind to the SQL operation, and then executing the operation. This process is sufcient for many applications but becomes cumbersome for any complicated statements. Dynamic SQL operations, where the operations are not known until runtime, require JDBC. In typical applications, however, this represents a minority of the SQL operations.
3-6
SQLJ
SQLJ offers an industry-standard way to embed any static SQL operation directly into Java source code in one simple step, without requiring the individual steps of JDBC. Oracle SQLJ complies with ANSI standard X3H2-98-320. SQLJ consists of a translatora precompiler that supports standard SQLJ programming syntaxand a runtime component. After creating your SQLJ source code in a .sqlj le, you process it with the translator, which translates your SQLJ source code to standard Java source code, with SQL operations converted to calls to the SQLJ runtime. In the Oracle SQLJ implementation, the translator invokes a Java compiler to compile the Java source. When your Oracle SQLJ application runs, the SQLJ runtime calls JDBC to communicate with the database. SQLJ also allows you to catch errors in your SQL statements before runtime. JDBC code, being pure Java, is compiled directly. The compiler has no knowledge of SQL, so it is unaware of any SQL errors. By contrast, when you translate SQLJ code, the translator analyzes the embedded SQL statements semantically and syntactically, catching SQL errors during development, instead of allowing an end-user to catch them when running the application.
3-7
Dene the Java variables name, id, and salary. Dene a prepared statement (this presumes you have already established a connection to the database so that you can use the prepareStatement() method of the connection object). You can use a prepared statement whenever values within the SQL statement must be dynamically set. You can use the same prepared statement repeatedly with different variable values. The question marks in the prepared statement are placeholders for Java variables and are given values in the pstmt.setInt() and pstmt.setFloat() lines of code. The rst ? is set to the int variable id (with a value of 37115). The second ? is set to the float variable salary (with a value of 20000).
3. 4.
Execute the query and return the data into a JDBC result set object. (You can use result sets to gather query data.) Retrieve the data of interest (the name) from the result set and print it. A result set usually contains multiple rows of data, although this example has only one row.
By comparison, here is some SQLJ code that performs the same task. Note that all SQLJ statements, both declarations and executable statements, start with the #sql token. SQLJ:
String name; int id=37115; float salary=20000; #sql {select ename into :name from emp where empno=:id and sal>:salary}; System.out.println(Name is: + name);
SQLJ, in addition to allowing SQL statements to be directly embedded in Java code, supports Java host expressions (also known as bind expressions) to be used directly in the SQL statements. In the simplest case, a host expression is a simple variable as in this example, but more complex expressions are allowed as well. Each host expression is preceded by : (colon). This example uses Java host expressions name, id, and salary. In SQLJ, because of its host expression support, you do not need a result set or equivalent when you are returning only a single row of data.
3-8
Declare your iterators. SQLJ uses a strongly typed version of JDBC result sets, known as iterators. The main difference between the two is that an iterator has a specic number of columns of specic datatypes. You must dene your iterator types beforehand, as in this example:
#sql iterator MyIter (String ename, int empno, float sal);
This declaration results in SQLJ creating an iterator class MyIter. Iterators of type MyIter can store results whose rst column maps to a Java String, whose second column maps to a Java int, and whose third column maps to a Java float. This denition also names the three columnsename, empno, and sal, respectivelyto match the table column names in the database. MyIter is a named iterator. See Chapter 3 of the Oracle9i SQLJ Developers Guide and Reference to learn about positional iterators, which do not require column names.
2.
3-9
Oracle.connect("jdbc:oracle:thin:@oow11:5521:sol2","scott", "tiger");
Oracle SQLJ furnishes the Oracle class, and its connect() method accomplishes three important things:
a. b.
Registers the Oracle JDBC drivers that SQLJ uses to access the database. Opens a database connection for the specied schema (user scott, password tiger) at the specied URL (host oow11, port 5521, SID so12, thin JDBC driver). Establishes this connection as the default connection for your SQLJ statements. Although each JDBC statement must explicitly specify a connection object, a SQLJ statement can either implicitly use a default connection or optionally specify a different connection.
c.
3.
#sql {insert into emp (ename, empno, sal) values ('SALMAN', 32, 20000)}; b.
The next() method is common to all iterators and plays the same role as the next() method of a JDBC result set, returning true and moving to the next row of data if any rows remain. You access the data in each row by calling iterator accessor methods whose names match the column names (this is a characteristic of all named iterators). In this example, you access the data using the methods ename(), empno(), and sal().
3-10
caught until a user runs your application. Furthermore, if changes are subsequently made to the schema, you can determine if this affects the application simply by re-running the translator.
The SQLJ translator checks the syntax and semantics of your SQL operations. You can enable online checking to check your operations against the database. If you choose to do this, you must specify an example database schema in your translator option settings. It is not necessary for the schema to have identical data to the one the program will eventually run against; however, the tables should have columns with corresponding names and datatypes. Use the user option to enable online checking and specify the username, password, and URL of your schema, as in the following example:
%sqlj -user=scott/tiger@jdbc:oracle:thin:@oow11:5521:sol2 MyExample.sqlj
There are no explicit database connections for code running in the server, only a single implicit connection. You do not need the usual connection code. If you are porting an existing client-side application, you do not have to remove your connection code, because it will be ignored. The JDBC server-side internal driver does not support auto-commit functionality. Use SQLJ syntax for manual commits and rollbacks of your transactions.
On the server, the default output device is a trace le, not the user screen. This is normally an issue or question only for development, because you would not write to System.out in a deployed server application.
To run a SQLJ program in the server, presuming you developed the code on a client, you have two options:
s
Translate your SQLJ source code on the client and load the individual components (Java classes and resources) to the server. In this case, it is easiest to bundle them into a .jar le rst. Load your SQLJ source code to the server for the embedded translator to translate.
In either case, use the Oracle loadjava utility to load the le or les to the server. See the Oracle9i SQLJ Developers Guide and Reference for more information.
Create a .jar le for your application components. Use the loadjava utility to load the .jar le to the server. Create a SQL wrapper in the server for your application. For example, to run the preceding MyExample application in the server:
create or replace procedure SQLJ_MYEXAMPLE as language java name MyExample.main(java.lang.String[]);
You can then execute SQLJ_MYEXAMPLE, as with any other stored procedure.
3-12
The debug Agent protocol that was introduced in Oracle8i, and is supported by JDK 1.2 and later versions of JDB. The class DebugProxy makes remote Java programs appear to be local. It lets any debugger that supports the sun.tools.debug.Agent protocol connect to a program as if the program were local. The proxy forwards requests to the server and returns results to the debugger. For detailed instructions, see the Oracle9i Java Developers Guide.
The Java Debug Wire Protocol supported by JDK 1.3 and later versions of the Sun Microsystems JDB debugger (http://java.sun.com/j2se/1.3/docs/guide/jpda/, http://java.sun.com/j2se/1.4/docs/guide/jpda/.) The use of this interface is documented on OTN. The JDWP protocol supports many new features, including the ability to listen for connections (no more DebugProxy), change the values of variables while debugging, and evaluate arbitrary Java expressions, including method evaluation. Oracle's JDeveloper provides a user-friendly integration with these debugging features. See the JDeveloper documentation for more information on how to debug your Java application through JDeveloper. Other independent IDE vendors will be able to integrate their own debuggers with Oracle9i.
1. Prepare code
connect
4. jdb 2.Start
DebugProxy
attach
3. Start DebugAgent
As shown in Figure 31, the steps for remotely debugging your Java application are as follows:
1. 2. 3. 4.
Prepare your code for debugging. Start the DebugProxy. The DebugProxy waits for a DebugAgent to attach to it from the server. Start the DebugAgent giving it the debug proxy address. This starts the communication between the debug agent and the debug proxy. Attach the jdb debugger to the debug proxy. Once attached, use the regular jdb commands.
Inform the server to compile the class with the debug option through the set_compiler_option procedure, as follows:
SQL> call dbms_java.set_compiler_option(myPackage.myCode,debug,true);
3-14
Note: The set_compiler_option procedure species many different compiler options on a certain class, package, or all classes. This example shows setting the option for a single class. See "loadjava" on page 7-7 for more information on this procedure.
Then, you must load the source code using loadjava, as follows:
% loadjava -u SCOTT/TIGER -v -f -r myCode.java
The server will compile this class with the debug option. Also, the server now has access to both the source and the compiled binary, which the debug agent needs for showing the breakpoints.
s
Compile your code on the client with the -g option, load the compiled class into the server, and copy the Java source le to the le system where Oracle9i exists, as follows:
% % % > > javac -g MyCode.java loadjava -u SCOTT/TIGER -v -f -r myCode.class ftp dbhost cd /private/sourcecode put myCode.java
When jdb starts, set the location of the source code with jdbs use command. This enables the debug agent to nd the source code.
> use /private/sourcecode
must have the correct FilePermission. See the Security chapter for more information.
debugproxy
The proxy prints out its name, its address, and the port it is waiting on.
Proxy Name: yourmachinename Proxy Address: aaa.bbb.ccc.ddd Proxy Port: 2286
However, the easiest method to start the DebugProxy is to append a command to start up the jdb debugger at the end of the debugproxy command. The debugproxy command takes in any option given, beyond the optional port, as a command to execute after it has started. If you choose this method, you do not need to execute step 4. For UNIX, provide the following within an executable shell script called startjdb:
#!/bin/sh xterm -e jdb -password &1 &
Then, you can automatically start up the jdb debugger within the debugproxy command, as follows:
debugproxy -port 1638 startjdb
For all Windows NT environments, provide the following within a batch le called startjdb.bat:
start jdb -password %1
Then, you can automatically start up the jdb debugger within the debugproxy command, as follows:
debugproxy -port 1638 startjdb.bat
3-16
granted to your user to run a debug agent. See "Debugging Permissions" in the Oracle9i Java Developers Guide for more information. Once a proxy is running, you can start a debug agent to connect to the proxy from SQL*Plus. You must specify the IP address or URL for a machine running a debug proxy, the port the proxy is waiting on, and a timeout in seconds. You start and stop the debug agent using methods specied within the DBMS_JAVA package.
SQL> call dbms_java.start_debugging('yourmachinename', 2286, 66);
There is no way to cause server-resident code to execute and break, that is, execute and remain indenitely in a halted mode. Instead, when you start the DebugAgent, you must specify a timeout period for the DebugAgent to wait before terminating. The start call waits until the timeout expires or until the main thread is suspended and resumed before it completes. Calculate a timeout that includes enough time for your debugger to start up, but not so much as to delay your session if you cannot connect a debugger.
Note: If an agent is already running, the Oracle9i JVM stops it and
starts a new agent. Stop the debug agent explicitly through the stop_debugging method. SQL> call dbms_java.stop_debugging(); Once a debug agent starts, it runs until you stop it, the debugger disconnects, or the session ends. Restart a stopped agent with any breakpoints still set with the restart_ debugging method. The call waits until the timeout expires before it completes. You can also restart a running agent just to buy some seconds to suspend threads and set breakpoints. SQL> call dbms_java.restart_debugging(66);
OracleAgent Class
The DBMS_JAVA debug agent and proxy calls are published entry points to static methods that reside in oracle.aurora.debug.OracleAgent class. Start, stop,
and restart the debug agent in Java code, using the class oracle.aurora.debug.OracleAgent directly, through the following methods:
public static void start(String host, int port, long timeout_seconds); public static void stop(); public static void restart(long timeout_seconds);
4. Connecting a Debugger
Start jdb and attach it to the debug proxy using the password provided by the DebugProxy when the DebugAgent connected to it. In order to preserve your timeout, suspend all threads through jdb, set your breakpoints, and then resume. Each time a debug agent connects to a debug proxy, the debug proxy starts a thread to wait for connections from a debugger. The thread prints out the number, name, and address of the connecting agent, the port it is waiting on, and the port encoded as a password. Here, a specic port and password are provided for illustration only:
Agent Agent Agent Agent Agent Number: 1 Name: servername Address: eee.fff.jjj.kkk Port: 2286 Password: 3i65bn
The rst thing you should do in the debugger is suspend all threads. Otherwise, your start_debugging call might time out and complete before you get your breakpoints set. If your code writes to System.out or System.err, then you may also want to use the dbgtrace ag to jdb, which redirects these streams to the debugging console:
jdb -dbgtrace -password 3i65bn
The following example shows how to debug an object that exists on the server. First, you need to start a proxy through the debugproxy command-line tool. This example starts up the proxy on the server, tstHost, and informs the debugproxy to start up the jdb debugger when contacted by the debug agent. In another window, make sure that the debug agent user has the correct privileges and then start up the debug agent. Once the agent starts, the debugproxy starts up the jdb debugger and allows you to set your breakpoints. Since you have a
3-18
specied amount of time before the agent times out, the rst thing you should do is suspend all threads. Then, set all of your breakpoints before resuming. This suspends the timeout until you are ready to execute.
window 1 on tstHost SQL> call dbms_java.set_compiler_option(, debug, true); SQL> exit % loadjava -u SCOTT/TIGER -v -f -r myCode.java % debugproxy -port 2286 start jdb -password . (wait until a debug agent starts up and . contact this proxy... when it does, jdb . starts up automatically and you can set . breakpoints and debug the object, as follows:) > suspend > load SCOTT:myCode > stop in myCode:updateAccount > resume > ... window 2 on tstHost SQL> grant JavaDebugPriv to SCOTT SQL> call dbms_java.start_debugging(tstHost,2286,30);
If executing in the server, it returns a String that represents the Oracle9i database release. If executing on the client, it returns null.
The minimum (and default) buffer size is 2,000 bytes; the maximum size is 1,000,000 bytes. In the following example, the buffer size is increased to 5,000 bytes:
SQL> SET SERVEROUTPUT ON SIZE 5000 SQL> CALL dbms_java.set_output(5000);
Output prints at the end of the call. For more information about SQL*Plus, see the SQL*Plus Users Guide and Reference.
3-20
4
Java Installation and Configuration
This chapter describes what you need to know to install and congure Oracle JVM within your database. To congure Java memory, see the "Java Memory Usage" section in Chapter 6, "Oracle9i Java Application Performance".
s
Initializing a Java-Enabled Database Conguring Oracle JVM Using The DBMS_JAVA Package Enabling the Java Client
Java memory requirementsYou must have at least 20 MB of JAVA_POOL_ SIZE and 50 MB of SHARED_POOL_SIZE. See "Java Memory Usage" on page 6-19 for information on conguring these parameters. Database processesYou must decide whether to use dedicated server processes or shared server processes for your database server. Connection protocolThe networking protocol used for communication between the client and the database is TTC, which is an Oracle-specic protocol used for most database communication.
4-2
The networking protocol is referred to as the "presentation layer" within the Oracle9i documentation. However, it is not the same as the presentation layer in the OSI model. Instead, it is a protocol-based server framework that accepts incoming network requests and processes these requests. The TTC protocol processes incoming Oracle Net requests for database SQL services from Oracle tools (such as SQL*Plus) and customer-written applications (using Forms, Pro*C, or the OCI). See "Conguring Multi-Threaded Server" in Chapter 9 of the Oracle Net Services Administrators Guide for conguration information.
s
Java stored proceduresThese procedures require a different conguration for your database type and connection conguration. Java stored procedures can run either in dedicated server mode or shared server mode. If you are primarily developing Java stored procedures, you can run them in the dedicated server conguration. You can use Java clients or PL/SQL clients over a Oracle Net connection to trigger a Java stored procedure. See the Oracle Net Services Administrators Guide for information on conguring an Oracle Net connection.
Return the full name from a Java schema object. Because Java classes and methods can have names exceeding the maximum SQL identier length, Oracle JVM uses abbreviated names internally for SQL access. This function simply returns the original Java name for any (potentially) truncated name. An example of this function is to print the fully qualied name of classes that are invalid:
select dbms_java.longname (object_name) from user_objects where object_type = 'JAVA CLASS' and status = 'INVALID'; FUNCTION shortname (longname VARCHAR2) RETURN VARCHAR2
You can specify a full name to the database by using the shortname() routine of the DBMS_JAVA package, which takes a full name as input and returns the
corresponding short name. This is useful when verifying that your classes loaded by querying the USER_OBJECTS view. Refer to "Shortened Class Names" on page 2-26 and the Oracle9i Java Stored Procedures Developers Guide for examples of these functions.
FUNCTION get_compiler_option(what VARCHAR2, optionName VARCHAR2) PROCEDURE set_compiler_option(what VARCHAR2, optionName VARCHAR2, value VARCHAR2) PROCEDURE reset_compiler_option(what VARCHAR2, optionName VARCHAR2)
These three entry points control the options of the Oracle9i Java and SQLJ compiler that Oracle9i delivers. See "Compiling Java Classes" on page 2-8 for an example of these options. Additionally, both theOracle9i Java Stored Procedures Developers Guide and the Oracle9i SQLJ Developers Guide and Reference document the options and these entry points.
PROCEDURE set_output (buffersize NUMBER)
This procedure redirects the output of Java stored procedures and triggers to the DBMS_OUTPUT package. See "Redirecting Output on the Server" on page 3-20 for an example.
PROCEDURE loadjava(options varchar2) PROCEDURE loadjava(options varchar2, resolver varchar2) PROCEDURE dropjava(options varchar2)
These procedures allow you to load and drop classes within the database using a call, rather than through the loadjava or dropjava command-line tools. To execute within your Java application, do the following:
call dbms_java.loadjava(... options...); call dbms_java.dropjava(... options...);
The options are identical to those specied for the loadjava and dropjava command-line tools. Each option should be separated by a blank. Do not separate the options with a comma. The only exception to this is the loadjava -resolver option, which contains blanks. For -resolver, specify all other options rst, separate these options by a comma, and then specify the -resolver options, as follows:
call dbms_java.loadjava(... options..., resolver_options);
Do not specify the following options, because they relate to the database connection for the loadjava command-line tool: -thin, -oci, -user, -password. The
4-4
output is directed to System.err. The output typically goes to a trace le, but can be redirected. For more information on the available options, see Chapter 7, "Schema Object Tools" for complete information on loadjava.
PROCEDURE grant_permission( grantee varchar2, permission_type varchar2, permission_name varchar2, permission_action varchar2 ) PROCEDURE restrict_permission( grantee varchar2, permission_type varchar2, permission_name varchar2, permission_action varchar2) PROCEDURE grant_policy_permission( grantee varchar2, permission_schema varchar2, permission_type varchar2, permission_name varchar2) PROCEDURE revoke_permission(permission_schema varchar2, permission_type varchar2, permission_name varchar2, permission_action varchar2) PROCEDURE disable_permission(key number) PROCEDURE enable_permission(key number) PROCEDURE delete_permission(key number)
These entry points control the JVM permissions. See "Setting Permissions" on page 5-5 for a description and example of these options.
PROCEDURE start_debugging(host varchar2, port number, timeout number) PROCEDURE stop_debugging PROCEDURE restart_debugging(timeout number)
These entry points start and stop the debug agent when debugging. See "Debugging Server Applications" on page 3-13 for a description and example of these options.
%ORACLE_HOME%, %JAVA_HOME%, %PATH%, and %LIB%. $JAVA_HOMEmust be set to the top directory of the installed JDK base $PATHrequires $JAVA_HOME/bin $LD_LIBRARY_PATH for Solaris or %LIB% for Windows NTmust include $JAVA_HOME/lib
4-6
For any interaction with JDBC, include the following ZIP le:
$ORACLE_HOME/jdbc/lib/classes111.zip
For any client that uses SSL, include the following JAR les:
$ORACLE_HOME/jlib/jssl-1_1.jar $ORACLE_HOME/jlib/javax-ssl-1_1.jar
For any client that uses Java Transaction API (JTA) functionality, include the following JAR le:
$ORACLE_HOME/jlib/jta.jar
For any client that uses JNDI functionality, include the following JAR le:
$ORACLE_HOME/jlib/jndi.jar
For JDK 1.2, include $JAVA_HOME/lib/dt.jar For JRE 1.2, include $JAVA_HOME/lib/rt.jar
For any interaction with JDBC, include the following ZIP le:
$ORACLE_HOME/jdbc/lib/classes12.zip
For any client that uses SSL, include the following JAR les:
$ORACLE_HOME/jlib/jssl-1_2.jar $ORACLE_HOME/jlib/javax-ssl-1_2.jar
For any client that uses Java Transaction API (JTA) functionality, include the following JAR le:
$ORACLE_HOME/jlib/jta.jar
For any client that uses JNDI functionality, include the following JAR le:
$ORACLE_HOME/jlib/jndi.jar
If you are using the Accelerator for native compilation, include $JAVA_ HOME/lib/tools.jar
Java 2 client using the current release of JDBC $ORACLE_HOME/sqlj/lib/runtime12.zip Java 2 Enterprise Edition client using the current release of JDBC $ORACLE_HOME/sqlj/lib/runtime12ee.zip JDK 1.1 client using the current release of JDBC $ORACLE_HOME/sqlj/lib/runtime11.zip Any JDK client using JDBC 8.1.7 or previous version $ORACLE_HOME/sqlj/lib/runtime.zip
If these samples do not compile or run, your environment is incorrect. Similarly, if these samples compile and run, but your code does not, then a problem exists within your build environment or code.
Note: It is important that you run these examples using the
supplied Makeles (or batch les on NT) when verifying your installation. Verify that the samples work before using more complex build environments, such as Visual Cafe, JDeveloper, or VisualAge.
4-8
5
Security For Oracle9i Java Applications
Security is a large arena that includes network security for the connection, access and execution control of operating system resources or of JVM and user-dened classes, and bytecode verication of imported JAR les from an external source. The following sections describe the various security support available for Java applications within Oracle9i.
s
Java 2 Security Setting Permissions Debugging Permissions Permission for Loading Classes
Use a username and password for client verication. Each incoming connection into the database has to provide the correct username/password congured within Oracle Net. For more information, see the Oracle Net Services Administrators Guide. Use Advanced Networking Option for encryption, kerberos, or secureId. See the Oracle Advanced Security Administrators Guide. Use SSL for certicate authentication. See the Oracle Advanced Security Administrators Guide.
JDBC
The JDBC connection security that is required is similar to the constraints required on an Oracle Net database connection. In addition to the books listed in the Oracle Net database connection section, see the Oracle9i JDBC Developers Guide and Reference.
database resources, such as tables and PL/SQL packages operating system resources, such as les and sockets Oracle9i JVM classes user-loaded classes
5-2
Description Authorization for database resources requires that database privileges (not the same as the Java 2 security permissions) are granted to resources. For example, database resources include tables, classes, and PL/SQL packages. For more information, see the Oracle9i Application Developers Guide - Fundamentals. All user-dened classes are secured against users from other schemas. You can grant execution permission to other users/schemas through an option on the loadjava command. For more information on setting execution rights when loading classes, see the -grant option discussed in "Loading Classes" on page 2-16 or Chapter 7, "Schema Object Tools" for complete information on loadjava.
JVM Security
Oracle9i JVM uses Java 2 security, which uses Permission objects to protect operating system resources. Java 2 security is automatically installed upon startup and protects all operating system resources and JVM classes from all users, except JAVA_ADMIN. JAVA_ADMIN can grant permission to other users to access these classes. See "Java 2 Security" on page 5-3 for how to manage and modify Java 2 Permissions and policies.
Java 2 Security
Each user or schema must be assigned the proper permissions to access operating system resources. For example, this includes sockets, les, and system properties. Java 2 security was created to provide a exible, congurable security for Java applications. With Java 2 security, you can dene exactly what permissions on each loaded object that a schema or role will have. In release 8.1.5, the security provided you the choice of two secure roles:
s
JAVAUSERPRIVfew Permissions, including examining properties JAVASYSPRIVmajor Permissions, including updating JVM protected packages
Note: Both roles still exist within this release for backward
compatibility; however, Oracle recommends that you specify each Permission explicitly, rather than utilize these roles.
Because Oracle9i JVM security is based on Java 2 security, you assign Permissions on a class by class basis. Permissions contains two string attributes:
s
These permissions are assigned through database management tools. Each permission is encapsulated in a Permission object and is stored within a Permission table. The methods for managing all permissions are the subject for most of this chapter. Java security was created for the non-database world. When you apply the Java 2 security model within the database, certain differences manifest themselves. For example, Java 2 security denes that all applets are implicitly untrusted, and all classes within the CLASSPATH are trusted. In Oracle9i, all classes are loaded within a secure database; thus, no classes are trusted. The following table briey describes the differences between the Sun Microsystems Java 2 security and the Oracle9i security implementation. This table assumes that you already understand the Sun Microsystems Java 2 security model. For more information, we recommend the following books:
s
Java 2 Security Standard Java classes located within the CLASSPATH are trusted.
You can specify the policy through the You must specify the policy within the -usepolicy ag on the java PolicyTable. command line. You can write your own SecurityManager or use the Launcher. You can write your own SecurityManager; Oracle recommends that you use only the Oracle9i SecurityManager or that you extend the Oracle9i SecurityManager. If you want to modify the behavior, you should not dene a SecurityManager; instead, you should extend oracle.aurora.rdbms. SecurityManagerImpl and override specic methods.
5-4
Java 2 Security Standard SecurityManager is not initialized for you. You must initialize the SecurityManager. Permissions are determined by the location where the application or applet is loaded (the URL) or keycode (signed code). The security policy is dened in a le.
Oracle9i Security Implementation The Oracle9i JVM always initializes SecurityManager at startup. Permissions are determined by the schema in which the class is loaded. Oracle9i does not support signed code. The PolicyTable denition is contained within a secure database table.
You can update the security policy le You can update the PolicyTable through through a text editor (if you have the DBMS_JAVA procedures. After initialization, correct Permissions) or through a tool. only JAVA_ADMIN has permission to modify the PolicyTable. JAVA_ADMIN must grant you the right to modify the PolicyTable for you to grant Permissions to others. Permissions are assigned to a protection domain, which classes can belong to. All classes within the same schema are within the same protection domain.
You can use the CodeSource class for You can use the CodeSource class for identifying code. identifying schema.
s
The equals method returns true if the URL and certicates are equal. The implies method returns true if the rst CodeSource is a generic representation that includes the specic CodeSource object.
The equals method returns true if the schemas are the same. The implies method returns true if the schemas are the same.
Setting Permissions
As with Java 2 security, Oracle9i supports the security classes. Normally, you set the Permissions for the code base either through a tool or by editing the security policy le. In Oracle9i, you set the Permissions dynamically through DBMS_JAVA procedures. These procedures modify a policy table, which is a new table within the database that exclusively manages Java 2 security Permissions.
Two views have been created for you to view the policy table: USER_JAVA_POLICY and DBA_JAVA_POLICY. Both views contain information about granted and limitation Permissions. The DBA_JAVA_POLICY view can see all rows within the policy table; the USER_JAVA_POLICY table can see only Permissions relevant to the current user. The following is a description of the rows within each view:
Table Column Kind Grantee Permission_schema Permission_type Permission_name Description GRANT or RESTRICT. Shows whether this Permission is a positive (GRANT) or a limitation (RESTRICT) Permission. The name of the user, schema, or role to which the Permission object is assigned. The schema in which the Permission object is loaded. The Permission class type, which is designated by a string containing the full class name, such as, java.io.FilePermission. The target attribute (name) of the Permission object. You use this name when dening the Permission. When dening the target for a Permission of type PolicyTablePermission, the name can become quite complicated. See "Acquiring Administrative Permission to Update Policy Table" on page 5-12 for more information. The action attribute for this Permission. Many Permissions expect a null value if no action is appropriate for the Permission. ACTIVE or INACTIVE. After creating a row for a Permission, you can disable or re-enable it. This column shows the status of whether the Permission is enabled (ACTIVE) or disabled (INACTIVE). Sequence number you use to identify this row. This number should be supplied when disabling, enabling, or deleting the Permission.
Permission_action Status
Key
Fine-Grain Denition for Each PermissionYou grant each Permission individually for specic users or roles. If you do not grant a Permission for access, the schema will be denied access. General Permission Denition Assigned to RolesIf you do not want to grant specic Permissions for each user, you can grant roles, which grants a collection of Permissions to the user. Oracle9i supplies the roles: JAVAUSERPRIV or JAVASYSPRIV.
5-6
ne-grain denition. The general denition is easier; but you might not get the exact security you require.
Permission name
Permission action
Key
You can either grant Java 2 Permissions or create your own. The Java 2 Permissions are listed in Table 51. If you would like to create your own Permissions, see "Creating Permissions" on page 5-14.
Table 51 Permission Types
s
You can grant permissions using either SQL or Java, as shown below. However, each returns a row key identier that identies the row within the permission table. In the Java version of DBMS_JAVA, each method returns the row key identier, either as a returned parameter or as an OUT variable in the parameter list. In the PL/SQL DBMS_JAVA package, the row key is returned only in the procedure that denes the key OUT parameter. This key is used to enable and disable specic Permissions. See "Enabling or Disabling Permissions" on page 5-18 for more information. If, after executing the grant, a row already exists for the exact Permission, no update occurs, but the key for that row is returned. If the row was disabled, executing the grant enables the existing row.
Note: If granting FilePermission, you must provide the
physical name of the directory or le, such as /private/oracle. You cannot provide either an environment variable, such as $ORACLE_HOME, or a symbolic link. Also, to denote all les within a directory, provide the * symbol, as follows: /private/oracle/*. To denote all directories and les within a directory, provide the - symbol, as follows: /private/oracle/-.
5-8
Assuming that you have appropriate Permissions to modify the policy table, you use the grant_permission method within the DBMS_JAVA package to modify the PolicyTable to allow the user access to the indicated le. In this example, the user, Larry, has PolicyTable modication Permission. Within a SQL package, Larry grants permission to read and write a le to the user Dave.
connect larry/larry REM Grant DAVE permission to read and write the Test1 file. call dbms_java.grant_permission(DAVE, java.io.FilePermission, /test/Test1, read,write); REM commit the changes to the PolicyTable commit;
You use the restrict method for specifying a limitation or exception to general rules. A general rule is a rule where, in most cases, the Permission is true. However, there may be exceptions to this rule. For these exceptions, you specify a limitation Permission. That is, if you have dened a general rule that no one can read or write for an entire directory, you can dene a limitation on an aspect of this rule through the restrict method. For example, if you want to allow access to all les within the /tmp directoryexcept for your password le that exists in that directoryyou would grant permission for read and write to all les within /tmp and limit read and write access to the password le. If you want to specify an exception to the limitation, you would create an explicit grant Permission to override the limitation Permission. In the scenario mentioned above, if you want the le owner to still be able to modify the password le, you can grant a more explicit Permission to allow access to one user, which will override
5-10
the limitation. Oracle9i JVM security combines all rules to understand who really has access to the password le. This is demonstrated in the following diagram: Grant PUBLIC permission to "/tmp/*" /tmp % ls -al . .. password limitation permission to PUBLIC test grant permission assigned to owner that myCode.java overrides the above limitation myCode.class updSQL.sqlj Makefile The explicit rule is as follows: If the limitation Permission implies the request, then for a grant to be effective, the limitation Permission must also imply the grant. The following is the code that implements this example:
1. 2. 3.
Grant everyone (PUBLIC) read and write permission to all les in /tmp. Limit everyone (PUBLIC) from reading or writing only the password le in /tmp. Grant only Larry (owner) explicit permission to read and write the password le.
connect larry/larry REM Grant permission to all users (PUBLIC) to be able to read and write REM all files in /tmp. call dbms_java.grant_permission(PUBLIC, java.io.FilePermission, /tmp/*, read,write); REM Limit permission to all users (PUBLIC) from reading or writing the REM password file in /tmp. call dbms_java.restrict_permission(PUBLIC, java.io.FilePermission, /tmp/password, read,write);
REM By providing a more specific rule that overrides the limitation, REM Larry can read and write /tmp/password. call dbms_java.grant_permission(LARRY, java.io.FilePermission, /tmp/password, read,write); commit;
5-12
long oracle.aurora.rdbms.security.PolicyTableManager.grantPolicyPermission( java.lang.String grantee, java.lang.String permission_type, java.lang.String permission_name); void oracle.aurora.rdbms.security.PolicyTableManager.grantPolicyPermission( java.lang.String grantee, java.lang.String permission_type, java.lang.String permission_name, long[] key); Parameter Grantee Permission_schema Permission_type Description The name of the user, schema, or role to which you want the grant to apply. PUBLIC species that the row applies to all users. The <schema> where the Permission class is loaded. The Permission class on which you are granting Permission. For example, if you were dening access to a le, the Permission type would be FilePermission. This parameter requires a fully-qualied name of a class that extends java.lang.security.Permission. If the class is not within SYS, the name should be prexed by <schema>:. For example, mySchema:myPackage.MyPermission is a valid name for a user generated Permission. The meaning of the target attribute is dened by the Permission class. Examine the appropriate Permission class for the relevant name. Number returned from grant or limitation to use on enable, disable, or delete methods.
Permission_name
Row_ number
Note: When looking at the policy table, the name within the
PolicyTablePermission rows contains both the Permission type and the Permission name, which are separated by a "#". For example, to grant a user administrative rights for reading a le, the name in the row contains java.io.FilePermission#read. The "#" separates the Permission class from the Permission name.
The following example shows JAVA_ADMIN (as SYS) giving Larry permission to update the PolicyTable for FilePermission. Once this Permission is granted, Larry can grant permissions to other users for reading, writing, and deleting les.
REM Connect as SYS, which is assigned JAVA_ADMIN role, to give Larry permission REM to modify the PolicyTable connect SYS/SYS as SYSDBA REM SYS grants Larry the right to administer permissions for REM FilePermission call dbms_java.grant_policy_permission(LARRY, SYS, java.io.FilePermission, *);
Creating Permissions
Create your own Permission type by performing the following steps: 1. Create and load the user Permission. 2. Grant administrative and action Permissions to specied users. 3. Implement security checks using the Permission. 1. Create and load the user Permission Create your own Permission by extending the Java 2 Permission class. Any user-created Permission must extend Permission. The following example creates MyPermission, which extends BasicPermission, which in turn extends Permission.
package test.larry; import java.security.Permission; import java.security.BasicPermission; public class MyPermission extends BasicPermission { public MyPermission(String name) { super(name); } public boolean implies(Permission p) { boolean result = super.implies(p); return result; } }
5-14
2. Grant administrative and action Permissions to specied users When you create a Permission, you are designated as owner of that Permission. The owner is implicitly granted administrative Permission. This means that the owner can be an administrator for this Permission and can execute grant_policy_permission. Administrative Permission permits the user to update the policy table for the user-dened Permission. For example, if LARRY creates a Permission, MyPermission, only LARRY can invoke grant_policy_permission for himself or another user. This method updates the PolicyTable on who can grant rights to MyPermission. The following code demonstrates this:
REM Since Larry is the user that owns MyPermission, Larry connects to REW the database to assign permissions for MyPermission. connect larry/larry REM As the owner of MyPermission, Larry grants himself the right to REM administer permissions for test.larry.MyPermission within the JVM REM security PolicyTable. Only the owner of the user-defined permission REM can grant administrative rights. call dbms_java.grant_policy_permission(LARRY, LARRY, test.larry.MyPermission, *); REM commit the changes to the PolicyTable commit;
Once you have granted administrative rights, you can grant action Permissions for the user-created Permission. For example, the following SQL grants permission for LARRY to execute anything within MyPermission and for DAVE to execute only actions that start with "act.".
REM Since Larry is the user that creates MyPermission, Larry connects to REW the database to assign permissions for MyPermission. connect larry/larry REM Once able to modify the PolicyTable for MyPermission, Larry grants himself REM full permission for MyPermission. Notice that the Permission is prepended REM with its owner schema. call dbms_java.grant_permission( LARRY, LARRY:test.larry.MyPermission, *, null); REM Larry grants Dave permission to do any actions that start with act.*. call dbms_java.grant_permission (DAVE, LARRY:test.larry.MyPermission, act.*, null);
3. Implement security checks using the Permission Once you have created, loaded, and assigned Permissions for MyPermission, you must implement the call to SecurityManager to have the Permission checked. There are four methods in the following example: sensitive, act, print, and hello. Because of the Permissions granted in the SQL example in step 2, the following users can execute methods within the example class:
s
LARRY can execute any of the methods. DAVE is given permission to execute only the act method. Anyone can execute the print and hello methods. The print method does not check any Permissions, so anyone can execute the print method. The hello method executes AccessController.doPrivileged, which means that the method executes with LARRYs Permissions. This is referred to as deners rights.
package test.larry; import java.security.AccessController; import java.security.Permission; import java.security.PrivilegedAction; import java.sql.Connection; import java.sql.SQLException; /** * MyActions is a class with a variety of public methods that * have some security risks associated with them. We will rely * on the Java security mechanisms to ensure that they are * performed only by code that is authorized to do so. */ public class Larry { private static String secret = "Larrys secret"; MyPermission sensitivePermission = new MyPermission("sensitive"); /** * This is a security sensitive operation. That is it can * compromise our security if it is executed by a "bad guy". * Only larry has permission to execute sensitive. */
5-16
public void sensitive() { checkPermission(sensitivePermission); print(); } /** * Will print a message from Larry. We need to be * careful about who is allowed to do this * because messages from Larry may have extra impact. * Both larry and dave have permission to execute act. */ public void act(String message) { MyPermission p = new MyPermission("act." + message); checkPermission(p); System.out.println("Larry says: " + message); } /** * Print our secret key * No permission check is made; anyone can execute print. */ private void print() { System.out.println(secret); } /** * Print "Hello" * This method invokes doPrivileged, which makes the method run * under definers rights. So, this method runs under Larrys * rights, so anyone can execute hello. * Only Larry can execute hello */ public void hello() { AccessController.doPrivileged(new PrivilegedAction() { public Object run() { act("hello"); return null; } }); } /** * If a security manager is installed ask it to check permission * otherwise use the AccessController directly */ void checkPermission(Permission permission) { SecurityManager sm = System.getSecurityManager(); sm.checkPermission(permission);
} }
The revoke_permission method takes in parameters similar to the grant and restrict methods. It searches the entire policy table for all rows that match the supplied parameters. The disable_permission method disables only a single row within the policy table. To do this, it takes in the policy table key. This key is also necessary to enable or delete a Permission. To retrieve the Permission key number, perform one of the following: * Save the key when it is returned on the grant or limit calls. If you do not foresee a need to ever enable or disable the Permission, you can use the grant and limit calls that do not return the Permission number. View DBA_JAVA_POLICY or USER_JAVA_POLICY for the appropriate Permission key number.
5-18
Permission Types
Table 52 lists the installed Permission types. Whenever you want to grant or limit a Permission, you must provide the Permission type within the DBMS_JAVA method. The Permission types with which you control access are the following:
s
Oracle-provided Permission types listed in Table 52 user created Permission types that extend java.security.Permission
java.util.PropertyPermission java.io.SerializablePermission java.io.FilePermission java.net.NetPermission java.net.SocketPermission java.lang.RuntimePermission java.lang.reflect.ReflectPermission java.security.SecurityPermission oracle.aurora.rdbms.security.PolicyTablePermission oracle.aurora.security.JServerPermission
All the Java Permission types are documented in the Sun Microsystems Java 2 documentation.
Oracle. However, Oracle9i JVM does not support other users loading libraries, because loading C within the database is insecure. Therefore, you are not allowed to grant permission for loadLibrary.* of RuntimePermission. The Oracle-specic Permissions, PolicyTablePermission and JServerPermission, are described below: oracle.aurora.rdbms.security.PolicyTablePermission This Permission controls who can update the policy table. Once granted the right to update the policy table for a certain Permission type, the user can control other users access to some resource. After Oracle9i JVM initialization, only the JAVA_ADMIN role can grant administrative rights for the policy table through PolicyTablePermission. Once it grants this right to other users, these users can in turn update the policy table with their own grant and limitation Permissions. To grant policy table updates, use the DBMS_JAVA method: grant_policy_permission, as discussed in "Acquiring Administrative Permission to Update Policy Table" on page 5-12. Once you have updated the table, you can view either the DBA_JAVA_POLICY or USER_JAVA_POLICY views to see who has been granted Permissions. oracle.aurora.security.JServerPermission Use this Permission to grant and limit access to Oracle9i JVM resources. The JServerPermission extends from BasicPermission. The following table lists the names for which JServerPermission grants access:
Permission Name Description
LoadClassInPackage.<package_name> grants the ability to load a class within the specied package Verier Debug JRIExtensions Memory.Call grants the ability to turn the bytecode verier on or off grants the ability for debuggers to connect to a session grants the use of MEMSTAT grants rights to call certain methods in oracle.aurora.vm.OracleRuntime on call settings
5-20
Description grants rights to call certain methods in oracle.aurora.vm.OracleRuntime on stack settings grants rights to call certain methods in oracle.aurora.vm.OracleRuntime on SGA settings grants rights to call certain methods in oracle.aurora.vm.OracleRuntime on garbage collector settings
Memory.SGAIntern
Memory.GC
The JAVA_ADMIN role is given access to modify the policy table for all Permissions. All DBAs, including SYS, are granted JAVA_ADMIN. Full administrative rights to update the policy table are granted for the following Permissions:
java.util.PropertyPermission java.io.SerializablePermission java.io.FilePermission java.net.NetPermission java.net.SocketPermission java.lang.RuntimePermission java.lang.reflect.ReflectPermission java.security.SecurityPermission oracle.aurora.rdbms.security.PolicyTablePermission oracle.aurora.security.JServerPermission
2.
In addition to the JAVA_ADMIN Permissions, SYS is also granted the following Permissions:
unnecessary granting of more specic Permission for loadlibrary.<package>. The reason for this is to override the limitation given to PUBLIC for loadLibrary.*.
3.
All users are initially granted the following Permissions. For the JServerPermission, all users can load classes, except for the list of classes specied in the table. These exceptions are limitation Permissions. For more information on limitation Permissions, see Example 52.
5-22
action on PropertyPermission, is no longer granted to all users. Instead, you must have either JAVA_ADMIN grant this Permission to you or you can receive it by being granted the role of JAVASYSPRIV.
5-24
The following example gives Larry and Dave the following Permissions:
s
Larry receives JAVASYSPRIV Permissions. Dave receives JAVADEBUGPRIV Permissions and the ability to read and write all les on the system.
REM Granting Larry the same permissions as exist within JAVASYSPRIV grant javasyspriv to larry; REM Granting Dave the ability to debug grant javadebugpriv to dave; commit; REM I also want Dave to be able to read and write all files on the system call dbms_java.grant_permission(DAVE, SYS:java.io.FilePermission, <<ALL FILES>>, read,write, null);
Debugging Permissions
A debug role, JAVADEBUGPRIV, was created to grant Permissions for running the debugger. The Permissions assigned to this role are listed in Table 57. To receive permission to invoke the debug agent, the caller must have been granted JAVADEBUGPRIV or the debug JServerPermission as follows:
REM Granting Dave the ability to debug grant javadebugpriv to dave; REM Larry grants himself permission to start the debug agent. call dbms_java.grant_permission (LARRY, oracle.aurora.security.JServerPermission, Debug, null);
Although a debugger provides extensive access to both code and data on the server, its use should be limited to development environments. Refer to the discussion in "Debugging Server Applications" on page 3-13 for information on using the debugging facilities in this release.
The class name is the fully qualied name of the class that you are loading.
This excludes loading into system packages or replacing any system classes. Even if you are granted permission to load a system class, Oracle9i prevents you from performing the load. System classes are classes that are installed by Oracle9i with CREATE JAVA SYSTEM. The following error is thrown if you try to replace a system class:
ORA-01031 "Insufficient privileges"
The following shows the ability of each user after database installation, including Permissions and Oracle9i JVM restrictions:
s
SYS can load any class except for system classes. Any user can load classes in its own schema that do not start with the following patterns: java.*, oracle.aurora.*, oracle.jdbc.*. If the user wants to load such classes into another schema, it must be granted the JServerPermission(LoadClassInPackage.<class>) Permission.
The following example shows how to grant SCOTT Permission to load classes into the oracle.aurora.* package:
dbms_java.grant_permission(SCOTT, SYS:oracle.aurora.tools.*, null);
5-26
6
Oracle9i Java Application Performance
You can increase your Java application performance through one of the following methods:
s
Natively Compiled Code Java Memory Usage End-of-Call Migration Memory Proling Utility
use of numerics degree of polymorphic message sends use of direct eld access, as opposed to accessor methods amount of Array accessing casts
Because Java bytecodes were designed to be compact, natively compiled code can be considerably larger than the original bytecode. However, because the native code is stored in a shared library, it is shared among all users of the database. Most JVMs use Just-In-Time compilers that convert the Java bytecodes to native machine instructions when methods are invoked. The Accelerator uses an Ahead-Of-Time approach to recompiling the Java classes.
Native Compiler Description
Just-In-Time
Provides the JVM the ability to translate the Java instructions just before needed by the JDK. The benets depends on how accurately the native compiler anticipates code branches and the next instruction. If incorrect, no performance gain is realized.
6-2
Native Compiler
Description
Ahead-Of-Time
The Accelerator natively compiles all Java code within a JAR le into native shared libraries, which are organized by Java package, before execution time. At runtime, Accelerator checks if a Java package has been natively compiled; and if so, uses the machine code library instead of interpreting the deployed Java code.
This static compilation approach provides a large, consistent performance gain, regardless of the number of users or the code paths they traverse on the server. After compilation, the tool loads the statically compiled libraries into Oracle9i, which are then shared between users, processes, and sessions.
Accelerator Overview
Most Ahead-Of-Time native compilers compile directly into a platform-dependent language. For portability requirements, this was not feasible. Figure 61 illustrates how the Accelerator translates the Java classes into a version of C that is platform-independent. The C code is compiled and linked to supply the nal platform-dependent, natively compiled shared libraries or DLLs.
Accelerator
Veries the classes that are loaded in the database. Retrieves the Java bytecodes for these classes from the database and stores them in a project directory where the Accelerator was invoked. Translates the Java bytecodes to C code. Compiles and links the C code using the C compiler for your platform. The Accelerator translates, compiles, and links the retrieved classes on the client. For this reason, you must natively compile on the intended platform environment to which this application will be deployed. The result is a single deployment JAR le for all classes within the project.
5.
6-4
only within Oracle9i. Also, these libraries can only be used within the same version of Oracle9i in which it was produced. If you want your application to be natively compiled on subsequent releases, you must recompile these classes. That is, native recompilation of existing libraries will not be performed automatically by any upgrade process.
Installation Requirements
You must install the following before invoking Accelerator:
1. 2.
Install a C compiler for the intended platform on the machine where you are running ncomp. Verify that the correct compiler and linker commands are referenced within the System*.properties le located in the $ORACLE_HOME/javavm/jahome directory. Since the compiler and linker information is platform-specic, the conguration for these items is detailed in the README for your platform. Add the appropriate JDK JAR les, library, and binary information in the following environment variables:
3.
Addition Required Set to the location where your JDK is installed. Include the appropriate JDK JAR les in your CLASSPATH as follows:
s s
For JDK 1.1, include $JAVA_HOME/lib/classes.zip. For JDK 1.2, include the $JAVA_HOME/lib/tools.jar and $JAVA_HOME/lib/dt.jar les.
PATH LD_LIBRARY_PATH 4.
Add the JDK binary path: $JAVA_HOME/bin Add the JDK library path: $JAVA_HOME/lib.
Grant the user that executes ncomp the following role and security permissions:
Note: DBA role contains both the JAVA_DEPLOY role and the
JAVA_DEPLOY: The user must be assigned to the JAVA_DEPLOY role in order to be able to deploy the shared libraries on the server, which both the ncomp and deploync utilities perform. For example, the role is assigned to DAVE, as follows:
SQL> GRANT JAVA_DEPLOY TO DAVE;
b.
FilePermission: Accelerator stores the shared libraries with the natively compiled code on the server. In order for Accelerator to store these libraries, the user must be granted FilePermission for read and write access to directories and les under $ORACLE_HOME on the server. One method for granting FilePermission for all desired directories is to grant the user the JAVASYSPRIV role, as follows:
SQL> GRANT JAVASYSPRIV TO DAVE;
See the Security chapter in the Oracle9i Java Developers Guide for more information JAVASYSPRIV and granting FilePermission.
6-6
Executing Accelerator
The following sections show how to do basic native compilation using Accelerator.
Note: Before you natively compile your Java server code, you
must have already loaded and tested it within Oracle9i. Native compilation of untested code is not recommended. Keep in mind that debuggers, such as the debugger provided with JDeveloper, are useful only with interpreted Java code. You cannot debug a natively compiled library. All the Java classes contained within a JAR le must already be loaded within the database. Execute the ncomp tool to instruct Accelerator to natively compile all these classes. The following code natively compiles all classes within the pubProject.JAR le:
ncomp -user scott/tiger pubProject.JAR
Note: Because native compilation must compile and link all your
Java classes, this process may execute over the span of a few hours. The time involved in natively compiling your code depends on the number of classes to compile and the type of hardware on your machine. If you change any of the classes within this JAR le, Accelerator recompiles the shared library for the package that contains the changed classes. It will not recompile all shared libraries. However, if you want all classes within a JAR le to be recompiledregardless of whether they were previously natively compiledexecute ncomp with the -force option, as follows:
ncomp -user scott/tiger -force pubProject.JAR
ncomp
Accelerator, implemented within the ncomp tool, natively compiles all classes within the specied JAR, ZIP, or list of classes. Accelerator natively compiles these classes and places them into shared libraries according to their package. Note that these classes must rst be loaded into the database.
If the classes are designated within a JAR le and have already been loaded in the database, you can natively compile your Java classes by executing the following:
ncomp -user SCOTT/TIGER myClasses.jar
your Java classes, this process may execute over the span of a few minutes or a few hours. The time involved depends on the number of classes to compile and the type of hardware on your machine. There are options that allow you control over how the details of native compilation are handled.
Syntax
ncomp [ options ] <class_designation_file> -user | -u <username>/<password>[@<database_url>] [-load] [-projectDir | -d <project_directory>] [-force] [-lightweightDeployment] [-noDeploy] [-outputJarFile | -o <jar_filename>] [-thin] [-oci | -oci8] [-update] [-verbose]
Argument Summary
Table 61 summarizes the ncomp arguments. The <class_designation_file> can be a <file>.jar, <file>.zip, or <file>.classes.
6-8
<file>.zip
<file>.classes
-force
-lightweightDeployment Provides an option for deploying shared libraries and native compilation information separately. This is useful if you need to preserve resources when deploying. See "lightweightDeployment" on page 6-11 for more information. -load Executes loadjava on the specied class designation le. You cannot use this option in combination with a <file>.classes le. All natively compiled classes output into a deployment JAR le. This option species the name of the deployment JAR le and its destination directory. If omitted, the ncomp tool names the output deployment JAR le the same name as the input <file> with "_depl.jar" appended as the sufx. If directory is not supplied, it stores the output JAR le into the project directory (denoted by -projectDir).
-outputJarFile <jar_filename>
-projectDir | -d <absolute_path>
-update
-verbose
Argument Details
user
{-user | -u} <user>/<password>[@<database>]
The permissible forms of @<database> depend on whether you specify -oci or -thin; -oci is the default.
s
-oci: @<database> is optional; if you do not specify, then ncomp uses the users default database. If specied, then <database> can be a TNS name or a Oracle Net Services name-value list. -thin: @<database> is required. The format is <host>:<lport>:<SID>. <host> is the name of the machine running the database. <lport> is the listener port that has been congured to listen for Oracle Net Services connections; in a default installation, it is 5521.
6-10
lightweightDeployment
Accelerator places compilation information and the compiled shared libraries in one JAR le, copies the shared libraries to $ORACLE_HOME/javavm/admin directory on the server, and deploys the compilation information to the server. If you want to place the shared libraries on the server yourself, you can do so through the lightweightDeployment option. The lightweightDeployment option enables you to do your deployment in two stages:
1.
Natively compile your JAR le with -noDeploy and -lightweightDeployment options. This creates an deployment JAR le with only ncomp information, such as transitive closure information. The shared libraries are not saved within the deployment JAR le. Thus, the deployment JAR le is much smaller. Deploy as follows:
a.
2.
Copy all output shared libraries from the lib directory of the native compilation project directory to the servers $ORACLE_ HOME/javavm/admin directory.
Note: You need to have FilePermission to write to this
Errors
Any errors that occur during native compilation are printed to the screen. Any errors that occur during deployment of your shared libraries to the server or during runtime can be viewed with the statusnc tool or by referring to the JACCELERATOR$DLL_ERRORS table. If an error is caught while natively compiling the designated classes, Accelerator denotes these errors, abandons work on the current package, and continues its compilation task on the next package. The native compilation continues for the rest of the packages. The package with the class that contained the error will not be natively compiled at all. After xing the problem with the class, you can choose to do one of the following:
6-11
recompile the shared library reload the Java class into the database
If you choose not to recompile the classes, but to load the correct Java class into the database instead, then the corrected class and all classes that are included in the resolution validation for that classwhether located within the same shared library or a different shared librarywill be executed in interpreted mode. That is, the JVM will not run these classes natively. All the other natively compiled classes will continue to execute in native format. When you execute the statusnc command on the reloaded class or any of its referred classes, they will have an NEED_ NCOMPING status message. Possible errors for a Java class:
1.
The Java class does not exist in the database. If you do not load the Java class into Oracle9i, Accelerator does not include the class in the shared library. The class is simply skipped. The Java class is invalid; that is, one of its references may not be found. Any Java class that is unresolved, Accelerator will try to resolve it before natively compiling. However, if the class cannot be resolved, it is ignored by Accelerator.
2. 3.
The native compilation of your JAR le executes correctly, but the deployment fails. In this case, do not recompile the JAR le, but deploy the output natively compiled JAR le with the deploync command.
6-12
Natively Compiling on Test PlatformJava Classes Already Loaded in the Database Natively Compiling Java Classes Not Loaded in the Database Clean Compile and Generate Output for Future Deployment Controlling Native Compilation Build Environment Natively Compiling Specic Classes Natively Compiling Packages That Are Fully or Partially Modied
If you change any of the classes within the class designation le and ask for recompilation, Accelerator recompiles only the packages that contain the changed classes. It will not recompile all packages.
6-13
The deployment JAR le contains the shared libraries for your classes, and installation classes specied to these shared libraries. It does not contain the original Java classes. To deploy the natively compiled deployment JAR le to any Oracle9i (of the appropriate platform type), you must do the following:
1.
Load the original Java classes into the destination server. In the previous example, the pubProject.jar le would be loaded into the database using the loadjava tool. Deploy the natively compiled deployment JAR le with the Accelerator deploync tool, which is described in deploync on page 6-16.
2.
6-14
import COM.myDomain.myPackage.myClass;
Once explicitly listed, specify the name and location of this class designation le on the command line. Given the following pubworks.classes le:
import import import import COM.myDomain.myPackage.*; COM.myDomain.hisPackage.hisSubPackage.*; COM.myDomain.herPackage.herClass; COM.myDomain.petPackage.petClass;
The following directs Accelerator to compile all classes designated within this le: all classes in myPackage, hisSubPackage and the individual classes, herClass and myClass. These classes must have already been loaded into the database:
ncomp -user SCOTT/TIGER /tmp/jaccel/pubComped/pubworks.classes
6-15
deploync
You can deploy any deployment JAR le with the deploync command. This includes the default output JAR le, <file>_depl.jar or the JAR created when you used the ncomp -outputJarFile option. The operating system and Oracle9i database version must be the same as the platform where it was natively compiled.
Note: The list of shared libraries deployed into Oracle9i are listed
Syntax
deploync [options] <deployment>.jar -user | -u <username>/<password>[@<database_url>] [-projectDir | -d <project_directory>] [-thin] [-oci | -oci8]
Argument Summary
Table 62 summarizes the deploync arguments.
Table 62 deploync Argument Summary
Argument <deployment>.jar Description and Values The full pathname and lename of a deployment JAR le. This JAR le is created when you specify the -outputJarFile option on the ncomp tool. Note that deploync does not verify that this is a native compilation deployment JAR. Species a user, password, and database connect string; the les will be loaded into this database instance. The argument has the form <username>/<password>[@<database>]. If you specify the database URL on this option, you must specify it with OCI syntax. To provide a JDBC Thin database URL, use the -thin option. Species the full path for the project directory. If not specied, Accelerator uses the directory from which ncomp is invoked as the project directory. The database URL that is provided on the -user option uses a JDBC Thin URL address for the database URL syntax.
6-16
Example Deploy the natively compiled deployment JAR le pub.jar to the dbhost database as follows:
deploync -user SCOTT/TIGER@dbhost:5521:orcl -thin /tmp/jaccel/PubComped/pub.jar
statusnc
After the native compilation is completed, you can check the status for your Java classes through the statusnc command. This tool will print outeither to the screen or to a designated lethe status of each class. In addition, the statusnc tool always saves the output within the JACCELERATOR$STATUS table. The values can be the following:
Class Native Compilation Status ALREADY_NCOMPED NEED_NCOMPING INVALID Description The class is currently natively compiled. A class within the shared library was reloaded after native compilation. Thus, you should recompile this shared library. A class loaded in the database is invalid. Accelerator tried to validate it and failed. The class will be excluded from the natively compiled shared library.
output from the last execution of the statusnc command. When executed, the statusnc command cleans out this table before writing the new records into it.
6-17
Syntax
statusnc [ options ] <class_designation_file> -user <user>/<password>[@database] [-output | -o <filename>] [-projectDir | -d <directory>] [-thin] [-oci | -oci8]
Argument Summary
Table 63 summarizes the statusnc arguments. The <class_designation_ file> can be a <file>.jar, <file>.zip, or <file>.classes.
Table 63 statusnc Argument Summary
Argument <file>.jar <file>.zip <file>.classes Description The full pathname and lename of a JAR le that was natively compiled. The full pathname and lename of a ZIP le that was natively compiled. The full pathname and lename of a classes le, which contains the list of classes that was natively compiled. See "Natively Compiling Specic Classes" on page 6-15 for a description of a classes le. Species a user, password, and database connect string where the les are loaded. The argument has the form <username>/<password>[@<database>]. If you specify the database URL on this option, you must specify it with OCI syntax. To provide a JDBC Thin database URL, use the -thin option. Designates that the statusnc should output to the specied text le rather than to the screen. Species the full path for the project directory. If not specied, Accelerator uses the directory from which ncomp is invoked as the project directory. The database URL that is provided on the -user option uses a JDBC Thin URL address for the database URL syntax. The database URL that is provided on the -user option uses an OCI URL address for the database URL syntax. However, if neither -oci or -thin are specied, the default assumes that you used an OCI database URL.
6-18
Example
statusnc -user SCOTT/TIGER -output pubStatus.txt /tmp/jaccel/PubComped/pub.jar
Conguring Memory Initialization Parameters Java Pool Memory Displaying Used Amounts of Java Pool Memory Correcting Out of Memory Errors
SHARED_POOL_SIZEShared pool memory is used by the class loader within the JVM. The class loader uses an average of about 8 KB for each loaded class. Shared pool memory is used when loading and resolving classes into the database. It is also used when compiling source in the database or when using Java resource objects in the database. The memory specied in SHARED_POOL_SIZE is consumed transiently when you use loadjava. The database initialization process (executing initjvm.sql against a clean database, as opposed to the installed seed database) requires SHARED_POOL_SIZE to be set to 50 MB as it loads the Java binaries for approximately 8,000 classes and resolves them. The SHARED_ POOL_SIZE resource is also consumed when you create call specications and as the system tracks dynamically loaded Java classes at runtime.
JAVA_POOL_SIZEThe Oracle9i JVM memory manager allocates all other Java state during runtime execution from the amount of memory allocated using JAVA_POOL_SIZE. This memory includes the shared in-memory representation of Java method and class denitions, as well as the Java objects
6-19
migrated to session space at end-of-call. In the rst case, you will be sharing the memory cost with all Java users. In the second case, in a shared server, you must adjust JAVA_POOL_SIZE allocation based on the actual amount of state held in static variables for each session. See "Java Pool Memory" on page 6-21 for more information on JAVA_POOL_SIZE.
s
JAVA_SOFT_SESSIONSPACE_LIMITThis parameter allows you to specify a soft limit on Java memory usage in a session, which will warn you if you must increase your Java memory limits. Every time memory is allocated, the total memory allocated is checked against this limit. When a user's session-duration Java state exceeds this size, Oracle9i JVM generates a warning that is written into the trace les. While this warning is simply an informational message and has no impact on your application, you should understand and manage the memory requirements of your deployed classes, especially as they relate to usage of session space.
JAVA_MAX_SESSIONSPACE_SIZEIf a user-invokable Java program executing in the server can be used in a way that is not self-limiting in its memory usage, this setting may be useful to place a hard limit on the amount of session space made available to it. The default is 4 GB. This limit is purposely set extremely high to be normally invisible. When a user's session-duration Java state attempts to exceeds this size, your application can receive an out-of-memory failure.
Oracle9is unique memory management facilities and sharing of read-only artifacts (such as bytecodes) enables HelloWorld to execute with a per-session incremental memory requirement of only 35 KB. More stateful server applications have a per-session incremental memory requirement of approximately 200 KB. Such applications must retain a signicant amount of state in static variables across multiple calls. Refer to the discussion in the "End-of-Call Migration" section on page 6-25 for more information on understanding and controlling migration of static variables at end-of-call.
6-20
6-21
This includes readonly memory, such as code vectors, and methods. In total, this can average about 4 KB-8 KB for each class.
s
None of the per-session Java state of each session. For a dedicated server, this is stored in UGA within the PGAnot within the SGA.
Under dedicated servers, the total required Java pool memory depends on the applications running and may range between 10 and 50 MB. Java pool memory used within a shared server The following is what constitutes the Java pool memory used within a shared server:
s
The shared part of each Java class that is used per session This includes readonly memory, such as vectors, and methods. In total, this can average about 4 KB-8 KB for each class.
Some of the UGA used for per-session state of each session is allocated from the Java pool memory within the SGA Because Java pool memory size is xed, you must estimate the total requirement for your applications and multiply by the number of concurrent sessions the applications want to create to calculate the total amount of necessary Java pool memory. Each UGA grows and shrinks as necessary; however, all UGAs combined must be able to t within the entire xed Java pool space.
Under shared servers, this gure could be large. Java-intensive, multi-user benchmarks could require more than 100 MB.
Note: If you are compiling code on the server, rather than
compiling on the client and loading to the server, you might need a bigger JAVA_POOL_SIZE than the default 20 MB.
6-22
SVRMGR> select * from v$sgastat; POOL NAME BYTES ----------- -------------------------- ---------fixed_sga 69424 db_block_buffers 2048000 log_buffer 524288 shared pool free memory 22887532 shared pool miscellaneous 559420 shared pool character set object 64080 shared pool State objects 98504 shared pool message pool freequeue 231152 shared pool PL/SQL DIANA 2275264 shared pool db_files 72496 shared pool session heap 59492 shared pool joxlod: init P 7108 shared pool PLS non-lib hp 2096 shared pool joxlod: in ehe 4367524 shared pool VIRTUAL CIRCUITS 162576 shared pool joxlod: in phe 2726452 shared pool long op statistics array 44000 shared pool table definiti 160 shared pool KGK heap 4372 shared pool table columns 148336 shared pool db_block_hash_buckets 48792 shared pool dictionary cache 1948756 shared pool fixed allocation callback 320 shared pool SYSTEM PARAMETERS 63392 shared pool joxlod: init s 7020 shared pool KQLS heap 1570992 shared pool library cache 6201988 shared pool trigger inform 32876 shared pool sql area 7015432 shared pool sessions 211200 shared pool KGFF heap 1320 shared pool joxs heap init 4248 shared pool PL/SQL MPCODE 405388 shared pool event statistics per sess 339200 shared pool db_block_buffers 136000 java pool free memory 30261248 java pool memory in use 19742720 37 rows selected.
6-23
Running out of memory while compiling Running out of memory while loading
The solution is to shut down your database and reset JAVA_POOL_SIZE to a larger value. The mention of "shared pool" in the error message is a misleading reference to running out of memory in the "Shared Global Area". It does not mean that you should increase your SHARED_POOL_SIZE. Instead, you must increase your JAVA_POOL_SIZE, restart your server, and try again.
Verify that the class was actually included in the set you are loading to the server. Many people have accidently forgotten to load just one class out of hundreds and spend considerable time chasing this down. Use the loadjava -force option to force the new class being loaded to replace the class already resident in the server. Use the loadjava -resolve option to attempt resolution of a class during the load process. This allows you to catch missing classes at load time, not run time. Double check the status of a newly loaded class by connecting to the database in the schema containing the class, and execute the following:
select * from user_objects where object_name = dbms_java.shortname();
6-24
End-of-Call Migration
The STATUS eld should be "VALID". If loadjava complains about memory problems or failures such as "connection lost", increase SHARED_POOL_SIZE and JAVA_POOL_SIZE, and try again.
End-of-Call Migration
Oracle9i preserves the state of your Java program between calls by migrating all objects that are reachable from static variables into session space at the end of the call. Session space exists within the clients session to store static variables and objects that exist between calls. Oracle9i JVM performs this migration operation at the end of every call, without any intervention by you. This migration operation is a memory and performance consideration; thus, you should be aware of what you designate to exist between calls, and keep the static variables and objects to a minimum. If you store objects in static variables needlessly, you impose an unnecessary burden on the memory manager to perform the migration and consume per-session resources. By limiting your static variables to only what is necessary, you help the memory manager and improve your servers performance. To maximize the number of users who can execute your Java program at the same time, it is important to minimize the footprint of a session. In particular, to achieve maximum scalability, an inactive session should take up as little memory space as possible. A simple technique to minimize footprint is to release large data structures at the end of every call. You can lazily recreate many data structures when you need them again in another call. For this reason, the Oracle9i JVM has a mechanism for calling a specied Java method when a session is about to become inactive, such as at end-of-call time. This mechanism is the EndOfCallRegistry notication. It enables you to clear static variables at the end of the call and reinitialize the variables using a lazy initialization technique when the next call comes in. You should execute this only if you are concerned about the amount of storage you require the memory manager to store in between calls. It becomes a concern only for more complex stateful server applications you implement in Java. The decision of whether to null-out data structures at end-of-call and then recreate them for each new call is a typical time and space trade-off. There is some extra time spent in recreating the structure, but you can save signicant space by not holding on to the structure between calls. In addition, there is a time consideration, because objectsespecially large objectsare more expensive to access after they have been migrated to session space. The penalty results from the differences in representation of session, as opposed to call-space based objects.
6-25
End-of-Call Migration
Examples of data structures that are candidates for this type of optimization include:
s
Buffers or caches. Static elds, such as Arrays, that once initialized, can remain unchanged during the course of the program. Any dynamically built data structure that could have a space-efcient representation between calls and a more speed-efcient representation for the duration of a call. Because this can be tricky and complicate your code, making it hard to maintain, so you should consider doing this only after demonstrating that the space saved is worth the effort.
are not invoked, because the session space will be cleared anyway. The way that you use the EndOfCallRegistry depends on whether you are dealing with objects held in static elds or instance elds.
s
Static eldsYou use EndOfCallRegistry to clear state associated with an entire class. In this case, the Callback object should be held in a private static eld. Any code that requires access to the cached data that was dropped between calls must invoke a method that lazily createsor recreatesthe cached data. The example below does the following:
1. 2.
Creates a Callback object within a static eld, thunk. Registers this Callback object for end-of-call migration.
6-26
End-of-Call Migration
3. 4.
Implements the Callback.act method to free up all static variables, including the Callback object itself. Provides a method, createCachedField, for lazily recreating the cache.
When the user creates the cache, the Callback object is automatically registered within the getCachedField method. At end-of-call, Oracle9i JVM invokes the registered Callback.act method, which frees the static memory.
import oracle.aurora.memoryManager.Callback; import oracle.aurora.memoryManager.EndOfCallRegistry; class Example { static Object cachedField = null; private static Callback thunk = null; static void clearCachedField() { // clear out both the cached field, and the thunk so they don't // take up session space between calls cachedField = null; thunk = null; } private static Object getCachedField() { if (cachedField == null) { // save thunk in static field so it doesn't get reclaimed // by garbage collector thunk = new Callback () { public void act(Object obj) { Example.clearCachedField(); } }; // register thunk to clear cachedField at end-of-call. EndOfCallRegistry.registerCallback(thunk); // finally, set cached field cachedField = createCachedField(); } return cachedField; } private static Object createCachedField() { .... } }
6-27
End-of-Call Migration
Instance eldsUse EndOfCallRegistry to clear state in data structures held in instance elds. For example, when a state is associated with each instance of a class, each instance has a eld that holds the cached state for the instance and lls in the cached eld as necessary. You can access the cached eld with a method that ensures the state is cached.
1. 2. 3. 4.
Implements the instance as a Callback object. Implements the Callback.act method to free up the instances elds. When the user requests a cache, the Callback object registers itself for end-of-call migration. Provides a method, createCachedField, for lazily recreating the cache.
When the user creates the cache, the Callback object is automatically registered within the getCachedField method. At end-of-call, Oracle9i JVM invokes the registered Callback.act method, which frees the cache. This approach ensures that the lifetime of the Callback object is identical to the lifetime of the instance, because they are the same object.
import oracle.aurora.memoryManager.Callback; import oracle.aurora.memoryManager.EndOfCallRegistry; class Example2 implements Callback { private Object cachedField = null; public void act(Object obj) { // clear cached field cachedField = null; obj = null; } // our accessor method private static Object getCachedField() { if (cachedField == null) { // if cachedField is not filled in then we need to // register self, and fill it in. EndOfCallRegistry.registerCallback(self); cachedField = createCachedField(); } return cachedField; } private Object createCachedField() { ....
6-28
End-of-Call Migration
} }
A weak table holds the registry of end-of-call callbacks. If either the Callback object or value are not reachable (see JLS section 12.6) from the Java program, both object and value will be dropped from the table. The use of a weak table to hold callbacks also means that registering a callback will not prevent the garbage collector from reclaiming that object. Therefore, you must hold on to the callback yourself if you need ityou cannot rely on the table holding it back. You can nd other ways in which end-of-call notication will be useful to your applications. The following sections give the details for methods within the EndOfCallRegistry class and the Callback interface: EndOfCallRegistry.registerCallback method The registerCallback method installs a Callback object within a registry. At the end of the call, Oracle9i JVM invokes the act methods of all registered Callback objects. You can register your Callback object by itself or with a value object. If you need additional information stored within an object to be passed into act, you can register this object within the value parameter.
public static void registerCallback(Callback thunk, Object value); public static void registerCallback(Callback thunk); Parameter thunk value Description The Callback object to be invoked at end-of-call migration. If you need additional information stored within an object to be passed into act, you can register this object within the value parameter. In some cases, the value parameter is necessary to hold state the callback needs. However, most users do not need to specify a value.
EndOfCallRegistry.runCallbacks method
static void runCallbacks()
The JVM calls this method at end-of-call and calls act for every Callback object registered using registerCallback. You should never call this method in your code. It is called at end-of-call, before object migration and before the last nalization step.
6-29
Callback Interface
Interface oracle.aurora.memoryManager.Callback
Any object you want to register using EndOfCallRegistry.registerCallback implements the Callback interface. This interface can be useful in your application, where you require notication at end-of-call. Callback.act method
public void act(Object value)
You can implement any activity that you require to occur at the end of the call. Normally, this method will contain procedures for clearing any memory that would be saved to session space.
call memory, which exists for the duration of a (possibly recursive) call into the database session memory, which exists for the duration of the session connected to the database permanent or global memory, which persists as long as the database instance is running
Java language semantics specify that static variables persist across calls. At the end of each call, the Oracle9i JVM copies the call memory that is accessible through the static variables in each class into session memory so that it can be saved and restored on subsequent calls to methods in those Java classes. If there is a lot of static data or a complex graph of interconnected objects, then there is considerable overhead during the end-of-call processing while the JVM allocates session memory and copies the static data to it.
6-30
A typical technique for tuning object-oriented programs for faster performance is to eliminate the allocation of unnecessary objects from your program. For example, you can create a static instance of a commonly used object and reuse it rather than creating a new one every time you need it. However, the interactions among the different database memories complicate such techniques, and can require analysis of the speed trade-off for allocating dynamic objects versus the space trade-off for the end-of-call copying of static objects. If a static object is large, or if there are many such objects, or if there are many calls, then the speed advantage gained by caching the object may be lost, due to the traversal of the object graph during end-of-call processing.
If the variable is a primitive object, such as an integer, MemStat records its class and size. If the variable is a non-primitive object (for example, one that refers to another object), MemStat follows the reference and recursively enumerates all objects to which it refers. If the variable is an array, MemStat enumerates all elements of the array.
This process is repeated recursively until all objects reachable from all static variables have been recorded. Because it is possible for large object graphs to contain cycles, MemStat also records any circular references it encounters during the analysis.
Using MemStat
The purpose of MemStat is to analyze and report on the object graph that is accessible from the static variables in your program. You can invoke the analysis directly from any point in your program, and you can also register it to run at the end of a call. Because there is no standard output mechanism for database calls, MemStat produces its report in the form of HTML les, in a directory that you specify. When the report is nished, you can view these les with any HTML-capable Web browser.
6-31
MemStat is implemented in three static methods on the class oracle.aurora.memstat.MemStat. You can call it in three different ways:
s
to report immediately on the static variables in a single class to report immediately on the static variables of all classes used in the current session to report at end-of-call on the static variables of all classes used in the current session
The method call for reporting on all loaded classes at the end-of-call is:
MemStat.writeDumpAtEOC (String outputPath, String filePrefix);
The outputPath parameter represents the directory in which the MemStat reports are generated. The outputPath string must be in a le name format that is suitable to the platform on which the report is generated. For example, /home/base/memstat is suitable for a Solaris platform; the Windows format might be c:\\base\\memstat. Note that Java requires doubling of the backslashes inside a string, but not the forward slashes. The filePrefix is the base le name for the HTML les that are generated in the outputPath directory. Because MemStat reports can be voluminous, and many Web browsers have limitations on the size of the les they can browse, MemStat breaks long reports into separate les. The filePrefix is the basis for all le names in a given report and is augmented by an incremental numeric sufx. If, for example, the test report produces three les, the main report le will be named test.htm, and additional report les will be named test1.htm and test2.htm. If you call MemStat more than once in a given call, be careful to use different base names or different output directories, lest the subsequent reports overwrite the previous ones. For example, if you call MemStat before and after you perform some memory-consuming operation, naming the rst report before and the second report after will prevent name collisions, while still writing the report les into the same directory. Using multiple directories is more complicated: you must
6-32
remember to grant separate FilePermissions (see below) for each directory in which you want to write. Here are some sample MemStat calls:
MemStat.writeDump (MyClass.class, c:\\base\\memstat, myclass); MemStat.writeDump (/home/base/memstat, test); MemStat.writeDumpAtEOC (/home/base/memstat, eoc);
MemStat Permissions
MemStat requires certain permissions to be granted to the user or role under which it runs. Because MemStat runs in the Oracle server process, these permissions grant access to the resources that MemStat requires:
s
Access to the private variables of the objects in the graph. If this permission is not granted, MemStat will still run, but it will not trace any objects that are pointed to by private variables. Access to the Java run-time system for determining which classes are loaded in the current session. If this permission is not granted, MemStat will nd zero classes loaded and will generate an empty report. Access to the server le system where the MemStat HTML reports are generated. If this permission is not granted, MemStat will raise an exception when it tries to create the report les.
If the Oracle Server is running on a Windows platform, the output le path named in the MemStat call is subtly different from the path in the SQL grant_ permission call. In Java strings, you must use double backslashes; in SQL you need only one backslash.
6-33
The report begins with a summary of the memory usage at the time MemStat is invoked. This summary should give you an overall idea of the amount of memory used by the Java call that you are analyzing. Following the summary is a list of the unique classes that are traversed during the MemStat analysis. For every object found during the memory analysis, MemStat has recorded its class and its size in each of call, session, and permanent memory. The largest objects are sorted rst, because eliminating these will yield the largest performance improvement. The list is actually sorted by the largest of these three sizes, calculated as max (call, max (session, permanent)). For each class, this table also shows how many bytes are occupied by objects of that class, how many objects there are, their minimum, maximum and average size, and for arrays, the standard deviation of the sizes. Following the class summary is one or more tables describing each root object. The title of the object describes the package and class of the object. Each row of the table describes:
s
a eld of the object a description of the object in that eld the total size of the object in each of the three memory spaces
Following the root objects are the objects pointed to by the roots; the objects are separated by a dividing rule. One, two, or three tables describe each object:
s
the object itself any other objects that the object refers to any objects that refer to this object
The title for each object describes the memory in which the object resides: Call, Session, or Permanent. Each object is described by:
s
a unique identier the output of applying the toString() method to the object
6-34
the objects direct size: the size of the object header and the elds of the object the objects total size: the sum of the sizes of all the objects to which it refers
An object that refers to another object is linked by an HTML link to the tables representing the object to which it refers. You can navigate the object graph using these links, as you would navigate hyperlinks in a text document. The following shows an example of the output of the MemStat tool:
Total Memory Allocation Objects Total Size Minimum Maximum Average Std Deviation
Call
Session
Permanent
6-35
Class
char[]
(P)
AVE (C)
157.2
(P)
java.lang.String 3816
4956 8195
382 445 34 57 3 0 0 8192 2048 1024 4,097.5 71.2 37.0 4,094.5 344.2 143.3
strictKeyValueSeparators 948: java.lang.String specialSaveChars whiteSpaceChars hexDigit 950: java.lang.String 952: java.lang.String 954: char[16]
6-36
7
Schema Object Tools
This chapter describes the schema object tools that you use in the Oracle9i Java environment. You run these tools from a UNIX shell or the Windows NT DOS prompt.
Note: All names supplied within these tools are case sensitive.
Thus, the schema, username, and password will not be uppercased. The following sections describe the schema object tools:
s
Schema Object Tool Overview What and When to Load Resolution Digest Table Compilation loadjava dropjava ojvmjava
Java class schema objects, which correspond to Java class les. Java source schema objects, which correspond to Java source les. Java resource schema objects, which correspond to Java resource les.
To make a class le runnable by the Oracle9i JVM, you use the loadjava tool to create a Java class schema object from the class le or the source le and load it into a schema. To make a resource le accessible to the Oracle9i JVM, you use loadjava to create and load a Java resource schema object from the resource le. The dropjava tool does the reverse of the loadjava tool; it deletes schema objects that correspond to Java les. You should always use dropjava to delete a Java schema object that was created with loadjava; dropping by means of SQL DDL commands will not update auxiliary data maintained by loadjava and dropjava.
7-2
Resolution
Drop a.java, load b.java (which denes x), then load the new a.java (which does not dene x). Load the new a.java (which does not dene x), then load b.java (which denes x).
Resolution
All Java classes contain references to other classes. A conventional JVM searches for classes in the directories, ZIP les, and JARs named in the CLASSPATH. The Oracle9i JVM, by contrast, searches schemas for class schema objects. Each Oracle9i class has a resolver spec, which is the Oracle9i counterpart to the CLASSPATH. For a hypothetical class, alpha, its resolver spec is a list of schemas to search for classes that alpha uses. Notice that resolver specs are per-class, whereas in a classic JVM, CLASSPATH is global to all classes. In addition to a resolver spec, each class schema object has a list of interclass reference bindings. Each reference list item contains a reference to another class and one of the following:
s
the name of the class schema object to invoke when class uses the reference a code indicating whether the reference is unsatised; in other words, whether the referent schema object is known
An Oracle9i facility known as the resolver maintains reference lists. For each interclass reference in a class, the resolver searches the schemas specied by the classs resolver spec for a valid class schema object that satises the reference. If all references are resolved, the resolver marks the class valid. A class that has never been resolved, or has been resolved unsuccessfully, is marked invalid. A class that depends on a schema object that becomes invalid is also marked invalid at the time the rst class is marked invalid; in other words, invalidation cascades upward from a class to the classes that use it and the classes that use them, and so on. When resolving a class that depends on an invalid class, the resolver rst tries to resolve the referenced class, because it may be marked invalid only because it has never been resolved. The resolver does not re-resolve classes that are marked valid. A class developer can direct loadjava to resolve classes or can defer resolution until run time. The resolver runs automatically when a class tries to load a class that is marked invalid. It is best to resolve before run time to learn of missing classes early; unsuccessful resolution at run time produces a class not found exception. Furthermore, run-time resolution can fail for the following reasons:
s
Digest Table
Load-and-resolve (-resolve option): Loads all classes you specify on the command line, marks them invalid, and then resolves them. Use this mode when initially loading classes that refer to each other, and in general when reloading isolated classes as well. By loading all classes and then resolving them, this mode avoids the error message that occurs if a class refers to a class that will be loaded later in the execution of the command. Load-then-resolve (no -resolve option): Resolves each class at runtime.
Note: As with a Java compiler, loadjava resolves references to
2.
classes but not to resources; be sure to correctly load the resource les your classes need. If you can, defer resolution until all classes have been loaded; this technique avoids the situation in which the resolver marks a class invalid because a class it uses has not yet been loaded.
Digest Table
The schema object digest table is an optimization that is usually invisible to developers. The digest table enables loadjava to skip les that have not changed since they were last loaded. This feature improves the performance of makeles and scripts that invoke loadjava for collections of les, only some of which need to be reloaded. A reloaded archive le might also contain some les that have changed since they were last loaded and some that have not. The loadjava tool detects unchanged les by maintaining a digest table in each schema. The digest table relates a le name to a digest, which is a shorthand representation of the les content (a hash). Comparing digests computed for the same le at different times is a fast way to detect a change in the les contentmuch faster than comparing every byte in the le. For each le it processes, loadjava computes a digest of the les content and then looks up the le name in the digest table. If the digest table contains an entry for the le name that has the identical digest, then loadjava does not load the le, because a corresponding schema object exists and is up to date. If you invoke loadjava with the -verbose option, then it will show you the results of its digest table lookups.
7-4
Compilation
Normally, the digest table is invisible to developers, because loadjava and dropjava keep the table synchronized with schema object additions, changes, and deletions. For this reason, always use dropjava to delete a schema object that was created with loadjava, even if you know how to drop a schema object using DDL. If the digest table becomes corrupted (loadjava does not update a schema object whose le has changed), use loadjavas -force option to bypass the digest table lookup or delete all rows from the table, which is named JAVA$CLASS$MD5$TABLE.
Compilation
Loading a source le creates or updates a Java source schema object and invalidates the class schema object(s) previously derived from the source. If the class schema objects do not exist, loadjava creates them. The loadjava tool invalidates the old class schema objects because they were not compiled from the newly loaded source. Compilation of a newly loaded source, called for instance A, is automatically triggered by any of the following conditions:
s
The resolver, working on class B, nds that it refers to class A, but class A is invalid. The compiler, compiling source B, nds that it refers to class A, but A is invalid. The class loader, trying to load class A for execution, nds that it is invalid.
To force compilation when you load a source le, use loadjava -resolve. The compiler writes error messages to the predened USER_ERRORS view; loadjava retrieves and displays the messages produced by its compiler invocations. The compiler recognizes some options. There are two ways to specify options to the compiler. If you run loadjava with the -resolve option (which may trigger compilation), you can specify compiler options on the command line. You can additionally specify persistent compiler options in a per-schema database table known as JAVA$OPTIONS, which you create as described shortly. You can use the JAVA$OPTIONS table for default compiler options, which you can override selectively with a loadjava command-line option.
Note: A command-line option both overrides and clears the
Compilation
A JAVA$OPTIONS row contains the names of source schema objects to which an option setting applies; you can use multiple rows to set the options differently for different source schema objects. The compiler looks up options in the JAVA$OPTIONS table when it has been invoked without a command linethat is, by the class loaderor when the command line does not specify an option. When compiling a source schema object for which there is neither a JAVA$OPTIONS entry nor a command-line value for an option, the compiler assumes a default value as follows:
s
encoding = System.getProperty("file.encoding"); online = true: See the Oracle9i SQLJ Developers Guide and Reference for a description of this option, which applies only to Java sources that contain SQLJ constructs. debug = true: This option is equivalent to javac -g.
You can set JAVA$OPTIONS entries by means of the following functions and procedures, which are dened in the database package DBMS_JAVA:
s
PROCEDURE set_compiler_option(name VARCHAR2, option VARCHAR2, value VARCHAR2); FUNCTION get_compiler_option(name VARCHAR2, option VARCHAR2) RETURNS VARCHAR2; PROCEDURE reset_compiler_option(name VARCHAR2, option VARCHAR2);
The name parameter is a Java package name, or a fully qualied class name, or the empty string. When the compiler searches the JAVA$OPTIONS table for the options to use for compiling a Java source schema object, it uses the row whose name most closely matches the schema objects fully qualied class name. A name whose value is the empty string matches any schema object name. The option parameter is either 'online' or 'encoding'. For the values you can specify for these options, see the Oracle9i SQLJ Developers Guide and Reference.. A schema does not initially have a JAVA$OPTIONS table. To create a JAVA$OPTIONS table, use the DBMS_JAVA packages java.set_compiler_option procedure to set a value; the procedure will create the table if it does not exist. Specify parameters in single quotes. For example:
SQL> execute dbms_java.set_compiler_option('x.y', 'online', 'false');
Table 71 represents a hypothetical JAVA$OPTIONS database table. Because the table has no entry for the encoding option, the compiler will use the default or the
7-6
loadjava
value specied on the command line. The online options shown in the table match schema object names as follows:
s
The name a.b.c.d matches class and package names beginning with a.b.c.d; they will be compiled with online = true. The name a.b matches class and package names beginning with a.b, but not a.b.c.d; they will be compiled with online = false. All other packages and classes will match the empty string entry and will be compiled with online = true.
a.b.c.dmatches the pattern exactly. a.b.c.d.erst part matches the pattern exactly; no other rule matches full name. a.bmatches the pattern exactly a.b.c.xrst part matches the pattern exactly; no other rule matches beyond specied rule name. a.cno pattern match with any dened name; defaults to (empty string) rule x.yno pattern match with any dened name; defaults to (empty string) rule
a.b
online
false
s s
(empty string)
online
true
loadjava
The loadjava tool creates schema objects from les and loads them into a schema. Schema objects can be created from Java source, class, and data les. loadjava can also create schema objects from SQLJ les; the Oracle9i SQLJ Developers Guide and Reference describes how to use loadjava with SQLJ. You must have the following SQL database privileges to load classes:
s
CREATE PROCEDURE and CREATE TABLE privileges to load into your schema. CREATE ANY PROCEDURE and CREATE ANY TABLE privileges to load into another schema. oracle.aurora.security.JServerPermission.loadLibraryInClass. <classname>. See the "Database Contents and JVM Security" section in Chapter 5 of the Oracle9i Java Developers Guide for more information.
loadjava
You can execute the loadjava tool either through the command line (as described below) or through the loadjava method contained within the DBMS_JAVA class. To execute within your Java application, do the following:
call dbms_java.loadjava(... options...);
where the options are the same as specied below. Separate each option with a blank. Do not separate the options with a comma. The only exception for this is the -resolver option, which contains blanks. For -resolver, specify all other options in the rst input parameter, and the -resolver options in the second parameter. This is demonstrated below:
call dbms_java.loadjava(..options..., resolver_options);
Do not specify the following options, because they relate to the database connection for the loadjava command-line tool: -thin, -oci, -user, -password. The output is directed to stderr. Set serveroutput on, and call dbms_java.set_output as appropriate.
Note: The loadjava tool is located in the bin subdirectory
under $ORACLE_HOME. Just before the loadjava tool exits, it checks whether the execution was successful. All failures are summarized preceeded by the following header:
The following operations failed
Some conditions, such as losing the connection to the database, cause loadjava to terminate prematurely. There errors are printed with the following syntax:
exiting: <error_reason>
Syntax
loadjava {-user | -u} <user>/<password>[@<database>] [options] <file>.java | <file>.class | <file>.jar | <file>.zip | <file>.sqlj | <resourcefile> ... [-action] [-andresolve] [-casesensitivepub] [-cleargrants] [-debug] [-d | -definer] [-dirprefix <prefix>]
7-8
loadjava
[-e | -encoding <encoding_scheme>] [-fileout <file>] [-f | -force] [-g | -grant <user> [, <user>]...] [-genmissing] [-genmissingjar <jar_file>] [-help] [-jarasresource] [-noaction] [-nocasesensitivepub] [-nocleargrants] [-nodefiner] [-nogrant] [-norecursivejars] [-noschema] [-noserverside] [-nosynonym] [-nousage] [-noverify] [-o | -oci | oci8] [-optionfile <file>] [-optiontable <table_name>] [-publish <package>] [-pubmain <number>] [-recursivejars] [-r | -resolve] [-R | -resolver "resolver_spec"] [-resolveonly] [-S | -schema <schema>] [-stdout] [-stoponerror] [-s | -synonym] [-tableschema <schema>] [-t | -thin] [-time] [-unresolvedok] [-v | -verbose]
Argument Summary
Table 72 summarizes the loadjava arguments. If you execute loadjava multiple times specifying the same les and different options, the options specied in the most recent invocation hold. There are two exceptions:
loadjava
1.
If loadjava does not load a le because it matches a digest table entry, most options on the command line have no effect on the schema object. The exceptions are -grant and -resolve, which are always obeyed. Use the -force option to direct loadjava to skip the digest table lookup. The -grant option is cumulative; every user specied in every loadjava invocation for a given class in a given schema has the EXECUTE privilege.
2.
-action
-andresolve
-cleargrants
-debug -definer
7-10
loadjava
-encoding
loadjava
-nocasesensitivepub
-nocleargrants
7-12
loadjava
-nogrant
-norecursivejars
-noschema
-nosynonym -noserverside
-nousage -noverify
-oci | -oci8
-optionfile <file>
loadjava
-publish <package>
-pubmain <number>
-recursivejars
-resolve
7-14
loadjava
-resolveonly -schema
-stdout -stoponerror
-synonym
-time
loadjava
-verbose
Argument Details
This section describes the details of loadjava arguments whose behavior is more complex than the summary descriptions contained in Table 72.
File Names
You can specify as many .class, .java, .sqlj, .jar, .zip, and resource les as you like, in any order. If you specify a JAR or ZIP le, then loadjava processes the les in the JAR or ZIP; there is no JAR or ZIP schema object. If a JAR or ZIP contains a JAR or ZIP, loadjava does not process them. The best way to load les is to put them in a JAR or ZIP and then load the archive. Loading archives avoids the resource schema object naming complications described later in this section. If you have a JAR or ZIP that works with the JDK, then you can be sure that loading it with loadjava will also work, without having to learn anything about resource schema object naming. Schema object names are slightly different from le names, and loadjava names different types of schema objects differently. Because class les are self-identifying (they contain their names), loadjavas mapping of class le names to schema object names is invisible to developers. Source le name mapping is also invisible to developers; loadjava gives the schema object the fully qualied name of the rst class dened in the le. JAR and ZIP les also contain the names of their les; however, resource les are not self identifying. loadjava generates Java resource schema object names from the literal names you supply as arguments (or the literal names in a JAR or ZIP le). Because running classes use resource schema objects, it is important that you specify resource le names correctly on the command line, and the correct specication is not always intuitive. The surere way to load individual resource les correctly is:
7-16
loadjava
Run loadjava from the top of the package tree and specify resource le names relative to that directory. (The top of the package tree is the directory you would name in a Java CLASSPATH list.) If you do not want to follow this rule, observe the details of resource le naming that follow. When you load a resource le, loadjava generates the resource schema object name from the resource le name as literally specied on the command line. Suppose, for example you type:
% cd /home/scott/javastuff % loadjava options alpha/beta/x.properties % loadjava options /home/scott/javastuff/alpha/beta/x.properties
Although you have specied the same le with a relative and an absolute path name, loadjava creates two schema objects, one called alpha/beta/x.properties, the other ROOT/home/scott/javastuff/alpha/beta/x.properties. (loadjava prepends ROOT because schema object names cannot begin with the / character; however, that is an implementation detail that is unimportant to developers.) The important point is that a resource schema objects name is generated from the le name as entered. Classes can refer to resource les relatively (for example, b.properties) or absolutely (for example, /a/b.properties). To ensure that loadjava and the class loader use the same name for a schema object, follow this rule when loading resource les: Enter the name on the command line that the class passes to getResource() or getResourceAsString(). Instead of remembering whether classes use relative or absolute resource names and changing directories so that you can enter the correct name on the command line, you can load resource les in a JAR as follows:
% cd /home/scott/javastuff % jar -cf alpharesources.jar alpha/*.properties % loadjava options alpharesources.jar
Or, to simplify further, put both the class and resource les in a JAR, which makes the following invocations equivalent:
% loadjava options alpha.jar % loadjava options /home/scott/javastuff/alpha.jar
loadjava
The two loadjava commands in this example make the point that you can use any pathname to load the contents of a JAR le. Even if you did execute the redundant commands shown above, loadjava would realize from the digest table that it did not need to load the les twice. That means that reloading JAR les is not as time-consuming as it might seem, even when few les have changed between loadjava invocations.
dener
{-definer | -d}
The -definer option is identical to deners rights in stored procedures and is conceptually similar to the UNIX setuid facility; however, whereas setuid applies to a complete program, you can apply -definer class by class. Moreover, different deners may have different privileges. Because an application may consist of many classes, you must apply -definer with care to achieve the results desired, namely classes that run with the privileges they need,0 but no more. For more information on deners rights, see the Oracle9i Java Stored Procedures Developers Guide.
7-18
loadjava
noverify
[-noverify]
Causes the classes to be loaded without bytecode verication. You must be granted oracle.aurora.security.JServerPermission(Verifier) to execute this option. In addition, this option must be used in conjunction with -r. The verier ensures that incorrectly formed Java binaries cannot be loaded for execution in the server. If you know that the JAR or classes you are loading are valid, use of this option will speed up the loadjava process. Some Oracle9i-specic optimizations for interpreted performance are put in place during the verication process. Thus, interpreted performance of your application may be adversely affected by using this option.
optionle
[-optionfile <file>]
A le can be provided with loadjava options. This <file> is read and processed by loadjava before any other loadjava options are processed. This <file> may contain one or more lines, each of which contains a pattern and a sequence of options. Each line must be terminated by a newline (\n). For each le (or JAR entry) that is processed by loadjava, the long name of the schema object that is going to be created (typically, the name of the class with a dot "." replaced by a slash "/") is checked against the patterns. Patterns can end in a wildcard (*) to indicate an arbitrary sequence of characters; otherwise, they must match the name exactly. Options to be applied to matching Java schema objects are supplied on the rest of the line. Options are appended to the command-line options, they do not replace them. In case more than one line matches a name, the matching rows are sorted by length of pattern, with the shortest rst, and the options from each row are appended. In general, loadjava options are not cumulative. Rather, later options override earlier ones. This means that an option specied on a line with a longer pattern will override a line with a shorter pattern. This le is parsed by a java.io.StreamTokenizer. Java comments (both /* */ and //) are allowed. A line comment begins with a #. Empty lines are ignored. The quote character is a double quote ("). That is, options containing spaces (common in -resolver options, for example) should be surrounded by double quotes. Certain options, such as -user or -verbose, affect the overall processing of loadjava and not the actions performed for individual Java schema objects. Such options are ignored if they appear in an option le. As an aid in packaging applications, loadjava looks for an entry named META-INF/loadjava-options in each JAR it processes. If it nds such an entry, it treats it as an options le that is applied for all other entries in the option le.
loadjava
However, loadjava does some processing on entries in the order in which they occur in the JAR. In case it has partially processed entities before it processes the META-INF/loadjava-options, the loadjava tool will attempt to patch up the schema object to conform to the applicable options. For example, by altering classes that were created with invokers rights when they should have been created with deners rights. The x for -noaction will be to drop the created schema object. This will yield the correct effect except that if a schema object existed before loadjava started, it will have been dropped.
publish
[-publish <package>] [-pubmain <number>]
The publishing options cause loadjava to create PL/SQL wrappers for methods contained in the processed classes. Typically, a user wants to publish wrappers for only a few classes in a JAR. These options are most useful when specied in an option le. To be eligible for publication, the method must satisfy the following:
1. 2. 3.
The method must be a member of a public class. The method must itself be declared public and static. The method signature must be "mapable", which is dened in the following rules: Java arithmetic types (byte, int, long, float, double) as arguments and return types are mapped to NUMBER. char as an argument and return type is mapped to VARCHAR. java.lang.String as an argument and return type is mapped to VARCHAR. If the only argument of the method has type java.lang.String, special rules apply, as listed in the -pubstring option description. If the return type is void, then a procedure is created. If the return type is arithmetic, char, or java.lang.String, then a function is created and its return type is as specied in an earlier rule.
Methods that take arguments or return types that are not covered by the above rules are not eligible. No provision is made for OUT, IN-OUT SQL arguments, OBJECT types, or for many other SQL features.
7-20
loadjava
resolve
{-resolve | -r}
Use -resolve to force loadjava to compile (if necessary) and resolve a class that has previously been loaded. It is not necessary to specify -force, because resolution is performed after, and independently of, loading.
resolver
{-resolver | -R} "resolver spec"
This option associates an explicit resolver spec with the class schema objects that loadjava creates or replaces. A resolver spec consists of one or more items, each of which consists of a name spec and a schema spec expressed in the following syntax:
"((name_spec schema_spec) [(name_spec schema_spec)] ...)"
s
A name spec is similar to a name in a Java import statement. It can be a fully qualied Java class name, or a package name whose nal element is the wildcard character *, or (unlike an imported package name) simply the wildcard character *; however, the elements of a name spec must be separated by / characters, not periods. For example, the name spec a/b/* matches all classes whose names begin with a.b. The special name * matches all class names. A schema spec can be a schema name or the wildcard character -. The wildcard does not identify a schema but directs the resolve operation to not mark a class invalid because a reference to a matching name cannot be resolved. (Without a - wildcard in a resolver spec, an unresolved reference in the class makes the class invalid and produces an error message.) Use a - wildcard when you must test a class that refers to a class you cannot or do not want to load; for example, GUI classes that a class refers to but does not call because when run in the server there is no GUI.
The resolution operation interprets a resolver spec item as follows: When looking for a schema object whose name matches the name spec, look in the schema named by the partner schema spec. The resolution operation searches schemas in the order in which the resolver spec lists them. For example,
-resolver ((* SCOTT) (* PUBLIC))
loadjava
Search for any reference rst in SCOTT and then in PUBLIC. If a reference is not resolved, then mark the referring class invalid and display an error message; in other words, call attention to missing classes. The following example:
-resolver "((* SCOTT) (* PUBLIC) (my/gui/* -))"
means the following: Search for any reference rst in SCOTT and then in PUBLIC. If the reference is not found, and is to a class in the package my.gui then mark the referring class valid, and do not display an error; in other words, ignore missing classes in this package. If the reference is not found and is not to a class in my.gui, then mark the referring class invalid and produce an error message.
user
{-user | -u} <user>/<password>[@<database>]
By default, loadjava loads into the login schema specied by the -user option. Use the -schema option to specify a different schema to load into. This does not involve a login into that schema, but does require that you have sufcient permissions to alter it. The permissible forms of @<database> depend on whether you specify -oci or -thin; -oci is the default.
s
-oci: @<database> is optional; if you do not specify, loadjava uses the users default database. If specied, <database> can be a TNS name or a Oracle Net Services name-value list. -thin: @<database> is required. The format is <host>:<lport>:<SID>. <host> is the name of the machine running the database. <lport> is the listener port that has been congured to listen for Oracle Net Services connections; in a default installation, it is 5521. <SID> is the database instance identier; in a default installation it is ORCL.
Connect to the default database with the default OCI driver, load the les in a JAR into the TEST schema, then resolve them.
loadjava -u joe/shmoe -resolve -schema TEST ServerObjects.jar
7-22
dropjava
Connect with the thin driver, load a class and a resource le, and resolve each class:
loadjava -thin -u SCOTT/TIGER@dbhost:5521:orcl \ -resolve alpha.class beta.props
Add Betty and Bob to the users who can execute alpha.class:
loadjava -thin -schema test -u SCOTT/TIGER@localhost:5521:orcl \ -grant BETTY,BOB alpha.class
dropjava
The dropjava tool is the converse of loadjava. It transforms command-line le names and JAR or ZIP le contents to schema object names, then drops the schema objects and deletes their corresponding digest table rows. You can enter .java, .class, .sqlj, .ser, .zip, .jar, and resource le names on the command line in any order. Alternatively, you can specify a schema object name (full name, not short name) directly to dropjava. A command-line argument that does not end in .jar, .zip, .class, .java, or .sqlj is presumed to be a schema object name. If you specify a schema object name that applies to multiple schema objects (such as a source schema object Foo and a class schema object Foo), all will be removed. Dropping a class invalidates classes that depend on it, recursively cascading upwards. Dropping a source drops classes derived from it.
Note: You must remove Java schema objects in the same way that
you rst loaded them. If you load a .sqlj source le and translate it in the server, you must run dropjava on the same source le. If you translate on a client and load classes and resources directly, run dropjava on the same classes and resources. You can execute the dropjava tool either through the command line (as described below) or through the dropjava method contained within the DBMS_JAVA class. To execute within your Java application, do the following:
call dbms_java.dropjava(... options...);
where the options are the same as specied below. Separate each option with a blank. Do not separate the options with a comma. The only exception for this is the
dropjava
-user option. The connection is always made to the current session, so you cannot specify another username through the -user option. For -resolver, you should specify all other options rst, a comma, then the -resolver option with its denition. Do not specify the following options, because they relate to the database connection for the loadjava command-line tool: -thin, -oci, -user, -password. The output is directed to stderr. Set serveroutput on and call dbms_java.set_output as appropriate.
Syntax
dropjava [options] {<file>.java | <file>.class | file.sqlj | <file>.jar | <file.zip> | <resourcefile>} ... -u | -user <user>/<password>[@<database>] [-genmissingjar <JARfile>] [-jarasresource] [-noserverside] [-o | -oci | -oci8] [-optionfile <file>] [-optiontable <table_name>] [-S | -schema <schema>] [ -stdout ] [-s | -synonym] [-t | -thin] [-time] [-v | -verbose]
Argument Summary
Table 73 summarizes the dropjava arguments.
Table 73 dropjava Argument Summary
Argument -user <filenames> Description Species a user, password, and optional database connect string; the les will be dropped from this database instance. You can specify any number and combination of .java, .class, .sqlj, .ser, .jar, .zip, and resource le names, in any order. dropjava treats the operand of this option as a le to be processed. Drops the whole JAR le, which was previously loaded as a resource.
7-24
dropjava
-oci | -oci8
-optionfile <file>
-optiontable <table> This has the same usage as for loadjava. -schema Designates the schema from which schema objects are dropped. If not specied, the logon schema is used. To drop a schema object from a schema that is not your own, you need the DROP ANY PROCEDURE and UPDATE ANY TABLE privileges. Causes the output to be directed to stdout, rather than to stderr. Drops a PUBLIC synonym that was created with loadjava. Directs dropjava to communicate with the database using the thin JDBC driver. -oci and -thin are mutually exclusive; if neither is specied, then -oci is used by default. Choosing -thin implies the form of the -user value. Prints a timestamp on every message. Directs dropjava to emit detailed status messages while running.
-time -verbose
Argument Details
File Names
.class les: dropjava nds the class name in the le and drops the corresponding schema object. .java and .sqlj les: dropjava nds the rst class name in the le and drops the corresponding schema object.
dropjava
.jar and .zip les: dropjava processes the archived le names as if they had been entered on the command line.
If a le name has another extension or no extension, then dropjava interprets the le name as a schema object name and drops all source, class, and resource objects that match the name. For example, the hypothetical le name alpha drops whichever of the following exists: the source schema object named alpha, the class schema object named alpha, and the resource schema object named alpha. If the le name begins with the / character, then dropjava prepends ROOT to the schema object name. If dropjava encounters a le name that does not match a schema object, it displays a message and processes the remaining le names.
user
{-user | -u} <user>/<password>[@<database>]
The permissible forms of @<database> depend on whether you specify -oci or -thin; -oci is the default.
s
-oci: @<database> is optional; if you do not specify, then dropjava uses the users default database. If specied, then <database> can be a TNS name or a Oracle Net Services name-value list. -thin: @<database> is required. The format is <host>:<lport>:<SID>. <host> is the name of the machine running the database. <lport> is the listener port that has been congured to listen for Oracle Net Services connections; in a default installation, it is 5521. <SID> is the database instance identier; in a default installation, it is ORCL.
Drop all schema objects in schema TEST in the default database that were loaded from ServerObjects.jar:
dropjava -u SCOTT/TIGER -schema TEST ServerObjects.jar
Connect with the thin driver, then drop a class and a resource le from the users schema:
dropjava -thin -u SCOTT/TIGER@dbhost:5521:orcl alpha.class beta.props
7-26
ojvmjava
Dropping Resources
Care must be taken if you are removing a resource that was loaded directly into the server. This includes proles if you translated on the client without using the -ser2class option. When dropping source or class schema objects, or resource schema objects that were generated by the server-side SQLJ translator, the schema objects will be found according to the package specication in the applicable .sqlj source le. However, the fully qualied schema object name of a resource that was generated on the client and loaded directly into the server depends on path information in the .jar le or on the command line at the time you loaded it. If you use a .jar le to load resources and use the same .jar le to remove resources, there will be no problem. If, however, you use the command line to load resources, then you must be careful to specify the same path information when you run dropjava to remove the resources.
ojvmjava
The ojvmjava tool is an interactive interface to a database instances session namespace. You specify database connection arguments when you start ojvmjava. It then presents you with a prompt to indicate that it is ready for commands. The shell can launch an executable, that is, a class with a static main() method. Executables must have been loaded with loadjava.
Syntax
ojvmjava {-user <user>[/<password>@database] [options] [@<filename>] [-batch] [-c | -command <command> <args>] [-debug] [-d | -database <conn_string>] [-fileout <filename>] [-o | -oci | -oci8] [-oschema <schema>] [-t | -thin] [-version | -v]
Argument Summary
Table 74 summarizes the ojvmjava command-line arguments.
ojvmjava
-password | -p @<filename>
-batch
-command
-debug -d | -database <conn_string> -fileout <file> -o | -oci | -oci8 -oschema <schema> -t | -thin
-verbose -version
7-28
ojvmjava
Open a shell on the session namespace of the database orcl on listener port 2481 on host dbserver.
ojvmjava -thin -user SCOTT/TIGER@dbserver:2481:orcl
The ojvmjava commands span several different types of functionality, which are grouped as follows:
s
ojvmjava OptionsDescribes the options for the ojvmjava command-line tool Shell CommandsDescribes the commands that are used for manipulating and viewing contexts and objects in the namespace.
ojvmjava Options
s
ojvmjava Tool Output Redirection Scripting ojvmjava Commands in the @<lename> Option
ojvmjava Tool Output Redirection You can specify that any output generated by the ojvmjava tool is put into a le by appending the "&><filename>" at the end of the command options. The following pipes all output to the listDir le:
ls -lR &>/tmp/listDir
Scripting ojvmjava Commands in the @<lename> Option This option designates a script le that contains one or more ojvmjava commands. The script le specied is located on the client. The ojvmjava tool reads in the le and then executes all commands on the designated server. Also, because the script le is executed on the server, any interaction with the operating system in the script lesuch as redirecting output to a le or executing another scriptwill occur on the server. If you direct ojvmjava to execute another script le, this le must exist within $ORACLE_HOME directory on the server. Type in the ojvmjava command followed by any options and any expected input arguments. The script le contains any ojvmjava command followed by options and input parameters. The input parameters can be passed in on the ojvmjava command-line. The ojvmjava command processes all known ojvmjava options and then passes on any other options and arguments to the script le. To access arguments within the commands in the script le, place &1...&n to denote the arguments. If all input parameters are passed into a single command, you can supply a the string "&*" to denote that all input parameters are to be passed to this command.
ojvmjava
Because only two input arguments are expected, you can implement the java command input parameters as follows:
java testhello &1 &2
After processing all other options, the ojvmjava tool passes "contexts" in as the argument to the "cd" command. To execute this le, do the following:
ojvmjava -user SCOTT -password TIGER -thin -database dbserver:2481:orcl \ @execShell alpha beta
The ojvmjava processes all options that it knows about and passes along any other input parameters to be used by the commands that exist within the script le. In this example, the parameters, alpha and beta, are passed to the java command in the script le. Thus, the actual command executed is as follows:
java testhello alpha beta
You can add any comments in your script le with the hash symbol (#). The "#" symbol makes anything to the end of the line a comment, which is ignored by ojvmjava. For example:
#this whole line is ignored by ojvmjava
7-30
ojvmjava
Shell Commands
The following shell commands behave similarly to their UNIX counterparts:
s
echo java
exit version
help whoami
echo
Prints to stdout exactly what is indicated. This is used mostly in script les. The syntax is as follows:
echo [<echo_string>] [<args>]
where <echo_string> is a string that contains the text you want written to the screen during the shell script invocation and <args> are input arguments from the user. For example, the following prints out a notication:
echo "Adding an owner to the schema" &1
If the input argument is "SCOTT", the output would be "Adding an owner to the schema SCOTT"
exit
The exit command terminates ojvmjava. Syntax
exit
ojvmjava
$ exit %
help
The help command summarizes the syntax of the shell commands. You can also use the help command to summarize the options for a particular command. Syntax
help [<command>]
java
The java command is analogous to the JDK java command; it invokes a classs static main() method. The class must have been loaded with loadjava. (There is no point to publishing a class that will be invoked with the java command.) The java command provides a convenient way to test Java code that runs in the database. In particular, the command catches exceptions and redirects the classs standard output and standard error to the shell, which displays them as with any other command output. (The usual destination of standard out and standard error for Java classes executed in the database is one or more database server process trace les, which are inconvenient and may require DBA privileges to read.) Syntax
java [-schema <schema>] <class> [arg1 ... argn]
7-32
ojvmjava
package hello; public class World { public World() { super(); } public static void main(String[] argv) { System.out.println("Hello from the Oracle9i ORB"); if (argv.length != 0) System.out.println("You supplied " + argv.length + " arguments: "); for (int i = 0; i < argv.length; i++) System.out.println(" arg[" + i + "] : " + argv[i]); } }
Compile, load, publish, and run the executable as follows, substituting your userid, host, and port information as appropriate:
% javac hello/World.java % loadjava -r -user SCOTT/TIGER@localhost:2481:orcl hello/World.class % ojvmjava -user SCOTT -password TIGER -database localhost:2481:orcl $ java testhello alpha beta Hello from the Oracle9i ORB You supplied 2 arguments: arg[0] : alpha arg[1] : beta
version
The version command shows the version of the ojvmjava tool. You can also show the version of a specied command. Syntax
version [options] [<command>]
whoami
Prints out the current user that logged into this session.
ojvmjava
7-34
Glossary
API API stands for Application Programming Interface. As applied to Java, an API is a well-dened set of classes and methods that furnish a specic set of functionality to the Java programmer. JDBC and SQLJ are APIs for accessing SQL data. Bytecodes The set of single-byte, machine-independent instructions to which Java source code is compiled using the Java compiler. Call Memory The memory that the memory manager uses to allocate new objects. CLASSPATH The environment variable (or command line argument) that the JDK or JRE uses to specify the set of directory tree roots in which Java source, classes, and resources are located. Context Switch In a uniprocessor system, the current thread is interrupted by a higher priority thread or by some external event, and the system switches to a different thread. The choice of which thread to dispatch is usually made on a priority basis or based on how long a thread has been waiting. Cooperative Multitasking The programmer places calls to the Thread.yield() method in locations in the code where it is appropriate to suspend execution so that other threads can run.
Glossary-1
This is quite error-prone because it is often difcult to assess the concurrent behavior of a program as it is being written. Core Class Libraries Generally, the Java packages delivered with the Sun Microsystems JDK, java.*. We also use this term to denote some sun.* packages. Deadlock The conict state where two or more synchronized Java objects depend on locking each other, but cannot, because they themselves are locked by the dependent object. For example, object A tries to lock object B while object B is trying to lock object A. This situation is difcult to debug, because a preemptive Java virtual machine can neither detect nor prevent deadlock. Without deadlock detection, a deadlocked program simply hangs. Dispatch The system saves the state of the currently executing thread, restores the state of the thread to be executed, and branches to the stored program counter for the new thread, effectively continuing the new thread as if it had not been interrupted. Driver As used with JDBC, a layer of code that determines the low-level libraries employed to access SQL data and/or communicate across a network. The three JDBC drivers supported in Oracle9i JVM are: Thin, OCI, and KPRB. End-of-Call Within your session, you may invoke Java many times. Each time you do this, end-of-call occurs at the point at which Java code execution completes. The memory manager migrates static variables to session space at end-of-call. Garbage Collection The popular name for the automatic storage reclamation facility provided by the Java virtual machine. IDE Integrated Development Environment. A Java IDE runs on a client workstation, providing a graphical user interface for access to the Java class library and development tools.
Glossary-2
Java Schema Object The term that Oracle9i uses to denote either Java source, binary, or resources when stored in the database. These three Java schema objects correspond to les under the JDK.java, .class, or other les (such as .properties les) used in the JDK CLASSPATH. JCK Java Compatibility Kit. The set of Java classes that test a Java virtual machine and Java compilers compliance with the Java standard. JCK releases correspond to the Sun Microsystems JDK releases, although in the case of Oracle9i, only the Java classes and not the virtual machine, are identical to the Sun Microsystems JDK. JDBC Java Database Connectivity. The standard Java classes that provide vendor-independent access to databases. JDBC Driver The vendor-specic layer of JDBC that provides access to a particular database. Oracle provides three JDBC driversThin, OCI, and KPRB. JDK Java Development Kit. The Java virtual machine, together with the set of Java classes and tools that Sun Microsystems furnishes to support Java application and applet development. The JDK includes a Java compiler; the JRE does not. JLS Java Language Specication. This specication denes the syntax and semantics of the Java language. JRE Java Runtime Environment. The set of Java classes supporting a Java application or applet at runtime. The JRE classes are a subset of the JDK classes. Lazy Initialization A technique for initializing data, typically used in accessor methods. The technique checks to see if a eld has been initialized (is non-null) before returning the initialized object to it. The overhead associated with the check is often small, especially in comparison to initializing a data structure that may never be accessed. You can employ this technique in conjunction with end-of-call processing to minimize session space overhead.
Glossary-3
Object Graph An object is said to reference the objects held in its elds. This collection of objects forms an object graph. The memory manager actually migrates the object graphs held in static variables; that is, it migrates not only the objects held in static elds, but the objects that those objects reference, and so on. Oracle9i JVM Oracles scalable Java server platform, composed of the Java virtual machine running within the Oracle9i database server, the Java runtime environment and Oracle extensions. Preemptive Multitasking The operating system preempts, or takes control away from a thread, under certain conditions, such as when another thread of higher priority is ready to run, or when an external interrupt occurs, or when the current thread waits on an I/O operation, such as a socket accept or a le read. Some Java virtual machines implement a type of round-robin preemption by preempting the current thread on certain virtual machine instructions, such as backward branches, method calls, or other changes in control ow. For a Java virtual machine that maps Java threads to actual operating system threads, the preemption takes place in the operating system kernel, outside the control of the virtual machine. Although this yields decent parallelism, it complicates garbage collection and other virtual machine activities. Process An address space and one or more threads. Session Memory The memory that the memory manager uses to hold objects that survive past the end-of-callthose objects reachable from Java static variables within your session. SQLJ Embedded SQL in Java. The standard that denes how SQL statements can be embedded in Java programs to access SQL data. A translator transforms the SQLJ programs to standard JDBC programs. Strong Typing In Java, the requirement that the class of each eld and variable, and the return type of each method be explicitly declared.
Glossary-4
Symmetric Multiprocessing (SMP) The hardware has multiple processors, and the operating system maps threads to different processors, depending on their load and availability. This assumes that the Java virtual machine maps OS threads to Java threads. This mechanism provides true concurrency among the threads, but can lead to subtle programming errors and deadlock conicts on synchronized objects. System Often used in discussion as the combination of the hardware, the operating system, and the Java virtual machine. Thread An execution context consisting of a set of registers, a program counter, and a stack. Virtual Machine A program that emulates the functionality of a traditional processor. A Java virtual machine must conform to the requirements of the Java Virtual Machine Specication.
Glossary-5
Glossary-6
Index
Symbols
#sql, 3-8, 3-9
C
call definition, 2-2 managing resources across calls, 2-35 static fields, 2-5 call specification, 3-4, 3-5 Callback class act method, 6-26 class attributes, 1-5, 1-7 definition, 1-5 dynamic loading, 1-18 execution, 2-2 hierarchy, 1-7 inheritance, 1-7, 1-8 loading, 2-2, 2-6, 2-16, 3-2 marking valid, 2-13 methods, 1-5, 1-7 name, 2-26 protected, 5-26 publish, 2-2, 2-25, 3-2 resolving references, 2-12, 3-2 schema object, 2-6, 2-13, 2-16, 2-17 .class files, 2-7, 2-16, 2-17 Class interface forName method, 2-27 class schema object, 7-2, 7-3 ClassForName class lookupClass method, 2-30 classForNameAndSchema method, 2-29 ClassNotFoundException, 2-27 CLASSPATH, 2-6, 2-27 client
A
Accelerator deploync tool, 6-16 for user applications, 6-5 installation requirements, 6-5 ncomp tool, 6-7 overview, 6-2, 6-3 statusnc tool, 6-17 act method, 6-26 ALREADY_NCOMPED status, 6-17 application compiling, 2-8 development, 2-3 executing in a session, 2-3 execution control, 2-6 execution rights, 2-20 invoking, 3-3, 3-20 threading, 2-38 attributes definition, 1-5 types of, 1-6 authentication, 5-2
B
BasicPermission, 5-14 bytecode defined, 1-10 verification, 2-15
Index-1
setup, 4-6 code native compilation, 6-2 CodeSource class, 5-5 equals method, 5-5 implies method, 5-5 compiling, 2-8 error messages, 2-9, 7-5 memory problems, 6-24 options, 2-9, 7-5 runtime, 2-8 setting options, 3-15 configuration, 4-1 JVM, 4-2 to ?? performance, 6-19 connection configuration, 4-3 security, 5-2
D
data confidentiality, 5-2 database configuration, 4-2 privileges, 5-2 DBA_JAVA_POLICY view, 5-6, 5-18, 5-20 DBMS_JAVA package, 3-17, 4-3 defined, 5-5 delete_permission method, 4-5, 5-19 disable_permission method, 4-5, 5-18 dropjava method, 4-4 enable_permission method, 4-5, 5-18 get_compiler_option method, 4-4 grant_permission method, 4-5, 5-8, 5-10 grant_policy_permission method, 4-5, 5-12, 5-20 loadjava method, 4-4 longname method, 2-23, 2-26, 4-3 modifying permissions, 5-19 modifying PolicyTable permissions, 5-10, 5-12 reset_compiler_option method, 4-4 restart_debugging method, 3-17, 4-5 restrict_permission method, 4-5, 5-9, 5-10 revoke_permission method, 4-5, 5-18 set_compiler_option method, 3-15, 4-4 set_output method, 3-20, 4-4
setting permissions, 5-5 shortname method, 2-24, 2-26, 4-3 start_debugging method, 3-17, 4-5 stop_debugging method, 4-5 DBMS_OUTPUT package, 4-4 DbmsJava class, see DBMS_JAVA package DbmsObjectInputStream class, 2-30 DbmsObjectOutputStream class, 2-30 deadlock, 2-39 DeadlockError exception, 2-39 debug compiler option, 2-10, 7-6 DebugAgent class, 3-14 debugging, 4-5, 5-25 agent, 3-14, 3-16, 3-17 connecting a debugger, 3-18 Java applications, 1-4, 3-13 necessary permissions, 5-25 setting compiler options, 3-15 starting Debug Agent, 3-16 starting proxy, 3-15 using OracleAgent class, 3-17 DebugProxy class, 3-14, 3-15 definer rights, 2-21 delete method, 5-19 delete_permission method, 4-5, 5-19 deploync tool, 6-16 digest table, 7-4, 7-5 disable method, 5-18 disable_permission method, 4-5, 5-18 dropjava method, 4-4 tool, 2-18 dropjava tool, 7-23
E
enable method, 5-19 enable_permission method, 4-5, 5-18 encoding compiler option, 2-9, 7-6 end-of-call migration, 6-25 EndOfCallRegistry class, 6-25 registerCallback method, 6-26 endSession method, 2-40
Index-2
equals method, 5-5 errors compilation, 2-9 exception ClassNotFoundException, 2-27 DeadlockError, 2-39 IOException, 2-33 LimboError, 2-39 ThreadDeathException, 2-40 execution rights, 2-20 exit command, 7-31 exitCall method, 2-40
H
help command, 7-32
I
implies method, 5-5 inheritance, 1-7, 1-8 installation, 4-1, 4-2 integrity, 5-2 interfaces defined, 1-8 user, 2-25 internet newsgroups, xv INVALID status, 6-17 invoker rights, 2-21 advantages, 2-21 IOException, 2-33
F
file names dropjava, 7-25 loadjava, 7-16 FilePermission, 5-7, 5-19, 5-21, 5-23, 6-6 files, 2-32 across calls, 2-35 lifetime, 2-33 relative path names, 2-34 finalizers, 2-35 footprint, 1-16, 2-4 forName method, 2-27
J
Java applications, 2-1, 2-8 loading, 2-16 attributes, 1-5 class, 1-5 client setup, 4-6 compiling, 2-8 development environment, 2-6 differences from Sun JDK, 2-3 documentation, xiv, 1-2, 1-22 execution control, 2-6 execution rights, 2-20 features, 1-13 in the database, 1-2, 1-14, 2-1, 2-2 interpreter, 2-2 introduction, xiii invoking, 2-2, 3-3 loading classes, 2-6, 3-2 checking results, 2-23 methods, 1-5 natively compiling, 6-2 overview, 1-2, 1-5 permissions, 4-5 polymorphism, 1-8
G
garbage collection, 1-14, 1-15, 2-5 managing resources, 2-32 misuse, 2-34 purpose, 2-34 get_compiler_option method, 2-10, 4-4, 7-6 getCallerClass method, 2-28 getClassLoader method, 2-28 getProperty method, 3-20 grant method, 5-8 grant_permission method, 4-5, 5-8, 5-10 grant_policy_permission method, 4-5, 5-12, 5-20 granting permission, 5-5 grantPolicyPermission method, 5-13 GUI, 2-25
Index-3
programming models, xiv publishing, 2-6 resolving classes, 2-12 resources, 1-5 stored procedures, see Java stored procedures Java 2 migrating from JDK 1.1, 1-2 security, 5-2 java command, 7-32 Java Compatibility Kit, see JCK .java files, 2-7, 2-16, 2-17 java interpreter, 2-2, 2-6 Java language specification, see JLS Java Native Interface, see JNI Java Remote Method Invocation, see RMI Java stored procedures, xiv, 2-5 defined, 1-19, 3-3 documentation, 1-22 invoking, 3-2 publishing, 2-25 Java virtual machine, see JVM JAVA$OPTIONS table, 2-9, 7-5 JAVA_ADMIN role assigned permissions, 5-21 example, 5-14 granting permission, 5-3, 5-5, 5-12, 5-20 JAVA_DEPLOY role, 6-6 JAVA_MAX_SESSIONSPACE_SIZE parameter, 6-20 JAVA_POOL_SIZE parameter default, 4-2 defined, 6-19, 6-21 errors, 6-24 JAVA_SOFT_SESSIONSPACE_LIMIT parameter, 6-20 JAVADEBUGPRIV role, 5-24, 5-25 JAVASYSPRIV role, 5-3, 5-23, 5-24 JAVAUSERPRIV role, 5-3, 5-23, 5-24 JCK, 1-12 jdb debugging tool, 3-13, 3-18 JDBC accessing SQL, 1-20 defined, 1-19, 3-2, 3-6 documentation, 1-22 driver types, 1-20, 3-6
example, 3-7 interacting with SQL, 3-12 security, 5-2 JDeveloper development environment, 1-22, 3-11, 4-8 JDK web location, xiv JLS specification, 1-12 web information, xiv JNI support, 3-5 JPublisher documentation, 1-22 JServerPermission, 5-8, 5-19, 5-20, 5-21, 5-22, 5-23, 5-24 defined, 5-20 JVM bytecodes, 1-10 configure, 4-1 defined, 1-5, 1-10 garbage collection, 1-14, 1-15 install, 4-1, 4-2 multithreading, 1-14 responsibilities, 2-4 security, 4-5 specification, 1-12 web information, xiv
L
LimboError exception, 2-39 loading, 2-16 to 2-25 checking results, 2-18, 2-23 class, 1-18, 2-6, 2-8 compilation option, 2-8 granting execution, 2-20 JAR or ZIP files, 2-19 necessary privileges and permissions, reloading classes, 2-19 restrictions, 2-18 loadjava method, 4-4 loadjava tool, 2-17 to 2-19, 7-7 to 7-23 compiling source, 2-8, 6-24 example, 3-4 execution rights, 2-20, 5-3
2-19
Index-4
loading class, 2-16 loading ZIP or JAR files, 2-19 restrictions, 2-18 using memory, 6-19 logging, 2-9 longname method, 2-23, 2-26, 4-3 lookupClass method, 2-30
M
main method, 2-6 memory across calls, 2-34 call, 2-5 java pool, 6-22 leaks, 2-34 lifetime, 2-32, 2-33 manager, 2-7 performance configuration, 6-19 report allocation, 6-30 running out of, 6-24 session, 2-5, 6-26 Memory Profiling Utility, see MemStat MemStat analysis options, 6-31 class, 6-32 writeDump method, 6-32 writeDumpAtEOC method, 6-32 example, 6-33, 6-35 reporting, 6-34 security permissions, 6-33 using, 6-32 utility, 6-30 warning, 6-32 methods, 1-5, 1-7 multithreading, 1-14
deploync tool, 6-16 designating build directory, 6-14 errors, 6-11 execution time, 6-8 force recompile, 6-14 ncomp tool, 6-7 scenarios, 6-13 statusnc tool, 6-17 ncomp tool, 6-5, 6-7 executing, 6-7 security, 6-6 NEED_NCOMPING status, 6-17 NEED_NCOMPING status message, 6-12 NetPermission, 5-7, 5-19, 5-21, 5-22 networking configuration, 4-3
O
object full to short name conversion, 2-23 lifetime, 2-33 schema, 2-6 serialization, 2-30 short name, 2-23 ObjectInputStream class, 2-30 ObjectOutputStream class, 2-30 ojvmjava tool, 7-27 to ?? online compiler option, 2-10, 7-6 operating system resources, 2-32 across calls, 2-35 lifetime, 2-33 performance, 6-19 OracleAgent class restart method, 3-17 start method, 3-17 stop method, 3-17 OracleRuntime class exitCall method, 2-40 getCallerClass method, 2-28 getClassLoader method, 2-28 output redirecting, 3-20
N
namespace, 7-27 native compilation, 1-17, 6-2 Accelerator, 6-3 classes loaded in database, 6-13 classes not loaded in database, 6-13 compile subset, 6-15
Index-5
P
packages DBMS_JAVA, 4-3 protected, 5-26 path relative path names, 2-34 performance, 1-17, 6-1 to 6-30 Permission class, 5-7, 5-13, 5-14, 5-19 permissions, 4-5, 5-2 to 5-25 administrating, 5-12 assigning, 5-4, 5-5 creating, 5-14 deleting, 5-19 disabling, 5-18 enabling, 5-18 FilePermission, 6-6 granting, 5-5, 5-8, 5-10 granting policy, 5-12 grouped into roles, 5-24 JAVA_ADMIN role, 5-21 JAVA_DEPLOY role, 6-6 JAVADEBUGPRIV role, 5-24 JAVASYSPRIV role, 5-23 JAVAUSERPRIV role, 5-23 PUBLIC, 5-22 restricting, 5-5, 5-9, 5-10 specifying policy, 5-4 SYS permissions, 5-22 types, 5-7, 5-19 policy table managing, 5-12 modifying, 5-5 setting permissions, 5-5 viewing, 5-5 PolicyTable class specifying policy, 5-4 updating, 5-5, 5-15 PolicyTableManager class delete method, 5-19 disable method, 5-18 enable method, 5-19 revoke method, 5-18 PolicyTablePermission, 5-8, 5-12, 5-19, 5-20, 5-21, 5-22
polymorphism, 1-8 privileges database, 5-2 .properties files, 2-7, 2-16, 2-17 PropertyPermission, 5-7, 5-19, 5-21, 5-22, 5-24 PUBLIC permissions, 5-22 publishing, 2-6, 2-8, 2-25, 3-2 example, 3-4
R
ReflectPermission, 5-8, 5-19, 5-21, 5-22 registerCallback method, 6-26 reset_compiler_option method, 2-10, 4-4, 7-6 resolver, 2-12 to ??, 7-3 default, 2-13 defined, 2-6, 2-8, 2-13, 2-27, 3-2 example, 3-4 ignoring non-existent references, 2-13, 2-15 resource schema object, 2-6, 2-16, 2-17, 7-2 restart method, 3-17 restart_debugging method, 3-17, 4-5 restrict method, 5-9 restrict_permission method, 4-5, 5-9, 5-10 revoke method, 5-18 revoke_permission method, 4-5, 5-18 RMI support, 3-5 RuntimePermission, 5-8, 5-19, 5-21, 5-22, 5-23, 5-24
S
schema object, 7-2 defined, 2-16 name, 2-26 using, 2-6 security, 5-1 to 5-26 book recommendations, 5-4 Java 2, 5-3 JDBC, 5-2 JVM, 4-5 network, 5-2 SecurityManager class, 5-4 SecurityPermission, 5-8, 5-19, 5-21, 5-22 .ser files, 2-7, 2-16, 2-17
Index-6
SerializablePermission, 5-7, 5-19, 5-21, 5-23 serialization, 2-30 ServerSocket class, 2-37 sess_sh commands in a script file, 7-29 redirecting output, 7-29 session coordination with JVM, 2-4 definition, 2-2 footprint, 1-16 namespace, 7-27 role in Java execution, 2-3 set_compiler_option method, 2-10, 3-14, 3-15, 4-4, 7-6 set_output method, 3-20, 4-4 SHARED_POOL_SIZE parameter default, 4-2 defined, 6-19 errors, 6-24 shortname method, 2-24, 2-26, 4-3 Socket class, 2-37 SocketPermission, 5-8, 5-19, 5-21, 5-23, 5-24 sockets across calls, 2-32, 2-37 defined, 2-37 lifetime, 2-33, 2-37 source schema object, 2-6, 2-16, 2-17, 7-2, 7-5 SQL query, 3-2, 3-6 SQLJ accessing SQL, 1-20 converting, 3-12 defined, xiv, 1-19, 1-21, 3-2, 3-6 documentation, 1-22 example, 3-8, 3-9 interoperates with PL/SQL, 3-12 running, 3-11 translating, 3-11 typing paradigm, 3-10 using JDBC, 1-21 .sqlj files, 2-7, 2-16, 2-17 sqlj utility, 3-11 start method, 3-17 start_debugging method, 3-17, 4-5 static variable, 2-5
end of call migration, statusnc tool, 6-17 stop method, 3-17 stop_debugging method, SYS assigned permissions, security permissions, System class getProperty method,
6-25
T
ThreadDeathException, 2-40 threading, 2-32 applications, 2-38 lifecycle, 2-39 model, 1-14, 2-38 trigger using Java stored procedures,
3-3
U
user interface, 2-25 USER_ERRORS view, 2-9 USER_JAVA_POLICY view, 5-6, 5-20 USER_OBJECTS view, 2-18, 2-23, 4-4
V
V$SGASTAT table, 6-22 variables static, 2-5 version retrieving, 3-20
W
web sites, xiv
Index-7
Index-8