Check here first when problems occur using JamaicaVM and its tools.
Q: I am using Eclipse to develop my Java applications. Is there a plug-in available which will help me to use JamaicaVM and the Builder from within Eclipse?
A: Yes. There is a plugin available that will help you to configure the Builder download and execute your application on your target. For more information, see http://www.aicas.com/eclipse.html. For a quick start, you can use the Eclipse Update Site Manager with the following Update Site URL: http://www.aicas.com/download/eclipse. This conveniently downloads and installs the plugin.
A: Yes. The RTSJ V1.0.2 is supported by JamaicaVM 3.2. The API documentation of the implementation can be found at http://www.aicas.com/jamaica/doc/rtsj_api/index.html.
Q: When I use javac from JDK 1.4 or JDK 5, I get error messages such as javac: Class <myclass> should be declared abstract or jamaica/jamaicavm: Link failed / method not found. What am I doing wrong?
A: There are incompatibilities between different versions of the Java standard classes. Interfaces have been extended, making it impossible to compile old code that does not implement the complete new interface, and new overloaded methods have been added causing linkage problems when compiling a class against newer classes and then executing it in an environment like JamaicaVM that implements classes according to the 1.3 specification. Unfortunately, these problems can also occur in code that does not use any of the new features. To avoid these difficulties, always use jamaicac to compile classes. It uses the system classes of the Jamaica distribution for its bootclasspath, i.e., it compiles against the classes library that will be used by JamaicaVM. If javac is used, always provide the Jamaica classes in the bootclasspath argument of javac, i.e., on a linux host use javac -bootclasspath /usr/local/jamaica/classes <MyClass.java>
Q: When I try to execute an application with the JamaicaVM I get the error message OUT OF MEMORY. What can I do?
A: The JamaicaVM has a predefined setting for the internal heap size. If
it is exhausted the error message OUT OF MEMORY
is printed and JamaicaVM exits with an error code. The predefined
heap size of 256MB is usually large enough, but for some
applications it may not be sufficient. You can set the heap size
via the jamaicavm options
Xmx<size>, via the environment variable
JAMAICAVM_MAXHEAPSIZE (e.g., under bash
with JAMAICAVM_MAXHEAPSIZE=268435456; export
JAMAICAVM_MAXHEAPSIZE;),
or, when using the builder, via the builder option maxHeapSize.
Q: When the built application terminates I see some output like WARNING: termination of thread 7 failed. What is going wrong?
A: At termination of the application the JamaicaVM tries to shutdown all running threads by sending some signal. If a thread is stuck in a native function, e.g., waiting in some OS kernel call, the signal is not received by the thread and there is no response. In that case the JamaicaVM does a hard-kill of the thread and outputs the warning. Generally, the warning can simply be ignored, but be aware that a hard-kill may leave the OS in an unstable state, or that some resources (e.g., memory allocated in a native function) can be lost. Such hard-kills can be avoided by making sure no thread gets stuck in a native-function call for a long time (e.g., more than 100ms).
A: The rmiregistry tool are included in JamaicaVM and can be executed like this:
jamaicavm gnu.java.rmi.registry.RegistryImpl
JamaicaVM 3.0 added support for the dynamic generation of stub classes at runtime, obviating the need to use the Java Remote Method Invocation (Java RMI) stub compiler, rmic, to pregenerate stub classes for remote objects.
When building a standalone application of your RMI server or client, the RMI service implementation and classes from the package gnu.java.rmi must be included in the binary. For example, the Builder arguments can look like this:
jamaica -includeClasses=MyServiceImpl:gnu.java.rmi... MyRMIServer
A: RMI applications often comprise two separate programs, a server and a client. A typical server program creates some remote objects, makes references to these objects accessible, and waits for clients to invoke methods on these objects. A typical client program obtains a remote reference to one or more remote objects on a server and then invokes methods on them. RMI provides the mechanism by which the server and the client communicate and pass information back and forth.
Like any other Jamaica application, a distributed application built by using Jamaica RMI is made up of interfaces and classes. The interfaces declare methods. The classes implement the methods declared in the interfaces and, perhaps, declare additional methods as well. In a distributed application, some implementations might reside in some Jamaica virtual machines but not others. Objects with methods that can be invoked across Jamaica virtual machines are called remote objects.
An object becomes remote by implementing a remote interface, which has the following characteristics:
A remote interface extends the interface java.rmi.Remote.
Each method of the interface declares java.rmi.RemoteException in its throws clause, in addition to any application-specific exceptions.
Using RMI to develop a distributed application involves these general steps:
Designing and implementing the components of your distributed application.
Compiling sources.
Making classes network accessible.
Starting the application.
First, determine your application architecture, including which components are local objects and which components are remotely accessible. This step includes:
Defining the remote interfaces. A remote interface specifies the methods that can be invoked remotely by a client. Clients program to remote interfaces, not to the implementation classes of those interfaces. The design of such interfaces includes the determination of the types of objects that will be used as the parameters and return values for these methods. If any of these interfaces or classes do not yet exist, you need to define them as well.
Implementing the remote objects. Remote objects must implement one or more remote interfaces. The remote object class may include implementations of other interfaces and methods that are available only locally. If any local classes are to be used for parameters or return values of any of these methods, they must be implemented as well.
mplementing the clients. Clients that use remote objects can be implemented at any time after the remote interfaces are defined, including after the remote objects have been deployed.
Here are the example source codes:
The remote interface IHello.java:
package example.hello;
import java.rmi.Remote;
import java.rmi.RemoteException;
public interface IHello extends Remote {
String sayHello() throws RemoteException;
}
|
The implementation of IHello interface Server.java:
package example.hello;
import java.rmi.registry.Registry;
import java.rmi.registry.LocateRegistry;
import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;
public class Server implements IHello {
public Server() {}
public String sayHello() {
return "Hello, world!";
}
public static void main(String args[]) {
try {
Server obj = new Server();
Hello stub =
(IHello) UnicastRemoteObject.exportObject(obj, 0);
// Bind the remote object's stub in the registry
Registry registry = LocateRegistry.getRegistry();
registry.bind("Hello", stub);
System.err.println("Server ready");
} catch (Exception e) {
System.err.println("Server exception: " + e.toString());
e.printStackTrace();
}
}
}
|
The Client-Program Client.java:
package example.hello;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
public class Client {
private Client() {}
public static void main(String[] args) {
String host = (args.length < 1) ? null : args[0];
try {
Registry registry = LocateRegistry.getRegistry(host);
IHello stub = (IHello) registry.lookup("Hello");
String response = stub.sayHello();
System.out.println("response: " + response);
} catch (Exception e) {
System.err.println("Client exception: " + e.toString());
e.printStackTrace();
}
}
}
|
You use the jamaicac compiler to compile the source files: jamaicac example/hello/*.java
When building a standalone application of your RMI server or client, the RMI service implementation and classes from the package gnu.java.rmi must be included in the binary. For example, the Builder arguments can look like this:
jamaica -includeClasses="gnu.java.rmi...:example.hello.Server" example.hello.Server
and
jamaica -includeClasses="gnu.java.rmi...:example.hello.Server" example.hello.Client
Starting the application includes running the RMI remote object registry, the server, and the client:
Starting the registry: jamaicavm gnu.java.rmi.registry.RegistryImpl
startin the server with: ./Server
and starting the client with: ./Client
Q: When I try to start a Jamaica compiled executable in a Linux 2.4.x environment, I get an error message like "__alloc_pages: 0-order allocation failed (gfp=0x1d0/0) from c0123886".
A: This is a bug in the Linux 2.4.10 kernel. Please use a newer kernel version. The problem seems to occur if the amount of allocated memory is close to the amount of available memory, which is usually no problem if you use Jamaica on a desktop PC, but occurs quite often on embedded systems running Linux 2.4.10 and Jamaica (e.g., the DILNet/PC).
Q: When I try to compile an application with the Builder I get the error message OUT OF MEMORY. What can I do?
A: The Builder has a predefined setting for the internal heap size. If
the memory space is exhausted, the error message OUT OF MEMORY
is printed and Builder exits with an error code. The predefined heap size (96MB)
is usually large enough, but for some applications it may not be
sufficient. You can set the heap size via the environment variable
JAMAICA_BUILDER_HEAPSIZE, e.g., under bash
with JAMAICA_BUILDER_HEAPSIZE=268435456; export JAMAICA_BUILDER_HEAPSIZE;.
Q: When I build an application which contains native code it seems that some fields of the class files can be accessed with the function GetFieldID() from the native code, but some others not. What happened to those fields?
A: If an application is built, the Builder removes from classes all unreferenced methods and fields. If a field in a class is only referenced from native code the Builder can not detect this reference and protect the field from the smart-linking-process. To avoid this use the includeClasses option with the class containing the field. This will instruct the Builder to fully include the specified class(es).
Q: When I build an application with the Builder I get some warning like WARNING: Unknown native interface type of class '...' (....h) - assume JNI calling convention. Is there something wrong?
A: In general, this is not an error. The Builder outputs this warning when it is not able to detect whether a native function is implemented using JNI (the standard Java native interface; see chapter Chapter 9) or JBI (a Jamaica specific, more efficient native interface used by the $Jamaica; boot classes). Usually this means the appropriate header file generated with some prototype tool like Jamaicah is not found or not in the proper format. To avoid this warning, recreate the header file with Jamaicah and place it into a directory that is passed via the builder argument Xinclude.
Q: How can I set properties (using -D<name>=<value>) for an application that was built using the builder?
A: For commands like jamaicavm, parsing of VM arguments such as -D<name>=<value> stops at the name of the main class of the application. After the application has been built, the main class is an implicit argument, so there is no direct way to provide additional options to the VM.
However, there is a way out of this problem: the Builder option -XnoMain removes the implicit argument for the main class, so jamaicavm's normal argument parsing is used to find the main class. When launching this application, the name of the main class must then be specified as an argument, so it is possible to add additional VM options such as -D<name>=<value> before this argument.
Q: When I run the Builder an error "exec fail" is reported when the intermediate C code should be compiled. The exit code is 69. What happened?
A: An external C compiler is called to compile the intermediate C code. The compiler command and arguments are defined in etc/jamaica.conf. If the compiler command can not be executed the Builder terminates with an error message and the exitcode 69 (see list of exit codes in the appendix). Try to use the verbose output with the option -verbose and check if the printed compiler command call can be executed in your command shell. If not check the parameters for the compiler in etc/jamaica.conf and the PATH environment variable.
Q: Can I build my own VM as an application which expects the name of the main class on the command line like JamaicaVM does?
A: With the Builder a standalone VM can be built with the option -XnoMain. If this option is specified, the Builder does not expect a main class while compiling. Instead, the build application expects the main class later after startup on the command line. Some classes or resources can be included in the created VM, e.g., a VM can be built including all classes of the selected API except the main program with main class.
A: The mapping between Java font names and native fonts is defined in the font.properties file. Each target system provides this file with useful default values. An application developer can provide a specialized version for this file. To do this the new mapping file must exist in the classpath at build time. The file must be added as a resource to the final application by adding -resource+=<path> where <path> is a path relative to a classpath root. Setting the system property 'jamaica.fontproperties' with the option -XdefineProperty=jamaica.fontproperties=<path> will provide the graphics environment with the location of the mapping file.
A: This linker error occurs when the VxWorks system is configured without one or more of the following function sets listed in "Configuration of VxWorks". Please check your vxWorks configuration (INCLUDE_* statements) in target/config/all/configAll.h in your VxWorks installation directory. Probably you have to recompile a new vxWorks kernel image.
A: Because of the C-like syntax of the VxWorks command shell, parameters to an application have to be passed as a string. An application can simply be started by jvm "..." (or <classname> "..." where <classname> is the value specified via the -destination option of the Jamaica Builder). "..." is a space separated list of arguments which should be passed to the application (just like a command line).