I have a simple spring boot webapp running on an embedded jetty server, i.e. the main application class:
#Configuration
#EnableAutoConfiguration
#EnableConfigurationProperties
#ComponentScan
public class SampleActuatorApplication {
public static void main(String[] args) throws Exception {
SpringApplication.run(SampleActuatorApplication.class, args);
}
}
I have a bunch of static files and directories in one of the auto-configured locations (/static) where static content will be served from. When I hit the base URI I want to be able to view a directory index of the static content so that I can browse through it.
I have read containers including jetty usually come with a default handler that will expose this, however my app just returns 404 so I assume there is some additional steps needed when doing this via spring-boot. Can anyone suggest what I need to do / is my understanding correct?
Somehow you'll have to set the dirAllowed to true. This is done in JettyEmbeddedServletContainerFactory
Take a look at addDefaultServlet
https://github.com/spring-projects/spring-boot/blob/master/spring-boot/src/main/java/org/springframework/boot/context/embedded/jetty/JettyEmbeddedServletContainerFactory.java
There is a line holder.setInitParameter("dirAllowed", "false");
Related
I am trying to load 2 properties file in spring boot.
One of them contains the metadata (Database connection and other such properties). The other contains business logic (mapping between upstream and downstream Entity. This mapping is different in Dev and Prod, hence can't have a single resource file for these).
I want to use Spring Profiles for different environments (Dev, Stage, Prod).
So, I created 3 different folders in src/main/resources 1 for each environment.
Using spring profies, I am aware how to have env specific application-env.properties file. However, I am unable to move forward on how to use the same for my use case.
PS : Not adding any code snippet, because the question doesn't require one.
Here's an example from the docs:
$ java -jar myproject.jar --spring.config.location=\
optional:classpath:/default.properties,\
optional:classpath:/override.properties
You could also define this in your code before starting Spring Boot:
public static void main(String[] args) {
System.setProperty("spring.config.location", "optional:classpath:/default.properties,optional:classpath:/override.properties");
SpringApplication.run(Application.class, args);
}
To use custom prefixes for your app specific properties you can define #ConfigurationProperties class(es):
#Data
#ConfigurationProperties(prefix = "app.mapper")
public class MapperProperties {
private String foo;
}
and use it in any component:
#Component
#RequiredArgsConstructor
#EnableConfigurationProperties
public class YourComponent {
private final MapperProperties properties;
}
I have written a custom spring cloud stream sink application that starts up when I run it as a spring boot project in eclipse. When I deploy my application I need to pass in some system proeprties. See below.
#ComponentScan
#EnableConfigurationProperties(MyProperties.class)
#SpringBootApplication
public class MyApplication {//extends SpringBootServletInitializer{
public static final String COMPONENT_NAME = "my-application";
#Autowired
private MyProperties properties;
public static void main(String[] args) {
System.setProperty("server.env", "DEVT1");
System.setProperty("some.other.var", "foo");
SpringApplication.run(MyApplication.class, args);
}
I am trying to pass these system properties into dataflow using the Deployment Properties screen, picture below. I am wondering if I pass one of these if it is working. It seems like my application starts up but is looking for the other property. When I try passing both I get this weird error saying the main class can not be found. So when I pass one my application seems to get farther. Am I close to being on the right track? Do I need to separate the arguments some way? I tried with commas but it didn't seem to make a difference.
Error when passing two arguments -
Error: Could not find or load main class
LURzZXJ2ZXIuZW52PVBEMDYsLURBbWljYV9RdWV1ZV9NYW5hZ2Vycz1HV0QwNiwtRGNmZ21nci5jbGFzcy5wYXRoPVxhbWljYS5jb20MaWxlcxtudmNvbmZpZwdwcHJlc291cmNlcw==
So the picture in my post above is actually correct for setting jvm arguments. My error stemmed from one of my jvm arguments being a file path that was not exposed through docker. Make sure use-spring-application-json is unchecked if you specify your jvm args this way. So this is valid for passing jvm arguments...
through docker /res/ maps to a folder on my c drive.
Right now I have a simple Spring Boot application that serves static images that I have placed in resources/static/img. This works just fine for displaying the actual content, but there are two things I'd like to fix:
I don't want any of these images to be bundled with the resulting .jar file, and I know that placing these images in the resources folder will do that.
Using my current setup, in order to see a new image on the webapp, I have to add it to the folder and restart it. I would instead like Spring to serve any static content that exists in a specific folder, so I can add images while the application is running and have them automatically served at localhost:8080/img/{image name}.
I attempted to solve this by setting up a resource handler, but I'm not sure if this is any different than simply serving them from resources/static. Unfortunately, I'm still struggling with getting this configured correctly, as I'm unable to see any images at all. Here's what I tried:
#Configuration
public class StaticResourceConfiguration extends WebMvcConfigurerAdapter {
#Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/img/**").addResourceLocations("file:" + Application.IMAGE_DIR);
super.addResourceHandlers(registry);
}
}
And here is my Application configuration:
#SpringBootApplication
public class Application extends SpringBootServletInitializer {
static String IMAGE_DIR;
#Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
return application.sources(Application.class);
}
public static void main(String[] args) throws IOException {
SpringApplication.run(Application.class, args);
IMAGE_DIR = new File(".").getCanonicalPath() + "/img/";
}
}
Again, my goal is to set up a folder in the root of my project called img which will store the images that I would like the webapp to serve on localhost:8080/img/{image name}. If possible, I'd like to be able to add content to this folder while the application is running and have Spring automatically serve them without having to restart it.
Does anyone have any ideas? Thanks in advance.
the problem with your approach is that you set IMAGE_DIR after spring boot application is ran and the constant IMAGE_DIR is not initialized and is null. Change it as follows:
public static void main(String[] args) throws IOException {
IMAGE_DIR = "/opt/img/";
SpringApplication.run(Application.class, args);
}
and remove all File(".").getCanonicalPath() related stuff and it will work. Your approach will fit in your needs when you have new image in selected directory it can be served.
A good solution for serving dynamic content with spring boot is to link a static content directory to a symbolic link with no cache and after that, you just need to rebuild symlink every time you need to reload. So in your case:
#Configuration
public class StaticResourceConfiguration extends WebMvcConfigurerAdapter {
#Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/img/**").addResourceLocations("file:/tmp/images/").setCacheControl(CacheControl.noCache());
super.addResourceHandlers(registry);
}
}
After that, you change your image directory like this:
Path link = Paths.get("/tmp/images"); //Symlink
Files.deleteIfExists(link);
Files.createSymbolicLink(link, Paths.get(your_new_images_directory));
The choice of symlink /tmp/images is personal, you can choose what you want. Pay attention, your application needs to have good administrator rights for symlink creation.
to solve the problem with your point 2.
Using my current setup, in order to see a new image on the webapp, I have to add it to the folder and restart it. I would instead like
Spring to serve any static content that exists in a specific folder,
so I can add images while the application is running and have them
automatically served at localhost:8080/img/{image name}.
You can create all those images under:
/resources/public
-img
-js,...
And to access just localhost:8080/img/yourImage.png
Everything under "public" folder will be accessible
I want to integrate Spring Shell within a spring boot application. I am able to execute the examples from the official git-repo. But when migrating the example code to my own project that is very very similar to this code, my individual shell is not shown or usable. Instead the default Spring Shell splash is shown is usable:
<SpringShell ASCII-Art>
1.1.0.RELEASE
Welcome to Spring Shell. For assistance press or type "hint" then hit ENTER
spring-shell>
Compilation gives no errors, but the individual sample #component marked classes are not used. All annotations are properly set. A standard loader outside is existent. I am not executing the code in an IDE.
Although the documentation (chapter 3.5) tells, that the components are automatically collected as far as i understood.
So my question is more or less how to setup the usage better than
this:
public class Main {
public static void main(String[] args) throws Exception {
Bootstrap.main(args);
}
}
And to defeat the default splash!
That comment in the documentation is a bit misleading (I'll change it).
For your components to be picked up, they need to be on the classpath AND you'll need to scan for them somehow.
See for example how in the Spring XD project, there is a scan for the org.springframework.xd.shell package. You need to do something similar for your own package.
SOLUTION:
ebottard's answer brought me to the point of creating a "spring-shell-plugin.xml" under resources\META-INF\spring\... Although the component scan was set externally already, this seems to be necessary. The following code shows how to start it up within an Spring Boot Application where CommandLineRunner is implemented. This should bridge starting problems.
#Component
public class CLIBean implements CommandLineRunner {
#Override
public void run(String... args) throws Exception {
Bootstrap bootstrap = new Bootstrap();
bootstrap.run();
}
}
i am looking for samples or tutorials of using Spring in a standalone (desktop/swing) application, i searched a lot but couldn't get to something useful, all the examples and tutorials are for web applications, please advise.
Create the standalone application with maven, as pointed here:
Create a standalone application with Maven
Put the applicationContext in classpath, and load it in the main class as follows:
ClassPathXmlApplicationContext ctx =
new ClassPathXmlApplicationContext("applicationContext.xml");
See full article here:
http://www.devdaily.com/blog/post/java/load-spring-application-context-file-java-swing-application
Here's a simple example with 2 classes. Wrote in groovy for ease of reading, but will run for you in java too with proper syntax tweaks
Here's your main:
class Main {
static void main(String[] args) {
def ctx = new AnnotationConfigApplicationContext()
ctx.register(AppConfig.class)
ctx.refresh()
def runner = ctx.getBean("mainRunner")
runner.run()
}
void run() {
println "running from bean"
}
}
Here's your config bean:
#Configuration
class AppConfig {
#Bean
Main mainRunner() {
new Main()
}
}
AppFuse provides different demo applications, all the source code can be downloaded using maven. You can get the complete code of this demo application which is build using Spring MVC,Spring, Hibernate.
Yes this is a web application, you can dig into it and convert it to a stand alone one.
create a Maven project
it will create an Application class for your project
#Configuration
#ComponentScan
#EnableAutoConfiguration
public class Application {
public static void main(String[] args) {
//SpringApplication.run(YourClass.class, args);
YourClass.main(args);
}
}
put YourClass main method in there instead of SpringApplication.run(YourClass.class,args);
it works that way just fine.
When I first started to learn spring I followed these tutorials:
tutorialspoint
They are fairly basic but will get you up and running quickly. After this is ultimately
comes down to what you are going to use it for. Are you looking for IOC, JMS, JDBC/Hibernate support etc etc?
As mentioned already:
ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext");
will bring all your spring beans into your app regardless of what type it is.
This is the first thing I found on google. It looks fair good too.
http://www.mkyong.com/spring/maven-spring-hibernate-annotation-mysql-example/
Take a look at "Barebones Spring". I think it's a nice, up to date example of how to use Spring 3.
This is the tutorial of Spring which I found to be very useful. This explains Spring based on a Standalone application.
https://www.youtube.com/watch?v=GB8k2-Egfv0
Author of this videos also has updated the Maven and Struts videos and explained it in a simple but in an effective way.
I hope it helps.
I have managed to run a standalone Spring Boot application with Swing.
public static void main(String[] args) {
ConfigurableApplicationContext ctx = new SpringApplicationBuilder(SwingApp.class)
.headless(false).run(args);
EventQueue.invokeLater(() -> {
SwingApp ex = ctx.getBean(SwingApp.class);
ex.setVisible(true);
});
}
We need to use the SpringApplicationBuilder and turn off the headless mode.
#SpringBootApplication
public class SwingApp extends JFrame {
The SwingApp is decorated with #SpringBootApplication annotation.
See my Spring Boot Swing integration tutorial for a full working example.
So, to boil it down: what makes your application (any type) a Spring application is the presence and use of at least one BeanFactory, usually extended as an ApplicationContext. In a web application you'd likely declare in web.xml a servlet such as DispatcherServlet which takes care of instantiating and initializing the context; in a standalone application your own code just makes and initializes a context, as shown above. The web framework stuff that magically gives you a context is doing pretty much the same thing under the covers.
Following 4 libraries are needed for a minimal standalone Spring application :
commons-logging.jar (see http://commons.apache.org/logging)
org.springframework.core-2.5.6.A.jar (see
http://www.springsource.org/download)
org.springframework.beans-2.5.6.A.jar (see
http://www.springsource.org/download)
org.springframework.context-2.5.6.A.jar (see
http://www.springsource.org/download)
A good example is given here.