3

I have been stuck in quite awkward situation in my program. The case is that... my project is having some A.jar file in classpath which packs many important utility classes..but this A.jar is quite old file and we cant replace this as we are not sure how and what importance it holds.... Now, i need the method request.setCharacterencoding() & response.setCharacterEncoding from ServletResponse I/F but this A.jar contains the old version of ServletResponse and due to which I am not getting the above two methods.. Now i have introduced new servlet-api.jar in classpath but still my project is taking the reference of servletResponse class from A.jar and not from new servlet-api.jar.

Can you guys, please suggest me a way to get the reference of new servletResponse from servlet-api.jar rather than A.jar

(P.s. : I can not remove/modify the A.jar)

Thanks...

abhinav
  • 3,199
  • 2
  • 21
  • 25
Rogger296
  • 147
  • 3
  • 15
  • You could use a custom class loader and use that one to load the class from servlet-api and then get it from there. This might be hard to do on your own, though. If you're running on an application server (e.g. JBoss, Websphere, Glassfish etc.) you could look into how its class loading strategy could support you there. – Thomas Dec 20 '11 at 08:07
  • This question might help you: http://stackoverflow.com/q/252893/644766 – melihcelik Dec 20 '11 at 08:11
  • Or this one: http://stackoverflow.com/q/60764/644766 – melihcelik Dec 20 '11 at 08:11

6 Answers6

5

When you run the jar file, make the classpath reflect the order of the jars you want loaded. Let me know if you need to exact syntax, but in general, if you have CLASSPATH=patch16.jar:patch15.jar:patch14.jar:... etc, it will load the first matching copy of the class, starting with patch16.jar then patch15.jar etc.

More info on exact syntax: http://javarevisited.blogspot.com/2011/01/how-classpath-work-in-java.html

LazyCubicleMonkey
  • 1,213
  • 10
  • 17
  • 2
    -1 This doesn't answer the question: Rearranging the classpath doesn't help, because there cross dependencies –  Dec 20 '11 at 08:13
  • Then you'd have to re-compile the code anyway. (Or make sure you overwrite all the old classes with new ones in the new jar to avoid any dependency issue). Also, the classpath can be set in a start script to retain portability. – LazyCubicleMonkey Dec 20 '11 at 08:21
  • You are seriously missing the point. Setting the classpath can *never* fix this problem, because some classes common to both jars he wants from A.jar and some from B.jar. Logic tells you that no matter how you set the classpath, you can never satisfy this requirement. You actually don't have to recompile either (java links dynamically... that's why he *has* this problem), but you do have to provide the JVM with a custom class loader - which will involve recompiling, but only of the custom class loader. –  Dec 21 '11 at 13:04
1

Have servlet-api.jar come before A.jar in your classpath.

However, your problems are not all solved! What does something in A.jar do if it expects the old implementation of the Servlet API, but the new one has been loaded? Or what happens when somebody else doesn't have the classpath in the same order?

You may be better off unzipping A.jar and repackaging it as A-modified.jar

Flwyd
  • 141
  • 1
  • 5
1

Actually JVM looks for classes sequentially trying load them from resources from the list. If for example, your classpath looks like new.jar;old.jar and both jars have different versions of the same class the version from new.jar will be used.

Please pay attention that if you are on Unix use : instead of ;.

But may I express my doubt. Something sounds wrong in your project. Why do you have ServletRequest in your custom jar? I should use standard j2ee.jar or something like that to get this kind of standard classes from. As far as I know there is only 1 method that was removed from servlet API during the last 12 years: ability to peform servlet-to-servlet communication. And this happened about 10 years ago. So if you are using the latest version standard servlet API everything including old code should work.

AlexR
  • 114,158
  • 16
  • 130
  • 208
  • Hi Alex, As the project is quite old and it contains many other small modules in it so may be for that purpose they have created this A.jar having all utility classes in it.(still i am not sure) – Rogger296 Dec 20 '11 at 08:43
  • Thank u all for your quick suggestions.. Finally I resolved it by putting the servlet-api.jar first in the classpath and then other files... – Rogger296 Dec 20 '11 at 15:07
0

Simple solution, if these two ServletRqquest are in different package, just don't import the legacy one but access it with full package name. Or you have to write your own class load to load that jar.

pinxue
  • 1,736
  • 12
  • 17
0

The only way I see is to get or create a ClassLoader, then get your content of your class as a byte array, then load your class.

belgther
  • 2,544
  • 17
  • 15
0

Without doing anything special, you'd be screwed: Classes are loaded in the order they are found in the classpath.

However, you can write a custom ClassLoader that can take special action for the classes you need, specifically in this case loading ServletResponse from servlet-api.jar, otherwise having A.jar in the classpath before servlet-api.jar

p.s. Find out whoever created a class with the same package and name as ServletRequest and kill them.

Bohemian
  • 412,405
  • 93
  • 575
  • 722