I have a multiple Spring Boot microservice apps managed by Gradle. There is a common jar and domain specific jars organized like so:
| common/
|-- common.jar
| p/
|-- p-ingest.jar
| g/
|-- g-ingest.jar
My common jar has a class, BaseRESTService
, that autowires HttpServletRequest
(which I already know is a bad idea - not my code). The p-ingest.jar imports common, as does the g-ingest jar. geoalloc runs without problem. But p-ingest, which was literally copied from g-ingest, does not run. p-ingest gets the following exception when the context attempts to initialize:
Field request in com.company.common.BaseRESTService required a bean of type 'javax.servlet.http.HttpServletRequest' that could not be found.
I'm not new to Spring, and I understand component scanning and autowiring and all that, but I've been working on this for 2 days and I cannot figure what's happening. I ran gradle dependencies
on both projects, and the trees are identical. Below is the boot application class of p-ingest:
@SpringBootApplication
@ComponentScan(
basePackageClasses = com.company.common.ConfigurationSearchCriteriaFactory.class,
basePackages = {"com.company.erd"})
@EnableJpaRepositories(basePackages = "com.company.erd")
@EntityScan(basePackages = {"com.company.erd"})
public class PortfolioRiskIngestApplication implements ApplicationRunner {
private static final Log logger = LogFactory.getLog(IngestApplication.class);
@Autowired
private IngestService ingestService;
public PIngestApplication(PIngestService ingestService) {this.ingestService = ingestService;}
public static void main(String[] args) {
SpringProfileHelper.setProfileFromAwsEnvironment();
SpringApplication app = new SpringApplication(PIngestApplication.class);
app.setWebEnvironment(false);
app.run(args);
}
@PostConstruct
void started() {
TimeZone.setDefault(TimeZone.getTimeZone("UTC"));
}
@Override
public void run(ApplicationArguments applicationArguments) {
// define the log info
LogInfo info = LogInfo.newInstance("run", new Object[] { StringUtility.arrayToString(applicationArguments.getSourceArgs()) });
// log entry
logger.info(info.entry());
ingestService.run(applicationArguments.getSourceArgs());
// log exit
logger.info(info.exit());
}
}
And here is an excerpt from BaseRestService
:
public class BaseRESTService
{
private static final Log logger = LogFactory.getLog(BaseRESTService.class);
@Autowired
private HttpServletRequest request;
@ResponseStatus(HttpStatus.NOT_FOUND)
@ExceptionHandler(value = EntityNotFoundException.class)
public ErrorResponse handleEntityNotFoundException(EntityNotFoundException e){
ErrorResponse errorResponse = new ErrorResponse();
errorResponse.setErrorCode(HttpStatus.NOT_FOUND.value());
errorResponse.setErrorMessage(e.getMessage());
logger.error(e.getMessage(), e);
return errorResponse;
}
Nothing special. All classes involved are pretty straightforward. I welcome ANY ideas that anyone has as to what I'm doing wrong...
I figured out my problem, and it was a rookie mistake. Out of laziness, I did a component scan across our entire codebase, which picked up the controller we had in the common jar that was only meant for our REST application. Component scanning only the actual desired packages worked.