It's not a secret anymore!*
The moose likes Java in General and the fly likes compiling code using different versions (jdk 1.3 and jdk 1.4) Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login


JavaRanch » Java Forums » Java » Java in General
Bookmark "compiling code using different versions (jdk 1.3 and jdk 1.4)" Watch "compiling code using different versions (jdk 1.3 and jdk 1.4)" New topic
Author

compiling code using different versions (jdk 1.3 and jdk 1.4)

Marilyn de Queiroz
Sheriff

Joined: Jul 22, 2000
Posts: 9046
    
  10
I am trying to compile some code using different versions (jdk 1.3 and jdk 1.4).

The problem is that I am implementing Connection. In version 1.4, Connection includes methods that use a "Savepoint" (a new interface only found in v1.4). If I implement those methods, I can compile using v1.4 but not v1.3 (since 1.3 doesn't have a Savepoint interface). If I don't implement those methods, I can compile using 1.3 but not 1.4 because the class must be declared abstract since all the methods of the interface haven't been implemented.

Is there any way to resolve this and allow compilation in both versions?


JavaBeginnersFaq
"Yesterday is history, tomorrow is a mystery, and today is a gift; that's why they call it the present." Eleanor Roosevelt
Michael Morris
Ranch Hand

Joined: Jan 30, 2002
Posts: 3451
Is it a single class that implements Connection, and how many other classes are associated with it/them? According to how decoupled the affected classes are, it would seem that you could use one of the GOF Creational Patterns to defer until runtime the implementation of one version or the other.


Any intelligent fool can make things bigger, more complex, and more violent. It takes a touch of genius - and a lot of courage - to move in the opposite direction. - Ernst F. Schumacher
Michael Morris
Ranch Hand

Joined: Jan 30, 2002
Posts: 3451
After further thought, the problem is compiletime not runtime. Tough problem.
Marilyn de Queiroz
Sheriff

Joined: Jul 22, 2000
Posts: 9046
    
  10
Is it a single class that implements Connection, and how many other classes are associated with it/them?

It is a single (inner) class.
Michael Morris
Ranch Hand

Joined: Jan 30, 2002
Posts: 3451
This is just a shot in the dark, but have you thought about compiling both with the 1.4 compiler and using the -target flag when compiling for 1.3?
For example:
javac -target 1.3 MyConnectionClass.java.
I tried a test class using Savepoint and it compiled without complaint. I also thought about using a custom ClassLoader, but if you try to define a class that starts with "java." a SecurityException is thrown.
Marilyn de Queiroz
Sheriff

Joined: Jul 22, 2000
Posts: 9046
    
  10
Yeah, I tried defining my own Savepoint class, but the compiler didn't like that.

The idea is that we want to post the source and let everyone compile their own version. Some people don't have v1.4 so it seems that using the -target idea wouldn't work in this instance.
[ June 07, 2003: Message edited by: Marilyn de Queiroz ]
Jim Yingst
Wanderer
Sheriff

Joined: Jan 30, 2000
Posts: 18671
The idea is that the people who have 1.3 wouldn't need to use the target option - they'd compile for 1.3 automatically. The question is - can someone with 1.4 compile the code using the -target 1.3 option? (Assuming the code is written for the 1.3 Connection.) I suspect the answer is no, that -target controls some details of the class file format, but not all the libraries which come with the JDK. In fact I believe that the default for -target is 1.2, meaning class files can run on JDK 1.2 - IF they don't use anything in the library that's specific to later JDKs. I might be wrong though.
I don't know a good solution here. I remember something sorta similar from using collections under 1.1 and 1.2 - for 1.1 you had to download an extra jar file, and there were some subtle differences between that code and the collections in 1.2, so it was difficult to get code to work in both environments - we kept having to make minor edits.
I see two possibilities. One: write the code for 1.3 only. Provide a jar file which was generated using 1.3. Others using 1.4 will be able to use it fine, as long as they don't try to use any 1.4-specific Connection methods. (This would give NoSuchMethodError.) They can recompile most of the project fine using 1.4 as long as there's a class file for your 1.3 Connection implementation somewhere in their path (PRIOR to the .java file for that class; we don't want that found and recompiled). However if they want to recompile the Connection implementation itself, they will have to use 1.3 for that. This is annoying but possible - most people who use 1.4 could run 1.3 in the same environment if they needed to, but the reverse may not be true. Most of the time it won't even come up because they can just use the jar you provide - how often will they really need to recompile that particular class? The bigger problem is if their code integrates with other packages that want to use the 1.4 Connection features - they may not have as much control as they'd like over what methods are getting called on Connection.
Option two: fork the source. Provide two different versions of your program, e.g. Jenny 1.0
which works with JDK 1.3, and Jenny 1.1 which works with JDK 1.4. Users just choose the version they want, download it, and everything works great for them. The downside is it's more work for you to manage and maintain two different versions. A good CVS tool will probably help here.
I'm inclined to vote for option two. But maybe there's some more elegant solution that I missed; I hope so.


"I'm not back." - Bill Harding, Twister
Steve Fahlbusch
Bartender

Joined: Sep 18, 2000
Posts: 563
    
    7

Greetings,
Don't know if this helps but....
Why not write your own Savepoint that is packaged very similarly to the 1.4 and place that in some jar. Have 1.3 users complile using the bootclasspath option that includes both the 1.3 core classes and your jar. 1.4 users would just compile as normal (whatever that is).
-steve
Vlad Roubtsov
Greenhorn

Joined: Jun 14, 2003
Posts: 9
Originally posted by Michael Morris:
This is just a shot in the dark, but have you thought about compiling both with the 1.4 compiler and using the -target flag when compiling for 1.3?
For example:
javac -target 1.3 MyConnectionClass.java.
I tried a test class using Savepoint and it compiled without complaint. I also thought about using a custom ClassLoader, but if you try to define a class that starts with "java." a SecurityException is thrown.

This will not help the original poster but -target does not do what you think. Check out What version is your Java code? for what that does.
Regarding the original problem I think the most correct approach is to not split the source but instead split the build so that Connection source file and any of its 1.3-only dependents are compiled using javac 1.4 but against 1.3 API:
...\jdk1.4.1\bin\javac -target 1.3 -bootclasspath ...\jdk1.3.1\jre\lib\rt.jar ...
[the rest of the sources are compiled using javac 1.4.1 with default parameters]
[ June 14, 2003: Message edited by: Vlad Roubtsov ]

<a href="http://emma.sourceforge.net" target="_blank" rel="nofollow">EMMA</a>: an open-source code coverage toolkit
Michael Morris
Ranch Hand

Joined: Jan 30, 2002
Posts: 3451
Hi Vlad,
Welcome to JavaRanch. I figured that was a long shot. The problem is, as Marilyn stated, the software in question is for JavaRanchers. Some still are using JDK 1.3, so your solution would not work without forcing everyone to install 1.4. But if you do that then the original problem vanishes. This sort of problem makes me wonder about the wisdom of not having conditional compiles in java. The problem, like overloading operators is that it is easy to abuse it. How many of us old farts have seen ugly code full of #if defined constucts that were very hard to follow?
David Weitzman
Ranch Hand

Joined: Jul 27, 2001
Posts: 1365
Over at the hsqldb project I recall seeing something called CodeSwitcher that they use to switch between several versions of the source (at least they did last time I used hsqldb).
I never really examined it, but it looks like a sort of really basic C preprocessor emulator.
You could probably implement your own system if you want. For example, you could have an input file that looks like this:

And then you'd call "java MyCoolPreprocessor -version 1.2 [dir]" and it might be modified to read

Then you might call "java MyCoolPreprocessor -version 1.2 [dir]" and it would turn back into the original. Just don't put any C-style comments in the middle of that block.
[ June 15, 2003: Message edited by: David Weitzman ]
Marilyn de Queiroz
Sheriff

Joined: Jul 22, 2000
Posts: 9046
    
  10
This problem arose because someone had 1.4 on their personal computer, but was required to use 1.3 at work.

It seems that there is no simple solution.
Michael Morris
Ranch Hand

Joined: Jan 30, 2002
Posts: 3451
This problem arose because someone had 1.4 on their personal computer, but was required to use 1.3 at work.
If that is the only problem, then maybe Vlad's solution would work. The only caveat would be that you would have to have the 1.3 jar and a 1.4 compiler for the build.
 
Consider Paul's rocket mass heater.
 
subject: compiling code using different versions (jdk 1.3 and jdk 1.4)