3

I am working on a project in which for few functionalities POI 2.5 version jars is being used and i have develop a new functionality for which i require POI version 3.10 jars so now the issue is that previous functionality is not working properly as it is working perfectly on poi 2.5 version jar

now if i keep both the versions of poi jars in my class path is there any way by which only for my classes i can call poi 3.10 version explicitly and for the previous functionality poi 2.5 version is being called

by default if i keep both the versions of poi jars then always the call goes in poi 2.5 versions of jar so i want for my class say class abc explicitly poi 3.10 version is being called

Please advise can i use class loaders explicitly here and also please advise is it possible if i can create the object of class dynamically also

class ABC 
{

//version of poi 3.10 being called here 
HSSFWorkbook workbookXls = new HSSFWorkbook();

}

class def which is being using earlier version of POI 2.5

class DEF
{

//version of poi 2.5 being called here 
HSSFWorkbook workbookXls = new HSSFWorkbook();

}
sss
  • 161
  • 1
  • 1
  • 13
  • 4
    This is not easily possible. It can be done with for example OSGi, but that is not simple. It will probably be easier to modify the code so that it needs only one version of POI instead of two versions at the same time. – Jesper Mar 03 '16 at 15:53
  • please advise is not there any way in java then.. – sss Mar 03 '16 at 16:17
  • also please advise how it is possible through OSGI – sss Mar 03 '16 at 16:22
  • 1
    This could help you: http://stackoverflow.com/questions/6105124/java-classpath-classloading-multiple-versions-of-the-same-jar-project/6108133#6108133 – Luca Putzu Mar 03 '16 at 16:24
  • Not very easy, IMO. If you really need to support two versions of POI, then I would introduce a server component to handle one of them. The server would run with another classpath, – DAB Mar 03 '16 at 16:34
  • 1
    You absolutely can do it with [separate classloaders](https://dzone.com/articles/java-classloader-handling), but it isn't a very clean way of doing it and you might run into a few unexpected problems. (Particularly around the class loader hierarchy and who gets to load a class first.) – biziclop Mar 03 '16 at 16:47
  • Can you please show how this can be achieved through class loaders if possible please show in my above piece of code Thanks in advance – sss Mar 03 '16 at 16:54
  • OSGi is a module framework, not something that can be explained very quickly here. It's not a quick or simple fix for your problem. You'd have to write your whole app in the form of OSGi modules. – Jesper Mar 03 '16 at 18:38
  • As the [accepted answer](http://stackoverflow.com/a/6108133/17300) from the linked question points out _"Classloader related problems are a quite complex matter."_ This is an _advanced_ topic which cannot be taught in an answer to your question here, and nobody is going to write your code _for you_, as you seem to be asking in your comment on idelvall's answer. If you study the topic yourself and have _specific_ questions about it, those would be appropriate to ask here on SO. Same goes for OSGI, as Jesper mentions. – Stephen P Mar 04 '16 at 01:00

1 Answers1

1

Yes this can be done, loading each jar from a different classloader.

  1. Move both jars out from your current classpath
  2. Create a URLClassLoader for each of them jar, with your actual classloader as parent
  3. Use reflection to deal with POI

You can also refactor one the jars to change its packages and avoid collisions. This can be done automatically if your are using maven with the jar-jar MOJO.

idelvall
  • 1,536
  • 15
  • 25
  • Thanks request you to please show how we can create a url class loader with actual class loader as parent and then use g reflection thanks in advance – sss Mar 04 '16 at 00:18