Skip to content

Session 3

Maven and frameworks for J2EE

Updated View as Markdown

Maven manages dependencies and the build so that Spring and Hibernate can be added by editing one file. This session sets up the project skeletons every later session builds on, and introduces inversion of control.

All four questions work on one Maven project, student-admission, which Sessions 4, 5 and 6 keep extending. Sessions 3 to 6 use classic Spring MVC 6 deployed as a WAR on Tomcat 10.1 (the manual calls this a “J2EE application”); Session 7 switches the same project to Spring Boot.

Objectives

Do not copy. Read for understanding and the viva
  • Complete questions 13 to 16 of the manual: maven and frameworks for j2ee
  • Prepare the deliverable before the lab and finish it during the session
  • Be ready to explain every step in the viva

Questions Covered

Do not copy. Read for understanding and the viva
QuestionRequirementStatus
Q13Create a Maven-based project using Spring InitializrComplete
Q14Create a Maven-based J2EE application for Spring MVCComplete
Q15Create a Maven-based J2EE application for Hibernate and JPA. Use the same database…Complete
Q16Define a new implementation of Teacher Interface for his/her favourite Course in…Complete

Preparation

Do not copy. Read for understanding and the viva
  • Generate a project at start.spring.io with the Spring Web dependency, then import it into the IDE as a Maven project.
  • Know what pom.xml contains: groupId, artifactId, dependencies, plugins. Be ready to explain what Maven downloads and where (~/.m2).
  • Inversion of control: the container creates the Teacher implementation and hands it to your code; you never call new.

Question 13

Problem Statement

Write in lab record

Create a Maven-based project using Spring Initializr.

Solution

Write in lab record

Steps

  1. Install JDK 17, Maven 3.9 and Eclipse IDE for Enterprise Java (or NetBeans / IntelliJ). Check with java -version and mvn -v.
  2. Open start.spring.io and fill the form: Project Maven, Language Java, Spring Boot latest stable 3.x, Group com.ignou.lab, Artifact student-admission, Name student-admission, Package name com.ignou.lab.admission, Packaging War, Java 17.
  3. Click Add dependencies and pick Spring Web. Click Generate; student-admission.zip downloads.
  4. Unzip into your workspace. Look at the tree: pom.xml, mvnw, src/main/java/com/ignou/lab/admission/StudentAdmissionApplication.java and ServletInitializer.java, src/main/resources/application.properties, src/test/java.
  5. Eclipse: File → Import → Maven → Existing Maven Projects → Root Directory = the unzipped folder → Finish. Maven downloads every dependency into ~/.m2/repository (internet needed; wait for the progress bar in the bottom right).
  6. Build once from a terminal in the project folder: mvn -q package. target/student-admission-0.0.1-SNAPSHOT.war appears.

Program

The generated pom.xml, unchanged:

pom.xml (generated by Spring Initializr)xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>3.3.5</version>
    <relativePath/> <!-- lookup parent from repository -->
  </parent>
  <groupId>com.ignou.lab</groupId>
  <artifactId>student-admission</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  <packaging>war</packaging>
  <name>student-admission</name>
  <description>Lab project for Student Admission</description>
  <properties>
    <java.version>17</java.version>
  </properties>
  <dependencies>
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-tomcat</artifactId>
      <scope>provided</scope>
    </dependency>
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-test</artifactId>
      <scope>test</scope>
    </dependency>
  </dependencies>
  <build>
    <plugins>
      <plugin>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-maven-plugin</artifactId>
      </plugin>
    </plugins>
  </build>
</project>

Output

Expected result, checked by reading (no JDK or Maven is available where this page was written):

$ mvn -q package
$ ls target
classes  generated-sources  maven-archiver  student-admission-0.0.1-SNAPSHOT  student-admission-0.0.1-SNAPSHOT.war  ...

A full mvn package ends with BUILD SUCCESS and the time taken. Eclipse shows the project with a small “M” decorator and a Maven Dependencies library.

Explanation

  • Spring Initializr writes a correct pom.xml so nobody types dependency coordinates by hand. The parent block imports Spring Boot’s dependency management: child dependencies need no version numbers.
  • groupId is the organisation, artifactId the project, together with version they name the WAR in ~/.m2 and in target/.
  • packaging is war because the manual deploys on Tomcat. The spring-boot-starter-tomcat dependency is provided, so the WAR does not carry a second Tomcat.
  • Maven phases: compile → test → package → install. mvn package runs everything up to and including packaging.

Question 14

Problem Statement

Write in lab record

Create a Maven-based J2EE application for Spring MVC.

Solution

Write in lab record

Steps

  1. Keep the folder from Q13. Replace pom.xml with the listing below (plain Spring 6, no Boot parent). Delete StudentAdmissionApplication.java, ServletInitializer.java, application.properties and the src/test folder; they belong to Spring Boot and return in Session 7.
  2. Right-click the project → Maven → Update Project → OK. The spring-webmvc jar and its dependencies download.
  3. Create WebAppInitializer.java and WebConfig.java in com.ignou.lab.admission, and HomeController.java in com.ignou.lab.admission.web.
  4. Create the folder src/main/webapp/WEB-INF/views/ and put home.jsp in it.
  5. Build: mvn -q package → target/student-admission.war (the finalName in the pom drops the version).
  6. Deploy: copy the WAR to $CATALINA_HOME/webapps/ and start Tomcat 10.1 with bin/startup.sh (or in Eclipse: Servers view → Tomcat v10.1 → Add and Remove → add the project → Start).
  7. Open http://localhost:8080/student-admission/.

Program

Lab record: every tab is one file of the answer. Write all of them.

pom.xmlxml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.ignou.lab</groupId>
  <artifactId>student-admission</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  <packaging>war</packaging>
  <name>student-admission</name>
  <description>Lab project for Student Admission using Spring MVC (classic, Tomcat 10.1)</description>

  <properties>
    <maven.compiler.release>17</maven.compiler.release>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <spring.version>6.1.14</spring.version>
  </properties>

  <dependencies>
    <!-- Spring MVC: DispatcherServlet, controllers, form tags -->
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-webmvc</artifactId>
      <version>${spring.version}</version>
    </dependency>
    <!-- Servlet API: Tomcat 10.1 provides it at run time -->
    <dependency>
      <groupId>jakarta.servlet</groupId>
      <artifactId>jakarta.servlet-api</artifactId>
      <version>6.0.0</version>
      <scope>provided</scope>
    </dependency>
    <!-- JSTL 3.0 (Jakarta namespace) for c:forEach and c:out in JSPs -->
    <dependency>
      <groupId>jakarta.servlet.jsp.jstl</groupId>
      <artifactId>jakarta.servlet.jsp.jstl-api</artifactId>
      <version>3.0.0</version>
    </dependency>
    <dependency>
      <groupId>org.glassfish.web</groupId>
      <artifactId>jakarta.servlet.jsp.jstl</artifactId>
      <version>3.0.1</version>
    </dependency>
  </dependencies>

  <build>
    <finalName>student-admission</finalName>
    <plugins>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-compiler-plugin</artifactId>
        <version>3.13.0</version>
      </plugin>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-war-plugin</artifactId>
        <version>3.4.0</version>
        <configuration>
          <!-- no web.xml: WebAppInitializer registers the DispatcherServlet -->
          <failOnMissingWebXml>false</failOnMissingWebXml>
        </configuration>
      </plugin>
    </plugins>
  </build>
</project>
WebAppInitializer.javajava
package com.ignou.lab.admission;

import jakarta.servlet.Filter;
import org.springframework.web.filter.CharacterEncodingFilter;
import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;

/**
 * Replaces web.xml. Tomcat finds this class through the Servlet 3+
 * ServletContainerInitializer mechanism and it registers the DispatcherServlet.
 */
public class WebAppInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {

    @Override
    protected Class<?>[] getRootConfigClasses() {
        return null; // one context is enough for this lab
    }

    @Override
    protected Class<?>[] getServletConfigClasses() {
        return new Class<?>[] { WebConfig.class };
    }

    @Override
    protected String[] getServletMappings() {
        return new String[] { "/" };
    }

    @Override
    protected Filter[] getServletFilters() {
        return new Filter[] { new CharacterEncodingFilter("UTF-8", true) };
    }
}
WebConfig.javajava
package com.ignou.lab.admission;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import org.springframework.web.servlet.view.InternalResourceViewResolver;

@Configuration
@EnableWebMvc
@ComponentScan("com.ignou.lab.admission")
public class WebConfig implements WebMvcConfigurer {

    /** "home" returned from a controller becomes /WEB-INF/views/home.jsp */
    @Bean
    public InternalResourceViewResolver viewResolver() {
        return new InternalResourceViewResolver("/WEB-INF/views/", ".jsp");
    }
}
HomeController.javajava
package com.ignou.lab.admission.web;

import java.time.LocalDateTime;
import org.springframework.core.SpringVersion;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;

@Controller
public class HomeController {

    @GetMapping("/")
    public String home(Model model) {
        model.addAttribute("springVersion", SpringVersion.getVersion());
        model.addAttribute("now", LocalDateTime.now());
        return "home";
    }
}
WEB-INF/views/home.jsphtml
<%@ page contentType="text/html;charset=UTF-8" %>
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Student Admission</title>
</head>
<body>
  <h1>Welcome to the Lab Project for Student Admission using Spring MVC</h1>
  <p>Spring Framework version: ${springVersion}</p>
  <p>Server time: ${now}</p>
  <p><a href="${pageContext.request.contextPath}/students">Students in the IGNOU database</a></p>
</body>
</html>

Output

Expected browser result at /student-admission/, checked by reading, not executed:

Welcome to the Lab Project for Student Admission using Spring MVC
Spring Framework version: 6.1.14
Server time: 2026-09-26T10:42:07.118
Students in the IGNOU database   (link; works after Q15)

Tomcat’s catalina.out shows Initializing Spring DispatcherServlet 'dispatcher' followed by Completed initialization when the WAR starts.

Explanation

  • No web.xml: Tomcat calls WebAppInitializer because it extends AbstractAnnotationConfigDispatcherServletInitializer. It registers a DispatcherServlet on / backed by WebConfig, plus a UTF-8 CharacterEncodingFilter so Indian-language names survive form posts.
  • @EnableWebMvc switches on annotation-driven controllers, @ComponentScan finds every @Controller, @Service, @Repository and @Configuration under com.ignou.lab.admission.
  • InternalResourceViewResolver turns the string "home" into /WEB-INF/views/home.jsp. JSPs under WEB-INF cannot be opened directly; only a controller can forward to them.
  • jakarta.servlet-api is provided: Tomcat has it. JSTL 3.0 is bundled because Tomcat does not ship it; its tag URI is jakarta.tags.core, not the old java.sun.com one.

Question 15

Problem Statement

Write in lab record

Create a Maven-based J2EE application for Hibernate and JPA. Use the same database created in Exercise no. 5 of Session 1.

Solution

Write in lab record

Steps

  1. Make sure the ignou database and its student table from Session 1 exist. If you are starting fresh, run ignou-student.sql in MySQL Workbench (Query tab → paste → Execute) or mysql -u root -p < ignou-student.sql.
  2. Add the three dependencies from pom-hibernate-fragment.xml inside the dependencies element of pom.xml, then Maven → Update Project.
  3. Add src/main/resources/db.properties with your MySQL user and password.
  4. Create JpaConfig.java next to WebConfig.java, Student.java in com.ignou.lab.admission.entity, StudentRepository.java in com.ignou.lab.admission.repo, StudentController.java in com.ignou.lab.admission.web and students.jsp in WEB-INF/views.
  5. Rebuild and redeploy. Open http://localhost:8080/student-admission/students.

Program

Lab record: every tab is one file of the answer. Write all of them.

pom.xml (Q15 additions)xml
<!-- Q15: add inside <dependencies> of pom.xml, then Maven > Update Project -->
<!-- Spring's JPA glue: LocalContainerEntityManagerFactoryBean, JpaTransactionManager -->
<dependency>
  <groupId>org.springframework</groupId>
  <artifactId>spring-orm</artifactId>
  <version>${spring.version}</version>
</dependency>
<!-- Hibernate 6 = JPA 3.1 provider; pulls in jakarta.persistence-api -->
<dependency>
  <groupId>org.hibernate.orm</groupId>
  <artifactId>hibernate-core</artifactId>
  <version>6.6.3.Final</version>
</dependency>
<!-- MySQL Connector/J 8 (driver class com.mysql.cj.jdbc.Driver) -->
<dependency>
  <groupId>com.mysql</groupId>
  <artifactId>mysql-connector-j</artifactId>
  <version>8.4.0</version>
</dependency>
ignou-student.sqlsql
-- Student table of the IGNOU database created in Session 1, Question 5.
-- If your Session 1 table used other column names, change the @Column names
-- in Student.java; hibernate.hbm2ddl.auto=update adds any column that is missing.
CREATE DATABASE IF NOT EXISTS ignou;
USE ignou;

CREATE TABLE IF NOT EXISTS student (
  id              BIGINT AUTO_INCREMENT PRIMARY KEY,
  enrolment_no    VARCHAR(12) UNIQUE,
  name            VARCHAR(80)  NOT NULL,
  email           VARCHAR(120) NOT NULL,
  mobile          VARCHAR(10)  NOT NULL,
  dob             DATE         NOT NULL,
  address         VARCHAR(255),
  programme       VARCHAR(10)  NOT NULL,
  courses         VARCHAR(255),
  hostel_required BIT(1)       NOT NULL DEFAULT 0
);

INSERT INTO student (enrolment_no, name, email, mobile, dob, address, programme, courses, hostel_required) VALUES
  ('2201234567', 'Asha Verma',  'asha@example.com',  '9876543210', '2003-04-12', 'Sector 4, Rohini, Delhi', 'MCA', 'MCS-218,MCS-220', 1),
  ('2201234568', 'Rahul Singh', 'rahul@example.com', '9123456780', '2002-11-30', 'Boring Road, Patna',      'MCA', 'MCS-219',         0);
db.propertiesproperties
# src/main/resources/db.properties
db.driver=com.mysql.cj.jdbc.Driver
db.url=jdbc:mysql://localhost:3306/ignou
db.username=root
db.password=Ignou@1234
JpaConfig.javajava
package com.ignou.lab.admission;

import java.util.Properties;
import javax.sql.DataSource;
import jakarta.persistence.EntityManagerFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import org.springframework.core.env.Environment;
import org.springframework.jdbc.datasource.DriverManagerDataSource;
import org.springframework.orm.jpa.JpaTransactionManager;
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;

/**
 * Hibernate 6 as the JPA provider, wired by Spring. Picked up by the
 * component scan in WebConfig, so nothing else needs to change.
 */
@Configuration
@EnableTransactionManagement
@PropertySource("classpath:db.properties")
public class JpaConfig {

    @Bean
    public DataSource dataSource(Environment env) {
        // ponytail: no connection pool; switch to HikariDataSource when more than one user hits the app
        DriverManagerDataSource ds = new DriverManagerDataSource();
        ds.setDriverClassName(env.getRequiredProperty("db.driver"));
        ds.setUrl(env.getRequiredProperty("db.url"));
        ds.setUsername(env.getRequiredProperty("db.username"));
        ds.setPassword(env.getRequiredProperty("db.password"));
        return ds;
    }

    @Bean
    public LocalContainerEntityManagerFactoryBean entityManagerFactory(DataSource dataSource) {
        LocalContainerEntityManagerFactoryBean emf = new LocalContainerEntityManagerFactoryBean();
        emf.setDataSource(dataSource);
        emf.setPackagesToScan("com.ignou.lab.admission.entity");
        emf.setJpaVendorAdapter(new HibernateJpaVendorAdapter());
        Properties props = new Properties();
        props.put("hibernate.hbm2ddl.auto", "update"); // adds missing columns, never drops
        props.put("hibernate.show_sql", "true");
        props.put("hibernate.format_sql", "true");
        emf.setJpaProperties(props);
        return emf;
    }

    @Bean
    public PlatformTransactionManager transactionManager(EntityManagerFactory emf) {
        return new JpaTransactionManager(emf);
    }
}
entity/Student.javajava
package com.ignou.lab.admission.entity;

import java.time.LocalDate;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.Table;

/** Maps the student table of the IGNOU database from Session 1. */
@Entity
@Table(name = "student")
public class Student {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @Column(name = "enrolment_no", length = 12, unique = true)
    private String enrolmentNo;

    @Column(nullable = false, length = 80)
    private String name;

    @Column(nullable = false, length = 120)
    private String email;

    @Column(nullable = false, length = 10)
    private String mobile;

    @Column(nullable = false)
    private LocalDate dob;

    @Column(length = 255)
    private String address;

    @Column(nullable = false, length = 10)
    private String programme;

    /** comma-separated course codes, as stored by the Session 1 servlet */
    @Column(length = 255)
    private String courses;

    @Column(name = "hostel_required")
    private Boolean hostelRequired;

    public Long getId() { return id; }
    public void setId(Long id) { this.id = id; }
    public String getEnrolmentNo() { return enrolmentNo; }
    public void setEnrolmentNo(String enrolmentNo) { this.enrolmentNo = enrolmentNo; }
    public String getName() { return name; }
    public void setName(String name) { this.name = name; }
    public String getEmail() { return email; }
    public void setEmail(String email) { this.email = email; }
    public String getMobile() { return mobile; }
    public void setMobile(String mobile) { this.mobile = mobile; }
    public LocalDate getDob() { return dob; }
    public void setDob(LocalDate dob) { this.dob = dob; }
    public String getAddress() { return address; }
    public void setAddress(String address) { this.address = address; }
    public String getProgramme() { return programme; }
    public void setProgramme(String programme) { this.programme = programme; }
    public String getCourses() { return courses; }
    public void setCourses(String courses) { this.courses = courses; }
    public Boolean getHostelRequired() { return hostelRequired; }
    public void setHostelRequired(Boolean hostelRequired) { this.hostelRequired = hostelRequired; }

    @Override
    public String toString() {
        return "Student[id=" + id + ", enrolmentNo=" + enrolmentNo + ", name=" + name
                + ", programme=" + programme + ", courses=" + courses + "]";
    }
}
repo/StudentRepository.javajava
package com.ignou.lab.admission.repo;

import java.util.List;
import jakarta.persistence.EntityManager;
import jakarta.persistence.PersistenceContext;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;
import com.ignou.lab.admission.entity.Student;

@Repository
@Transactional
public class StudentRepository {

    @PersistenceContext
    private EntityManager em;

    @Transactional(readOnly = true)
    public List<Student> findAll() {
        return em.createQuery("from Student s order by s.id", Student.class).getResultList();
    }
}
web/StudentController.javajava
package com.ignou.lab.admission.web;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import com.ignou.lab.admission.repo.StudentRepository;

@Controller
public class StudentController {

    private final StudentRepository repo;

    public StudentController(StudentRepository repo) {
        this.repo = repo;
    }

    @GetMapping("/students")
    public String list(Model model) {
        model.addAttribute("students", repo.findAll());
        return "students";
    }
}
WEB-INF/views/students.jsphtml
<%@ page contentType="text/html;charset=UTF-8" %>
<%@ taglib prefix="c" uri="jakarta.tags.core" %>
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Students</title>
</head>
<body>
  <h1>Students (IGNOU database, via Hibernate/JPA)</h1>
  <table border="1" cellpadding="4">
    <tr><th>Id</th><th>Enrolment No</th><th>Name</th><th>Email</th><th>DOB</th><th>Programme</th><th>Courses</th></tr>
    <c:forEach items="${students}" var="s">
      <tr>
        <td>${s.id}</td>
        <td><c:out value="${s.enrolmentNo}"/></td>
        <td><c:out value="${s.name}"/></td>
        <td><c:out value="${s.email}"/></td>
        <td>${s.dob}</td>
        <td><c:out value="${s.programme}"/></td>
        <td><c:out value="${s.courses}"/></td>
      </tr>
    </c:forEach>
  </table>
  <p><a href="${pageContext.request.contextPath}/">Home</a></p>
</body>
</html>

Output

Expected, checked by reading, not executed. Tomcat’s console shows the SQL Hibernate ran because show_sql is on:

Hibernate:
    select
        s1_0.id,
        s1_0.address,
        s1_0.courses,
        ...
    from
        student s1_0
    order by
        s1_0.id

The browser table at /students lists the two seeded rows: 2201234567 Asha Verma ... MCA MCS-218,MCS-220 and 2201234568 Rahul Singh ... MCA MCS-219. If db.properties has a wrong password, deployment fails with Access denied for user 'root'@'localhost' in the log.

Explanation

  • JPA is the standard API (jakarta.persistence); Hibernate is the provider that implements it. Code talks to EntityManager, Hibernate translates to MySQL SQL.
  • LocalContainerEntityManagerFactoryBean scans the entity package for @Entity classes and builds one EntityManagerFactory when Tomcat starts. JpaTransactionManager plus @EnableTransactionManagement make @Transactional methods open and commit a transaction.
  • @PersistenceContext injects a thread-safe EntityManager proxy; each transaction gets its own real one.
  • hibernate.hbm2ddl.auto=update compares the entity with the table and adds missing columns (here hostel_required), so an older Session 1 table keeps working. It never drops or alters existing columns.
  • @Transactional(readOnly = true) on findAll lets Hibernate skip dirty checking; the JSP receives plain entity objects.

Question 16

Problem Statement

Write in lab record

Define a new implementation of Teacher Interface for his/her favourite Course in Spring using Inversion of Control and retrieving the information from the new teacher implementation.

Solution

Write in lab record

Steps

  1. Create package com.ignou.lab.admission.ioc with Teacher.java, JavaTeacher.java and TeacherApp.java.
  2. Run TeacherApp as a plain Java program: right-click → Run As → Java Application, or from the terminal mvn -q compile exec:java -Dexec.mainClass=com.ignou.lab.admission.ioc.TeacherApp.
  3. Add a second implementation (say NetworksTeacher returning MCS-218) and run again to see Spring refuse with NoUniqueBeanDefinitionException; remove it or add @Primary to one. This is the viva question.

Program

Lab record: every tab is one file of the answer. Write all of them.

ioc/Teacher.javajava
package com.ignou.lab.admission.ioc;

public interface Teacher {
    String getName();
    String getFavouriteCourse();
}
ioc/JavaTeacher.javajava
package com.ignou.lab.admission.ioc;

import org.springframework.stereotype.Component;

/** New implementation of Teacher. The container creates it; nobody calls new. */
@Component
public class JavaTeacher implements Teacher {

    @Override
    public String getName() {
        return "Dr. Rao";
    }

    @Override
    public String getFavouriteCourse() {
        return "MCS-220 Web Technologies";
    }
}
ioc/TeacherApp.javajava
package com.ignou.lab.admission.ioc;

import org.springframework.context.annotation.AnnotationConfigApplicationContext;

public class TeacherApp {

    public static void main(String[] args) {
        try (var ctx = new AnnotationConfigApplicationContext(JavaTeacher.class)) {
            Teacher teacher = ctx.getBean(Teacher.class); // asked for by interface, not by class
            System.out.println("Bean class : " + teacher.getClass().getSimpleName());
            System.out.println(teacher.getName() + " prefers " + teacher.getFavouriteCourse());
        }
    }
}

Output

Expected console output, checked by reading, not executed:

Bean class : JavaTeacher
Dr. Rao prefers MCS-220 Web Technologies

Explanation

  • Inversion of control: TeacherApp never writes new JavaTeacher(). It hands the class to AnnotationConfigApplicationContext, the container instantiates it, and the program asks for it by the interface Teacher.
  • @Component marks the class as a bean. Because the request is by interface, swapping in another implementation touches one file only.
  • The context is AutoCloseable; the try-with-resources closes it and destroys the beans.
  • Session 4 injects a CourseService into JavaTeacher so that the favourite course changes on every call.

Viva Questions

Do not copy. Read for understanding and the viva
  • Q: What does Maven download and where does it keep it? A: Every dependency jar and its transitive dependencies, in the local repository ~/.m2/repository, keyed by groupId, artifactId and version.
  • Q: Why is the servlet API marked provided? A: Tomcat already has it; shipping a second copy inside the WAR causes class-loading clashes.
  • Q: Where is web.xml? A: Not needed. WebAppInitializer uses the Servlet 3+ initializer API to register the DispatcherServlet in code.
  • Q: What is the difference between JPA and Hibernate? A: JPA is the specification (annotations and EntityManager); Hibernate is one implementation of it and also has its own Session API.
  • Q: What does hbm2ddl.auto=update do, and would you use it in production? A: Adds missing tables and columns at start-up. No; production schemas are migrated with scripts.
  • Q: What is inversion of control? A: The container creates objects and wires them; application code asks for them instead of constructing them.
  • Q: Why ask for the bean by interface rather than by JavaTeacher? A: So the caller does not depend on one implementation; a different teacher can be plugged in without changing TeacherApp.

Common Mistakes

Do not copy. Read for understanding and the viva
  • Using javax.servlet or javax.persistence imports. Tomcat 10 and Spring 6 use the jakarta packages; the old ones compile and then fail at run time.
  • Forgetting Maven → Update Project after editing pom.xml, then reporting “cannot resolve import”.
  • Writing the JSTL taglib URI as http://java.sun.com/jsp/jstl/core; with JSTL 3 on Tomcat 10 it is jakarta.tags.core.
  • Committing db.properties with the real root password. Use a lab user with rights on one database.
  • Putting JSPs outside WEB-INF/views; they are then reachable without a controller and the view resolver prefix no longer matches.

Session Summary

Write in lab record
  • Question 13: Spring Initializr project student-admission (Maven, WAR, Java 17), imported and built with mvn package
  • Question 14: classic Spring MVC 6 on Tomcat 10.1: pom.xml, WebAppInitializer, WebConfig, HomeController, home.jsp
  • Question 15: Hibernate 6 / JPA on the Session 1 ignou database: JpaConfig, Student entity, StudentRepository, /students page
  • Question 16: Teacher interface with JavaTeacher created by the Spring container and read back through the interface
Navigation

Type to search…

↑↓ navigate↵ selectEsc close