jack
jack

Reputation: 465

Read Manifest file in Spring boot application

We are using Spring-boot to build micro-services. In my project set-up we have a common maven module named platform-boot with main class with annotation SpringBootApplication

If we want to create a new micro-service (say Service-1), we simply add a dependency of platform-boot module and provide the main-class path in pom.xml and we are good to go.

Problem is when I try to read Manifest.MF file of Service-1 by writing code in my 'main-class' in dependent module. It reads the Manifest.MF file of platform-boot.

Below is the code snippet of how I am reading Manifest.MF file in my main class.

MyMain.class.getProtectionDomain().getCodeSource().getLocation().getPath();
//Returns the path of MyMain.class which is nested jar

Please suggest a way to read the Manifest.MF file of Service-1.

PS: I want to read the Maifest.MF file to get Implementation-Version. Please suggest if any other way of getting it as well.

Upvotes: 4

Views: 6463

Answers (2)

jack
jack

Reputation: 465

I found two ways to solve this problem:

  1. We can use maven-dependency-plugin to unpack the child jar while executing the phase prepare-package. This plug in will extract the class file from my platform-boot jar to my Service-1.

    <plugin>
     <groupId>org.apache.maven.plugins</groupId>
     <artifactId>maven-dependency-plugin</artifactId>
     <version>3.0.2</version>
     <executions>
       <execution>
         <id>unpack</id>
         <phase>prepare-package</phase>
         <goals>
           <goal>unpack</goal>
         </goals>
         <configuration>
           <artifactItems>
             <artifactItem>
               <groupId>my.platform</groupId>
               <artifactId>platform-boot</artifactId>
               <type>jar</type>
               <overWrite>false</overWrite>
               <outputDirectory>${project.build.directory}/classes</outputDirectory>
               <includes>**/*.class,**/*.xml,**/*.text</includes>
               <excludes>**/*test.class</excludes>
             </artifactItem>
           </artifactItems>
           <includes>**/*.java, **/*.text</includes>
           <excludes>**/*.properties</excludes>
           <overWriteReleases>false</overWriteReleases>
           <overWriteSnapshots>true</overWriteSnapshots>
         </configuration>
       </execution>
     </executions>
    </plugin>  
    
  2. Second approach is much simpler, in spring-boot-maven-plugin add a goal build-info. This will write a file build-info.properties in your META-INF folder and is accessible in code as below.

    <plugin>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-maven-plugin</artifactId>
        <executions>
            <execution>
                <goals>
                    <goal>build-info</goal>
                    <goal>repackage</goal>
                </goals>
            </execution>
        </executions>
    </plugin>     
    

    In your main method you can get this information using the BuildProperties bean already registered in ApplicationContext.

    ApplicationContext ctx = SpringApplication.run(Application.class, args);
    BuildProperties properties = ctx.getBean(BuildProperties.class);
    

    In fact, Spring-actuator also uses this BuildProperties to get the build information which is helpful in monitoring.

Upvotes: 3

karthi
karthi

Reputation: 264

Hi could you please elaborate the need of reading your service-1manifest.mf ?

If you just want the service1 as a dependeny in your parent common module and should not conflict with your service1 bootable application , you can do generate two jars through the exec configuration in spring-boot-maven-plugin .

Upvotes: 1

Related Questions