Friday, July 21, 2006

Fedex in Romania to be Avoided

I had to send a small package abroad and I decided to use Fedex. I quickly reached the Fedex Romania page http://www.fedex.com/ro/contact/?link=4 and after trying to no avail to get through to about 3 of the listed phone numbers, someone finally picked up the phone. According that web page, the phone numbers are for International Romexpress Service Ltd. So I give them my contact details so that they would come and pick up the package.

So far so good. But when a guy comes for my package, I found out he was not from International Romexpress Service Ltd, but form Fan Courier Express.

Ok I say, I don't care too much about that. I only want my package delivered asap and nothing else. Thus I give the courier guy my package and get an 8-digits long tracking number AWB (Air Way Bill). That number looked surprisingly short compared to the last fedex tracking number I had seen which had 12 digits.

Thereafter I lookup up the AWB number on the fedex website to be told that the tracking number doesn't exist. Ok I say, perhaps it's only valid on facnourier.ro. I try to look it up there, but I get a similar message. So I though that it might take some time until the two databases get updates.

The next day I lookup up the AWB, again to no avail. So I decided it's time to call up the customer services representative. Well, on the phone I was told that my order is this and that, and I wasn't explained why the look up facility on their website doesn't work.

Of course I subsequently asked for the Fedex tracking number, as Fancourier seems too dodgy so it's probably not worth arguing too much about their web site not working as it should. But I was told that they don't have the Fedex tracking number "yet", but it should become available later on.

Well I say, by what means are you gonna advise me of the Fedex tracking number once it becomes available ? Email ? Phone ? So the customer representative starts mumbling something about that not being possible, and that I should "try" again in 3 (three!) days to see if it has become available or not.

So one day after I sent the package I haven't got any usable tracking number, and there are no prospects I might get one in the next 2 days either.

The reason why I chose Fedex and thus pay about 10 (ten) times the cost of the same service provided by the Romanian Post Office was the tracking number itself. It's easy to guess I won't be doing that any time soon.

I recently had a lousy experience receiving a Fedex package in Romania, when the courier guy called me up saying that he had problems delivering the package, when he had actually never tried to do so.

My recommendations:

1. don't send packages through Fedex from Romania
2. if possible, avoid receiving packages through Fedex in Romania

Tuesday, May 30, 2006

Finally got a reply

Today after exactly 1 year since I reported the LinkedBlockingQueue bug I got a reply for all 3. It seems that the LinkedBlockingQueue issue has been fixed in jdk 1.5_07, while the charset ones in Mustang.

Thursday, September 15, 2005

Unanswered CharsetDecoder.decode bug report

dateCreated: Tue Aug 23 06:26:27 MDT 2005
type: bug
cust_name: Daniel Aioanei
jdcid: aioaneid
status: Waiting
category: java
subcategory: classes_nio
company: undisclosed
release: 5.0
hardware: x86
OSversion: win_xp
priority: 4
synopsis: java.nio.charset.CharsetDecoder.decode(ByteBuffer) does not call implFlush()
description: FULL PRODUCT VERSION :
java version "1.5.0_04"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0_04-b05)
Java HotSpot(TM) Client VM (build 1.5.0_04-b05, mixed mode, sharing)

A DESCRIPTION OF THE PROBLEM :
java.nio.charset.CharsetDecoder.decode(ByteBuffer in) should call implFlush() as per the method's javadoc, but it doesn't.

STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Run the attached program.


REPRODUCIBILITY :
This bug can be reproduced always.

---------- BEGIN SOURCE ----------
import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.nio.charset.CharacterCodingException;
import java.nio.charset.Charset;
import java.nio.charset.CharsetDecoder;
import java.nio.charset.CharsetEncoder;
import java.nio.charset.CoderResult;

public class CharsetDecoderTest {

public static void main(String[] args) throws CharacterCodingException {
new MyCharset().newDecoder().decode(ByteBuffer.wrap(new byte[1]));
System.out.println(MyCharsetDecoder.IMPL_FLUSH_CALLED);
}

static class MyCharset extends Charset {

protected MyCharset() {
super("canonicalName", null);
}

@Override
public boolean contains(Charset cs) {
return false;
}

@Override
public CharsetEncoder newEncoder() {
return null;
}

@Override
public CharsetDecoder newDecoder() {
return new MyCharsetDecoder(this);
}
}

static class MyCharsetDecoder extends CharsetDecoder {

protected MyCharsetDecoder(Charset cs) {
super(cs, 1, 1);
}

public static boolean IMPL_FLUSH_CALLED;

@Override
protected CoderResult decodeLoop(ByteBuffer in, CharBuffer out) {

while (in.remaining() > 0) {
in.get();
}

return CoderResult.UNDERFLOW;
}

@Override
protected CoderResult implFlush(CharBuffer out) {
IMPL_FLUSH_CALLED = true;
return CoderResult.UNDERFLOW;
}

}

}

---------- END SOURCE ----------

CUSTOMER SUBMITTED WORKAROUND :
public static final CharBuffer decode(CharsetDecoder decoder, ByteBuffer in)
throws CharacterCodingException {

CharBuffer out = decoder.decode(in);

int n = 16;
CharBuffer tail = CharBuffer.allocate(n);

CoderResult cr;

do {
try {
cr = decoder.flush(tail);
} catch (IllegalStateException ise) {
return out;
}

if (cr.isOverflow()) {
n *= 2;
CharBuffer o = CharBuffer.allocate(n);
tail.flip();
o.put(tail);
tail = o;
}
} while (cr.isOverflow());

tail.flip();

if (tail.position() == tail.limit()) {
return out;
} else {
CharBuffer bb = CharBuffer.allocate(out.limit() - out.position()
+ tail.limit() - tail.position());
bb.put(out);
bb.put(tail);
bb.flip();
return bb;
}

}

Unanswered CharsetEncoder.encode Bug Report

dateCreated: Tue Aug 23 01:52:56 MDT 2005
type: bug
cust_name: Daniel Aioanei
jdcid: aioaneid
status: Waiting
category: java
subcategory: classes_nio
company: undisclosed
release: 5.0
hardware: x86
OSversion: win_xp
priority: 4
synopsis: java.nio.charset.CharsetEncoder.encode(CharBuffer in) does not call implFlush
description: FULL PRODUCT VERSION :
java version "1.5.0_04"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0_04-b05)
Java HotSpot(TM) Client VM (build 1.5.0_04-b05, mixed mode, sharing)

ADDITIONAL OS VERSION INFORMATION :
Microsoft Windows XP [Version 5.1.2600]

A DESCRIPTION OF THE PROBLEM :
According to the javadoc of java.nio.charset.CharsetEncoder.encode(CharBuffer), it finally flushes the encoder. This is not really happening though.


REPRODUCIBILITY :
This bug can be reproduced always.

---------- BEGIN SOURCE ----------
import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.nio.charset.CharacterCodingException;
import java.nio.charset.Charset;
import java.nio.charset.CharsetDecoder;
import java.nio.charset.CharsetEncoder;
import java.nio.charset.CoderResult;

public class CharsetTest {

public static void main(String[] args) throws CharacterCodingException {
new MyCharset().newEncoder().encode(CharBuffer.wrap("abc"));
System.out.println(MyCharsetEncoder.IMPL_FLUSH_CALLED);
}

static class MyCharset extends Charset {

protected MyCharset() {
super("canonicalName", null);
}

@Override
public boolean contains(Charset cs) {
return false;
}

@Override
public CharsetDecoder newDecoder() {
return null;
}

@Override
public CharsetEncoder newEncoder() {
return new MyCharsetEncoder(this);
}

}

static class MyCharsetEncoder extends CharsetEncoder {

protected MyCharsetEncoder(Charset cs) {
super(cs, 1, 1, new byte[1]);
}

public static boolean IMPL_FLUSH_CALLED;

@Override
protected CoderResult encodeLoop(CharBuffer in, ByteBuffer out) {

while (in.remaining() > 0) {
in.get();
}

return CoderResult.UNDERFLOW;
}

@Override
protected CoderResult implFlush(ByteBuffer out) {
IMPL_FLUSH_CALLED = true;
return CoderResult.UNDERFLOW;
}

@Override
public boolean isLegalReplacement(byte[] repl) {
return true;
}
}

}

---------- END SOURCE ----------

CUSTOMER SUBMITTED WORKAROUND :
I think that calling encode(CharBuffer in, ByteBuffer out, boolean endOfInput) followed by flush() should do the trick.

Tuesday, August 23, 2005

LinkedBlockingQueue loses elements

I submitted this bug to Sun but I've got no answer back.


dateCreated: Thu May 26 02:50:20 MDT 2005

description: FULL PRODUCT VERSION :
java version "1.5.0_03"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0_03-b07)
Java HotSpot(TM) Client VM (build 1.5.0_03-b07, mixed mode, sharing)



A DESCRIPTION OF THE PROBLEM :
After I put an element into a LinkedBlockingQueue, then remove the element and subsequently add another element to the queue, queue.size() correctly returns 1, but queue.iterator() returns an empty iterator.

EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
before putting 1 []
before removing 1 [1]
before putting 2 []
AFTER putting 2, q.size() = 1 but q = [2]
The elements are: 2
That's all the queue.

ACTUAL -
before putting 1 []
before removing 1 [1]
before putting 2 []
AFTER putting 2, q.size() = 1 but q = []
The elements are:
That's all the queue.


REPRODUCIBILITY :
This bug can be reproduced always.

---------- BEGIN SOURCE ----------
import java.util.concurrent.LinkedBlockingQueue;

public class A {

public static void main(String[] args) throws Exception {

LinkedBlockingQueue<Object> q = new LinkedBlockingQueue<Object>();

System.out.println("before putting 1 " + q);
q.put("1");
System.out.println("before removing 1 " + q);
q.remove("1");
System.out.println("before putting 2 " + q);
q.put("2");


System.out.println("AFTER putting 2, q.size() = " + q.size() + " but q = " + q);

System.out.println("The elements are: ");

for (Object element : q) {
System.out.println("element " + element);
}

System.out.println("That's all the queue.");
}

}