0

Try to build a classpath with jars to invoke my program with java-command

"java -cp %classpath% %mainclass%".

But can't manage to get to it run.

When building the jar with "spring-boot-maven-plugin" I always get an error because mainclass cannot be found. When building the jar with "maven-jar-plugin/maven-assembly-plugin", the Spring environment is not found. I have setup a small sample project to test and show. It would be great if someone could give me some help here.

My project looks like this:

  • mysample-base (has a packaging of "pom" and has module "mysample-frontend")
    • mysample-frontend (has a packaging of "pom" and has module "mysample-frontend-programs")
      • mysample-frontend-programs (has a packaging of "jar" and contains the programs). These are the poms:

mysample-base/pom.xml

<groupId>com.mysamples</groupId>
<artifactId>mySamples-base</artifactId>
<version>1.0.0</version>
<packaging>pom</packaging>

<properties>
    <java.version>1.8</java.version>
    <maven.compiler.source>1.8</maven.compiler.source>
    <maven.compiler.target>1.8</maven.compiler.target>
    <revision>1.0.0</revision>
    <targetJarDir>E:/$SysProg/mySample/RUN/lib</targetJarDir>
</properties>

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.3.3.RELEASE</version>
</parent>

<modules>
   <module>mySamples-frontend</module>
</modules>

<dependencies>

    <!-- *************************************************************************************************** 
        * Springboot *************************************************************************************************** -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web-services</artifactId>
    </dependency>
            <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>

    <!-- *************************************************************************************************** 
        * Database Access *************************************************************************************************** -->


    <!-- https://mvnrepository.com/artifact/org.codehaus.mojo/jaxb2-maven-plugin -->
    <dependency>
        <groupId>org.codehaus.mojo</groupId>
        <artifactId>jaxb2-maven-plugin</artifactId>
        <version>2.5.0</version>
    </dependency>

    <!-- https://mvnrepository.com/artifact/ch.qos.logback/logback-classic -->
    <dependency>
        <groupId>ch.qos.logback</groupId>
        <artifactId>logback-classic</artifactId>
        <version>1.2.3</version>
    </dependency>

</dependencies>

<build>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-compiler-plugin</artifactId>
            <version>3.1</version>
            <configuration>
                <source>1.8</source>
                <target>1.8</target>
            </configuration>
        </plugin>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-javadoc-plugin</artifactId>
            <version>2.9.1</version>
            <configuration>
                <show>private</show>
                <nohelp>true</nohelp>
            </configuration>
        </plugin>

        <plugin>
            <artifactId>maven-dependency-plugin</artifactId>
            <executions>
                <execution>
                    <phase>install</phase>
                    <goals>
                        <goal>copy-dependencies</goal>
                    </goals>
                    <configuration>
                        <outputDirectory>${targetJarDir}</outputDirectory>
                    </configuration>
                </execution>
            </executions>
        </plugin>

    </plugins>
</build>

mysample-frontend/pom.xml

<artifactId>mySamples-frontend</artifactId>
<packaging>pom</packaging>

<parent>
    <groupId>com.mysamples</groupId>
    <artifactId>mySamples-base</artifactId>
    <version>1.0.0</version>
</parent>

<modules>
    <module>mySamples-frontend-programs</module>
</modules>

mysample-frontend-progams/pom.xml - with "spring-boot-maven-plugin"

<artifactId>mySamples-frontend-programs</artifactId>
<version>1.0.0</version>
<packaging>jar</packaging>

<parent>
    <groupId>com.mysamples</groupId>
    <artifactId>mySamples-frontend</artifactId>
    <version>1.0.0</version>
</parent>


<build>
    <plugins>
  <plugin>
     <groupId>org.springframework.boot</groupId>
     <artifactId>spring-boot-maven-plugin</artifactId>
     <version>2.3.4.RELEASE</version>
     <configuration>
        <fork>true</fork>
        <mainClass>com.mysamples.calling.MainCalling</mainClass>
     </configuration>
     <executions>
        <execution>
           <goals>
              <goal>repackage</goal>
           </goals>
        </execution>
     </executions>
  </plugin>
    </plugins>
</build>

mysample-frontend-progams/pom.xml - with "maven-assembly-plugin"

<artifactId>mySamples-frontend-programs</artifactId>
<version>1.0.0</version>
<packaging>jar</packaging>

<parent>
    <groupId>com.mysamples</groupId>
    <artifactId>mySamples-frontend</artifactId>
    <version>1.0.0</version>
</parent>


<build>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-assembly-plugin</artifactId>
            <version>3.3.0</version>
            <configuration>
                <archive>
                    <manifestEntries>
                        <Build-Version>${project.version}</Build-Version>
                        <Built-By>${user.name}</Built-By>
                        <Build-Jdk>${java.version}</Build-Jdk>
                        <Build-Time>${maven.build.timestamp}</Build-Time>
                        <Build-Number>${buildNumber.value}</Build-Number>
                        <Build-YearStarted>2020</Build-YearStarted>
                        <DeveloperName>Ulrich Schmidt</DeveloperName>
                    </manifestEntries>
                </archive>
                <descriptorRefs>
                    <descriptorRef>jar-with-dependencies</descriptorRef>
                </descriptorRefs>
            </configuration>
            <executions>
                <execution>
                    <id>make-assembly</id> <!-- this is used for inheritance merges -->
                    <phase>package</phase> <!-- bind to the packaging phase -->
                    <goals>
                        <goal>single</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>

I' m running this command:

cd /D .....
SET CLASSPATH=mySamples-frontend-programs-1.0.0.jar
java -Duser.language=en -cp mySamples-frontend-programs-1.0.0.jar com.mysamples.calling.MainCalling

In case of using "spring-boot-maven-plugin" for building jar, I get this message: Error: Could not find or load main class com.mysamples.calling.MainCalling

Looking in the jar file shows, that the main-class is stored to "ROOT-INF/classes". In the root-path of the jar I can only find the spring framework.

In case of using "maven-assembly-plugin" for building jar, I get this message:

java.lang.IllegalArgumentException: No auto configuration classes found in META-INF/spring.factories. If you are using a custom packaging, make sure that file is correct.
    at org.springframework.util.Assert.notEmpty(Assert.java:467)
    at org.springframework.boot.autoconfigure.AutoConfigurationImportSelector.getCandidateConfigurations(AutoConfigurationImportSelector.java:180)
    at org.springframework.boot.autoconfigure.AutoConfigurationImportSelector.getAutoConfigurationEntry(AutoConfigurationImportSelector.java:123)
    at org.springframework.boot.autoconfigure.AutoConfigurationImportSelector$AutoConfigurationGroup.process(AutoConfigurationImportSelector.java:434)
    at org.springframework.context.annotation.ConfigurationClassParser$DeferredImportSelectorGrouping.getImports(ConfigurationClassParser.java:878)
    at org.springframework.context.annotation.ConfigurationClassParser$DeferredImportSelectorGroupingHandler.processGroupImports(ConfigurationClassParser.java:808)
    at org.springframework.context.annotation.ConfigurationClassParser$DeferredImportSelectorHandler.process(ConfigurationClassParser.java:779)
    at org.springframework.context.annotation.ConfigurationClassParser.parse(ConfigurationClassParser.java:192)
    at org.springframework.context.annotation.ConfigurationClassPostProcessor.processConfigBeanDefinitions(ConfigurationClassPostProcessor.java:319)
    at org.springframework.context.annotation.ConfigurationClassPostProcessor.postProcessBeanDefinitionRegistry(ConfigurationClassPostProcessor.java:236)
    at org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanDefinitionRegistryPostProcessors(PostProcessorRegistrationDelegate.java:280)
    at org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(PostProcessorRegistrationDelegate.java:96)
    at org.springframework.context.support.AbstractApplicationContext.invokeBeanFactoryPostProcessors(AbstractApplicationContext.java:707)
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:533)
    at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:758)
    at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:750)
    at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:397)
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:315)
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1237)
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1226)
    at com.mysamples.calling.MainCalling.main(MainCalling.java:27)

The both of the classes created are:

@ComponentScan({"com.mysamples"})
@SpringBootApplication
public class MainCalling {

private static final Logger LOGGER = LoggerFactory.getLogger(MainCalling.class);

@Autowired
public MainCalling(final ClassToBeCalled toBeCalled) {
    toBeCalled.isCalled();
}

public static void main(String[] args) {
    try {
        SpringApplication.run(MainCalling.class);
    } catch (Exception e) {
        LOGGER.error("", e);
        System.exit(-1);
    }
}

and

@Service
public class ClassToBeCalled {
    
    private static final Logger LOGGER = LoggerFactory.getLogger(ClassToBeCalled.class);
    
    public void isCalled() {
        LOGGER.info("have been called");
    }
}
Ulrich
  • 715
  • 2
  • 7
  • 25
  • 1
    The pom content needs to be in this question, not on some external site. You don't need to post the entire thing, just post the relevant plugin configuration. When you're dealing with classnotfound problems, it is wise to include package statements in your code. – Gimby Oct 07 '20 at 13:20
  • In relationship with Spring Boot it does not make sense to use the maven-assembly-plugin to package your application. Let spring-boot-maven-pugin it's work done. Apart from that if you start a spring-boot application just via `java -jar thejaryouhavebuilt... ` and no mentioning the main class. It's done by Spring boot on it's own. – khmarbaise Oct 07 '20 at 14:36
  • How does the code of `ClassToBeCalled` look like? The full class? – khmarbaise Oct 07 '20 at 14:39
  • @Gimby: It took me hours of trying to edit this question. I started over several times, formatting as code and as html - nothing worked. There is something wrong with the service - as I had said, it all looked fine in the preview. It is not a class not found error with "spring-boot-maven-plugin" - which really should be used. – Ulrich Oct 07 '20 at 14:53
  • @khmarbaise: I have multiple main classes to be run for different requests. I know about adding the mainclass to the manifest. I'm using it often. My problem is with spring-webservices ( I don't need it for my sample but I need it for my real problem). Without using webservices the packaging is fine - even with "spring-boot-maven-plugin". Something wrong with the plugin? – Ulrich Oct 07 '20 at 15:00
  • @khmarbaise: This is the full class. I just left out the "import"-statements and the "class" statement: (at)Service public class ClassToBeCalled { private static final Logger LOGGER = LoggerFactory.getLogger(ClassToBeCalled.class); public void isCalled() { LOGGER.info("have been called"); } } – Ulrich Oct 07 '20 at 15:00
  • 1
    The plugin is perfect. You are using it wrong. If you have several main classes in your spring boot packages project that is not the right way... You should make different apps... Furthermore it would be helpful to have a full working example on github or alike .... – khmarbaise Oct 07 '20 at 15:17
  • @khmarbaise/@Gimby: Did some work to the GitHub-project: Finished README for full documentation and added the both of the poms (with meaningful names) to the root-directory. – Ulrich Oct 07 '20 at 16:30

1 Answers1

0

I think I got it. "spring-boot-maven-plugin" does not allow for the command "java -cp ${classpath} ${chosenMain}". You have to use "java -jar ${classpath}" - the way the jar is created, by only springframework in the rootDir of the jar does not nable for calling directly the designated mainClass. The way how to invoke multiple main-Classes is described in "Running spring boot with multiple main classes"

Thanks to @khmarbaise for the hint. Couldn't believe in the first place, but after some reading, I got, he is right.

Ulrich
  • 715
  • 2
  • 7
  • 25