Run Spring's .class instead of .jar file - java

I have a Java Spring application which I built with maven, and a .jar file together with .class files were generated.
Instead of running the .jar file, is there a way for me to run the .class files instead?
I tried executing java -cp . hello.Application in the same directory as the Application.class (source code of Application.java below), but was given Error: Could not find or load main class hello.Application. Removing the hello. did not work either.
package hello;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
#SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}

I am doing the Spring boot application.I think you can also use maven to create a jar file and then use linux commend to run it.

you can run a class by executing follow command :
java Application
for only simple console application. to run Spring Boot application you need maven to build jar file and executing jar file to call main method to load spring boot context. Spring Boot need several requirements and dependencies to run. Spring load context and create a special structure to load. for more you can see following links:
https://spring.io/guides/gs/spring-boot/
http://www.logicbig.com/tutorials/spring-framework/spring-boot/boot-exploded-structure/

Related

How to deploy spring boot app on external tomcat server?

I have a spring boot app. It only has few api.
Its running fine on embedded tomcat server.
Now I need to deploy to my external tomcat server.
So I added packaging as war in pom file
I tried making a war using export as war option and put this war file inside my external tomcat webapps folder and tried running it. It failed with 404 status.
War file Name
CghsMobileApp.war
My rest controller
#RestController
#RequestMapping("/cghs")
public class HcoRestController {
#Autowired
private hcoService hcoSrvc;
#GetMapping("/cghsCity")
public List<CghsCity> getCghsCity() {
return hcoSrvc.getCghsCity();
}
}
URL I tried to hit
http://localhost:8080/CghsMobileApp/cghs/cghsCity
There is no html page inside my api project. Do I need to add one for war file to work.
I am lost here.
Any help will be appriciated.
Looked at the spring boot specification, found out that in class annotated with #SpringBootApplication have to extend SpringBootServletInitializer, for external server war deployment.
package gov.cghs.CghsMobileApp;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
#SpringBootApplication
public class CghsMobileAppApplication extends SpringBootServletInitializer {
public static void main(String[] args) {
SpringApplication.run(CghsMobileAppApplication.class, args);
}
}
but unfortunately only this will not help when working with Spring Profile. If any of your classes are using #Profile("profileName"), it needs to be passed in.
With the fat jar it was easy with the command line parameter --spring.profiles=<name>
When deployed in an external Tomcat that external tomcat has to to be modified (that is catalina.properties requires a -Dspring.profile=)

How does Java runtime find my main class?

I am learning Spring Boot. I made a simple Spring Boot project that can output a hello world string at http://localhost:8080/welcome
I use Maven to build my project that would output a jar file.
To start up my spring boot app, I use the command as below
java -jar my-springboot-app.jar
My question is:
How is java smart enough to locate my main class and its main method (e.g. the application launcher)?
I checked the jar file and browsed those BOOT-INF & META-INF and could not find any clues.
Does the spring boot framework (#SpringBootApplication) or maven automatically do the magic for me?
In case of spring boot jar the things are little bit more complicated than regular jar. Mainly because spring boot applicaton jar is not really a JAR (by jar I mean something that has manifest and compiled classes). Regular JARs can be "recognized" and processed by jvm, however in Spring Boot there are also packed dependencies (take a look at BOOT-INF/lib) so its jars inside JARs. How to read this?
It turns out that spring boot always has its own main class that is indeed referred to in MANIFEST.MF and this a real entry point of the packaged application.
The manifest file contains the following lines:
Main-Class: org.springframework.boot.loader.JarLauncher
Start-Class: com.example.demo.DemoApplication
Main-Class is a JVM entry point. This class, written by spring developers, basically does two things:
- Establishes a special class loader to deal with a "non-regular-jar" nature of spring boot application. Due to this special class loaders spring boot application that contains "jars" in BOOT-INF/lib can be processed, for example, regular java class loaders apparently cannot do this.
- Calls the main method of Start-Class value. The Start-Class is a something unique to spring boot applications and it denotes the class that contains a "main" method - the class you write and the class you think is an entry point :) But from the point of view of the spring boot infrastructure its just a class that has an "ordinary" main method - a method that can be called by reflection.
Now regarding the question "who builds the manifest":
This MANIFEST.MF is usually created automatically by plugins offered by Spring Developers for build systems like Maven or Gradle.
For example, the plugin looks like this:
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
During its work, this plugin identifies your main class (com.example.demo.DemoApplication in my example). This class is marked with #SpringBootApplication annotation and has a public static void main method.
However, if you put many classes like this the plugin probably won't recognize the correct class so you'll need to configure the plugin properties in POM.xml to specify the right class.
Java classes are executed within a larger context,
you run java -jar somejar.jar the class in question will be selected in the .jar file's manifest.
#SpringBootApplication will have componentscan, enabling auto configuration(autowired)
componentscan - to identify all the controller, service and configuration classes within the package.

Spring boot not serving static files from inside jar

Spring boot is not serving static files placed inside a jar.
I've had a backend app which I decided to add frontend to. Setup tasks to copy static frontend files to src/main/resources/static. Went through a bunch of answers here on SO, all of them advise the static content (index.html, .js and .css files) should reside under src/main/resources/static or src/main/resources/public, which i both tried. I open the built .jar and the static files are there, but starting application using java -jar myApp.jar and opening localhost:8080 gives me default whitelabel error page. My application works, since i can access the api i have running on it.
Application doesn't have #EnableWebMvc or any other custom configuration.
If i manually copy/paste same static resources to project's src/main/resources/static and ran the application using #SpringBootApplication class in IDE - the resources are loaded without problem and index.html opens upon visiting localhost:8080, so it's only a problem when files are in .jar.
Should the static files be somewhere different when they're in runnable spring boot .jar file?
Spring boot version 2.1.1
I am facing the same problem.
In case it is helpfull, I can manage to serve the static files properly by adding the following configuration :
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
#Configuration
#EnableWebMvc
public class StaticFilesConfig implements WebMvcConfigurer {
#Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/static/**").addResourceLocations("classpath:/static/");
}
}
... but it overrides the "implicit" auto configuration from spring boot and the rest of my filters etc. doesn't work anymore... => this is because #EnableWebMvc deactivates spring's default configuration.
[EDIT] In the end, I happened to understand that the jar containing the static files was not included in the built bootJar. You may want to check that.
HTH!

Spring boot Configuration FileNotFoundException when extending configuration from another spring boot app

I have 2 spring boot apps, and I want one of them to extend the configuration properties of the other. Everything works fine in Eclipse when I run the project as a maven spring boot app, however, when I run the jar or mvn spring-boot: run, I'm getting:
org.springframework.beans.factory.BeanDefinitionStoreException:
Failed to parse configuration class [com.xyz.integration.app.my.Application]; nested exception is java.io.FileNotFoundException:
class path resource [com/xyz/integration/app/pdfthing/ConfigurationManager.class] cannot be opened because it does not exist
I've searched all over and tried many variations, including:
#ComponentScan (using both com.xyz.. and classpath)
#Import
Class-Path in Manifest to the external jar file (In Linux, how to execute Java jar file with external jar files?)
Here's part of the configuration class:
#Component
#ComponentScan("classpath:com/xyz/integration/app/pdfthing")
public class MyConfigurationManager extends ConfigurationManager{
I'm guessing running as a jar doesn't load the external jar in the configuration. Any thoughts/hints? Thanks!

What is the difference between spring cloud config server exec.jar and .jar suffix

We are currently using spring cloud config server spring-cloud-config-server-1.1.0.M2-exec.jar and would like to upgrade to the latest version. However, i've noticed that beyond 1.1.0.M2 version there's only standard jars and no exec.jar in Maven repo http://maven.springframework.org/milestone/org/springframework/cloud/spring-cloud-config-server/
Could someone please explain what the difference is? Will I be able to just substitute the exec one with the standard non exec one?
Thanks
The exec jar contains an executable version of the config server (as a Spring Boot application). The non-exec jar contains only the config server classes. So you can't just replace the exec jar with the other one. What you basically have to do is to create a basic Spring Boot application with the config server dependencies and the appropriate annotations (like in the example):
#SpringBootApplication
#EnableDiscoveryClient
#EnableConfigServer
public class ConfigServerApplication {
public static void main(String[] args) {
SpringApplication.run(ConfigServerApplication.class, args);
}
}

Categories

Resources