0

I'm trying to get a repository into a class annotated with @Service using the @Autowired annotation in a Spring-boot class. However, the repository turns up as a null.

Here's the relevant code:

@Service
public class ImportLicenses {


    @Autowired
    private LicenseRepository licenseRepository;

   public static void main (String[] args) {
            ImportLicenses importLicenses = new ImportLicenses();
            importLicenses.listFiles("/Users/admin/Licenses/licenses");
    }



  private void processLicense (Path path) {


        try {
            count++;
            BasicFileAttributes attr = Files.readAttributes(path, BasicFileAttributes.class);
            FileTime fileTime = attr.lastModifiedTime();

            Permission permission = new Permission(readLineByLineJava8(path.toFile().getAbsolutePath()));

            LicensePojo licensePojo = new LicensePojo(permission, path);


            Optional<License> licenseOptional = licenseRepository.findById(licensePojo.getId());

at which point it gets an NPE since licenceReposity is null.

I am able to access the licenseRepository in a controller class with this constructor

public LicenseController(LicenseRepository licenseRepository,
                         UserRepository userRepository) {
    this.licenseRepository = licenseRepository;
    this.userRepository = userRepository;
}

However, since I'm calling the constructor directly in the static main method, this doesn't seem like it's available. What's the best way to get the repository into this class?

Edit: Thanks for the responses. To clarify the question, I'm trying to pull this class into the structure of the existing Spring Boot application, instead of creating a separate one.

Option 1: Create a button or menu selection on the UI, and create a new controller class to run the import. This would be the simplest, but I don't want to necessarily have that on the UI.

Option 2: Code the import class create another Spring Application

@SpringBootApplication
public class ImportLicenses implements ApplicationRunner {

    private final Logger logger = LoggerFactory.getLogger(LicenseGenApplication.class);

    @SpringBootApplication
    public static void main() {
        main();
    }


    public static void main(String[] args) {

        SpringApplication.run(ImportLiceneses.class, args);
    }

    @Override
    public void run(ApplicationArguments args) throws Exception {
 
        listFiles("/Users/admin//licenses");

    }

    public void listFiles(String path) {

        try {
            Files.walk(Paths.get(path))
                    .filter(ImportLicenses::test)
                    .forEach(p -> processLicense(p));
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    ....

}

Option 3 - Create a non-executable jar file from the existing application for use in the new application to avoid duplicating code.

Option 1 is the quickest, I'm not sure if option 2 work, Option 3 I'll take a look at to see if it's do-able.

Jack BeNimble
  • 35,733
  • 41
  • 130
  • 213
  • You are not instating Spring Boot, you should go with some starters: https://start.spring.io/ – abc Jun 22 '20 at 00:15
  • @Sotirios Delimanolis: The question you referred has completely different reason. It describes a case when an instance was created without Spring. But it is a Spring application, and the target bean is managed by Spring. Where as in this case Spring is not used at all, Spring is not even initialized. This case is definitely **not a duplicate**. – mentallurg Jun 22 '20 at 00:30
  • This is a Spring Boot application, as I referenced in LicenseController entry. I will edit to make it more obvious. The problem is I'm trying to run a separate class to import data and would prefer not to make a separate application out of it. – Jack BeNimble Jun 22 '20 at 00:36
  • 1
    You're missing the point. If you're initializing the object yourself, obviously Spring isn't involved, whether the rest of the objects are "operating within the context of Spring" or not. It very much is a duplicate. You're not using Spring to create your instance. The answer is to use Spring to create your instance, if what you want is Spring to inject beans appropriately. – Sotirios Delimanolis Jun 22 '20 at 00:37
  • @JackBeNimble: The class `ImportLicenses` that you show is *not* a Spring application. – mentallurg Jun 22 '20 at 00:39
  • Yes, that's clear. I'm trying to figure out how to use the existing Spring application to create the instance. – Jack BeNimble Jun 22 '20 at 00:39
  • @JackBeNimble: Start by eliminating field injection and using constructor injection. That is usually sufficient for the compiler/IDE to identify to you where you need to make adjustments. – chrylis -cautiouslyoptimistic- Jun 22 '20 at 16:33

1 Answers1

0

Your application is a usual Java application. It is not a Spring Boot application.

What should you do? Make a Spring Boot application of it. For instance, create a demo app at https://start.spring.io/, compare your main class to the main class in the demo application, then adjust your main class correspondingly. Also compare your Maven or Gradle config to the config of the demo app and adjust correspondingly.

At least, your application should have an annotation @SpringBootApplication. Also, it should be launched via SpringApplication.run(...). This is a minimum. Depending on what you need, you may want to use @EnableAutoConfiguration and other configuration options.

mentallurg
  • 4,967
  • 5
  • 28
  • 36
  • Thanks for your answer. I'm going with a GUI link for this. It's a one-off, so I don't really need to create a whole separate application for it. It's kind of a utility function, and for a more fully-fleshed out app I probably would have and admin section, so it kind of belongs on a GUI anyway. – Jack BeNimble Jun 23 '20 at 15:16
  • You cannot initialize a Spring bean without initializing Spring context. It doesn't have to be *the whole* Spring application. You can create an alternative "light" context. But in any case you need to initialize Spring context. – mentallurg Jun 23 '20 at 15:45