NullPointer Exception while calling webservice in play framework - java

Anything wrong in this program ?
I am getting nullPointerException while calling web service in play framework in version 2.4.3.
package com.enkindle.box;
import javax.inject.Inject;
import play.libs.ws.WSClient;
/**
* #author thirumal
*
*/
public class Sample {
#Inject WSClient ws;
public static void main(String[] args) {
Sample sample = new Sample();
sample.callAPI();
}
public void callAPI() {
ws.url("www.thomas-bayer.com/sqlrest/CUSTOMER/").get();
}
}

The issue is that your Sample class is not available within the context of your dependency injection - I'm assuming Guice. There are a couple ways to tackle this but the easiest is to create a Sample interface and bind its implementation, SampleImpl, using Guice so that it will be available for injected dependencies. I'm going to assume that this gets spawned from a controller, so you could inject Sample into your controller and hit the callApi() method from there.
Controller:
public class SampleController extends Controller {
#Inject Sample sample;
public Promise<Result> apiCall() {
sample.callApi();
return promise(() -> ok());
}
}
Interface:
#ImplementedBy(SampleImpl.class)
public interface Sample {
public void callApi();
}
And the interface implementation:
public class SampleImpl implements Sample {
#Inject WSClient ws;
#Override
public void callApi() {
// ws should not be null
ws.url("www.thomas-bayer.com/sqlrest/CUSTOMER/").get();
}
}
Reference docs: https://www.playframework.com/documentation/2.4.x/JavaDependencyInjection#Binding-annotations

Related

Overriding a dependency in a Micronaut test

I'm testing a Micronaut class that has a bean injected into it. In my test I provide a #MockBean class to override it. However, it seems Micronaut still injects the real dependency.
#MicronautTest
public class ClassUnderTestTest {
#Inject ClassUnderTest classUnderTest;
#Test
public void test() {
}
#MockBean
Dependency dependency() {
return mock(Dependency.class);
}
}
I uploaded a minimum repro to Github: https://github.com/crummy/micronaut-test-dependencies . The real dependency throws an exception, and the test does too. I would not have expected this to happen because of my #MockBean.
If I change the annotation to be #MockBean(Dependency.class) then I get this error: Message: No bean of type [di.failure.example.Dependency] exists. This seems even more confusing to me - now it doesn't resolve my real or my mock dependency?
Injecting mock bean with #MockBean annotation works if your dependency in ClassUnderTest is represented by interface. Let's say Dependency is a simple interface like:
package di.failure.example;
public interface Dependency {
void run();
}
Your application may provide an implementation for this interface called DependencyImpl:
package di.failure.example;
import javax.inject.Singleton;
#Singleton
public class DependencyImpl implements Dependency {
#Override
public void run() {
throw new RuntimeException("I don't want this to load!");
}
}
Now, for test purpose you can define a mock that replaces DependencyImpl:
package di.failure.example;
import io.micronaut.test.annotation.MicronautTest;
import io.micronaut.test.annotation.MockBean;
import org.junit.jupiter.api.Test;
import javax.inject.Inject;
import static org.mockito.Mockito.mock;
#MicronautTest
public class ClassUnderTestTest {
#Inject
ClassUnderTest classUnderTest;
#Test
public void test() {
classUnderTest.run();
}
#MockBean(DependencyImpl.class)
public Dependency dependency() {
return mock(Dependency.class);
}
}
This test executes and the mock returned by dependency() method is used in place of DependencyImpl.
Using #Replaces annotation
As Sergio mentioned in the comments section you can replace class based bean dependency using #Replaces annotation. Consider following example:
package di.failure.example;
import io.micronaut.context.annotation.Replaces;
import io.micronaut.test.annotation.MicronautTest;
import org.junit.jupiter.api.Test;
import javax.inject.Inject;
import javax.inject.Singleton;
#MicronautTest
public class ClassUnderTestTest {
#Inject
ClassUnderTest classUnderTest;
#Test
public void test() {
classUnderTest.run();
}
#Replaces(Dependency.class)
#Singleton
public static class MockDependency extends Dependency {
public MockDependency() {
System.out.println("MockDependency.<init>");
}
#Override
void run() {
System.out.println("Does not throw any exception...");
}
}
}
In this example we have defined a class MockDependency and we instruct Micronaut's DI mechanism to replace Dependency bean with MockDependency. However, there is one important thing we need to remember about - because our MockDependency extends Dependency class, parent construct gets invoked. The example you have shown in the question won't work in this case, because Dependency.<init> throws RuntimeException and the test fails. In this modified example I have used class like this one:
package di.failure.example;
import javax.inject.Singleton;
#Singleton
public class Dependency {
public Dependency() {
System.out.println("Dependency.<init>");
}
void run() {
throw new RuntimeException("I don't want this to load!");
}
}
When I run the test it passes and I see following console output:
Dependency.<init>
MockDependency.<init>
Does not throw any exception...
The main difference comparing to #MockBean is that in case of #Replaces you are using a concrete class object. As a workaround (if we really need a Mockito mock object) is to create a mock internally and delegate calls to this object, something like this:
#Replaces(Dependency.class)
#Singleton
public class MockDependency extends Dependency {
private final Dependency delegate;
public MockDependency() {
this.delegate = mock(Dependency.class);
}
#Override
void run() {
delegate.run();
}
}
I had the case - controller MyController with service MyService.
#MockBean(MyServiceImpl.class) did't mock injected service.
when(myService.doSomething()).thenReturn... immediately called real method.
I fixed mocking issue with giving MyService-bean a name and passing this name to #MockBean(name = )
controller:
#Controller
public class MyController {
private MyService myService;
...
}
factory:
#Factory
public class MyFactory {
#Named("myService") // Named just because #MockBean didn't work without it
#Context
public MyService myService() {
return new MyServiceImpl();
}
}
test:
#MicronautTest
class MyControllerTest {
#Inject
MyService myService;
#Inject
#Client("/")
#HttpClient client;
#MockBean(named = "myService")
MyService mockMyService() {
return mock(MyService.class);
}
#Test
void test() {
when(myService.doSomething()).thenReturn(genDto());
...
}
}
Details:
micronaut-test-junit5 3.1.1
junit-jupiter-api 5.6.2

Spring Boot: how to inject dependencies into a class called by a library?

I'm using Kinesis Client Library (KCL) and Spring boot. To use KCL, I have to implement a class (I named it RecordProcessor) for interface IRecordProcessor. And KCL will call this class and process records from kinesis. But when I tried to use dependency injection, I found it was not succeeded.
Here's the snippet for RecordProcessor:
#Component
public class RecordProcessor implements IRecordProcessor {
#Autowired
private SingleRecordProcessor singleRecordProcessor;
#Override
public void initialize(String shardId) {
...
}
#Override
public void processRecords(List<Record> records, IRecordProcessorCheckpointer checkpointer) {
...
}
}
I use Class SingleRecordProcessor to process single each record from kinesis. And this is my SingleRecordProcessor class snippet:
#Component
public class SingleRecordProcessor {
private Parser parser;
private Map<String, Table> tables;
public SingleRecordProcessor() {
}
#Autowired
private void setParser(Parser parser) {
this.parser = parser;
}
#Autowired
private void setTables(Map<String, Table> tables) {
this.tables = tables;
}
public void process(String record) {
...
}
}
I want to let spring framework automatically inject the SingleRecordProcessor instance into the class and use it. But I found that the field singleRecordProcessor is null.
Any idea why the dependency injection is failed? Or is it impossible to inject dependencies into a class which is called by other framework (in this case it's KCL)? Any suggestions will be appreciated! Really need some help please!!
[UPDATE]:
Sorry for not expressing the error clearly. The error was NullPointerException. I tried to inject singleRecordProcessor and call method process() on it. I think the injection was not successful so the instance singleRecordProcessor is null and there comes the NullPointerException.
More information is as follows:
I have a major class called Application
#SpringBootApplication
public class Application{
public static void main(String[] args) {
SpringApplication application = new SpringApplication(Application.class);
application.addListeners(new ApplicationPidFileWriter("./app.pid"));
ConfigurableApplicationContext ctx = application.run(args);
}
}
And I have the MainProcessor class which will call KCL.
#Service
public final class MainProcessor {
#EventListener(ApplicationReadyEvent.class)
public static void startConsumer() throws Exception {
init();
IRecordProcessorFactory recordProcessorFactory = new RecordProcessorFactory();
Worker worker = new Worker(recordProcessorFactory, kinesisClientLibConfiguration);
...
worker.run(); // this line will call KCL library and eventually call ProcessorRecord class.
}
}
[UPDATE2]
RecordProcessorFactory only has one method like this
#Component
public class RecordProcessorFactory implements IRecordProcessorFactory {
#Autowired
RecordProcessor recordProcessor;
#Override
public IRecordProcessor createProcessor() {
return recordProcessor;
}
}
It creates a new RecordProcessor instance for KCL to use it.
You should autowire an instance of this into your MainProcessor:
#Component
public class RecordProcessorFactory {
#Lookup IRecordProcessor createProcessor() { return null; }
}
Spring will instantiate a RecordProcessorFactory for you, and replace the implementation of createProcessor() in it with one that will return a new IRecordProcessor each time it's called. Both the factory and the processors will be Spring beans - which is what you want.

Dependency Injection in java

I was trying dependency injection in java using the #Inject annotation and I was following the tutorial in this link. According to the tutorial I created the following.
import javax.inject.Inject;
public class GreetingBean {
#Inject private static HelloBean helloBean;
// #Inject
// public GreetingBean(HelloBean helloBean){
// this.helloBean = helloBean;
// }
public static void sayGreeting(){
helloBean.sayHello();
}
public static void main(String[] args) {
GreetingBean.sayGreeting();
}
}
The HelloBean class is as follows.
public class HelloBean {
public void sayHello(){
System.out.println("Hello user");
}
}
On execution I got a null pointer exception which is obvious as helloBean is not initialised. According to what I understood from the tutorial #Inject is supposed to take care of that. I feel that I have to do something more to make this work but I could not find any reference. Can someone help me in this matter.
Take a look here if you want to use CDI with a standard Java application. (This is using the reference CDI implementation, Weld)

Dropwizard Integrated Testing with TestResource

Does anyone knows how to add a test Resource (i.e. one that is only for testing purposes and not added in run() method of the app)?
Here is an example:
public class MyTest {
#ClassRule
public static final DropwizardAppRule<TestConfiguration> RULE =
new DropwizardAppRule<TestConfiguration>(MyApp.class, "my-app-config.yaml");
#BeforeClass
public static void setUpBeforeClass() throws Exception
{
MyTest.RULE.getEnvironment().jersey().register(new JustForTestingResource());
}
#Test
public final void testTestResource()
{
Client client = new Client();
ClientResponse response = client.resource(
String.format("http://localhost:%d/rest/v1/test", RULE.getLocalPort()))
.get(ClientResponse.class);
assertThat(response.getStatus(), is(200));
}
}
and
public class JustForTestingRessource {
#GET
#Path("test")
#Produces(MediaType.APPLICATION_JSON)
public Response getInTestResource()
{
return Response.status(Status.OK).type(MediaType.TEXT_PLAIN).entity("get #Path(\"test\") is ok").build();
}
}
My problem is that the added resource is not added and I get resource not found 404 error response. It seems that I am registering the new resource after resource publishing and there is no refresh inside Dropwizard after start.
I dont want to extend my Application class and I dont want to insert test code into my real application code. Does anyone knows how to register the test resource without registering it in run() method of the Application?
This works, but a new class is needed:
public class TestService extends MyService{
#Override
public void run(
TestConfigurationconfiguration,
Environment environment) throws ClassNotFoundException
{
environment.jersey().register(new JustForTestingRessource());
super.run(configuration,environment);
}
}
Call in JUnit as already known:
#ClassRule
public static DropwizardAppRule<TestConfiguration> RULE =
new DropwizardAppRule<TestConfiguration>(TestService.class, "my-app-config.yaml");
Edit: Removing previous answer because it didn't solve your problem the way you wanted to do it.
I dug into the environment startup code and realized the reason why registering a controller didn't make it available is because jetty had already been started. If you stop jetty, register your controller and start jetty back up again, your resource will be available and you can use it in your test.
#BeforeClass
public static void setUpBeforeClass() throws Exception
{
MyTest.RULE.environment.applicationContext.stop()
MyTest.RULE.environment.jersey().register(new JustForTestingResource())
MyTest.RULE.environment.applicationContext.start()
}
You can test the Resource itself in a Jersey Container without starting a full dw-instance.
Check the "Testing Resources" section.
import static org.fest.assertions.api.Assertions.assertThat;
import static org.mockito.Mockito.*;
public class PersonResourceTest {
private static final PeopleStore dao = mock(PeopleStore.class);
#ClassRule
public static final ResourceTestRule resources = ResourceTestRule.builder()
.addResource(new PersonResource(dao))
.build();
private final Person person = new Person("blah", "blah#example.com");
#Before
public void setup() {
when(dao.fetchPerson(eq("blah"))).thenReturn(person);
// we have to reset the mock after each test because of the
// #ClassRule, or use a #Rule as mentioned below.
reset(dao);
}
#Test
public void testGetPerson() {
assertThat(resources.client().resource("/person/blah").get(Person.class))
.isEqualTo(person);
verify(dao).fetchPerson("blah");
}
}
I had the similar issue with the #ClassRule, maybe it can help to somebody..
In my test (Groovy) the invocation of RULE.getApplication() or getEnvironment() from #BeforeClass method returned null:
def setupSpec() {
RULE.application.run()
}
shown
java.lang.NullPointerException: Cannot invoke method run() on null object
I.e. RULE.testSupport had both null application and environment.
I found out that the call to
RULE.testSupport.before()
just before run() solves the error:
def setupSpec() {
RULE.testSupport.before()
RULE.application.run()
}
And then #AfterClass method:
def cleanupSpec() {
RULE.testSupport.after()
}
Or just use #Rule instead of #ClassRule and call
def setup() {
RULE.application.run()
}
inside of #Before method instead of #BeforeClass.
Though It seems strange, maybe there is some other better solution exists..
public class TestMain extends Main{
public static void main(String ... args) throws Exception {
new TestMain().run(args);
}
#Override
public void initialize(Bootstrap<AppConfiguration> bootstrap) {
super.initialize(bootstrap);
bootstrap.addBundle(
new MigrationsBundle<AppConfiguration>() {
#Override
public DataSourceFactory getDataSourceFactory(
AppConfiguration configuration) {
return configuration.getDataSourceFactory();
}
});
}
}

Spring console application configured using annotations

I want to create spring console application (running from command line with maven for example: mvn exec:java -Dexec.mainClass="package.MainClass").
Is this application I want to have some kind of services and dao layers. I know how to do it for a web application but I have not found any information on how to do in case of a console application (leter maybe with Swing).
I'm trying to create something like:
public interface SampleService {
public String getHelloWorld();
}
#Service
public class SampleServiceImpl implements SampleService {
public String getHelloWorld() {
return "HelloWorld from Service!";
}
}
public class Main {
#Autowired
SampleService sampleService;
public static void main(String [] args) {
Main main = new Main();
main.sampleService.getHelloWorld();
}
}
Is it possible?
Can I find somewhere an example of how to do it?
Take a look at the Spring Reference, 3.2.2 Instantiating a container.
In order to use Spring in console application you need to create an instance of ApplicationContext and obtain Spring-managed beans from it.
Creating a context using XML config is described in the Reference. For completely annotation-based approach, you can do someting like this:
#Component // Main is a Spring-managed bean too, since it have #Autowired property
public class Main {
#Autowired SampleService sampleService;
public static void main(String [] args) {
ApplicationContext ctx =
new AnnotationConfigApplicationContext("package"); // Use annotated beans from the specified package
Main main = ctx.getBean(Main.class);
main.sampleService.getHelloWorld();
}
}
The Spring Reference suggests using ClassPathXmlApplicationContext in the main method to create the application context, then calling the getBean method to get an initial reference to a bean from the application context. After writing this same code a few times, you wind up refactoring the boilerplate into this utility class:
/**
* Bootstraps Spring-managed beans into an application. How to use:
* <ul>
* <li>Create application context XML configuration files and put them where
* they can be loaded as class path resources. The configuration must include
* the {#code <context:annotation-config/>} element to enable annotation-based
* configuration, or the {#code <context:component-scan base-package="..."/>}
* element to also detect bean definitions from annotated classes.
* <li>Create a "main" class that will receive references to Spring-managed
* beans. Add the {#code #Autowired} annotation to any properties you want to be
* injected with beans from the application context.
* <li>In your application {#code main} method, create an
* {#link ApplicationContextLoader} instance, and call the {#link #load} method
* with the "main" object and the configuration file locations as parameters.
* </ul>
*/
public class ApplicationContextLoader {
protected ConfigurableApplicationContext applicationContext;
public ConfigurableApplicationContext getApplicationContext() {
return applicationContext;
}
/**
* Loads application context. Override this method to change how the
* application context is loaded.
*
* #param configLocations
* configuration file locations
*/
protected void loadApplicationContext(String... configLocations) {
applicationContext = new ClassPathXmlApplicationContext(
configLocations);
applicationContext.registerShutdownHook();
}
/**
* Injects dependencies into the object. Override this method if you need
* full control over how dependencies are injected.
*
* #param main
* object to inject dependencies into
*/
protected void injectDependencies(Object main) {
getApplicationContext().getBeanFactory().autowireBeanProperties(
main, AutowireCapableBeanFactory.AUTOWIRE_NO, false);
}
/**
* Loads application context, then injects dependencies into the object.
*
* #param main
* object to inject dependencies into
* #param configLocations
* configuration file locations
*/
public void load(Object main, String... configLocations) {
loadApplicationContext(configLocations);
injectDependencies(main);
}
}
Call the load method in your application main method. Notice that the Main class is not a Spring-created bean, and yet you can inject one of its properties with a bean from the application context.
public class Main {
#Autowired
private SampleService sampleService;
public static void main(String[] args) {
Main main = new Main();
new ApplicationContextLoader().load(main, "applicationContext.xml");
main.sampleService.getHelloWorld();
}
}
I'd to figure this out for a project recently. I was building a CLI for a utility that would be run from a scheduled job and reused part of the web application code for the project. I had a problem bootstrapping all of the #Autowired dependencies, and I didn't actually need them all, so I bootstrapped the specific dependencies in the main class using the AnnotationConfigApplicationContext register(java.lang.Class...) method as follows:
#Component
public class SpringAppCLI
{
/**
* Service to be autowired!
*/
#Autowired
private SampleService sampleService;
/**
*
*/
public static void main(String[] args) throws Exception {
final AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext();
// setup configuration
applicationContext.register(SampleServiceConfig.class);
applicationContext.register(SampleServiceRepository.class);
applicationContext.register(JpaConfig.class);
applicationContext.register(CommandLineConfig.class);
applicationContext.register(SampleService.class);
applicationContext.register(SpringAppCLI.class);
// add CLI property source
applicationContext.getEnvironment().getPropertySources()
.addLast(new SimpleCommandLinePropertySource(args));
// setup all the dependencies (refresh) and make them run (start)
applicationContext.refresh();
applicationContext.start();
try {
SpringAppCLI springAppCLI = applicationContext.getBean(SpringAppCLI.class);
springAppCLI.doWhatever();
} catch (Exception e) {
//some handling
} finally {
applicationContext.close();
}
}
}
and here's the configuration class:
#Configuration
#ComponentScan(basePackageClasses = SolrLoadCLI.class, includeFilters = #Filter(Controller.class), useDefaultFilters = false)
class CommandLineConfig implements ApplicationContextAware {
/**
*
*/
private ApplicationContext applicationContext;
/**
*
*/
#Override
public void setApplicationContext(ApplicationContext applicationContext)
throws BeansException {
this.applicationContext = applicationContext;
}
/**
*
* #return
*/
#Bean
public static PropertyPlaceholderConfigurer propertyPlaceholderConfigurer() {
PropertyPlaceholderConfigurer ppc = new PropertyPlaceholderConfigurer();
Resource[] resourceArray = new Resource[2];
resourceArray[0] = new ClassPathResource("/SampleService.properties");
resourceArray[1] = new ClassPathResource("/Database.properties");
ppc.setLocations(resourceArray);
return ppc;
}
}
Regarding Chin Huang's answer above...
Your example won't actually work, or at least isn't working for me locally. That's because you're initializing the SampleService object using #Autowired, but you specify AutowireCapableBeanFactory.AUTOWIRE_NO on the properties. Instead set it to AutowireCapableBeanFactory.AUTOWIRE_BY_TYPE or AutowireCapableBeanFactory.AUTOWIRE_BY_NAME.
Also, this is odd, so I may be doing something wrong. But it seems that with AutowireCapableBeanFactory.AUTOWIRE_BY_TYPE, I have to have a setProp() with #Autowired for it to work. So instead of this:
public class Main {
#Autowired
private SampleService sampleService;
public static void main(String[] args) {
Main main = new Main();
ApplicationContextLoader loader = new ApplicationContextLoader();
loader.load(main, "applicationContext.xml");
main.sampleService.getHelloWorld();
}
}
I have to do this:
public class Main {
private SampleService sampleService;
public static void main(String[] args) {
Main main = new Main();
ApplicationContextLoader loader = new ApplicationContextLoader();
loader.load(main, "applicationContext.xml");
main.sampleService.getHelloWorld();
}
#Autowired
public void setSampleService(SampleService sampleService) {
this.sampleService = sampleService;
}
}
If I have, as in Chin's original example, private data with #Autowired, the DI fails. I'm using 3.1.1.RELEASE and I think some of the auto-wiring stuff has changed in 3.1.x, so it may be due to that. But I'm curious as to why this wouldn't work, since that's consistent with earlier releases of Spring.
You can do it this way :
Do the initialization in your main method
You can then use the start method as your sudo controller
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.stereotype.Component;
import com.org.service.YourService;
#Component
public class YourApp{
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext(
"ApplicationContext.xml");
YourApp p = context.getBean(App.class);
p.start(args);
}
#Autowired
YourService yourService;
private void start(String[] args) {
yourService.yourMethod();
}
}
This was my solution to run an exit. I use it in a module which works as common ground to all other specific ones: a website and an API one. When I specify the right arguments on the right module it will run the right task.
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.annotation.ComponentScan;
#ComponentScan
#EnableAutoConfiguration
public class CLIApp {
public static void main(String[] args) {
ConfigurableApplicationContext ctx =
new SpringApplicationBuilder(CLIApp.class)
.web(false)
.properties("spring.jmx.enabled=false")
.run(args);
final int exitCode = SpringApplication.exit(ctx);
System.out.println("************************************");
System.out.println("* Console App sucessfully executed *");
System.out.println("************************************");
System.exit(exitCode);
}
}
As you see, I also disabled the unused web environment and JMX. I will focus on scanning the classpath from the package of the class and use the autoconfiguration skills of Spring Boot.
After the application finishes doing what it needs it closes like a console app.
I used EliuX's approach with other findings from around the web and came up with this one-class command line application.
It also demonstrates how you can take advantage of the annotation scanning and spring context to pull in, say, spring services from other parts of your application to use in the CLI.
Also note that the API has changed for .web since #EliuX's answer above.
// spring boot imports
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.boot.Banner;
import org.springframework.boot.WebApplicationType;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;
// spring imports
import org.springframework.context.annotation.ComponentScan;
// my import from another package that has spring annotations like
// #Service, #Component, #Autowired, to demonstrate how I can wrap those
// in a command line application
import my.packages.having.annotations.services.MyOtherService;
// This starts the spring container
#SpringBootApplication
// I deliberately scan packages in MY namespace that I know to have
// Spring annotations
#ComponentScan(value = "my.packages.having.annotations.*")
public class MyCliWithSpringAnnotations implements ApplicationRunner
{
// I can autowire other services in since spring instantiates
// this CLI class - as long as these are component-scanned (above)
private MyOtherService _otherService;
#Autowired
public MyCliWithSpringAnnotations(MyOtherService otherService)
{
_otherService = otherService;
}
// This implements the ApplicationRunner interface which Spring is going
// to find, then instantiate, then autowire, and then _run_ when I call
// run() below in the main method.
// This can be be implemented in any other scanned class (or classes)
// on the classpath and will be run, but I'm sticking it all in one
// class for simplicity.
#Override
public void run(ApplicationArguments args) throws Exception
{
// getSourceArgs() returns the original String[] of command
// line args to the main() method
_otherService.toSomethingWithThese(args.getSourceArgs());
}
public static void main(String... args)
{
new SpringApplicationBuilder(MyCliWithSpringAnnotations.class)
.web(WebApplicationType.NONE)
.bannerMode(Banner.Mode.OFF)
.logStartupInfo(false)
.build()
.run(args);
}
}

Categories