Search code examples
javaspringmavenantclassloader

How to load classes, resources, jars dynamically in java?


Here we exhibit two project structure.

  1. first one for multiple projects
  2. and another one for single project structure.

we want to assemble single project that consist of multiple projects. Our requirement is to load it's dependency like classes, resources, jars from different location dynamically by java program. without adding class path entry into it's jar MANIFEST.MF.

You are permitted to add java options at run time for recognizing class path but we are preferred to load dynamically by java program.

/opt/java/chorke/multiple/projects/home/
    ├─ bin/
    │   ├─ mspn/
    │   │   ├─ lib/
    │   │   │   ├─ chorke-mspn-utlity-2.0.00-SNAPSHOT.jar
    │   │   │   └─ chorke-mspn-webapp-2.0.00-SNAPSHOT.jar
    │   │   ├─ chorke-mspn-server-2.0.00-SNAPSHOT.jar         [executable jar]
    │   │   ├─ README.md
    │   │   └─ LICENSE
    │   ├─ mllp/
    │   │   ├─ lib/
    │   │   │   ├─ chorke-mllp-utlity-2.0.00-SNAPSHOT.jar
    │   │   │   └─ chorke-mllp-webapp-2.0.00-SNAPSHOT.jar
    │   │   ├─ chorke-mllp-server-2.0.00-SNAPSHOT.jar         [executable jar]
    │   │   ├─ README.md
    │   │   └─ LICENSE
    │   └─ itis/
    │       ├─ lib/
    │       │   ├─ chorke-itis-utlity-2.0.00-SNAPSHOT.jar
    │       │   └─ chorke-itis-webapp-2.0.00-SNAPSHOT.jar
    │       ├─ chorke-itis-server-2.0.00-SNAPSHOT.jar         [executable jar]
    │       ├─ README.md
    │       └─ LICENSE
    ├─ lib/
    │   ├─ commons-lang3-3.3.2.jar
    │   ├─ ...more...hidden...jars...here.jar
    │   ├─ slf4j-log4j12-1.7.12.jar
    ├─ opt/
    │   ├─ org.eclipse.swt.gtk.linux.x86-4.4.2.jar
    │   ├─ org.eclipse.swt.cocoa.macosx.x86-4.4.2.jar
    │   ├─ ...more...optional...hidden...jars...here.jar
    │   └─ org.eclipse.swt.win32.win32.x86_64-4.4.2.jar
    └─ etc/
        ├─ mspn/
        │   ├─ application.properties
        │   ├─ application.yml
        │   └─ log4j.xml
        ├─ mllp/
        │   ├─ application.properties
        │   ├─ application.yml
        │   └─ log4j.xml
        └─ itis/
            ├─ application.properties
            ├─ application.yml
            └─ log4j.xml

Here we split the multiple project structure to single project for your kind consideration.

/opt/java/chorke/single/project/home/
    ├─ bin/
    │   └─ itis/
    │       ├─ lib/
    │       │   ├─ chorke-itis-utlity-2.0.00-SNAPSHOT.jar
    │       │   └─ chorke-itis-webapp-2.0.00-SNAPSHOT.jar
    │       ├─ chorke-itis-server-2.0.00-SNAPSHOT.jar         [executable jar]
    │       ├─ README.md
    │       └─ LICENSE
    ├─ lib/
    │   ├─ commons-lang3-3.3.2.jar
    │   ├─ ...more...hidden...jars...here.jar
    │   ├─ slf4j-log4j12-1.7.12.jar
    ├─ opt/
    │   ├─ org.eclipse.swt.gtk.linux.x86-4.4.2.jar
    │   ├─ org.eclipse.swt.cocoa.macosx.x86-4.4.2.jar
    │   ├─ ...more...optional...hidden...jars...here.jar
    │   └─ org.eclipse.swt.win32.win32.x86_64-4.4.2.jar
    └─ etc/
        └─ itis/
            ├─ application.properties
            ├─ application.yml
            └─ log4j.xml

Edited

Let's say we want to run chorke-itis-server-2.0.00-SNAPSHOT.jar by

java -jar ./bin/itis/chorke-itis-server-2.0.00-SNAPSHOT.jar

command but it will not executed as lacks of it's dependency in class path, such as:-

  1. Own jar library ./bin/itis/lib/*.jar
  2. Common jar library ./lib/*.jar
  3. Optional jar library ./opt/*.jar
  4. Config resources ./etc/itis/*.*

These dependency will not loaded as usual process. We should do more to recognized these class path. It would be pass from command line by providing class path parameter or dynamically by java program.

Could you please help us to build dynamic class loader by helping of core java or any kind of opensource framework?


Solution

  • Here is the single sample project structure as your demand while BootstrapMainApplication is the main class inside the com.chorke.boot package for executing the java application :-

    /opt/java/chorke/itis/project/home/
        ├─ bin/
        │   └─ itis/
        │       ├─ lib/
        │       │   ├─ chorke-itis-utlity-2.0.00-SNAPSHOT.jar
        │       │   └─ chorke-itis-webapp-2.0.00-SNAPSHOT.jar
        │       ├─ chorke-itis-server-2.0.00-SNAPSHOT.jar         [executable jar]
        │       ├─ classes/
        │       ├─ README.md
        │       └─ LICENSE
        ├─ lib/
        │   ├─ usr/
        │   │   ├─ chorke-amqp-client-2.0.00-SNAPSHOT.jar
        │   │   └─ chorke-comn-spring-2.0.00-SNAPSHOT.jar
        │   └─ gpl/
        │       ├─ activemq-broker-5.10.2
        │       ├─ commons-lang3-3.3.2.jar
        │       ├─ ..more...and..more..jar
        │       └─ slf4j-log4j12-1.7.12.jar
        ├─ etc/
        │   └─ itis/
        │       ├─ application.properties
        │       ├─ application.yml
        │       └─ log4j.xml
        ├─ launch.bat
        └─ launch.sh
    

    Considering this project structure you can write bat or shell script named launch.bat and launch.sh for Windows as well as Linux platform.

    launch.bat

    goto launch
    
    :launch
        SET CKI_HOME=.
        SET BIN_PATH=%CKI_HOME%\bin
        SET LIB_PATH=%CKI_HOME%\lib
        SET ETC_PATH=%CKI_HOME%\etc
        SET ITI_HOME=%BIN_PATH%\itis
        SET CLS_PATH=%ETC_PATH%\itis\;%ITI_HOME%\classes\
        SET CLS_PATH=%CLS_PATH%;%LIB_PATH%\gpl\*;%LIB_PATH%\usr\*;%ITI_HOME%\lib\*;%ITI_HOME%\*
    
        @REM SET CMD_EXCE=java -cp %CLS_PATH% com.chorke.boot.BootstrapMainApplication
        SET CMD_EXCE=java -classpath %CLS_PATH% com.chorke.boot.BootstrapMainApplication
        %CMD_EXCE%
    

    For Linux platform using this shell script may work fine

    launch.sh

    #!/bin/bash
    
    function launch(){
        CKI_HOME='.';
        BIN_PATH="$CKI_HOME/bin";
        LIB_PATH="$CKI_HOME/lib";
        ETC_PATH="$CKI_HOME/etc";
        ITI_HOME="$BIN_PATH/itis";
        CLS_PATH="$ETC_PATH/itis/:$ITI_HOME/classes/";
        CLS_PATH="$CLS_PATH:$LIB_PATH/gpl/*:$LIB_PATH/usr/*:$ITI_HOME/lib/*:$ITI_HOME/*";
    
        #CMD_EXCE="java -cp $CLS_PATH com.chorke.boot.BootstrapMainApplication";
        CMD_EXCE="java -classpath $CLS_PATH com.chorke.boot.BootstrapMainApplication";
        $CMD_EXCE;
    }
    
    launch;
    

    It's suppose to me these script would be helpful to build your own application ecosystem/structure as well as able to load classes/config/library from different location.