Tuesday, October 9, 2012

Eclipse and native library not found

Eclipse as Java IDE is great. But there's (at least) one part of the GUI that's a bit cumbersome. One thing that frequently pops up is the problem of not finding a native library.

For example if you use TIBCO Rendezvous, your project uses a tibrvj.jar file which is dependent on a native libary, for example tibrv.dll on Windows. Of course you can solve this by setting a Run Configurations 'VM argument' to -Djava.library.path=. But if you have many Run configurations, for example because you write JUnit tests around your software, it would be a pain to configure java.library.path for every JUnit Run Configuration.

You would think you can do Project -> Properties -> 'default java library path' - or so.
Or maybe Windows -> Preferences -> 'default VM arguments'. But neither exists :-(
That's the part where I say the GUI design of Eclipse could be improved: it's not quite obvious that you can actually edit properties of a jar file in 'Referenced Libraries'. You add jar files and they look like non-editable references to files. But you can actually change some properties.

Select your jar file and do a right-mouse-click:


In this dialog you can specify the path to a dependent native library which is then added to your java.library.path for every existing and future Run Configuration of this project.

Another interesting jar-file setting is the 'Javadoc Location'. Once you specified the path to a Javadoc's index.htm, the online documentation will be available when you program against that API (IntelliSense and F2 work). For TIBCO Rendezvous however, there's no real Javadoc part of the product.

Please note, though, that when you upgrade to another version of the jar file, these jar-file settings are lost. You have to repeat the steps above. It would be nice from Eclipse to be asked whether to keep Javadoc Location/Native Library settings when upgrading a jar file.


Tuesday, July 12, 2011

Eclipse doesn't start after crash

After a crash on Windows 7, my beloved Eclipse environment wouldn't start again! It just hung there, showing nothing but the Splash screen. eclipse -clean didn't help, monitoring files with Sysinternal's ProcMon or 'handle.exe' didn't help - quite devastating... But finally I found the solution here:
  1. cd to your Eclipse home directory
  2. cd .metadata/.plugins
  3. ren org.eclipse.core.resources BAK (Keep this directory around)
  4. Restart Eclipse, ignore the error message.
  5. Close all open editors tabs !! (in my case, playing with the .xsd file editor caused the issue)
  6. Exit Eclipse.
  7. del org.eclipse.core.resources (Delete the newly created directory.)
  8. ren BAK org.eclipse.core.resources (Restore the original directory.)
  9. Restart Eclipse.

Wednesday, December 15, 2010

How to implement a 'repeating' Swing JButton ?

Sometimes you want to repeat your JButton action after the button was pressed. This is definitely not rocket-science, but I thought it's nice and small enough to share. Here's the usual code with a one-click action: a 'Next' button that selects the next row in a table.

    nextButton.addActionListener( new ActionListener() {
      public void actionPerformed(ActionEvent arg0)
      {
        selectNextRow(...);
      }});
For a repeating button, you can replace this code with the code snippet below. Adjust the times appropriately. I wonder why this isn't standard functionality in a Swing JButton(..., startMsec, repeatMsec) ?

    nextButton.addMouseListener( new MouseAdapter() {
      
      Timer repeatTimer;
      
      public void mousePressed(MouseEvent arg0)
      {
        selectNextRow(...); // initial execution
        
        repeatTimer = new Timer(100, new ActionListener() {
          public void actionPerformed(ActionEvent e)
          {
            selectNextRow(...); // execute every 100 msec
          }});
        repeatTimer.setInitialDelay(1000); // start repeating only after 1 second
        repeatTimer.start();
      }
      
      public void mouseReleased(MouseEvent arg0)
      {
        repeatTimer.stop();
      }});

Tuesday, May 18, 2010

Managing Oracle Tablespace (ORA-01653 error)

This procedure helped me a bit to manage an Oracle DB's tablespace. I was getting ORA-01653: unable to extend table SYSTEM... errors.
Maybe the following procedure is useful for others as well:
  1. In order to manage/see the current usage, here's a good script posted by 'bipul' on http://forums.oracle.com/forums/thread.jspa?messageID=3590569
  2. To check which data files are used:

    select name from v$datafile

  3. To increase that setting:
alter database datafile 'C:\ORACLEXE\ORADATA\XE\SYSTEM.DBF' autoextend on next 100m maxsize 2000m;

Wednesday, February 24, 2010

Quants

An interesting documentation about quants, including Emanuel Derman,
starts in Dutch first, but in English later.

Monday, February 15, 2010

Java: Sorted List

Sometimes you might have the need for a Java list, that is sorted with every element insertion. If you use a sorted TreeSet, you are stuck with iterators, no random access for elements. If you use an ArrayList, you could call Collections.sort() after every add, but that's not necessarily efficient. Collection.sort() will have to check the order for every element. If your list is long, this might take time.
But here's the trick: if you know your list was already sorted before your insertion, there's no need to re-sort everything again. You can find the proper insertion point with a quick binary search, and insert the new element at the proper position. VoilĂ , your list is always sorted.
Surprisingly simple to do this in Java:



/** A LinkedList that efficiently sorts itself with every add.
 * 
 * @author apodehl
 *
 */
public class SortedList< T extends Comparable> extends LinkedList
{
  /** Adds this element to the list at the proper sorting position.
   * If the element already exists, don't do anything.
   */
  @Override
  public boolean add(T e)
  {
    if( size()==0 ) {
      
      return super.add(e);
    }
    else {
      
      // find insertion index
      int idx = -Collections.binarySearch(this, e)-1;
      
      if( idx < 0 ) {
        return true; // already added
      }
      
      // add at this position
      super.add(idx, e);
      return true;
    }
  }
}



Java BiMap, BidiMap

After doing some research and trying to find just the right Java Bi-Map, I couldn't find any, so I had to roll my own :-( To my surprise, implementation of a Bi-Maps is not straight-forward, there's not such thing as the 'one Bi-Map functionality'.
The interesting case is this one: say there are mappings A->1 and B->2. What happens once you insert C->2 ?
Will you remove B->2 to ensure uniqueness of keys and values ? (resulting in A->1 and C->2)
or not, resulting in A->1, B->2 and C->2. Please note that in the latter case, there's no well-defined lookup for value "2". Is it B or is it C ?
So what I needed was uniqueness of both keys and values, in all cases, using generics. Here it goes:


import java.util.Collection;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Set;

/**
 * One possible implementation of a Bi-directional Map.
 * 
 * Note: there are several variations of BiMap, depending on the behaviour of put(k,v)... Is it allowed to have more
 * than one k for one value ?? Modify
 * 
 * @author apodehl
 * 
 * @param 
 * @param 
 */
public class BiMap implements Map
{
  Map keyVal; // maps key->value

  Map valKey; // maps value->key

  public BiMap()
  {
    keyVal = new LinkedHashMap();
    valKey = new LinkedHashMap();
  }

  @Override
  public V put(K key, V val)
  {
    // --- this implementation allows one-to-one ONLY !! ---
    if (valKey.containsKey(val)) {
      keyVal.remove(valKey.get(val));
    }
    if (keyVal.containsKey(key)) {
      valKey.remove(keyVal.get(key));
    }
    // --- remove above if that's not what you want ---

    // 
    valKey.put(val, key);
    return keyVal.put(key, val);
  }

  @Override
  public void putAll(Map< ? extends K, ? extends V> m)
  {
    for (Entry< ? extends K, ? extends V> e : m.entrySet()) {
      put(e.getKey(), e.getValue());
    }
  }

  /**
   * Type-safe get.
   * 
   * @param key
   * @return
   */
  public K getKey(V val)
  {
    return valKey.get(val);
  }

  /**
   * Type-safe get.
   * 
   * @param key
   * @return
   */
  public V getVal(K key)
  {
    return keyVal.get(key);
  }

  @Override
  // unfortunately Map interface isn't type-safe
  public V get(Object key)
  {
    return getVal((K) key);
  }

  /**
   * Type-safe contains.
   * 
   * @param key
   * @return
   */
  public boolean contains(K key)
  {
    if (keyVal == null) return false;
    return keyVal.containsKey(key);
  }

  /**
   * Type-safe containsValue.
   * 
   * @param key
   * @return
   */
  public boolean containsVal(V val)
  {
    if (valKey == null) return false;
    return valKey.containsKey(val);
  }

  // unfortunately Map interface isn't type safe here ..
  @Override
  public boolean containsKey(Object key)
  {
    return contains((K) key);
  }

  // unfortunately Map interface isn't type safe here ..
  @Override
  public boolean containsValue(Object value)
  {
    return containsVal((V) value);
  }

  @Override
  public Set< java.util.Map.Entry> entrySet()
  {
    return keyVal.entrySet();
  }

  @Override
  public boolean isEmpty()
  {
    return keyVal.isEmpty();
  }

  @Override
  public int size()
  {
    return keyVal.size();
  }

  @Override
  public Collection values()
  {
    return keyVal.values();
  }

  public V removeByKey(K key)
  {
    V val = keyVal.remove(key);
    valKey.remove(val);
    return val;
  }

  public K removeByVal(V val)
  {
    K key = valKey.remove(val);
    keyVal.remove(key);
    return key;
  }

  // unfortunately Map interface isn't type-safe
  @Override
  public V remove(Object key)
  {
    return removeByKey((K) key);
  }

  @Override
  public Set keySet()
  {
    return keyVal.keySet();
  }

  @Override
  public void clear()
  {
    keyVal.clear();
    valKey.clear();
  }

  public String toString()
  {
    String s = "BiMap:\n";
    s += "  key->value: " + keyVal.toString();
    s += "\n";
    s += "  value->key: " + valKey.toString();
    return s;
  }

  public static void main(String[] args)
  {

    BiMap biMap = new BiMap();
    biMap.put("A", 1);
    biMap.put("B", 2);
    System.out.println(biMap); // {A=1, B=2}

    biMap.put("C", 2);
    System.out.println(biMap); // {A=1, C=2}

    biMap.removeByVal(1);
    System.out.println(biMap); // {C=2}
  }
}