Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Java > Substituting Java API classes for enhanced functionality (e.g. java.io.File)

Reply
Thread Tools

Substituting Java API classes for enhanced functionality (e.g. java.io.File)

 
 
Christian Schlichtherle
Guest
Posts: n/a
 
      07-02-2005
Hi,

I have written a substitute for some java.io.* classes. My classes treat ZIP
or JAR files exactly like directories, so that you can e.g. list ZIP files
and arbitrarily read or write or delete their entries. My substitutes have
the same name as in the java.io package, but live in their own package (e.g.
de.schlichtherle.io.File instead of java.io.File). This provides 98% source
code compatibility - most of the time a simple import statement at the top
of a using class is enough to use the new functionality.

To achieve 100% compatibility I would like to provide a modified classloader
which loads my classes instead of the java.io.* classes. This is not a
problem, as their is enough documentation on how to do it (basically you
only need to override the loadClass(...) method). However, my classes
delegate to the original java.io.* classes when e.g. encountering ordinary
files.

So how can I make an application using my classes as java.io.* when at the
same time my classes need to delegate to the original java.io.* classes???

Any hints would be helpful.

With best regards,
Christian


 
Reply With Quote
 
 
 
 
Dale King
Guest
Posts: n/a
 
      07-02-2005
Christian Schlichtherle wrote:
> Hi,
>
> I have written a substitute for some java.io.* classes. My classes treat ZIP
> or JAR files exactly like directories, so that you can e.g. list ZIP files
> and arbitrarily read or write or delete their entries. My substitutes have
> the same name as in the java.io package, but live in their own package (e.g.
> de.schlichtherle.io.File instead of java.io.File). This provides 98% source
> code compatibility - most of the time a simple import statement at the top
> of a using class is enough to use the new functionality.
>
> To achieve 100% compatibility I would like to provide a modified classloader
> which loads my classes instead of the java.io.* classes. This is not a
> problem, as their is enough documentation on how to do it (basically you
> only need to override the loadClass(...) method). However, my classes
> delegate to the original java.io.* classes when e.g. encountering ordinary
> files.
>
> So how can I make an application using my classes as java.io.* when at the
> same time my classes need to delegate to the original java.io.* classes???


Better reread the license for Java again. You'll find that such a thing
would violate the license agreement:

"Sun grants you a non-exclusive, non-transferable, limited license
without fees to reproduce and distribute the Software, provided that...
(iii) you do not distribute additional software intended to replace any
component(s) of the Software..."

--
Dale King
 
Reply With Quote
 
 
 
 
Patricia Shanahan
Guest
Posts: n/a
 
      07-02-2005
Dale King wrote:
> Christian Schlichtherle wrote:
>
>> Hi,
>>
>> I have written a substitute for some java.io.* classes. My classes
>> treat ZIP or JAR files exactly like directories, so that you can e.g.
>> list ZIP files and arbitrarily read or write or delete their entries.
>> My substitutes have the same name as in the java.io package, but live
>> in their own package (e.g. de.schlichtherle.io.File instead of
>> java.io.File). This provides 98% source code compatibility - most of
>> the time a simple import statement at the top of a using class is
>> enough to use the new functionality.
>>
>> To achieve 100% compatibility I would like to provide a modified
>> classloader which loads my classes instead of the java.io.* classes.
>> This is not a problem, as their is enough documentation on how to do
>> it (basically you only need to override the loadClass(...) method).
>> However, my classes delegate to the original java.io.* classes when
>> e.g. encountering ordinary files.
>>
>> So how can I make an application using my classes as java.io.* when at
>> the same time my classes need to delegate to the original java.io.*
>> classes???

>
>
> Better reread the license for Java again. You'll find that such a thing
> would violate the license agreement:
>
> "Sun grants you a non-exclusive, non-transferable, limited license
> without fees to reproduce and distribute the Software, provided that...
> (iii) you do not distribute additional software intended to replace any
> component(s) of the Software..."
>


In addition to the license, there is a strong program readability
objection to replacing java.lang classes.

A reasonable Java programmer, seeing e.g. "import java.io.File;" at the
top of a program, would expect references to type File in the code to
mean the one in the normal API libraries.

They would expect, for example, to be able to use features of a later
version of File by merely installing a new JDK/JRE, with a new rt.jar.
They would look at the Sun-distributed source code when trying to
understand a NullPointerException with a java.io.File method in the
stack trace.

Patricia
 
Reply With Quote
 
Christian Schlichtherle
Guest
Posts: n/a
 
      07-02-2005
Hi,

I'm not breaking any of these statements as I would not redistribute Sun's
JDK/JRE. My classes would simply be distributed as part of an application or
a JAR library which requires the separately provided JDKJRE to run. There is
actually no difference to any other application or library.

Regards,
Christian

"Dale King" <(E-Mail Removed)> schrieb im Newsbeitrag
newsqyxe.124533$nG6.98353@attbi_s22...
> Christian Schlichtherle wrote:
>> Hi,
>>
>> I have written a substitute for some java.io.* classes. My classes treat
>> ZIP or JAR files exactly like directories, so that you can e.g. list ZIP
>> files and arbitrarily read or write or delete their entries. My
>> substitutes have the same name as in the java.io package, but live in
>> their own package (e.g. de.schlichtherle.io.File instead of
>> java.io.File). This provides 98% source code compatibility - most of the
>> time a simple import statement at the top of a using class is enough to
>> use the new functionality.
>>
>> To achieve 100% compatibility I would like to provide a modified
>> classloader which loads my classes instead of the java.io.* classes. This
>> is not a problem, as their is enough documentation on how to do it
>> (basically you only need to override the loadClass(...) method). However,
>> my classes delegate to the original java.io.* classes when e.g.
>> encountering ordinary files.
>>
>> So how can I make an application using my classes as java.io.* when at
>> the same time my classes need to delegate to the original java.io.*
>> classes???

>
> Better reread the license for Java again. You'll find that such a thing
> would violate the license agreement:
>
> "Sun grants you a non-exclusive, non-transferable, limited license without
> fees to reproduce and distribute the Software, provided that... (iii) you
> do not distribute additional software intended to replace any component(s)
> of the Software..."
>
> --
> Dale King



 
Reply With Quote
 
Christian Schlichtherle
Guest
Posts: n/a
 
      07-02-2005
Hi,

please note that no application could use this code just by accident. There
needs to be some static method call in front to replace the genuine
java.io.File by installing a custom class loader for the running thread. It
would actually work a bit like installing pluggable UI classes for Swing.
Thus, whoever uses it does know that he is not dealing with a genuine
java.io.File.

Second, if someone wants to upgrade to a new JDK/JRE, fine: Just do it and
my replacement classes will delegate to the updated JDK/JRE when needed
(e.g. when working on ordinary files rather than ZIP files), so there is no
need to worry about this.

Third, thanks to the delegation, the whole API is tested to be 100% backward
compatible with JDK 1.4.2 and JDK 1.5.0. Whatever you do with ordinary files
and directories, my API will behave exactly the same as the genuine
java.io.* classes (including exception throwing).

Thinking in layers, here is how it works in terms of program flow:

Application code -> substituted java.io.* -> genuine java.io.* (residing in
rt.jar)

As you can see, the rt.jar is not touched (reengineered or whatever) at all.
My substitute is just an add-on. It needs to be installed once by any
application who wants to use its enhanced features.

Regards,
Christian

"Patricia Shanahan" <(E-Mail Removed)> schrieb im Newsbeitrag
news:iAyxe.3000$(E-Mail Removed) nk.net...
> Dale King wrote:
>> Christian Schlichtherle wrote:
>>
>>> Hi,
>>>
>>> I have written a substitute for some java.io.* classes. My classes treat
>>> ZIP or JAR files exactly like directories, so that you can e.g. list ZIP
>>> files and arbitrarily read or write or delete their entries. My
>>> substitutes have the same name as in the java.io package, but live in
>>> their own package (e.g. de.schlichtherle.io.File instead of
>>> java.io.File). This provides 98% source code compatibility - most of the
>>> time a simple import statement at the top of a using class is enough to
>>> use the new functionality.
>>>
>>> To achieve 100% compatibility I would like to provide a modified
>>> classloader which loads my classes instead of the java.io.* classes.
>>> This is not a problem, as their is enough documentation on how to do it
>>> (basically you only need to override the loadClass(...) method).
>>> However, my classes delegate to the original java.io.* classes when e.g.
>>> encountering ordinary files.
>>>
>>> So how can I make an application using my classes as java.io.* when at
>>> the same time my classes need to delegate to the original java.io.*
>>> classes???

>>
>>
>> Better reread the license for Java again. You'll find that such a thing
>> would violate the license agreement:
>>
>> "Sun grants you a non-exclusive, non-transferable, limited license
>> without fees to reproduce and distribute the Software, provided that...
>> (iii) you do not distribute additional software intended to replace any
>> component(s) of the Software..."
>>

>
> In addition to the license, there is a strong program readability
> objection to replacing java.lang classes.
>
> A reasonable Java programmer, seeing e.g. "import java.io.File;" at the
> top of a program, would expect references to type File in the code to
> mean the one in the normal API libraries.
>
> They would expect, for example, to be able to use features of a later
> version of File by merely installing a new JDK/JRE, with a new rt.jar.
> They would look at the Sun-distributed source code when trying to
> understand a NullPointerException with a java.io.File method in the
> stack trace.
>
> Patricia



 
Reply With Quote
 
Patricia Shanahan
Guest
Posts: n/a
 
      07-02-2005
Christian Schlichtherle wrote:
> Hi,
>
> please note that no application could use this code just by accident. There
> needs to be some static method call in front to replace the genuine
> java.io.File by installing a custom class loader for the running thread. It
> would actually work a bit like installing pluggable UI classes for Swing.
> Thus, whoever uses it does know that he is not dealing with a genuine
> java.io.File.


I've done a lot of maintenance work, so I tend to think about
programming in terms of picking up a large, unfamiliar program and
attempting a bug fix or feature extension, rather than writing a program
from scratch. In my model of programming, some other programmer, who I
may never have met, did the work to use your code before I even knew the
application existed. Even when I am writing from scratch, that model
influences my programming.

Most interesting programs are far too large for me to completely read
and understand them before starting productive work. The better a
programming style supports selective reading the better I like it.

I would not expect to need to read the application initialization flow
to understand what a java.io class does, for a Zip file or for any other
sort of file. I find that out by reading the java.io javadocs.

The requirement to put a distinguishing import statement in each file
that depends on your package is a valuable feature, not a bug. The
frustrating thing is that, with the import, your package looks very
useful. Without it, it opens up fresh fields for code obfuscation in java.

> Second, if someone wants to upgrade to a new JDK/JRE, fine: Just do it and
> my replacement classes will delegate to the updated JDK/JRE when needed
> (e.g. when working on ordinary files rather than ZIP files), so there is no
> need to worry about this.


How do you make sure the JVM will not object when I call a method that
was added to a java.io class, say around JDK 1.8.2, but does not exist
in the corresponding class in your package?

On the licensing issue, how to do you interpret item C in "SUPPLEMENTAL
LICENSE TERMS", in the JDK 1.5 license?

Patricia
 
Reply With Quote
 
Christian Schlichtherle
Guest
Posts: n/a
 
      07-02-2005

"Patricia Shanahan" <(E-Mail Removed)> schrieb im Newsbeitrag
news:9LBxe.86$(E-Mail Removed). net...
> I would not expect to need to read the application initialization flow
> to understand what a java.io class does, for a Zip file or for any other
> sort of file. I find that out by reading the java.io javadocs.


Although I understand your point (cause I do have the same experience), I'ld
like to add something: Your criticism applies the same to the pluggable L&F
of Swing and any other pluggable code based on Reflection. This feature
really does make code harder to debug und understand, but looking at all the
plugin code and all sorts of *Beans stuff, I also think that this kind of
"dynamic linking" is one of the core advantages of Java compared to e.g.
C++. Without this ability, we wouldn't have (Enterprise) JavaBeans or SPI
code (like in the java.security package) at all. In essence, Java wouldn't
be Java.

>> Second, if someone wants to upgrade to a new JDK/JRE, fine: Just do it
>> and my replacement classes will delegate to the updated JDK/JRE when
>> needed (e.g. when working on ordinary files rather than ZIP files), so
>> there is no need to worry about this.

>
> How do you make sure the JVM will not object when I call a method that
> was added to a java.io class, say around JDK 1.8.2, but does not exist
> in the corresponding class in your package?


That's a fair point: If the classloader approach would work, all that is
required for a normal application is to compile the code against the java.io
package. If that changes, my plugin code would need to change as well. I
might be able to provide this through the use of the Proxy class, but still
this would leave the opportunity of my code to yield new methods which do
not behave correctly when used within ZIP files.

> On the licensing issue, how to do you interpret item C in "SUPPLEMENTAL
> LICENSE TERMS", in the JDK 1.5 license?


I would not (re)distribute JREs or JDKs, so that term doesn't apply at all.

After all, the point about maintainability makes me rethink the strategy
again: The existing de.schlichtherle.io package works fine for about nine
months in daily use. But as it needs to inherit from java.io.File (in order
for a JFileChooser to browse ZIP files), there are some subtle traps which I
hoped to escape by turning the package into a pluggabe replacement for the
java.io package...

With best regards,
Christian


 
Reply With Quote
 
Joan
Guest
Posts: n/a
 
      07-03-2005

"Christian Schlichtherle" <(E-Mail Removed)> wrote in message
news:da5pcf$l7i$(E-Mail Removed)...
> Hi,
>
> I have written a substitute for some java.io.* classes. My classes treat

ZIP
> or JAR files exactly like directories, so that you can e.g. list ZIP files
> and arbitrarily read or write or delete their entries.


Why bother, microsoft "explorer" does this already.

> My substitutes have
> the same name as in the java.io package, but live in their own package

(e.g.
> de.schlichtherle.io.File instead of java.io.File). This provides 98%

source
> code compatibility - most of the time a simple import statement at the top
> of a using class is enough to use the new functionality.
>
> To achieve 100% compatibility I would like to provide a modified

classloader
> which loads my classes instead of the java.io.* classes. This is not a
> problem, as their is enough documentation on how to do it (basically you
> only need to override the loadClass(...) method). However, my classes
> delegate to the original java.io.* classes when e.g. encountering ordinary
> files.
>
> So how can I make an application using my classes as java.io.* when at the
> same time my classes need to delegate to the original java.io.* classes???
>
> Any hints would be helpful.
>
> With best regards,
> Christian
>
>



 
Reply With Quote
 
John Currier
Guest
Posts: n/a
 
      07-04-2005
What does your File.isFile() and isDirectory() return? Do they both
return true?

John
http://schemaspy.sourceforge.net

 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
regular expressions, substituting and adding in one step? John Salerno Python 6 05-10-2006 01:52 PM
Substituting AOL Wav files with MSN Wav files Thaqalain Computer Support 6 07-07-2005 08:17 PM
Python to C++ conversion substituting vectors for lists in a recursive function lugal Python 2 03-23-2005 02:51 PM
substituting lighting changes for software edit David Virgil Hobbs Digital Photography 1 11-18-2004 06:31 PM
substituting values in property file Andy Fish Java 2 12-29-2003 05:11 PM



Advertisments