You are not logged in.

Dear visitor, welcome to Jabaco - Community. If this is your first visit here, please read the Help. It explains in detail how this page works. To use all features of this page, you should consider registering. Please use the registration form, to register here or read more information about the registration process. If you are already registered, please login here.

jbExplorer

Trainee

  • "jbExplorer" started this thread

Posts: 111

Date of registration: Mar 18th 2013

  • Send private message

1

Wednesday, January 1st 2014, 9:31pm

Using External Jars without including them in the Jabaco project

If for performance reasons during compilation, you would like to load some methods from external Jars at runtime, without including them in the Jabaco classpath, here is one way.

The attached project is on my hard drive, at c:\Projects_Programming\Jabaco\ExternalJars. The jcl.jar file in the zip archive, is from

https://github.com/kamranzafar/JCL.


You will also need to obtain the log4j-1.2.17.jar, from an archive at

http://www.apache.org/dyn/closer.cgi/log…og4j-1.2.17.zip


, and include it in the classpath of the Jabaco project.


I haven't tested this with ALL kinds of jars, but here is a simple way of executing the sayWhatthe() method, from WhattheWorld.jar, without including WhattheWorld.jar as part of the Jabaco project.
jbExplorer has attached the following file:
  • ExternalJars.zip (21.73 kB - 171 times downloaded - latest: Sep 8th 2019, 12:49am)

theuserbl

Intermediate

Posts: 436

Date of registration: Dec 20th 2008

  • Send private message

2

Thursday, January 2nd 2014, 4:42pm

Great. It is fantastic!

Thanks for the link.

It is a small nice library, where the jar-file isn't too big with 17'311 bytes. But it makes use of log4j which is in version 1.2.17 a 489'883 byte jar-file 8|
Seems that the logging part have to be removed from jcl. :)


Currently I am looking, how your example program can be used for reflection:

Jabaco Source

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
Public Sub main(ByJava args() As String)
   Dim myArgs() As String
   Dim jclWhatThe As JarClassLoader
   Dim oWhatThe As Object
   
   myArgs = args
    
   System.out.println( "Here we go..." )
   
   System.out.println( "Creating instance of JarClassLoader" )
   jclWhatThe = New JarClassLoader() 

   System.out.println( "Adding the jar" )
   jclWhatThe.add( "WhattheWorld.jar" )

   System.out.println( "Loading the class" )
   oWhatThe = jclWhatThe.loadClass( "Module1" ).newInstance()
  
   CallByName oWhatThe, "showAllMethods"

   'showAllMethods()
   'showAllMethods("java.lang.String")

End Sub


Public Sub showAllMethods()   'Public Sub showAllMethods(ClassName As String )
  'Dim ClassName As String = "java.lang.String"
  Dim ClassName As String = "WhattheWorld"
  Dim cls As java#lang#Class =  java#lang#Class.forName(ClassName)
  Dim mets() As java#lang#reflect#Method
  
  'mets() = cls.getMethods
  mets() = cls.getDeclaredMethods
  
  Int i
  For i = 0 To Ubound(mets)
    System.out.println(mets(i))
  Next i
End Sub


Sadly it don't work.
Reflection is an important point for loaded jar-files. Normally you don't know all the class names nor all of the methods of the classes of a loaded jar-file.

The handling of the JarClassLoader seems to be itself similar to reflection.

I will continuesly playing around with it. Thanks again.

Greatings
theuserbl

theuserbl

Intermediate

Posts: 436

Date of registration: Dec 20th 2008

  • Send private message

3

Thursday, January 2nd 2014, 10:13pm

Here jcl without logger.

in JclWithoutLogger.zip are three files

- JclMod.jar (like the original jcl.jar, but without debug output and so without Apache Logger)
- JclModDebug.jar (like the original jcl.jar, without Apache Logger)
- JclModSrc.jar (the source of JclModDebug.jar. JclMod.jar have the same source, only public static boolean DEBUG is in all calsses set to false)

So, the big logger, isnt needed.

Greatings
theuserbl
theuserbl has attached the following file:

theuserbl

Intermediate

Posts: 436

Date of registration: Dec 20th 2008

  • Send private message

4

Thursday, January 2nd 2014, 10:59pm

Ok, it is really normal reflection.

Jabaco Source

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
Public Sub main(ByJava args() As String)
   Dim myArgs() As String
   Dim jclWhatThe As JarClassLoader
   Dim oWhatThe As Object
   
   myArgs = args
    
   System.out.println( "Here we go..." )
   
   System.out.println( "Creating instance of JarClassLoader" )
   jclWhatThe = New JarClassLoader() 

   System.out.println( "Adding the jar" )
   jclWhatThe.add( "WhattheWorld.jar" )

   System.out.println( "Loading the class" )
   oWhatThe = jclWhatThe.loadClass( "WhattheWorld" ).newInstance()

   System.out.println( "Show all methods" )
  
   
   Dim cls As java#lang#Class = oWhatThe.getClass
   Dim mets() As java#lang#reflect#Method
  
   'mets() = cls.getMethods
   mets() = cls.getDeclaredMethods
  
   Int i
   For i = 0 To Ubound(mets)
     System.out.println(mets(i))
   Next i
 
End Sub

jbExplorer

Trainee

  • "jbExplorer" started this thread

Posts: 111

Date of registration: Mar 18th 2013

  • Send private message

5

Friday, January 3rd 2014, 2:17am

Ok, it is really normal reflection.

Jabaco Source

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
Public Sub main(ByJava args() As String)
   Dim myArgs() As String
   Dim jclWhatThe As JarClassLoader
   Dim oWhatThe As Object
   
   myArgs = args
    
   System.out.println( "Here we go..." )
   
   System.out.println( "Creating instance of JarClassLoader" )
   jclWhatThe = New JarClassLoader() 

   System.out.println( "Adding the jar" )
   jclWhatThe.add( "WhattheWorld.jar" )

   System.out.println( "Loading the class" )
   oWhatThe = jclWhatThe.loadClass( "WhattheWorld" ).newInstance()

   System.out.println( "Show all methods" )
  
   
   Dim cls As java#lang#Class = oWhatThe.getClass
   Dim mets() As java#lang#reflect#Method
  
   'mets() = cls.getMethods
   mets() = cls.getDeclaredMethods
  
   Int i
   For i = 0 To Ubound(mets)
     System.out.println(mets(i))
   Next i
 
End Sub
Yep, I'm sure the source for JCL makes use of native reflection, but it's packaged in a way that makes it easier to operate on modules which aren't initially loaded, or in the class path.

Thanks for removing the log requirements, will give it a try.

theuserbl

Intermediate

Posts: 436

Date of registration: Dec 20th 2008

  • Send private message

6

Friday, January 3rd 2014, 2:26am

Thanks for removing the log requirements, will give it a try.


I have now added a compiled version of JCL version2 from github.

It is at the beginning without the logging, but on the other side, it is itself a lot of bigger.

On github stands, that version 2 is faster, have more functions and so on.

So, here is version 2. The jar-file in the the zip-file, because it is not possible to upload a jar-file in this forum.

Greatings
theuserbl
theuserbl has attached the following file:
  • jcl2.zip (70.34 kB - 159 times downloaded - latest: Sep 10th 2019, 10:31am)

jbExplorer

Trainee

  • "jbExplorer" started this thread

Posts: 111

Date of registration: Mar 18th 2013

  • Send private message

7

Friday, January 3rd 2014, 11:30am

Thanks for removing the log requirements, will give it a try.


I have now added a compiled version of JCL version2 from github.

It is at the beginning without the logging, but on the other side, it is itself a lot of bigger.

On github stands, that version 2 is faster, have more functions and so on.

So, here is version 2. The jar-file in the the zip-file, because it is not possible to upload a jar-file in this forum.

Greatings
theuserbl
Will play with it today, thanks theuserbl.

theuserbl

Intermediate

Posts: 436

Date of registration: Dec 20th 2008

  • Send private message

8

Friday, January 3rd 2014, 8:46pm

More information about JarClassLoader:
Seems that the unloadClass()-method don't work correct.

But possible that it depends on the ClassLoader itself, which JarClassLoader is based on.

I have now read in the internet and as answer from the author of JarClassLoader, that changing a class in one JCL-instance is not possible.


What I mean with it:

For example, you have three external jar-files:
- mygui-1.2.jar
- mynet-0.4.jar
- mydb-1.1.jar

All jars are loaded with JarClassLoader (or if you doing it your own way with URLClassLoader or ClassLoader).
And for example you program makes use of some of the classes in each of the jar-files.

When you then plan, to change one of that jar-files with an other one (for example mynet-0.4.jar to mynet-0.5.jar) in a running system (without restarting the java-program), then it is not possible, to unload the net-classes and reload the newer version of it.

The only way, to load a new version of the same class is, to create a new instance of JarClassLoader.


So, if you have an instance of JarClassLoader called "jclWhatThe" and want to change the loaded mynet-0.4.jar to mynet-0.5.jar, then you have to remove all instances of classes, which are in mygui-1.2.jar, mynet-0.4.jar and mydb-1.1.jar.
After that creating a new instance of JarClassLoader (for example, writing "jclWhatThe = New JarClassLoader()" again), loading mygui-.1.2.jar and mydb-1.1.jar again and loading the new mynet-0.5.jar.


So again:
WIth one instance of a ClassLoader you can only add classes. You can not remove or replace them.
If you want to remove or replace a class, then you have to create a new ClassLoader-instance, which needed be again loading all classes.

Thats the information I currently have.

And btw to the JarClassLoader-license. Currently in the head of that files is only the LGPL-mentioned. But the next time the author will write there, what on github stands, that JarClassLoader is under the LGPL and ApacheLicense.


Greatings
theuserbl

jbExplorer

Trainee

  • "jbExplorer" started this thread

Posts: 111

Date of registration: Mar 18th 2013

  • Send private message

9

Saturday, January 4th 2014, 3:01am

More information about JarClassLoader:
Seems that the unloadClass()-method don't work correct.

But possible that it depends on the ClassLoader itself, which JarClassLoader is based on.

I have now read in the internet and as answer from the author of JarClassLoader, that changing a class in one JCL-instance is not possible.


What I mean with it:

For example, you have three external jar-files:
- mygui-1.2.jar
- mynet-0.4.jar
- mydb-1.1.jar

All jars are loaded with JarClassLoader (or if you doing it your own way with URLClassLoader or ClassLoader).
And for example you program makes use of some of the classes in each of the jar-files.

When you then plan, to change one of that jar-files with an other one (for example mynet-0.4.jar to mynet-0.5.jar) in a running system (without restarting the java-program), then it is not possible, to unload the net-classes and reload the newer version of it.

The only way, to load a new version of the same class is, to create a new instance of JarClassLoader.


So, if you have an instance of JarClassLoader called "jclWhatThe" and want to change the loaded mynet-0.4.jar to mynet-0.5.jar, then you have to remove all instances of classes, which are in mygui-1.2.jar, mynet-0.4.jar and mydb-1.1.jar.
After that creating a new instance of JarClassLoader (for example, writing "jclWhatThe = New JarClassLoader()" again), loading mygui-.1.2.jar and mydb-1.1.jar again and loading the new mynet-0.5.jar.


So again:
WIth one instance of a ClassLoader you can only add classes. You can not remove or replace them.
If you want to remove or replace a class, then you have to create a new ClassLoader-instance, which needed be again loading all classes.

Thats the information I currently have.

And btw to the JarClassLoader-license. Currently in the head of that files is only the LGPL-mentioned. But the next time the author will write there, what on github stands, that JarClassLoader is under the LGPL and ApacheLicense.


Greatings
theuserbl
Roger on the license, I'll include the notice next time.

I'm getting different results from you, when running the JCL2. The original JCL.jar works fine.

In JCL2, if the project is Maked, and the executable is run, then no problem running the following:


myArgs = args
System.out.println( "Here we go..." )

System.out.println( "Creating instance of JarClassLoader" )
jclWhatThe = New JarClassLoader()

System.out.println( "Adding the jar" )
jclWhatThe.add( "c:\Projects_Programming\Jabaco\ExternalJars\WhattheWorld.jar" )

System.out.println( "Loading the class" )
oWhatThe = jclWhatThe.loadClass( "WhattheWorld" ).newInstance()

System.out.println( "Invoking sayWhatthe" )
CallByName oWhatThe, "sayWhatthe"


System.out.println( "Unloading the class" )
jclWhatThe.unloadClass( "WhattheWorld" )

System.out.println( "...Finished" )


, but if it's run in the IDE, then there's a NullPointerException at

oWhatThe = jclWhatThe.loadClass( "WhattheWorld" ).newInstance()



Both In and Out of the IDE, using JCL2, there's a NullPointerException at


Dim cls As java#lang#Class = oWhatThe.getClass()



Regarding the prohibition about reloading a class, that's fine. This is useful enough, even with that limitation.


Thanks, theuserbl. Most of it's working fine, will continue to experiment.

This post has been edited 2 times, last edit by "jbExplorer" (Jan 4th 2014, 3:16am)


Rate this thread
WoltLab Burning Board