Thursday, August 17, 2006

Parsing and verifying hex, octal and decimal numbers...

How to parse a number that might be octal, decimal or hexadecimal. Numbers like 0xFF, 0x1e, 077, -123, -0x12, -066. This must have been solved a million times, and here's my version:

Thank you for all the comments! My code is stupid! Use Long.decode(numberString).longValue() Instead!
String sign="";
int base=10;
if(numberString.startsWith("-")) {
sign="-";
numberString=numberString.substring(1);
}
if(numberString.startsWith("0x")) {
numberString=numberString.substring(2);
base=16;
} else if(numberString.startsWith("0") && numberString.length()>1) {
numberString=numberString.substring(1);
base=8;
}
return Long.parseLong(sign+numberString,base);


OK, and here is my VerifyListener:
class NumberVerifyer implements VerifyListener {
final boolean fSigned;
NumberVerifyer(boolean signed) {
fSigned=signed;
}
public void verifyText(VerifyEvent e) {
Text text = ((Text)e.widget);
StringBuffer fulltext = new StringBuffer(text.getText());
fulltext.replace(e.start, e.end, e.text);
String sign=""; //$NON-NLS-1$
if(fSigned)
sign="-?"; //$NON-NLS-1$
e.doit = fulltext.toString().matches(sign+"(0?|[1-9][0-9]*|0x[0-9a-fA-F]*|0[0-7]+)"); //$NON-NLS-1$
}
}

Wednesday, August 16, 2006

Vote for the eclipse 3.3 release train name. Europa is a bad choice!

Vote for the Eclipse Release Train Name (2007). There has been some discussions in bugzilla.

I think Europa is a very bad choice for two reasons:

1. There are too many Google hits already if you search for eclipse europa.

2. In many languages Europa means Europe and this will confuse. Messages like the "Europa Build Workshop", sounds for many non-native speakers like "The Build Workshop Europe". If English is your native language, you might not understand this point, but for Germans this is very confusing. For the same reason you would not call a workshop held in the nice Austrian village called Fucking the "Fucking Workshop" ;-)....

Tuesday, August 15, 2006

Am I the only person having problems with the update manager?

I wonder if I am the only person in the world using the update manager and having problems. Two weeks ago I reported a real show-stopper update manager bug: Update does not work if *ANY* error is found in configuration. I expected that it would be marked as a duplicate but I seem to be the only person having the problem. I cannot finish the updates dialog because of some mysterious errors:



The annoying thing is that "Manage Configuration" seems happy and shows no error:



The error is caused by some installed features that require a specific version of a plugin.

<?xml version="1.0" encoding="UTF-8"?>
<feature id="broken.feature" label="Broken Feature" version="1.0.0">
<description>.</description><copyright>.</copyright>
<license>.</license>
<requires>
<import feature="org.eclipse.platform" version="3.1.2" match="perfect"/>
</requires>
</feature>


What puzzles me the most is not the bug itself, but the fact I seem to be the only one getting the bug (I get it with 3.2 and 3.3M1).....

If you want to try it, just unzip this feature in your eclipse/feature directory and restart eclipse and try to install a feature using the update manager.

Workarounds
Fix the feature.xml file by removing the required version string.
Or use another working eclipse installation and install the plugins into a new extension location and add the extension location to your eclipse using "Manage Configuration".

Update manager battle: the players Yoxos - YUM - eclipse...

Yoxos

I am very frustrated with the eclipse update manager. In my opinion, it is simply unusable. But what are the alternatives? A few weeks ago, I bought a 1 year subscription of yoxos for $99. Unfortunately, since then, no new updates appeared on my yoxos update manager. The yoxos update manager is quite cool. It's a perspective that allows you to select the plugins you want:



This looks very much like the yoxos on demand site (yes, this is a screenshot of an ajax application!):



I don't know how it works, when new updates are available, but I expect it will work smoothly (well, I payed for it -- therefore it has to work ;-))


TUM - Tikal Update Manager

TUM (Tikal Update Manager) is a open source project forge project called tikal run by Tikal.

They create a dialog with some cool icons. Yoxos seems much more mature, but TUM was just announced....



The Eclipse Update Manager

The eclipse update manager seems also to be enhanced. I have not seen it (because I hope for yoxos to install it for me...), but the screenshots seem promising.



The battle shall start...

I really hope that finally the update manager gets more attention. My favorite is clearly yoxos, because they don't use annoying blocking dialogs, but a perspective. The funny thing is, that eclipse 1 used a perspective as well, and in eclipse 2 it became wizard based...

Monday, August 07, 2006

How far are the hotels from the eclipse summintOctober 11-12 2006 in Esslingen/Stuttgart Germany?

I'm about to register for the The eclipse summit 2006 October 11-12 in Germany. On the web page there are 4 hotels suggested, but no clue how far they are away from the actual summit (are they in walking distance?). The summit seems to be at Ebershaldenstraße 12, 73728 Esslingen, Germany. I called all of them to ask for the price for the eclipse summit. The hotels all seem to be in the 100 Euro category. I think breakfast is included in all cases.


Best Western Premier Hotel Park Consul Esslingen
Grabbrunnenstr. 19
73728 Stuttgart/Esslingen am Neckar
Tel: +49(0)711-41111-0
Fax: +49(0)711-41111-699
Distance: 150 meters
Email: marcus.schlaich@consul-hotels.com
Single Room: 110 Euro

Hotel Linde Berkheim
Ruiterstraße 2
73734 Esslingen am Neckar
Tel: +49(0)711-345305
Fax: +49(0)711-3454125
Distance: 4 km
Email: info@linde-berkheim.de
Single room: 85 Euro - Double room 114 Euro (until Sep. 8th)

Hotel Am Schillerpark
Neckarstr. 60, 73728 Esslingen am Neckar
Tel: +49(0)711 931 33-0
Fax: +49(0)711 931 33 100
Distance: 1.2 km (walking distance 800 meter)
Email: info@hotel-am-schillerpark.de
Singe Room: 89 euro (20 rooms for the summit)

Ringhotel Rosenau
Plochinger Straße 65
D-73730 Esslingen am Neckar
Tel: +49(0)711 315 45 60
Fax: +49(0)711 316 13 44
Distance: 1 km
Email: info@hotel-rosenau.de
Prices: The lady at the reception did not know about the "Eclipse Summit". I should call tomorrow before 4PM.

How to quickly add a new repository location to CVS...

The eclipse Add a new CVS Repository dialog allows you to quickly fill the form, if you drop a string like :pserver:anonymous@dev.eclipse.org:/home/dsdp into the Host: field. If you see a string like
cvs -d:pserver:anonymous@foo.cvs.sourceforge.net:/cvsroot/foo login 
at sourceforge, grab the highlighted part (including the colon before pserver)...

You can also select a location in the CVS Repositories view and "Copy to Clipboard" and send it to someone. The receiver can then drop it into the Add a new CVS Repository.

Saturday, August 05, 2006

Eclipse was hanging my machine regularly -- solution -XX:MaxPermSize=128m

I have quite some plugins installed in my eclipse installation. Since a few weeks, eclipse was running mad from time to time, my XP laptop was totally starving, I was not even able to get to the task manager to kill eclipse (keyboard and mouse barley reacted). The only solution was to kill my machine :-(.

Well, but how to find out who is the bad guy? Which of the many plugins I have installed "killing me"? I was using Stack Trace, a cool application that lets you attach to eclipse and get a stack trace.

Most of the time the stack traces of the wild application ended in:
 at java.lang.ClassLoader.defineClass1(Native Method)
at java.lang.ClassLoader.defineClass(Unknown Source)
at org.eclipse.osgi.internal.baseadaptor.DefaultClassLoader.defineClass(DefaultClassLoader.java:160)
at org.eclipse.osgi.baseadaptor.loader.ClasspathManager.defineClass(ClasspathManager.java:498)
at org.eclipse.osgi.baseadaptor.loader.ClasspathManager.findClassImpl(ClasspathManager.java:468)
at org.eclipse.osgi.baseadaptor.loader.ClasspathManager.findLocalClassImpl

Hmm, the class loader puts the class files in a special area of the garbage collector, (perm generation). The starving (100 % CPU and being really bad) seemed to be caused by not enough memory in the perm space. To fix this, I added -vmargs -XX:MaxPermSize=128m to the shortcut that starts eclipse. That solved the problem! The sun default seems to be 64MB (I could not find information for java1.5).

But how much is the perm size really? How to find this out? Today, I found a blog entry by Igor Shabalov describing a cool tool called jconsole, that comes with jdk1.5.0, that allows you to inspect memory related information of your java applications life. All you have to do, it to add -Dcom.sun.management.jmxremote to the eclipse -vmargs. Then you can attach to eclipse and see life the different garbage collection pools and the loaded classes and threads -- pretty cool...

Friday, August 04, 2006

How to create apply a patch that contains changes in multiple projects?

Eclipse has a nice feature to apply patches (context menu of a project: Team->Apply Patch....). If you have multiple projects under CVS control, then you can create a patch that contains changes from multiple projects. The patch looks slightly odd, because id adds some additional lines that tell eclipse which projects a file belongs to. This has is new in eclipse 3.2 (bug 110481).

However if you have a patch created with diff outside eclipse that contains files from multiple projects, eclipse cannot apply the patch.

To apply my multi project patches I wrote a small Eclipse Monkey script that converts a patch on the clipboard to a Eclipse Workspace Patch 1.0, by adding some additional lines.

To install and run the script:

  • Install Eclipse Monkey (if you have not already installed it)
  • Copy the script below (including the odd lines at the beginning and the end) to the clipboard
  • In the Monkey menu do Paste New Script
  • Now you can convert patches to Eclipse Workspace Patch 1.0, by copying that patch to the clipboard and running Monkey->Tools->Convert patch in clipboard to workspace patch


--- Came wiffling through the eclipsey wood ---
/*
* Menu: Tools > Convert patch in clipboard to workspace patch
* Kudos: Michael Scharf(eclipsemonkey @ scharf . gr)
* License: EPL 1.0
*/

// pseudo imports
var ArrayList=Packages.java.util.ArrayList;
var Pattern=Packages.java.util.regex.Pattern;
var StringBuffer=Packages.java.lang.StringBuffer;
var BufferedReader=Packages.java.io.BufferedReader;
var StringReader=Packages.java.io.StringReader;
var ResourcesPlugin=Packages.org.eclipse.core.resources.ResourcesPlugin;
var MessageDialog=Packages.org.eclipse.jface.dialogs.MessageDialog;

var dnd=Packages.org.eclipse.swt.dnd;


function main() {
var patch = getFromClipboard();
if(patch == null) {
showMessage("The clipboard does not contain a string!");
} else {
// is this already a workspace patch?
// the (?m) makes sure that the ^ matches the beginning of a line
// and not just the beginning of the string!
var pattern=Pattern.compile("(?m)^### Eclipse Workspace Patch 1.0");
if(pattern.matcher(patch).find()) {
showMessage("This is already a Workspace Patch!\n" +
"It contains a line beginning with:\n" +
"\"### Eclipse Workspace Patch 1.0\"");
} else {
var messages = new StringBuffer();
patch = convertToWoskspacePatch(patch, messages);
// has it been converted?
if(patch == null) {
showMessage("The clipboard does not contain a valid patch.");
} else {
// OK let's put it on the clipboard
putOnClipboard(patch);
showMessage("Patch converted to clipboard\n\n" + messages.toString());
}
}
}
}

// show a simple message dialog
function showMessage(message) {
MessageDialog.openInformation(
window.getShell(), "Convert patch to workspace patch", message);

}
function convertToWoskspacePatch(patch, messages) {
var reader = new BufferedReader( new StringReader(patch));
var patchBeginPattern = Pattern.compile("^(---|[+][+][+]|RCS file:)\\s+([^\t\n,]+)");
var result = new StringBuffer();
result.append("### Eclipse Workspace Patch 1.0\n");
var projects = ResourcesPlugin.getWorkspace().getRoot().getProjects();
var guessedProjects = new ArrayList();
var patchFound = false;
var line;
var prevLine = null;
var hunkFound = false;
while((line = reader.readLine()) != null) {
var m = patchBeginPattern.matcher(line);
if(m.find()) {
patchFound = true;
var fileName = m.group(2).trim();
var pathSegments = fileName.split("[/\\\\]");
var segment = 0; // the segment in the path that is the project
var projectName = null;
for(var i = 0; i < pathSegments.length; i++) {
var name = pathSegments[i];
if(isProjectName(projects, name)) {
projectName = name;
segment = i;
hunkFound=true;
// report every guessed project only once
if(!guessedProjects.contains(projectName)) {
messages.append("Guessed Project: ");
messages.append(projectName);
messages.append("\n");
guessedProjects.add(projectName);
}
break;
}
}
if(projectName != null) {
result.append("#P ");
result.append(projectName);
result.append("\n");
result.append("Index: ");
// concat the remaining path segments
for(var j = segment + 1; j < pathSegments.length; j++) {
if(j != segment + 1) result.append("/");
result.append(pathSegments[j]);
}
result.append("\n");
result.append("===================================================================\n");
}
}
if(line.startsWith("+++")) {
if(!hunkFound) {
messages.append("No project found for: ");
messages.append(fileName);
messages.append("\n");
}
hunkFound = false;
}
if(prevLine != null) {
result.append(prevLine);
result.append("\n");
}
prevLine = line;
}
if(prevLine != null) {
result.append(prevLine);
result.append("\n");
}
reader.close();
if(!patchFound)
return null;
return result.toString();
}

function isProjectName(projects, name) {
// is the name a name of a project?
for(var i = 0; i < projects.length; i++) {
if(projects[i].getName().equals(name))
return true;
}
// ok let's guess...
if(name.startsWith("com.") || name.startsWith("org.")) {
return true;
}
return false;
}
function putOnClipboard(str) {
var clipboard = new dnd.Clipboard(window.getShell().getDisplay());
try {
clipboard.setContents([str], [dnd.TextTransfer.getInstance()]);
} finally {
clipboard.dispose();
}
}
function getFromClipboard() {
var textTransfer = dnd.TextTransfer.getInstance();
var clipboard = new dnd.Clipboard(window.getShell().getDisplay());
try {
return clipboard.getContents(textTransfer);
} finally {
clipboard.dispose();
}
}

--- And burbled as it ran! ---

Friday, July 28, 2006

Why is super.super illegal?

Well, from time to time I have the need to call super.super. I wonder why this is illegal. Doing some research on the Internet, the best answer I can come up with is, that it breaks encapsulation of the super.super class. Hmm, probably true in a clean world, but sometimes you really want to call back back the original functionality:

class A {
protected void foo(){..}
}
class B extends A {
protected void foo(){
super.foo();
doSomethingStupid();
}
}
class C extends B {
protected void foo(){
super.super.foo(); // it is illegal to omit the stupid stuff of class B
doSomethingUseful();
}
}

Yes, B should not do stupid things. But why can't C undo what B does? In real software systems, that's exactly something that is somtimes needed. The answer that B should provide access to A.foo() if B thinks C would need it does not really satisfy me...

Come on, if java would really be concerned about encapsulation, all methods would default to final unless otherwise specified. Does everybody think about the fact that any non-final public or protected method can be overridden? No! We live with this accidental breakage of encapsulation and why is the small breakage of encapsulation that super.super does forbidden? Hey, a subclass can just override any non-final method without calling super at all, right? And C can call any method on B or A, but not super.super.foo()....

But maybe someone can give me an explanation that can convince me....

I hate ClassCastExceptions...

...because they don't tell me what the class of the "wrong" object was. No message, just empty. Where is the difficulty in telling me, what the actual type of the object was that caused the class cast exception? I rarely see them, but when I see them it's not informative enough -- I have to run the debugger but those rare class cast exceptions are often hard to reproduce...

Sun, please add runtime type of the casted object to the ClassCastExceptions message