Java 8 Compability

Well jme has one little thing breaking it on java 8, this IOException is not thrown anymore in java 8.
Now the problem arises, that the compiler denys a compile due to not possible catches sigh

In class UDPEndpoint
[java]
public void send( ByteBuffer data )
{
if( !isConnected() ) {
throw new KernelException( “Endpoint is not connected:” + this );
}

    try {
        DatagramPacket p = new DatagramPacket( data.array(), data.position(), 
                                               data.remaining(), address );
                                               
        // Just queue it up for the kernel threads to write
        // out
        kernel.enqueueWrite( this, p );
                                                           
        //socket.send(p);
    } catch( IOException e ) {
        throw new KernelException( "Error sending datagram to:" + address, e );
    }
}

[/java]

My suggested solution would be this;

[java]
public void send( ByteBuffer data )
{
if( !isConnected() ) {
throw new KernelException( “Endpoint is not connected:” + this );
}

    try {
        DatagramPacket p = new DatagramPacket( data.array(), data.position(), 
                                               data.remaining(), address );
                                               
        // Just queue it up for the kernel threads to write
        // out
        kernel.enqueueWrite( this, p );
                                                           
        //socket.send(p);
    } catch( Exception e ) {
        if(e instanceof IOException){
              throw new KernelException( "Error sending datagram to:" + address, e );  //no logic change to prior exception handeling visible from outside
        }else{
              throw new RuntimeException(e);  //to shut the java compiler up in case the method defines a checked exception
        }
    }
}

[/java]

So are there better options than this? other ideas how to solve this more clean?

2 Likes

If anything, I would suggest inverting if/else - check if e instanceof RuntimeException, if yes, rethrow it directly without wrapping, else wrap into KernelException.

Agree. The Oracle guys really screwed up on this one… just one of the many hidden evils of “checked exceptions”.

I vote to doing a RuntimeException check or just always wrapping the exception. It’s stupid that we have to, though.

Well yes just always wrapping might be more simple, and simpler is better.

@pspeed said: Agree. The Oracle guys really screwed up on this one... just one of the many hidden evils of "checked exceptions".

I vote to doing a RuntimeException check or just always wrapping the exception. It’s stupid that we have to, though.

Why blame Oracle for changing the API between major releases? It’s not like they haven’t told everyone what to expect and why.

http://www.oracle.com/technetwork/java/javase/8-compatibility-guide-2156366.html

1 Like
@jmaasing said: Why blame Oracle for changing the API between major releases? It's not like they haven't told everyone what to expect and why.

http://www.oracle.com/technetwork/java/javase/8-compatibility-guide-2156366.html

This change is not mentioned anywhere in that doc and it was really an unnecessary change. Methods can list throws exceptions even if nothing in the body throws it… but anyone using this constructor would have had to deal with the exception and now the code breaks. I think they screwed up.

Well I think in the rend the romoval is correct, else they would force the check of that exception for quite a long time.

It’s just unfortunate if you have sourcecode that supports from 1.5 to 1.8, a syou somehow have to use the most common denominator.

Pro tip: Just allowing to catch not thrown CheckedExceptions with an compile warning instead of a compile error would have been a good solution, allowing older code to compile without errors.

@pspeed said: This change is not mentioned anywhere in that doc and it was really an unnecessary change. Methods can list throws exceptions even if nothing in the body throws it... but anyone using this constructor would have had to deal with the exception and now the code breaks. I think they screwed up.

Area: Core Libs / java.net
Synopsis
Prior to Java SE 8, the java.net.DatagramPacket constructors that accept a java.net.SocketAddress argument declared that a java.net.SocketException can be thrown. However, that exception was never thrown by those constructors. In the Java SE 8 release, these constructors do not declare that a java.net.SocketException can be thrown. If you have existing code that explicitly catches SocketException or its superclass java.io.IOException, remove the catch block for the exception before compiling with Java SE 8.

Nature of Incompatibility
source

RFE
8022126

1 Like
@jmaasing said: Area: Core Libs / java.net Synopsis Prior to Java SE 8, the java.net.DatagramPacket constructors that accept a java.net.SocketAddress argument declared that a java.net.SocketException can be thrown. However, that exception was never thrown by those constructors. In the Java SE 8 release, these constructors do not declare that a java.net.SocketException can be thrown. If you have existing code that explicitly catches SocketException or its superclass java.io.IOException, remove the catch block for the exception before compiling with Java SE 8.

Nature of Incompatibility
source

RFE
8022126

Bah… I searched the wrong keywords.

“If you have existing code that explicitly catches SocketException or its superclass java.io.IOException, remove the catch block for the exception before compiling with Java SE 8.”

The evil of checked exceptions is that this could not even have been avoided.

This issue still requires manual fix.
Other problem is that gradle file specifies source compatibility 1.5, but this is not true - there is plenty of spaces where @Override is used for interface methods, which is legal only from 1.6 onwards. It has to be bumped to at least 1.6 to work properly. And if we are at that, maybe 1.7 could be used, to allow diamond syntax for generics?

Note for eclipse users - it is enough to slap
apply plugin: ‘eclipse’
in build.gradle and common.gradle, then hit gradlew.bat eclipse and then import existing projects into workspace (only subprojects, without top level). Then get rid of skd project and you are good to go.

The sdk and antive builds can just be disabled, n o need to get actually rid of them.

Using the gradle build since quite some time now, also thanks to git I can just use a local fix for the excpetion stuff and 1.8

But fixing this in the actual repro would be a good idea, as it looks really unprofessional if compiling fails out of the box for an up to date machine.

If someone submits a pull request with the “always wrapped” solution above then we can apply it. I haven’t had time to setup to build the latest JME yet so I haven’t had time to hand fix it.

is it possible to send a pull request from a non github based git repository? cause I use a somewhat modified jme wich includes a few changes for the ES (eg making some internal vehicle data visible)

This should be fixed now in the HitGub

@Empire Phoenix said: is it possible to send a pull request from a non github based git repository? cause I use a somewhat modified jme wich includes a few changes for the ES (eg making some internal vehicle data visible)
I looked around a bit and didn't find anything of much use, just this discussion on BitBucket. I like the idea of some sort of open protocol to accommodate service-agnostic pull requests though.

If you find a good way to do this, please share.