Java and JCA
Kenneth Evans, Jr.
October 12, 2004
Part of the EPICS “Getting Started” Lecture Series
Argonne National Laboratory
A U.S. Department of Energy
Office of Science Laboratory
Office of Science
U.S. Department of Energy Operated by The University of Chicago
Outline
• Java
• Java and EPICS
• Overview of JCA
• Examples
- SimpleJCAGet
- SimpleJCAMonitor
- JProbe
2
Pioneering Office of Science
Science and U.S. Department
Technology of Energy
Java
• Java is designed to be platform independent
- Write once, run everywhere
• Java programs are interpreted by another program, possibly
on another machine
- The Java Virtual Machine (Java VM)
• Java technology includes
- J2SE Standard Edition
- J2EE Enterprise Edition (Multi-tier business apps)
- J2ME Micro Edition (Phones, PDAs, etc.)
• Java is advertised to be all of these
Simple Architecture neutral Object oriented
Portable Distributed High performance
Interpreted Multithreaded Robust
Dynamic Secure 3
Pioneering Office of Science
Science and U.S. Department
Technology of Energy
Java and EPICS
• EPICS Channel Access is native code
- Not platform independent
- Build cycle is edit – compile [to machine code] - link - run
• Pure Java
- Build cycle is edit – compile [to byte code] – run [anywhere]
• Java Native Interface [JNI] is used to access native code
- Not “Pure Java”
- No longer platform independent
- You generate shared object or DLL libraries that must be used
with the Java program
• You can write your own JNI
- Not that hard if you know Channel Access
• The EPICS build system handles Java projects and JNI
• Ant is an alternative 4
Pioneering Office of Science
Science and U.S. Department
Technology of Energy
JCA
• Stands for Java Channel Access
• JCA is a JNI implementation of an EPICS Channel Access client
library for Java
- Provides equivalents to most of the Channel Access API
- Developed by Eric Boucher while at the APS
- Currently taken over by Cosylab
• Available for download at
- [Link]
• Latest version is 2.1.3 at Cosylab
• JCA Version 1 uses EPICS Base 3.13
• JCA Version 2 uses EPICS Base 3.14
- Channel Access is threaded
- Allows for preemptive callbacks
- Works better with Java, which is inherently threaded 5
Pioneering Office of Science
Science and U.S. Department
Technology of Energy
CAJ
• CAJ is a Java replacement for Channel Access
• Under development at Cosylab (Control Systems Laboratory)
- [Link]
- Located in Ljubljana in Slovenia
- Situated between Austria (North), Italy (West), Hungary (East)
and Croatia (South)
- Cosylab also develops VDCT
• Will allow your programs to be “Pure Java”
• Can be used with JCA
- Replaces JNI implementation
- Requires replacing only one line of code
- [Link](JCALibrary.JNI_THREAD_SAFE);
- [Link](“[Link]”);
6
Pioneering Office of Science
Science and U.S. Department
Technology of Energy
Requirements
• Java J2SE installed (Current [suggested] version is 1.4.2)
• JCA
- Java libraries
- Download source and/or JAR files from the web
- Native JNI libraries
- Download from the web or build them
- Currently found with the 2.1.2 distribution only
- [Link] Windows
- [Link] Unix (Currently only Linux)
• Your project
- JCA files need to be in your CLASSPATH
- UNIX: Shared object library needs to be in your
LD_LIBRARY_PATH
- Windows: DLL needs to be in your PATH 7
Pioneering Office of Science
Science and U.S. Department
Technology of Energy
Resources
• EPICS web pages
- [Link]
- Look under Extensions, then JCA
• JCA 2.1.2 API
- [Link]
html
• JCA 2.1.3 API
- [Link]
• Java Tutorial
- [Link]
• J2SE Documentation
- [Link]
• J2SE 1.4.2 API (Javadoc)
- [Link] 8
Pioneering Office of Science
Science and U.S. Department
Technology of Energy
JCA Packages
• Five Packages
- [Link] Channel-Access-like routines
- [Link] Configuration
- [Link] DBR types
- [Link] Event handling
- [Link] Native interface functions
9
Pioneering Office of Science
Science and U.S. Department
Technology of Energy
[Link]
• This is the package you will use most directly
• Classes
- CASeverity Enum
- CAStatus JCALibrary
- Channel Monitor
- [Link] ValuedEnum
- Context
• Exceptions
- CAException TimeoutException
10
Pioneering Office of Science
Science and U.S. Department
Technology of Energy
JCALibrary
• Initializes JCA
JCALibrary jca=[Link]();
• There is only one instance
• Used to create contexts and manage JCA configuration info
• Properties
- JNI_THREAD_SAFE preemptive
- Suggested for Java, which is inherently threaded
- JNI_SINGLE_THREADED non-preemptive
• Methods
- createContext
- getProperty
- listProperties
- getVersion, getRevision, getModification
11
Pioneering Office of Science
Science and U.S. Department
Technology of Energy
Context
• Corresponds to a Channel Access context
• Created by [Link]
createContext(JCALibrary.JNI_SINGLE_THREADED)
createContext(JCALibrary.JNI_THREAD_SAFE)
• Controls all IO
• You can have more than one context
• Methods
- createChannel
- flushIO, pendIO, pendEvent, poll
- attachCurrentThread
- addContextExceptionListener, removeContextExceptionListener
- addContextMessageListener, removeContextMessageListener
- destroy
12
Pioneering Office of Science
Science and U.S. Department
Technology of Energy
Channel
• Represents a Channel Access channel
• Created by [Link]
createChannel(String name, connectionListener l)
• Properties
- CLOSED CONNECTED
- DISCONNECTED NEVER_CONNECTED
• Methods
- get, many overloads
- put, many overloads
- getName, getConnectionState, getElementCount, etc.
- addMonitor
- addConnectionListener, removeConnectionListener
- addAccessRightsListener, removeAccessRightsListener
- destroy 13
Pioneering Office of Science
Science and U.S. Department
Technology of Energy
Monitor
• Represents a Channel Access monitor
• Created by [Link]
addMonitor(DBRType type, int count, int mask,
MonitorListener l)
• Properties
- ALARM LOG VALUE
• Methods
- addMonitorListener, removeMonitorListener
- getMonitorListener, getMonitorListeners
- clear
- getChannel, getContext
- getCount, getMask, getType
- isMonitoringAlarm, isMonitoringLog, isMonitoringValue
14
Pioneering Office of Science
Science and U.S. Department
Technology of Energy
MonitorListener
• Part of [Link]
• One method
- monitorChanged
• Example
private class MyMonitorListener implements
MonitorListener
{
public void monitorChanged(MonitorEvent ev) {
// Call my handler
onValueChanged(ev);
}
};
• The value and status comes with the MonitorEvent
15
Pioneering Office of Science
Science and U.S. Department
Technology of Energy
MonitorEvent
• Part of [Link]
• Methods
- getDBR How you get the value
- getStatus How you determine the status
• Example
if([Link]() == [Link]) {
DBR dbr=[Link]();
double [] value=((DOUBLE)dbr).getDoubleValue();
}
16
Pioneering Office of Science
Science and U.S. Department
Technology of Energy
Event Types
• MonitorListener MonitorEvent
• GetListener GetEvent
• PutListener PutEvent
• AccessRightsListener AccessRightsEvent
• ConnectionListener Connection Event
• ContextExceptionListener ContextExceptionEvent
• ContextMessageListener ContextMessageEvent
• Events all inherit from CAEvent
• They all work similarly to Monitor
- Call the routine that fires the event when it occurs
- Add a listener with the appropriate handler
- Get the data from the event that is passed to your handler
17
Pioneering Office of Science
Science and U.S. Department
Technology of Energy
[Link]
• Implements the EPICS DBR_xxx types
• Interfaces
- DOUBLE, FLOAT, INT, STRING, TIME, CTRL, etc.
• Primary Class
- DBR
• Subclasses of DBR
- DBR_Double, DBR_Float, DBR_Int, DBR_STS_Double, etc.
• Example: DBR_STS_Double
- Interfaces
- STS, DOUBLE
- Extends
- DBR_Double
- Subclasses
- DBR_GR_Double, DBR_Time_Double 18
Pioneering Office of Science
Science and U.S. Department
Technology of Energy
SimpleJCAGet
package simplejca;
import [Link].*;
import [Link].*;
19
Pioneering Office of Science
Science and U.S. Department
Technology of Energy
SimpleJCAGet
public class SimpleJCAGet
{
public static void main(String[] args)
{
SimpleJCAGet simpleJCAGet = new SimpleJCAGet();
JCALibrary jca=null;
Context ctxt=null;
Channel chan=null;
// Parse the command line
if() [Link](1);
if(![Link]) {
[Link]("No PV specified\n");
[Link](1);
}
20
Pioneering Office of Science
Science and U.S. Department
Technology of Energy
SimpleJCAGet
// Initialize and search
try {
// Get the JCALibrary instance
jca=[Link]();
// Create a non-preemptive context
context=[Link](
JCALibrary.JNI_SINGLE_THREADED);
// Search
chan=[Link]([Link]);
// Wait for search
[Link]([Link]);
} catch(Exception ex) {
[Link]("Search failed for " +
[Link] + ":\n" + ex);
[Link](1);
} 21
Pioneering Office of Science
Science and U.S. Department
Technology of Energy
SimpleJCAGet
// Get the first value as a String
try {
// Get the value
String [] value;
value=((STRING)[Link]([Link],1)).
getStringValue();
// Wait for the get
[Link]([Link]);
// Print the value
[Link]("The value of " + [Link]
+ " is " + value[0]);
} catch(Exception ex) {
[Link]("Get failed for " +
[Link] + ":\n" + ex);
[Link](1);
}
22
Pioneering Office of Science
Science and U.S. Department
Technology of Energy
SimpleJCAGet
// Clean up
try {
// Clear the channel
[Link]();
// Destroy the context
[Link]();
} catch(Exception ex) {
[Link]("Clean up failed for " +
[Link] + ":\n" + ex);
[Link](1);
}
// Successful exit
[Link](0);
}
23
Pioneering Office of Science
Science and U.S. Department
Technology of Energy
SimpleJCAGet output
[Link] -classpath
<simplejca-path>\[Link];
<jca-path>\[Link]
[Link] evans:calc
The value of evans:calc is 3
24
Pioneering Office of Science
Science and U.S. Department
Technology of Energy
SimpleJCAMonitor
• Similar to SimpleJCAGet
- Imports, parsing the command line, etc. are the same
• We will have listeners
• We will use JNI_THREAD_SAFE (preemptive)
• We will use flushIO and not pendIO, etc.
25
Pioneering Office of Science
Science and U.S. Department
Technology of Energy
SimpleJCAMonitor
/** Implementation of Connection Listener class
*/
private class SJCAConnectionListener implements
ConnectionListener {
public void connectionChanged(ConnectionEvent ev) {
onConnectionChanged(ev);
}
};
/** Implementation of MonitorListener class
*/
private class SJCAMonitorListener implements
MonitorListener {
public void monitorChanged(MonitorEvent ev) {
onValueChanged(ev);
}
};
26
Pioneering Office of Science
Science and U.S. Department
Technology of Energy
SimpleJCAMonitor
// Instance of SimpleJCAMonitor
SimpleJCAMonitor sjcam=new SimpleJCAMonitor();
// Initialize JCA
try {
// Get the JCALibrary instance
jca=[Link]();
// Create a preemptive context, default configuration
ctxt=[Link](JCALibrary.JNI_THREAD_SAFE);
} catch(Exception ex) {
[Link]("Initialization failed for " +
[Link] + ":\n" + ex);
[Link](1);
}
27
Pioneering Office of Science
Science and U.S. Department
Technology of Energy
SimpleJCAMonitor
// Search
try {
// Search
chan=[Link]([Link],
[Link] SJCAConnectionListener());
[Link]();
} catch(Exception ex) {
[Link]("Search failed for " +
[Link] + ":\n" + ex);
[Link](1);
}
28
Pioneering Office of Science
Science and U.S. Department
Technology of Energy
SimpleJCAMonitor
private void onConnectionChanged(ConnectionEvent ev) {
Channel ch=(Channel)[Link]();
Context ctxt=[Link]();
// Start a monitor on the first connection
if(connectionCounter == 0 &&
[Link]() == [Link]) {
try {
// Add a monitor listener and flush
[Link]([Link],1,
[Link]|[Link]|[Link],
new SJCAMonitorListener());
[Link]();
} catch(Exception ex) {
[Link]();
}
} 29
Pioneering Office of Science
Science and U.S. Department
Technology of Energy
SimpleJCAMonitor
// Print connection state
if([Link]() == [Link]) {
[Link]([Link]() + " is connected");
} else if([Link]() == [Link]) {
[Link]([Link]() + " is closed");
} else if([Link]() ==
[Link]) {
[Link]([Link]() + " is disconnected");
} else if([Link]() ==
Channel.NEVER_CONNECTED) {
[Link]([Link]() + " is never
connected");
}
30
Pioneering Office of Science
Science and U.S. Department
Technology of Energy
SimpleJCAMonitor
private void onValueChanged(MonitorEvent ev) {
Channel ch=(Channel)[Link]();
Context ctxt=[Link]();
// Check the status
if ([Link]() != [Link]) {
[Link]("monitorChanged: Bad status”);
}
// Get the value from the DBR
try {
DBR dbr=[Link]();
String [] value=((STRING)dbr).getStringValue();
[Link]([Link]() + " " +
getName() + ": “ + value[0]);
} catch(Exception ex) {
...
}
} 31
Pioneering Office of Science
Science and U.S. Department
Technology of Energy
Simple JCAMonitor output
Oct 11, 2004 10:36:43.661 Starting Simple JCA Monitor
Oct 11, 2004 10:36:44.083 Search successful for:
evans:calc
CHANNEL : evans:calc
TYPE : [Link][DBR_DOUBLE=6]
COUNT : 1
STATE :
[Link]$ConnectionState[CONNECTED=2]
HOSTNAME : [Link]
READ : true
WRITE : true
Oct 11, 2004 10:36:44.208 evans:calc is connected
Oct 11, 2004 10:36:44.224 evans:calc: 2
Oct 11, 2004 10:36:44.224 evans:calc: 3
...
Oct 11, 2004 10:36:53.240 evans:calc: 3
Oct 11, 2004 10:36:53.740 evans:calc: 4
Oct 11, 2004 10:36:54.036 All Done
32
Pioneering Office of Science
Science and U.S. Department
Technology of Energy
JProbe
• JProbe is a simple example that demonstrates using JCA in a
Swing GUI
33
Pioneering Office of Science
Science and U.S. Department
Technology of Energy
Write once, run everywhere?
34
Pioneering Office of Science
Science and U.S. Department
Technology of Energy
Source files for Simple JCA routines
• All the source and JAR files should be available with the
presentation
- LICENSE
- [Link]
- simplejca
- [Link]
- [Link]
- [Link]
- [Link]
- jprobe
- [Link]
- [Link]
- [Link]
• Stored as [Link] 35
Pioneering Office of Science
Science and U.S. Department
Technology of Energy
Acknowledgements
• JCA was developed by Eric Boucher while at the APS
• Matej Sekoranja [Cosylab] has taken over JCA and is
developing CAJ
• Both of these people were very helpful in getting JCA working
for me
36
Pioneering Office of Science
Science and U.S. Department
Technology of Energy
Thank You
This has been an
APS Controls Presentation
37
Pioneering Office of Science
Science and U.S. Department
Technology of Energy
Thank You
This has been an
APS Controls Presentation
38
Pioneering Office of Science
Science and U.S. Department
Technology of Energy