This is jakelib2.info, produced by makeinfo version 4.8 from jakelib2.texi. INFO-DIR-SECTION Java-Like Library 2 START-INFO-DIR-ENTRY * Serveez: (serveez). Serveez Documentation. END-INFO-DIR-ENTRY This file documents the Java-Like Library 2.  File: jakelib2.info, Node: Top, Next: Java vs. C++, Prev: (dir), Up: (dir) * Menu: * Java vs. C++:: GNU General Public License  File: jakelib2.info, Node: Java vs. C++, Next: Garbage Collection, Prev: Top, Up: Top 1 Java vs. C plus plus **********************  File: jakelib2.info, Node: Garbage Collection, Prev: Java vs. C++, Up: (dir) 1.1 Garbage Collection ====================== One of Java's most important features is automatic garbage collection which is handled by the Java Virtual Machine. This allows the programmer to create new objects without having to worry when to free or delete them. From time to time the garbage collector goes through the whole heap memory and frees all objects that are not referenced any longer. Unfortunately C or C++ does not provide an automatic garbage collector. But there are garbage collector libraries out there that can be used instead. Jakelib2 uses Hans-J. Boehm's garbage collector (`http://www.hpl.hp.com/personal/Hans_Boehm/gc/'). So this garbage collector library seems to be the limiting factor for jakelib's protability: If the gc can be compiled and does work for a certain platform, jakelib2 should also work. If not, one will have to find out why and fix the issue! The gc provides a class named `gc_cleanup'. All classes derived from this base class will be automatically garbage collected and their destructor (finalizer) will be called before disposal. This is why jakelib's counterpart to Java's `java.lang.Object' - `jakelib::lang::Object' - is derived from `gc_cleanup', so that all of jakelib's classes will be garbage collected. The garbage collector does not scan arrays allocated by the standard `malloc' functions. Objects that are referenced only from such arrays will probably be deleted by the gc. The new functions `GC_MALLOC', `GC_REALLOC' and `GC_FREE' can be used to allocate and free memory that the gc will scan. This is absolutely necessary when storing references in an array like it is done in `jakelib::util::ArrayList'. On the other hand, a byte buffer for IO operations can be allocated using standard `malloc' since it will not contain any references to objects. 1.1.1 Problems -------------- The gc will not guarantee that every single object will be freed if it is not referenced any longer. However, it seems that the amount of uncollected objects stays quite stable throughout a program's runtime. Practice shows that we don't need to worry too much about this issue. But one should keep in mind that there is no guarantee! Thus it's useful to provide some classes with methods like `destroy' or `close' that allow to release the acquired resources explicitely (i.e. close a file or free a large buffer). If a set of objects is referenced cyclically, the garbage collector won't finalize (i.e. call the object's destructor) these objects before disposing of them because there is no way to determine a safe order to finalize and free the objects one by one. 1.2 Primitive data types ======================== Java offers a set of well defined primitive data types: Type name size in bits boolean 1 byte 8 short 16 int 32 long 64 float 32 double 64 char 16 When programming in C or C++ the size of a certain primitive type depends on the platform you are actually using. This is why jakelib provides a set of typedefs that are defined in `include/jakelib2.h'. The names of these typedefs all start with a lower case `j'. It depends on the certain platform which types are used to represent a `jint' or a `jlong'. On an Intel/Linux system the following substitutions are done: Type name C type jboolean int jbyte char jshort short jint int jlong long long jfloat float jdouble double jchar unsigned short A `jboolean' variable should be assigned either `true' (`=1') or `false' (`=0') only. `TRUE' and `FALSE' should not be used. `null' is an alias for `NULL' and should be used instead. 1.3 Interfaces and Classes ========================== In jakelib every class should be derived from `jakelib::lang::Object' like all Java classes are derived from `java.lang.Object'. As C++ does not know interfaces in opposition to real classes, jakelib uses abstract classes as a substitution for Java's interfaces. These interface classes are not derived from `jakelib::lang::Interface'. 1.4 Arrays ========== To provide a portable way to work with typed arrays, Jakelib2 uses a special class for every data type to be stored. Templates are not used because they are known to cause problems on certain compilers. However, the result would actually be quite the same. 1.4.1 Primitive data types -------------------------- 1-dimensional array classes are already implemented for all of Jakelib2's primitive data types: `jchar', `jbyte', `jint', `jlong', `jfloat', `jdouble', `jboolean' and `jshort'. The array classes have the name of the original data type with an '`s'' append to express the plural: `jchars', `jbytes', `jints', `jlongs', `jfloats', `jdoubles', `jbooleans' and `jshorts'. Example: jints* arr = new jints(10); for (int idx = 0; idx < arr->length(); idx++) { arr->set(idx, 100*idx); } for (int idx = 0; idx < arr->length(); idx++) { a = arr->get(idx); } 1.4.2 Objects ------------- Jakelib2 provides two macros to declare and implement an array class for a given `Object'-derivate: `JAKELIB2_DECLARE_ARRAY(classname)' declares an array class (to be used in header files) and `JAKELIB2_IMPLEMENT_ARRAY(classname)' implements the array class' methods (to be used in `jlc'-files). These array classes provide the same operators and methods as those for primitive data types. By now a 1-dimensional array for `String' objects has been implemented. More classes will follow as needed. 1.5 Run Time Type Identification ================================ All classes derived from `jakelib::lang::Object' have extra type information that allows RTTI (runtime type identification). Each Object provides a `.getClass()' method that returns its Class object. `.instanceOf()' can be used to determine whether an object is derived from a certian class. See API documentation for more details. 1.6 Exceptions ============== In Jakelib all exceptions are created using `new' and thrown as pointers. Example: try { ... throw new FileNotFoundException(); } catch (Exception *ex) { System::out->println(ex); } The super-class for all exceptions should be `jakelib::lang::Throwable'. 2 Compiling and Installing ************************** Jakelib2 runs under GNU/Linux, Solaris, Win32 and probably some other Unix-like systems. Jakelib depends on a couple of external libraries: Hans-J. Boehm's garbage collector is absolutely needed to compile and use jakelib2. Other libraries like pcre (Perl Compatible Regular Expressions) and MySQL's client libs are optional. 2.1 The garbage collector ========================= First thing to do is download version 6.0 of the garbage collector, compile and install it. Hans-J. Boehm's garbage collector can be downloaded directly from his own homepage `http://www.hpl.hp.com/personal/Hans_Boehm/gc' or from `http://www.jakelib.org'. Unpack the zipped tar archive: gunzip -c boehm-gc.tar.gz | tar x Cd into the extracted directory: cd gc6.0 Configure, compile and install: ./configure --enable-threads=pthreads [--prefix=] make make install If you don't supply the `--prefix' option to `./configure', the library files will be copied to `/usr/local/lib'. 2.2 Jakelib2 ============ Now download the latest version of jakelib2 from `http://www.jakelib.org'. Unpack the zipped archive: gunzip -c jakelib2-2.X.XX.tar.gz | tar x Cd into the extracted directory: cd jakelib2-2.X.XX Configure and compile: ./configure [--prefix=] [--with-gc-dir=/lib] make If you don't supply the `--prefix' option to `./configure', the library files will be copied to `/usr/lib' and include files will be copied to `/usr/include'. If you didn't install the garbage collector in the default location you'll need to supply the `--with-gc-dir' option. Just set it to the directory where your `libgc.a' file is located. If compilation succeeded, run make test to see if it works. The test program covers a wide range of operations all across the library. Finally run make install to copy the library and include files to their target locations. 2.3 Additional external libraries ================================= There are extension packages for Jakelib2 that make use of the following libraries: `pcre' Perl Compatible Regular Expressions (`http://www.pcre.org') `mysqlclient' Client libraries for the MySQL data base (`http://www.mysql.org') `GTK2' The Gimp Toolkit: A complete toolkit for GUI programming. Intergration in Jakelib is not yet ready to be used! (`http://www.gtk.org') 3 Using Jakelib2 **************** Jakelib2 is a pure C++ library designed to be statically linked to C++ programs. To use Jakelib2 for your own projects, you need to have several compiler options, include and library paths set. To simplify the process of extending your makefiles accordingly, Jakelib2 provides the `jakelib2-config' script. Just call `jakelib2-config' to see what options and actions are supported. Examples: `jakelib2-config --cppflags' Prints all compiler options including include directories to stdout. The output of such a call of `jakelib2-config' is usually appended to the `CPPFLAGS' variable in Makefiles. `jakelib2-config --libs' Prints a list of all libraries to be linked to the user program. The output of such a call of `jakelib2-config' is usually appended to the `xxx_LDADD' variable in Makefiles. `jakelib2-config --version' Prints the complete version number, like `2.0.0g'. 3.1 Starting a new project using Jakelib2 ========================================= Since Jakelib2 2.0.0j there is a simple but nice script called `jakelib2-skeleton' that creates all files needed to compile and link a program using Jakelib2. Just create a new directory, cd into it and run `jakelib2-skeleton '. If there were no errors you should be able to compile your new project by running `make'. The linked executeable will be called `src/'. Edit the main source file to get a feeling for the whole thing: `src/Main.jlc'. However, notice that `JAKELIB_INIT;' must be called in your program (preferably in the `main()' function) before any other Jakelib2 object is created or method called. `JAKELIB_INIT' is a macro that calls `jakelib::lang::Object::initJakelib2()' which initializes several classes (such as the default character conversion classes or the standard input and output streams). 3.2 Debugging ============= To debug your own programs written for Jakelib2 (or Jakelib itself ;-) ) I recommend using the famous GNU debugger gdb. You should have at least gdb 5.2 since 5.0 (and prior) won't work when using pthreads. There are several GUIs providing an easier access to gdb: `KDbg (1.2.5)' `Data Display Debugger (DDD) 3.3' 4 Extending Jakelib2 ******************** Jakelib uses `autoconf' and `automake' to create Makefiles and control the compilation and linking process. 4.1 Understanding Jakelib ========================= 4.1.1 Directory structure ------------------------- jakelib2/ +-- doc/ | +-- html/ +-- include/ | +-- jakelib2/ | +-- gc/ | +-- gtk/ | +-- io/ | +-- lang/ | +-- lua/ | +-- net/ | +-- servlet/ | | +-- http/ | +-- sql/ | +-- text/ | | +-- enc/ | +-- util/ | +-- regex/ +-- jlpp/ | +-- include/ | +-- lib/ +-- src/ | +-- gtk/ | +-- io/ | +-- lang/ | +-- lua/ | +-- net/ | +-- servlet/ | | +-- http/ | +-- sql/ | +-- test/ | +-- text/ | | +-- enc/ | +-- util/ | +-- regex/ +-- samples/ The `include/jakelib2/' directory contains a subdirectory for each `jakelib::' package. These subdirectories contain the header (`.h') files, one for each class. Each subdirectory should also contain a single header file that simply includes all header files in the subdirectory (example: `include/jakelib2/util/all.h'). The `src/' directory has a subdirectory for every package as well. These subdirectories contain the source files: `.jlc' and `.cpp'. Each class should have its own source file. If there is a `.jlc' file for a certain class, this file will be automatically converted to `.cpp' by the make process. In this case the `.cpp' file should not be modified manually. 4.2 Coding style ================ 4.2.1 Indentation ----------------- Two spaces should be used as the unit of indentation. Avoid using tabs whenever possible. However, tabs must be set exactly every 8 spaces (not 4). If XEmacs is your text editor of choice, you won't have any problems with this guidelines. Opening braces '`{'' should be set on the same code line where their `if', `while', `for' or whatever statement is. Exception: braces after class or method declarations. Closing braces should always be set on their own empty line. Example: void foo(int n) { for (int idx = 0; idx < n; idx++) { if (doSomeThing(idx)) { ... } else { ... } } } 4.2.2 Naming conventions ------------------------ Classnames always start with a capital letter, method and variable names start with a lower case letter. Underline characters (`_') are neither used in class nor in method or variable names. Constant names are upper case and may contain underlines to make them more readable. 4.2.3 Pointer operators ----------------------- The pointer operator `*' should be written next to the variable name rather than the type name: String *str = "aaaa"; rather than String* str = "aaaa"; The reason is that the pointer operator seems to belong to the variable rather than to the type name as the following example illustrates: String* str1, str2; This does not--as one might expect -- declare two pointer variables *STR1 and *STR2 to `String'. It rather declares one pointer *STR1 and one static instance STR2. This is why you should write instead: String *str1, *str2; 4.3 Coding guide lines ====================== This section contains a set of rules that should be followed when developing for Jakelib2. These rules are necessary to achieve a certain level of platform independency. Some of the rules below are taken - or at least inspired by - Mozilla's coding guide lines (`http://www.mozilla.org/hacking/portable-cpp.html'). 1. Do not use C++ templates! 2. Use pointers (`Object* obj') rather than C++ references (`Object& obj'). 3. We have a garbage collector! Methods may return `new' objects without worrying when to `delete' them. See *Note Garbage Collection::. 4. Don't use static initializers. Code like this will definitely cause problems on one compiler or the other: Locale *MyClass::loc = Locale::getDefault(); The problem is that the order in which such static initializers are called on program start-up is highly compiler-dependend. In this case the class `Locale' might not yet be initialized when `MyClass'' initializers are invoked. 5. Every source file must have a unique name 4.4 Writing new classes ======================= To add a new class to Jakelib, you should feel encouraged to follow these steps: 4.4.1 Create a new header file ------------------------------ Create a new header file in the according package subdirectory in `include/jakelib2/': The given file `include/jakelib2/template.h' can serve as a template. The new header file should not contain more `#include' statements than absolutely necessary. I.e., includes are necessary to make the direct super class known. Classes that are just referenced as properties or parameters for methods or constructors can be declared forward with `class ;'. Do not use `using namespace jakelib::...' to save time when typing the class names! This should be done in the source files only. Instead write the fully qualified class names if the desired class comes from a different package, example: `jakelib::lang::String* text'. Example (header file `include/jakelib2/util/SampleClass.h' for class `jakelib::util::SampleClass'): /* * Java-Like C++ Class Library * Copyright (C) 2001 Florian Wolff (florian@donuz.de) * ... */ #ifndef INCLUDE_JAKELIB2_UTIL_SAMPLECLASS_H # define INCLUDE_JAKELIB2_UTIL_SAMPLECLASS_H #include "../lang/Integer.h" namespace jakelib { namespace io { class OutputStream; } namespace util { class Iterator; /** * This class implements a streamable integer. * ... * @class SampleClass * @version $Id: jakelib2.texi,v 1.52 2006-02-18 12:25:28 florian Exp $ * @author Your Name Here (email@foo.bar) */ class SampleClass : public jakelib::lang::Integer { public: SampleClass(jakelib::lang::Integer* anInteger); jakelib::lang::String* toString(); Iterator* iterator(); jakelib::io::OutputStream* getOutputStream(); JAKELIB_DECLARE_CLASS(SampleClass); }; } } #endif Btw, `JAKELIB_DECLARE_CLASS' is a macro that declares a property and a method used for run time type identification purposes. Now you should update the `Makefile.am' file that is located in the same subdirectory: Add the name of your new file to the list of header files (`pkginclude_HEADERS'). 4.4.2 Create the source file ---------------------------- Create a new `.jlc' source file in the according package subdirectory in `src/': The given file `src/template.jlc' can serve as a template. After that update the `Makefile.am' file that is located in the same subdirectory: Add the name of your new file to the `EXTRA_DIST' list and add the name of the according `.cpp' file to `libjake2__a_SOURCES'. 4.4.3 Documenting classes ------------------------- 4.4.4 Write a test program -------------------------- 5 Strings ********* In Jakelib2 all strings should be represented by instances of `jakelib::lang::String' rather than by standard `char*' arrays. An instance of `jakelib::lang::String' holds an immutable unicode character sequence. Every character is represented by one 16-bit wide `jchar' value. Thus, only the first 65535 unicode characters are actually supported. Perhaps Jakelib will learn how to handle 32-bit wide characters in the future. But it appears that you normally don't need any of these strange characters. 5.1 Character Encoding ====================== Whenever strings are created from C-style `char*' arrays, read from streams or written to streams, character encoding is necessary to convert between the internal unicode representation and any other character encoding. `jakelib::io::InputStreamReader' and `jakelib::io::OutputStreamWriter' do these conversions for IO streams. The following character encodings are supported by now: ISO8859-1 (latin-1) ISO8859-2 (latin-2) ISO8859-3 (latin-3) ISO8859-4 (latin-4) ISO8859-5 (Cyrillic) ISO8859-6 (Arabic) ISO8859-7 (Greek) ISO8859-8 (Hebrew) ISO8859-9 (latin-5) ISO8859-10 (latin-6) ISO8859-11 (Thai) ISO8859-13 (latin-7) ISO8859-14 (latin-8) ISO8859-15 (latin-9) UTF-8 (Unicode) ASCII (7-bit ASCII) CP1252 (Windows) CP437 (Windows, US) CP850 (Windows, latin1) The actual work of encoding is done by two groups of classes: `jakelib::text::enc::ByteToChar' convert byte sequences to unicode characters (input) and `jakelib::text::enc::CharToByte' convert unicode characters to bytes (output). 5.2 Jakelib Preprocessor ======================== Jakelib2 has its own C++ preprocessor (`jlpp'). jlpp helps the programmer as it allows writing more Java-like code. For now this means that string handling is very much simplified. jlpp creates `cpp' files from `jlc' files. So, if you look at Jakelib's sources, don't look at the `cpp' files. Instead look at the `jlc' files wherever exsisting. Without the preprocessor one would have to write something like this: System::out->println(String("Just a lousy test: ").plus((jlong) 12345)); In Java the same line of code would look like this: System.out.println("Just a lousy test: " + 12345); The disadvantage of the upper C++ version without jlpp is not just that it looks quite ugly: For every invocation of this `println' method, a new instance of the (constant) string `"Just a lousy test: "' is created. This would not only cost memory but also some time because some kind of character encoding needs to be done when creating strings from C-style character arrays. To avoid this, jlpp replaces string literals by constant static instances of `jakelib::lang::String'. This way every constant string will be created only once. jlpp also offers the new `..' operator which is a substitution for Java's string concatenation operator `+'. Example: System::out->println(`"Just a lousy test: "` .. (jlong) 12345); By default jlpp replaces only string literals that are enclosed in back ticks ``' _and_ double quotes `"'. This is to stay downwards compatible. Otherwise it would not be possible to call other library functions that take `char*' as arguments. In source files that do not contain any function calls to non-jakelib functions taking `char*' as arguments, the `javasyntax' pragma can be used: #pragma javasyntax System::out->println("Just a lousy test: " .. (jlong) 12345); From the line of code downwards where the `javasyntax' pragma is given, jlpp will replace string literals that are enclosed in back ticks or double quotes. The `cppsyntax' pragma returns to the default mode. #pragma javasyntax System::out->println("Just a lousy test: " .. (jlong) 12345); #pragma cppsyntax printf("Returning to normal c++ syntax"); For every string literal jlpp encounters, a static `jchar' array called `chars_jakelib2_str_'n is inserted at the beginning of the `cpp' file. This array contains the unicode characters of the string. The string object itself will be created on-demand when it is actually used for the first time. The string objects are stored in an array called `jakelib2_strings[]'. Note: In multi-threaded applications it is not guaranteed that every string object will be created only once. That is, the on-demand creation of these strings is not synchronized! 6 Multi Threading ***************** 6.1 Synchronization =================== In Java any object derived from `Object' can be used as a monitor. In Jakelib only classes implementing the `jakelib::lang::Synchronizeable' interface can be used as a monitor. This is simply to save system resources. By now only Java's `synchronized' keyword is implemented, `wait()' and `notufy()' are yet to be implemented. class Sync : public Object, public Synchronizeable { public: Sync() {}; void Sync::foo() { ... { JAKELIB_SYNCHRONIZED(this) // We are inside the synchronized block :-) } // End of synchronized block. ... } }; Internally the `JAKELIB_SYNCHRONIZED' macro instantiates a `Sentry' object on the stack. A `Sentry' locks a mutex in its constructor and unlocks it in its destructor which is called when the `Sentry' object runs out of scope. 7 License ********* GNU Lesser General Public License Version 2.1, February 1999 Jakelib2 is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1, or any later version. This software is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this package; see the file `COPYING'. If not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. Copyright (C) 2000 - 2003 Florian Wolff Verbatim copying and distribution of this entire document is permitted in any medium, provided this notice is preserved.  Tag Table: Node: Top259 Node: Java vs. C++409 Node: Garbage Collection549  End Tag Table