Category Archives: Software

Software related topics

Retro gaming on the Amiga

When I was a kid I could only afford having a ZX spectrum (I’m in Europe), and an Amiga was out of reach. Nowadays the Amiga scene is very active, I am in several facebook groups and people are still selling and buying them. Because getting an old machine is very risky I set out to use emulation to feel the Amiga experience. Got the Amiga Forever that runs on Windows and bundles several games with it.

Using the kickstart ROMs that came with it, and UAE4Arm I have set up retroPi on a Raspberry Pi 3 I had lying around. Loaded up “The Secret of Monkey Island” on it and went back a few years when I was playing that same game on a PC.

DC motor

Some weeks ago I disassembled an old portable radio with two tape decks. The only parts I kept was two identical DC motors that powered the tape decks and the speakers. I am now trying to get one of the motors spinning, but I don’t know the wiring because it has a different color scheme. All the wires are white and two of them have dashed lines on them. I’m gonna ask the electronics community on the net for some pointers.

CGLib class enhancement and RMI

I am developing some software (hosted on source forge : https://sourceforge.net/projects/jmxbox/) that is basically an application container. One annotates the classes in the application and they are instantiated, remoted and you can schedule classes to run as jobs, work pools, etc. Check-it out.

To implement remoting I wanted to put the least burden on the application developer. RMI requires that a interface that extends remote (the remote interface) is implemented by the object that is to be remoted. I wanted to reduce the requirements imposed by RMI, such as not implementing a remote interface but instead deriving it from the business object.

For that purpose I investigated CGLib, a byte-code manipulation library. The documentation is scarce so a lot of experimenting is in order.

I tried to derive the interface from the object, but I didn’t manage to get CGLib generate an interface that extended another interface (java.rmi.Remote required by the RMI subsystem). So I required that the app developer implement the remote interface. But I didn’t want to make the interface extend java.rmi.Remote. So I tried creating a proxy to the business object that would extend the object AND implement the Remote marker interface. So I developed the following code :

public void bind(Remote objectInstance) {
 try {
 Enhancer classEnhancer = new Enhancer();
 classEnhancer.setSuperclass(objectInstance.getClass());
 classEnhancer.setInterfaces(new Class[]{Remote.class});
 classEnhancer.setCallback(new MethodInterceptor() {
 @Override
 public Object intercept(Object obj, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
 return methodProxy.invokeSuper(obj, args);
 }
 });
 Object proxy = classEnhancer.create();
 Remote stub =
 (java.rmi.Remote)UnicastRemoteObject.exportObject((Remote)proxy, 0);
 Registry registry = LocateRegistry.getRegistry();
 registry.rebind("Object", stub);
 System.out.println("object instance bound");
 } catch (RemoteException e) {
 System.out.print("error : " + e.getMessage());
 e.printStackTrace();
 } catch (Throwable t) {
 t.printStackTrace();
 }
}

The code ran fine, but when I tried to access the remote object from a java client and casting the stub to the remote interface I got the error that the stub didn’t implement it.

So I used a RMI registry browser to lookup the stub and found out that the only implemented interface was java.rmi.Remote. My interface wasn’t implemented by the stub.

When I coded the remote interface to directly implement the marker interface it worked. So lesson learned. The RMI subsystem requires that the interface extends remote and not the business object. Since CGLib does not allow interface extension AFAIK, I now require that an app developer explicitly extends remote on the business interface.

The methods of the business interface must throw java.rmi.RemoteException, so to really eliminate the requirements of dealing with RMI by the app developer, I would need to wrap the calls to the business object in methods that conform to the RMI spec.

Selecting the java version in Mac OS

I have currently two versions of the JDK installed on my mac. I want to select which one I am going to use in a terminal session. I found out about this neat command that allows me to set the Java home path :

/usr/libexec/java_home -verbose

This will output the installed versions of the JDK. In my case this is the output

1.7.0_07, x86_64: "Java SE 7" /Library/Java/JavaVirtualMachines/jdk1.7.0_07.jdk/Contents/Home
1.6.0_65-b14-462, x86_64: "Java SE 6" /System/Library/Java/JavaVirtualMachines/1.6.0.jdk/Contents/Home
1.6.0_65-b14-462, i386: "Java SE 6" /System/Library/Java/JavaVirtualMachines/1.6.0.jdk/Contents/Home

To set the JAVA_HOME environment variable and use the desired JDK type something like :

export JAVA_HOME=$(/usr/libexec/java_home -v '1.6*')

Then, when we execute the java executable :

java -version

we will get the desired version of the executable

java version "1.6.0_65"
Java(TM) SE Runtime Environment (build 1.6.0_65-b14-462-11M4609)
Java HotSpot(TM) 64-Bit Server VM (build 20.65-b04-462, mixed mode)

 

 

 

 

 

 

NSCollectionView to display a remote collection : part 4

Handling the selection of the collection view.

Because the prototype view is custom made, we have to implement the visual feedback to the user when an item is selected.

First set the collection view as multiple selectable in the NIB file. Below is the place where that is changed in interface builder :

collectionview_selection

Then, in the prototype’s view class (a subclass of NSView) add a property named ‘selected’. In the draw method draw a background according to the state of this variable.

- (void)drawRect:(NSRect)dirtyRect{
    if ([self selected]) {
        [[NSColor grayColor] set];
        NSRectFill([selfbounds]);
    }
    [super drawRect:dirtyRect];
    // Drawing code here.
}

In the CollectionViewItem subclass override the setSelected method that the NSCollectionView UI control will be calling when the user makes a selection or a deselection

- (void) setSelected:(BOOL)selected {
    [super setSelected:selected];
    [(RemovePhotosImageItemView*)[selfview] setSelected: selected];
    [(RemovePhotosImageItemView*)[selfview] setNeedsDisplay: TRUE];
}

Now, when a selection is made or unmade in the UI the item will either draw a background or not (respectively).

NSCollectionView to display a remote collection : part 3

continuing …

The item prototype will have a view defined in it’s own NIB file. For this example I have defined a view that has an image well and a label. On top of the image well is a circular progress indicator. The image well is hidden in the NIB file so that the progress indicator is shown when the nib is first loaded.

The item prototype class is a subclass of NSCollectionViewItem. We define this class in our project and define outlets for the controls we want to manipulate.

@interface RemovePhotosCollectionViewItem : NSCollectionViewItem
@property IBOutlet NSProgressIndicator* progressIndicator;
@property BOOL imageLoaded;- (void) loadImage;
@end

Then create a new NIB file that defines the item prototype’s view.  Set the file’s owner to be the subclass of the NSCollectionViewItem defined above. This subclass already has some outlets defined in the superclass that are suitable to our example namely the imageView and textField outlets.

collectionview_item_connections

In the above image a binding can be see below the connections. We will bind the item view’s controls to the prototypical object that the view represents. The binding to the image well is shown below :

imagewell_binding

The NSCollectionViewItem has a representedObject property that can be used as the key path to the properties of the element prototype. (The class RemovePhotosCollectionViewItem)

We still have to go into the main NIB and bind the NSCollectionView to the array controller as shown below :

NSCollectionView_binding

The ‘arrangedObjects’ path refers to the ArrayController defined in the main NIB.

In the Collection View Item subclass we do two things. Start the circular progress indicator animation to give feedback to the user that the data is loading, and trigger a call to the server to load the image.

The imageLoaded property marks the loading call as terminated and we manage that in the view item code. First we set it to false in -awakeFromNib.

- (void) awakeFromNib {
    [self setImageLoaded: FALSE];
}

Then we need a way to trigger the loading process. Since we access the represented object (the underlying ImageBrowserImage object stored in the array on the main view’s controller) we can only  access it after the bindings are established by the cocoa framework. We trigger the loading process by overriding the “setRepresentedObject” message as below :

- (void) setRepresentedObject:(id)representedObject {
    [super setRepresentedObject:representedObject];
    if (nil != representedObject && ![self imageLoaded]) {        [NSThreaddetachNewThreadSelector: @selector(loadImage) toTarget:selfwithObject:nil];
        [self setImageLoaded: TRUE];
}
}

In the loadImage method defined in the item view’s class we synchronously call the server in another thread, that does not block the user interface. When the image is loaded we set the attributes on the represented object that triggers the display of the data in the user interface.

ImageBrowserImage* imageDataObj = (ImageBrowserImage*)[selfrepresentedObject];
// ... load the image from the server        [imageDataObj setImageKey:imageKey];        [imageDataObj setImageData: decodedImageData];                [[self progressIndicator] setHidden: TRUE];        [[selfimageView] setHidden: FALSE];

As can be seen in the above code we swap the visibility of the image well and the progress indicator when the data is loaded.

That’s it.

NSCollectionView to display a remote collection : part 2

Post with 2nd part of this subject.

First drag a Collection View from the palette in Xcode into a window. This will create three new objects in the NIB file :

  • The collection view object
  • The collection view item prototype
  • The collection view item prototype’s view

The IDE automatically creates a view for the prototype, but we will have a NIB file dedicated to this view.

In this example we will have an array of objects that hold an image and a text label. The code that follows is the declaration of the model object :

@interface ImageBrowserImage : NSObject
@property NSUInteger imageIndex;
@property NSString* queryKey;
@property (strong) NSString* imageKey;
@property (strong) NSData* imageData;
@property ServerAPI* serverAPI;
@end

Next, in the controller class that manages the window with the collection view declare a property as an NSMutableArray :

@property NSMutableArray* imageBrowserArray;

And add the necessary methods to make the above array KVO compliant.

- (void)insertObject:(ImageBrowserImage *)p inImageBrowserArrayAtIndex:(NSUInteger)index;
- (void)removeObjectFromImageBrowserArrayAtIndex:(NSUInteger)index;

Now create a NSArrayController in the main NIB file.

main_nib_objects In the array controller’s attributes inspector set the Object controller as the following :

arraycontroller_attrinspector

We set the mode of the object controller’s to class and specify the item class. We then specify which of the item classe’s properties will be exposed to the view layer.

Now we will bind the array declared in the main view’s controller to the NSArrayController we just added to the main NIB. In the NSArrayController’s bindings inspector set the ‘Bind To’ drop down to the main view’s controller class (which must be declared in the NIB). The model key path is the name of the KVC compliant  mutable array property declared in the bound class.

arraycontroller_binding

In the next post we will create the item prototype NIB file and configure its outlets.

NSCollectionView to display a remote collection : part 1

I wanted to display a large number of images stored on a server in a cocoa desktop app. My first approach was to use the class IKImageBrowserView.

But this class does not allow customisation of the collection item. One good thing it does is that it’s able to lazy load the collection elements (that are images) so the user interface remains responsive even when the collection’s size is very large.

Wanting to have both item customisation and lazy loading, I implemented a collection view with an item prototype that displays a circular progress indicator while it is loading the data and shows an image and some other controls afterwards.

All the collection’s elements are created immediately but the bulk of the data is loaded in the background with the use of one thread per collection element. Each collection item triggers this thread that loads the data from the server.

One thing to note is that on the server side, a query’s results are persisted on a database, so the client (cocoa app) can obtain the collection element at an index for a given server side query.

The collection size is known in advance, and while the cocoa view displays its elements it is assumed that the collection does not change.

In the next posts I will go into the details of this setup.

Inserting a NSTimer in the main threads run loop

So I am implementing an UI control, much like a textfield, but supposedly configurable so that I can give it the look and feel that I want.

To make a caret blink when the control receives focus I attach a NSTimer to the main thread’s run loop. Todo that I just have to call a class method from the NSTimer class and it creates and adds it to the run loop object.

To create a timer I have to instantiate it with a call to 

+ (NSTimer *)scheduledTimerWithTimeInterval:(NSTimeInterval)seconds invocation:(NSInvocation *)invocation repeats:(BOOL)repeats

Which takes me to the subject of instantiating an NSInvocation Object. For that we have the method

+ (NSInvocation *)invocationWithMethodSignature:(NSMethodSignature *)signature

To create a NSMethodSignature we need to call the method :

+ (NSMethodSignature *)signatureWithObjCTypes:(const char *)types

The apple docs say that “Returns an NSMethodSignature object for the given Objective C method type string.”

What is an Objective C type string ? Its a character code for every primitive type in the Objective C language and can be consulted in the following link:

https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/ObjCRuntimeGuide/Articles/ocrtTypeEncodings.html
So the rest is just as easy as RTFM.
Edit : WAIT !
I just RTFM and indeed the above method of creating the method signature for the NSInvocation is platform dependent. Depending on the version of OS X you are on it may change. So we are better off using the rolling procedure : 
    NSInvocation* blinkMethod = [NSInvocation invocationWithMethodSignature: [self methodSignatureForSelector:@selector(blinkCaret)]];
 

Using log4jdbc on weblogic server 10.3

I am having a problem on a specific EJB container managed transaction. It fails to update a database row on some occasions. So I need to have a look at what is being sent  the database and check for any errors. Since I am connecting to an Oracle database, I am aware that logging through the oracle JDBC driver does not show me variable bindings on prepared statements. So I need to use another way to see what’s happening, and that’s when log4jdbc comes in.

EDIT : currently log4jdbc does not support XA. Only found this out at the end of the process.

Log4jdbc sits between the application and the real driver and gives us the chance to log JDBC calls with fine detail. In this post I will be logging just SQL statements.

First, get the libraries. We need the log4jdbc jar and the jars from the SLF4J project for abstracting away the concrete logging framework, which in this case is log4j.

So put the following jars :

  • log4jdbc4-1.2.jar
  • slf4j-log4j12-1.7.6.jar
  • slf4j-api-1.7.6.jar

in a directory (here named $LOGGING_HOME), and find the weblogic script named commEnv.sh, which should be in the directory $BEA_HOME/wlserver_10.3/common/bin.

In this file you should place the three jars in the $LOGGING_HOME directory in the beginning of the classpath defined by the WEBLOGIC_CLASSPATH variable.

Then run the WLST command line tool to update your connection pool information. Execute the following commands replacing the shell variables with the values specific for your environment :

> readDomain('$DOMAIN_HOME') ;

find the path to the descriptor with your datasource’s connection pool configuration. In this case the datasource is named ‘portalPoolDataSource’ :

> cd('/JDBCSystemResource/portalPoolDataSource/JdbcResource');
> cd('portalPoolDataSource/JDBCDriverParams/NO_NAME_0');

If you then do an ls() you will see the configuration of the connection pool.

We want to change the properties named ‘DriverName’ and  ‘URL’:

> set('DriverName', 'net.sf.log4jdbc.DriverSpy');
> set('URL', 'jdbc:log4jdbc:oracle:thin:@localhost:1521:xe');

As per the log4jdbc documentation the new database URL is equal to the old one, but putting the string ‘:log4jdbc:’ between the leading ‘jdbc’ and the ‘oracle’ substrings.

Then write the configuration to disk :

> setOption('OverwriteDomain', 'true');
> updateDomain();

, and exit the WLST tool. Now we need to configure logging. I already had a log4j configuration file in xml format called log4j.xml. In my startup procedure I am using the WLST tool to start the AdminServer, and pass system properties to the startServer command. To indicate where the log configuration is located one may define the system property :

-Dlog4j.configuration=file://$DOMAIN_HOME/log4j.xml

In my case this setting was always ignored. The config file considered by weblogic was one found inside one of its jars. It was looking for the first file in the classpath with the path described in the following line extracted from the startup log :

log4j: Trying to find [resources/comdev/default-log4j.properties] using context classloader weblogic.utils.classloaders.GenericClassLoader@1dea651

This output was logged only when the system property ‘-Dlog4j.debug’ is passed on server startup.

I then proceeded to convert my log4j.xml into properties format and placing it first on the classpath, so that It could be found before any other file with a similar relative path.

In the logging configuration file I defined the log level for the jdbc.sqlonly category :

log4j.category.jdbc.sqlonly=INFO, FILE

That was it. the SQL is now being logged on the appender named FILE.