Skip to main content


Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Language IDEs » Java Development Tools (JDT) » ClassCastException with Java compiler, but not with Eclipse compiler????
ClassCastException with Java compiler, but not with Eclipse compiler???? [message #1499633] Fri, 05 December 2014 09:27 Go to next message
Mathieu MARCIACQ is currently offline Mathieu MARCIACQFriend
Messages: 4
Registered: December 2014
Junior Member
Hi.

I have a curious thing.
See the small attached java file.

	public static void test(List<Long> list) {

		for (Object keyId : list) {
			Long id;
			if (keyId instanceof String)
				id = new Long((String) keyId);
			else
				id = (Long) keyId;
			System.out.println(id);
		}
	}

	public static void main(String[] args) {
		List list = new ArrayList<Object>();
		list.add("1234");
		list.add(1000L);
		test(list);
	}


(No comments, I know this code is *BAD*)

Theses few lines compiles without problems (except warning)
If I compile this with Eclipse, and run it, no problem. All works.
But if I compile this with javac, and run it, I get a ClassCastException.

I'm seeking for a way to have Eclipse compiler behave 100% like javac compiler.
And so, to compile to a code that will throw the ClassCastException too....

Any hint ?

Thanks for your help.
Re: ClassCastException with Java compiler, but not with Eclipse compiler???? [message #1500316 is a reply to message #1499633] Fri, 05 December 2014 21:54 Go to previous messageGo to next message
Stephan Herrmann is currently offline Stephan HerrmannFriend
Messages: 1853
Registered: July 2009
Senior Member
That's a really weird thing you're trying to achieve.

First: The only compilers generating the code that trows CCE are javac 1.5 and javac 1.6.
Starting with version 1.7, javac agrees with ecj and no exception is raised.

Background: the CCE in javac-1.5-compiled code stems from the head of the loop:
for (Object keyId : list) {

The compiler knows that list contains Long instances (that's how it's declared) hence the javac 1.5 compiler feels obliged to cast the result of Iterator.next() - which at bytecode level has type Object - to the declared Long. Perfectly legal, but unnecessary, because the program is not interested in knowing that keyId is a Long.

Modern compilers optimize the code as to avoid casts that are definitely unnecessary.

If you really want to see the exception (which makes sense as it makes your program fail fast, rather than propagating erroneous values), you could try to change the loop header to:
for (Long keyId : list) {

Now the compilers no longer regard the cast as unnecessary and all will create the code that throws CCE at runtime.
However, with this modification, the compiler will also detect that the subsequent code is bogus:
----------
1. ERROR in /tmp/TestCast.java (at line 10)
        if (keyId instanceof String)
            ^^^^^^^^^^^^^^^^^^^^^^^
Incompatible conditional operand types Long and String
----------
2. ERROR in /tmp/TestCast.java (at line 11)
        id = new Long((String) keyId);
                      ^^^^^^^^^^^^^^
Cannot cast from Long to String
----------


Having a CCE at the loop header means, the subsequent code will never be entered with a String value. Hence the if-then part is nonsense, and a good compiler will detect that, unless you trick the compiler with declaring keyId as Object.

best,
Stephan



Re: ClassCastException with Java compiler, but not with Eclipse compiler???? [message #1504373 is a reply to message #1499633] Tue, 09 December 2014 07:42 Go to previous messageGo to next message
Mathieu MARCIACQ is currently offline Mathieu MARCIACQFriend
Messages: 4
Registered: December 2014
Junior Member
Hi.

Thanks for your reply....

Yes, I know it's weird.....But it is very old code....And my concern is only to know WHY it works with Eclipse, and not with Java.....(We will adapt the code to make it look good)

Your explain about Java version looks good......But there is still something curious....
Java & JavaC used as standalone here are version 1.6. So I understand that an exception is raised.
But Eclipse is configured to use 1.6 in Java Compiler settings ? So it should raise too an exception.....?

Any idea ?
Re: ClassCastException with Java compiler, but not with Eclipse compiler???? [message #1504567 is a reply to message #1504373] Tue, 09 December 2014 11:11 Go to previous messageGo to next message
Stephan Herrmann is currently offline Stephan HerrmannFriend
Messages: 1853
Registered: July 2009
Senior Member
It's javac versions 1.5 and 1.6 that cause the problematic behavior.
Eclipse doesn't use javac - when I mentioned "ecj" this stands for "Eclipse Compiler for Java".
No mystery involved.
S.
Re: ClassCastException with Java compiler, but not with Eclipse compiler???? [message #1504572 is a reply to message #1504567] Tue, 09 December 2014 11:19 Go to previous messageGo to next message
Mathieu MARCIACQ is currently offline Mathieu MARCIACQFriend
Messages: 4
Registered: December 2014
Junior Member
Ok ! Thanks for your answer, it's now clear.

Stupid question : Is there any way to change Eclipse compiler behavior? And get the exception with Eclipse too ?
Re: ClassCastException with Java compiler, but not with Eclipse compiler???? [message #1504604 is a reply to message #1504572] Tue, 09 December 2014 11:54 Go to previous messageGo to next message
Stephan Herrmann is currently offline Stephan HerrmannFriend
Messages: 1853
Registered: July 2009
Senior Member
Mathieu MARCIACQ wrote on Tue, 09 December 2014 12:19

Stupid question :


I agree Razz

Quote:
Is there any way to change Eclipse compiler behavior? And get the exception with Eclipse too ?


I think the list of options in my initial response was pretty exhaustive. I might only add one more:
for (Object keyId : list) {
   Long unused = (Long) keyId;
   ...


S.


Re: ClassCastException with Java compiler, but not with Eclipse compiler???? [message #1504616 is a reply to message #1504604] Tue, 09 December 2014 12:04 Go to previous messageGo to next message
Mathieu MARCIACQ is currently offline Mathieu MARCIACQFriend
Messages: 4
Registered: December 2014
Junior Member
Yes, fully agree about getting error during code edition....

But as I said, I can't change code.....
What i was looking for is a way to get Eclipse have same compilation behavior as JavaC 1.6.....And so that when I run my test, I get the exception throwed.....
It's a very huge software, with this kind of errors potentially in multiple places, on which several peoples are involved.
At the moment, Eclipse only display a warning for such bad code.
And if the <evil> programmer does such bad programming, and ignore the warning, all will runs fine on Eclipse, he will never see that a problem will occurs on the final software version, compiled with JavaC....

So, understanding your answers, I don't have any way to get Eclipse behavior 100% same as JavaC on this point....So we will teach to the team to avoid this kind of programmation, and hope they will do it....

Thanks for your help!


Re: ClassCastException with Java compiler, but not with Eclipse compiler???? [message #1504647 is a reply to message #1504616] Tue, 09 December 2014 12:31 Go to previous message
Stephan Herrmann is currently offline Stephan HerrmannFriend
Messages: 1853
Registered: July 2009
Senior Member
Quote:
he will never see that a problem will occurs on the final software version, compiled with JavaC


You still have the option to compile the final software using ecj, to achieve consistency among development time and final build.
If, e.g., you build using maven, you may want to have a look at https://wiki.eclipse.org/Tycho/FAQ#Can_I_use_the_Tycho_compiler_support_in_non-OSGi_projects.2C_too.3F

Previous Topic:Custom Execution Environment
Next Topic:Consistency of development time vs. production builds
Goto Forum:
  


Current Time: Thu Mar 28 20:53:19 GMT 2024

Powered by FUDForum. Page generated in 0.03671 seconds
.:: Contact :: Home ::.

Powered by: FUDforum 3.0.2.
Copyright ©2001-2010 FUDforum Bulletin Board Software

Back to the top