-2

Class School,Teacher,Test belong to same package and are files themselves. As we can see in Test file, i am using new to make all the objects but i want to know how to use HK2 to do the same. I know how to do with guice or spring (either by using configuration file or using xml file) but i don't know how to do DI in HK2. I went through this source but not able to do even after reading from there.

public class School
{
   public Teacher t;
}
public class Teacher
{
   public void intro
   {
      System.out.println("I am Math Teacher");
   }

}
public class Test
{
   public static void main(String[] args)
   {
     School s = new School();
     s.t = new Teacher();
     s.t.intro();
   }
}

It will be of great help if additional information like how to do DI with HK2 using constructor or setter is given.

  • [Getting Started](https://javaee.github.io/hk2/getting-started.html) is a good place to start. You need a ServiceLocator that is populated with your services. Then you would get the `School` class from the locator, and it will be injected with your `Teacher` instance. Just add `@Inject` on the `School` constructor with a `Teacher` parameter. – Paul Samsotha Jun 23 '21 at 01:54

1 Answers1

2

The easiest way to get started with HK2 is to use the hk2-inhabitant-generator. This plugin will generate a META-INF/hk2-locator/default file which HK2 will use to populate the ServiceLocator when you call

ServiceLocatorUtilities.createAndPopulateServiceLocator();

The file gets populated with the service classes annotated with @Service. Just add the hk2-inhabitant-generator plugin to your pom.xml

<plugin>
    <groupId>org.glassfish.hk2</groupId>
    <artifactId>hk2-inhabitant-generator</artifactId>
    <version>${hk2.version}</version>
    <executions>
        <execution>
            <goals>
                <goal>generate-inhabitants</goal>
            </goals>
        </execution>
    </executions>
</plugin>

And the classes

@Service
public class School {

    private final Teacher teacher;

    @Inject
    public School(Teacher teacher) {
        this.teacher = teacher;
    }
}

@Service
public class Teacher {

    private final String name;

    public Teacher(String name) {
        this.name = name;
    }

    public Teacher() {
        this(DEFAULT_NAME);
    }
}

Then you can get the service from the ServiceLocator

public static void main(String... args) {
    ServiceLocator locator = ServiceLocatorUtilities.createAndPopulateServiceLocator();
    Teacher t = locator.getService(Teacher.class);
    System.out.println(t.getName());
}

Complete project

https://github.com/psamsotha/hk2-getting-started

Update: hk2-metadata-generator

The repo also includes a branch metadata-generator that makes use of the hk2-metadata-generator instead of the hk2-inhabitants-generator. The difference between the two is that the metadata-generator will create the inhabitants files during compilation. All it requires is to be on the classpath during compilation. This might be more natural to use. You can include the hk2-metadata-generator inside the maven-compiler-plugin configuration

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-compiler-plugin</artifactId>
    <version>3.8.1</version>
    <inherited>true</inherited>
    <configuration>
        <source>1.8</source>
        <target>1.8</target>
        <annotationProcessorPaths>
            <annotationProcessorPath>
                <groupId>org.glassfish.hk2</groupId>
                <artifactId>hk2-metadata-generator</artifactId>
                <version>${hk2.version}</version>
            </annotationProcessorPath>
        </annotationProcessorPaths>
    </configuration>
</plugin>

See also

Paul Samsotha
  • 205,037
  • 37
  • 486
  • 720
  • It's saying cannot invoke getName() because t is NULL – Daniel Wayne Jun 24 '21 at 04:20
  • Please clone the project, cd to the directory and run the command mentioned in the README. I just did it and it works fine. Output is "Mr. Miyagi". Please see what you are doing differently from the project. – Paul Samsotha Jun 24 '21 at 05:17
  • I pasted code snippets in your answers into the files, wrote required import statements, and than ran the file containing the last code snippet and it gave error. I will try to work with your git code – Daniel Wayne Jun 24 '21 at 05:23
  • The code in this post are just snippets. I linked to the repo for a full runnable example. – Paul Samsotha Jun 24 '21 at 05:38
  • I cloned your project and opened with eclipse. Still it's giving t is null error (Exception in thread "main" java.lang.NullPointerException: Cannot invoke "com.demo.Teacher.getName()" because "t" is null at com.demo.Main.main(Main.java:11)). Also I am getting error in the pom.xml file at line 40 : Plugin execution not covered by lifecycle configuration: org.glassfish.hk2:hk2-inhabitant-generator:3.0.2:generate-inhabitants (execution: default, phase: process-classes) . I am not getting any errors with import statements – Daniel Wayne Jun 24 '21 at 05:40
  • Please follow the instructions in my comments and README – Paul Samsotha Jun 24 '21 at 05:43
  • Different ways of running it will cause different outcomes. And I don't use Eclipse. No problems for me in IntelliJ – Paul Samsotha Jun 24 '21 at 05:45
  • After running the command it worked completely fine. It's printing "Mr. Miyagi" . What that command actually do ? We can also use HK2 with bind statements and in that case we don't need to run any command. Just pom.xml will do – Daniel Wayne Jun 24 '21 at 05:50
  • You can do that. Just use binders like you would with Jersey and register the binder with the ServiceLocator. You will have to programmatically bind all your services in the binder. It's also possible to use the metadata-generator with the maven-compiler-plugin. See [this post](https://stackoverflow.com/q/68066827/2587435) – Paul Samsotha Jun 24 '21 at 05:54
  • Where I can learn more about the command mentioned in your readme ? What it does and why we use it? – Daniel Wayne Jun 24 '21 at 05:56
  • All it is is the maven-exec-plugin. It just runs your main class using the goal `exec:java`. The plugin is declared in the pom. `clean` is to clear all the previously built artifacts and `package` is to rebuild the project. And `mvnw` is just a Maven wrapper like the Gradle wrapper so you are using the same Maven version and people can just run Maven without actually having to install Maven. You could run the same command with `mvn` instead of `./mvnw`. Same thing. – Paul Samsotha Jun 24 '21 at 05:57
  • can we run the Main.java file without using that command ? Only using pom.xml and importing HK2 libraries. – Daniel Wayne Jun 24 '21 at 08:30
  • Please pull the new branch I added to the repo `metadata-generator`. It uses the metadata-generator like I mentioned in my previous comment. I just tested it and you should be able to run the Main class from your IDE. I updated the answer – Paul Samsotha Jun 24 '21 at 09:02
  • In repo metadata-generator I still need to run the command $ ./mvnw clean package exec:java before executing the Main file else it gives "t is null". Is it possible to run the main without running that command ? – Daniel Wayne Jun 24 '21 at 10:48
  • Do you know what a Git branch is? It's not a new repository that I linked to. It is a branch in the same repo. You need to pull that branch. I think you're still running the code from the main branch. – Paul Samsotha Jun 24 '21 at 10:55
  • I used from here https://github.com/psamsotha/hk2-getting-started/tree/metadata-generator . I downloaded the zip and then ran – Daniel Wayne Jun 24 '21 at 11:09
  • Have you ever used Git before? If not, I suggest you just go to the link and look at the code. And change your code accordingly. You only need to change the pom file. – Paul Samsotha Jun 24 '21 at 11:11
  • Can you tell the command I need to use for downloading your project through GIT Bash. I have GIT Bash but I haven't used it before. Do you mean I only need to copy the pom.xml file in your new branch to the previous one ? – Daniel Wayne Jun 24 '21 at 11:33
  • I think the problem is that you do not have Maven installed in your Eclipse. I've tried downloading the branch the same way you did, and I opened the project in IntelliJ and and ran the Main class through the IDE and worked just fine. – Paul Samsotha Jun 24 '21 at 21:43
  • I was able to run the HK2 command though. How to do it without IDE ? using GIT Bash ? I have mvn installed on system and when I do mvn -version it displays the version – Daniel Wayne Jun 25 '21 at 03:36
  • mvn and mvnw are the same thing. Just mvnw is local to your project. Everything you can do with mvn you can do with mvnw. This is what I was trying to explain to you. And you don’t run anything with Git. Git is for version control. – Paul Samsotha Jun 25 '21 at 05:10
  • When I do mvn clean package, then I found .class files in target/classes/test. But when I try to run the main file (having main method) say MainFile.class by doing java test/MainFile it gives lot of exception (No class found error related to hk2 libraries I am importing ). Do you know how to resolve it ? I just wanted to run my files through command line without any IDE. (Please tell if I am not clear here I will try to elaborate my doubt more) – Daniel Wayne Jun 25 '21 at 10:29
  • Go to the official Java tutorial and learn about the classpath. You need all the libraries on the classpath. You said you know how to use Spring. How did you run those classes? What you're asking is completely off topic for this question and the comment section is not meant for this type of discussion. – Paul Samsotha Jun 25 '21 at 10:36
  • @DanielWayne If you have additional problems - consider asking a new question or allowing yourself some time to fully explore this answer. You're asking quite a bit of folks with back-to-back questions and our platform really isn't designed to handle this in comments. Thanks! – Tim Post Jun 25 '21 at 17:05
  • @TimPost I apologize to you for making so many comments. Will improve in future. – Daniel Wayne Jun 25 '21 at 17:40