JCA 2.1.2
JCA
- EPICS Home Page
- Channel Access(3.14)
JCA2.1.2
- Download
- Installation
- API documentation
- Tutorial
Tutorial

 

 

1) A word on the JCALibrary class.


The JCALibrary class is the entry point for all JCA enabled application.
There is only one instance available within a JVM (Java Virtual Machine) which can be accessed with the static method getInstance().

The two main purposes of the JCALibrary is to provide a centralized configuration tool for other JCA objects and to act as a Context factory.

The JCALibrary as a configuration tool.

The JCALibrary holds a set of read-only Properties. These Properties are loaded at initialization time from different sources.

  • Sitewide properties: <jre.home>/lib/JCALibrary.properties
  • User's properties: <user.home>/.JCALibrary/JCALibrary.properties
  • Command line properties: specified on the command line with the -D switch.

The properties specified on the command line take precedence over the user's properties which take precedence over the sitewide properties.

What these properties represent and are going to be used for really depends on the Objetcs that need them.

Some core JCA objects, like JNI_THREAD_SAFE and JNI_SINGLE_THREADED contexts, use them to get their default configuration, ie default communication ports, default thread priorities, etc...

 

The JCALibrary as a Context factory

The JCA package has been design in such a way that the role of each JCA component has been dissociated from the real implementation. This design allows the JCA to evolve without breaking it's contract with the applications using it.
The JCALibrary offers two methods to create Contexts with very few knowledge of the specific underlying implementation.

  • createContext(String fqn):
    This method take a String representing the fully qualified name of the Context class to instantiate. The class should provide a public no argument constructor. This is up to the class implementation to configure itself with sensible default values.

  • createContext(Configuration conf):
    This method take a Configuration object to create and configure the context. The fully qualified class name must be specified as an attribute called "class". The Context instance will be created using its default no arguments constructor and the complete Confiuration object will be passed to the Context if it implements the Configurable interface.

 

2) A word on JNI_THREAD_SAFE and JNI_SINGLE_THREADED contexts


The core JCA package comes with two different Context's implementations.

  • JNI_THREAD_SAFE Context:
    This type of context is usefull if you don't want to worry (too much) about thread safety in your application. However you should be aware that this feature comes with a price in term of complexity. The internal implementation of this type of Context is indeed quite complex and might affect the overall performance of your application.

  • JNI_SINGLE_THREADED Context:
    This type of Context uses a quite simple implementation but doesn't offer any thread safety. Thread safety should be taking care of by the user's application. This allow a complete control over the final complexity of the application.

 

The following table shows the parameters that can be configured for these two type of contexts.

parameter
range
Default
Description
preemptive_callback
true/false
true
Define whether the context should use independant threads to send request callback notifications (events).
If set to no, your application should periodically call pendEvent to process pending events.
addr_list
string
empty string
A space-separated list of broadcast address for process variable name resolution. Each address must be of the form: ip.number:port or host.name:port
auto_addr_list
true/false
true
Define whether or not the network interfaces should be discovered at runtime.
connection_timeout
>0.1
30.0
If the context doesn't see a beacon from a server that it is connected to for connection_timeout seconds then a state-of-health message is sent to the server over TCP/IP. If this state-of-health message isn't promptly replied to then the context will assume that the server is no longer present on the network and disconnect.
beacon_period
>0.1
15.0
Period in second between two beacon signals
repeater_port
>5000
5065
Port number for the repeater to listen to
server_port
>5000
5064
Port number for the server to listen to
max_array_bytes
>=16384
16384
Length in bytes of the maximum array size that may pass through Channel Access
event_dispatcher
string
gov.aps.jca.event.DirectEventDispatcher
The fully qualified class name of the event dispatcher used to dispatch callback event. This class must have a default constructor with no arguments. Check the documentation of the event dispatcher to see how to configure it.
priority 0<P<11
5
Integer value representing the internal thread priority. Only relevant for JNI_THREAD_SAFE Contexts


Example of XML Configuration file:

Specifying parameters as attributes.

<Context
  class="gov.aps.jca.jni.ThreadSafeContext"
  preemptive_callback="true"
  addr_list="my.ca.server:port"
  auto_addr_list="true"
  connection_timeout="30.0"
  beacon_period="15.0"
  repeater_port="5065"
  server_port="5064"
  max_array_bytes="16384"
  priotiry="5"/>

Specifying parameters as nested elements.

<context class="gov.aps.jca.jni.SingleThreadedContext">
  <preemptive_callback>true             </preemptive_callback>
  <addr_list>          my.ca.server:port</addr_list>
  <auto_addr_list>     false            </auto_addr_list>
  <connection_timeout> 15.0             </connection_timeout>
  <beacon_period>      30.0             </beacon_period>
  <repeater_port>      5065             </repeater_port>
  <server_port>        5064             </server_port>
  <max_array_bytes>    16384            </max_array_bytes>
  <event_dispatcher 
    class="gov.aps.jca.event.QueuedEventDispatcher"/>
</context>
            

If you do not specify all parameters in the Configuration, default values will be retreived from the JCALibrary Properties if they have been defined.
To define JCALibrary properties for the parameters, just prepend the FQN name of the Context class for which you want to define a default value.

Example:

# define the default value of auto_addr_list for JNI_THREAD_SAFE contexts.
gov.aps.jca.jni.ThreadSafeContext.auto_addr_list=true   

# define the default value of server_port for JNI_SINGLE_THREADED contexts
gov.aps.jca.jni.SingleThreadedContext.server_port=8888

# define the default value of preemptive_callback for both JNI_SINGLE_THREADED and JNI_THREAD_SAFE contexts
gov.aps.jca.jni.JNIContext.preemptive_callback=true
            

 

Important: There are two special properties that should be defined for the JNI_XXXX Contexts to work correctly. These properties are platform dependent and are needed to load shared Channel Access libraries and executable.

gov.aps.jca.jni.epics.<your arch>.library.path= the/path/to/the/epics/shared/libraries
gov.aps.jca.jni.epics.<your arch>.caRepeater.path= the/path/to/the/caRepeater/executable

where <your arch> is the epics architecture type of your system, ie win32-x86, linux-x86, solaris-sparc, etc...
              

 

 

3) A real life example


In the following chapters, we will go trough all the necessary steps to setup JCA for a particular user, named toto.
The examples will be given for the windows and linux operating systems.

 

4) Defining JCALibrary Properties for your system



Create or edit the following file: <jre.home>/lib/JCALibrary.properties where <jre.home> is the path to your java runtime environment.

Example:
windows: c:\j2sdk1.4.2\jre\lib\JCALibrary.properties
linux: /usr/java/jre/lib/JCALibrary.properties

In this file we are going to define sitewide properties for different JCA components.
Add or modify the following lines

# define the location of the epics shared libraries and caRepeater executable
gov.aps.jca.jni.epics.win32-x86.library.path= c:/epics/baseR3.14.4/bin/win32-x86
gov.aps.jca.jni.epics.win32-x86.caRepeater.path= c:/epics/baseR3.14.4/bin/win32-x86

gov.aps.jca.jni.epics.linux-x86.library.path= /usr/share/epics/baseR3.14.4/lib/linux-x86
gov.aps.jca.jni.epics.linux-x86.caRepeater.path= /usr/share/epics/baseR3.14.4/bin/linux-x86

# define default values for both JNI_THREAD_SAFE and JNI_SINGLE_THREADED contexts.
gov.aps.jca.jni.JNIContext.preemptive_callback= true
gov.aps.jca.jni.JNIContext.addr_list=
gov.aps.jca.jni.JNIContext.auto_addr_list= true
gov.aps.jca.jni.JNIContext.connection_timeout= 30.0
gov.aps.jca.jni.JNIContext.beacon_period= 15.0
gov.aps.jca.jni.JNIContext.repeater_port= 5065
gov.aps.jca.jni.JNIContext.server_port= 5064
gov.aps.jca.jni.JNIContext.max_array_bytes= 16384

# define default values only for JNI_SINGLE_THREADED context
gov.aps.jca.jni.SingleThreadedContext.event_dispatcher= gov.aps.jca.event.DirectEventDispatcher

# define default values only for JNI_THREAD_SAFE context
gov.aps.jca.jni.ThreadSafeContext.event_dispatcher= gov.aps.jca.event.QueuedEventDispatcher
gov.aps.jca.jni.ThreadSafeContext.priority= 5

# define default values for QueuedEventDispatcher components
gov.aps.jca.event.QueuedEventDispatcher= 5

 

5) Defining JCALibrary Properties for a particular user


Create or edit the following file: <user.home>/.JCALibrary/JCALibrary.properties where <user.home> is the home directory of the user.

Example:
windows: c:\Documents and Settings\toto\.JCALibrary\JCALibrary.properties
linux: /home/toto/.JCALibrary/JCALibrary.properties

In this file we can override default values to match the specific need of our user toto.
Add or modify the following lines:

# Overwrite the default addr_list to point to a specific ca server
gov.aps.jca.jni.JNIContext.addr_list= toto.uses.this.ca.server
			  
# overwrite the default auto_addr_list so that network interfaces will not be automatically added to the addr_list.
gov.aps.jca.jni.JNIContext.auto_addr_list= false
			  
# toto is going to use very large array, so we want to increase the maximum array size.
gov.aps.jca.jni.JNIContext.max_array_size= 32768
			  

 

6) A first program


Now that all the configuration has been done, lets write our first program.
This program will take a PV name as an argument, connect to the PV and display basic information.

// File: example1.java
 
public class example1 {
  public static void main(String[] args) {
    if(args.length!=1) {
      System.out.println("usage: java example1 <pvname>");
      return;
    }
 
    try {
      // Get the JCALibrary instance.
      JCALibrary jca= JCALibrary.getInstance();
      
      // Create a single threaded context with default configuration values.
      Context ctxt= jca.createContext(JCALibrary.JNI_SINGLE_THREADED);
      
      // Display basic information about the context.
      ctxt.printInfo();
      
      // Create the Channel to connect to the PV.
      Channel ch= ctxt.createChannel(args[0]);


      // send the request and wait 5.0 seconds for the channel to connect to the PV.
      ctxt.pendIO(5.0);
 
      // If we're here, then everything went fine.
      // Display basic information about the channel.
      ch.printInfo();

 
      // Disconnect the channel.
      ch.destroy();
 
      // Destroy the context.
      ctxt.destroy();


    } catch(Exception ex) {
      System.err.println(ex);
    }
  }
}
            

Now, our user toto starts the program with the following command line: java example1 test:my_pv

The program creates a context with the default parameters defined in the JCALibrary configuration files.
The context will thus only look for the PV in the toto.uses.this.ca.server:5064
If it is present on the server and that the connection is established within 5.0 seconds, then the program will display information about the channel.
If it is not present on the server or the connection was not established within 5.0 seconds, a TimeoutException is thrown and the program exits.

 

7) Overriding default Context parameters


In the next example, we'll learn how to specify context parameters at runtime.
To do so, will need to create a Configuration object.


// File: example2.java
 
public class example2 {
  public static void main(String[] args) {
    if(args.length!=2) {
      System.out.println("usage: java example2 server pvname");
      return;
    }
    try {
      // Get the JCALibrary instance.
      JCALibrary jca= JCALibrary.getInstance();


      // Create the Configuration object for our context.

      DefaultConfiguration conf= new DefaultConfiguration("myContext");


      // Define the context class.
      conf.addAttribute("class", JCALibrary.JNI_SINGLE_THREADED);

 
      // Define the addr_list
      conf.addAttribute("addr_list", args[0]);
 
      // Now, we'll create a context with this configuration.
      Context ctxt= jca.createContext(conf);


      // Do whatever you want with this context.
      ...

      
    } catch( Exception ex) {
      System.err.println(ex);
    }
  }
}