What Is JHipster?
In this blog, you will learn more about JHipster and how it can help you with developing modern web applications. Enjoy!
Join the DZone community and get the full member experience.
Join For FreeIn this blog, you will learn more about JHipster and how it can help you with developing modern web applications. Enjoy!
1. Introduction
JHipster is a development platform that helps you quickly set up an application. It goes beyond setting up a project structure: JHipster will generate code, database tables, CRUD (Create, Read, Update, Delete) webpages, unit and integration tests, etc.
You are not bound to a specific framework or technology. Many options are available for server-side technologies (Spring Boot, Micronaut, Quarkus, etc.), databases (MySQL, MariaDB, PostgreSQL, MongoDB, etc.), build tooling (Maven, Gradle, Jenkins, GitLab CI, etc.), client-side technologies (Angular, React, Vue, etc.) and deployment (Docker, Kubernetes, AWS, GCP, etc.). The complete list can be found on the JHipster website. The list is huge and impressive.
JHipster exists since 2013, so it is definitely not a new kid on the block. Enough for the introduction; let’s get started in order to see how it works and what it looks like!
The sources used in this blog are available on GitHub.
2. Prerequisites
It is very useful when you have basic knowledge of how applications are built with Spring Boot, Vue.js, PostgreSQL, Liquibase, and Maven. If you do not have knowledge of these technologies, JHipster can be a stepping stone for you to see what such an application looks like.
The installation instructions for JHipster are executed based on the instructions provided on the JHipster website. It is good to check the official instructions in addition to the ones mentioned below.
Installation of JHipster requires Java (in this blog Java 17 is used, you can use SDKMAN to install Java), Git, and Node.js (Node.js v18.15.0 is used in this blog). See the respective websites for installation instructions.
Install JHipster:
$ sudo npm install -g generator-jhipster
Create a new directory myjhipsterplanet
and navigate into the directory:
$ mkdir myjhipsterplanet
$ cd myjhipsterplanet
3. Create JHipster Application
Creating a JHipster application requires answering some questions after running the jhipster
command. However, at the time of writing, executing the jhipster
command resulted in an error.
$ jhipster
INFO! Using bundled JHipster
node:internal/modules/cjs/loader:571
throw e;
^
Error [ERR_PACKAGE_PATH_NOT_EXPORTED]: Package subpath './lib/util/namespace' is not defined by "exports" in /usr/lib/node_modules/generator-jhipster/node_modules/yeoman-environment/package.json
at new NodeError (node:internal/errors:399:5)
at exportsNotFound (node:internal/modules/esm/resolve:361:10)
at packageExportsResolve (node:internal/modules/esm/resolve:697:9)
at resolveExports (node:internal/modules/cjs/loader:565:36)
at Module._findPath (node:internal/modules/cjs/loader:634:31)
at Module._resolveFilename (node:internal/modules/cjs/loader:1061:27)
at Module._load (node:internal/modules/cjs/loader:920:27)
at Module.require (node:internal/modules/cjs/loader:1141:19)
at require (node:internal/modules/cjs/helpers:110:18)
at Object.<anonymous> (/usr/lib/node_modules/generator-jhipster/utils/blueprint.js:19:25) {
code: 'ERR_PACKAGE_PATH_NOT_EXPORTED'
}
An issue exists for this problem, and a workaround is provided.
Open the package.json
file with a text editor.
$ sudo vi /usr/lib/node_modules/generator-jhipster/node_modules/yeoman-environment/package.json
Add the following line to the exports
section:
"exports": {
...,
"./lib/util/namespace": "./lib/util/namespace.js"
}
Executing the jhipster
command will be successful now. A list of questions will be asked in order for you to choose the technologies you want to use in the application. In bold, the answers are provided that are used for this blog.
- May JHipster anonymously report usage statistics to improve the tool over time? n
- Which type of application would you like to create? Monolithic application
- What is the base name of your application? (myjhipsterplanet)
- Do you want to make it reactive with Spring WebFlux? n
- What is your default Java package name? com.mydeveloperplanet.myjhipsterplanet
- Which type of authentication would you like to use? HTTP Session Authentication (stateful, default Spring Security mechanism)
- Which type of database would you like to use? SQL (H2, PostgreSQL, MySQL, MariaDB, Oracle, MSSQL)
- Which production database would you like to use? PostgreSQL
- Which development database would you like to use? H2 with disk-based persistence
- Which cache do you want to use? (Spring cache abstraction) No cache – Warning, when using an SQL database, this will disable the Hibernate 2nd level cache!
- Would you like to use Maven or Gradle for building the backend? Maven
- Do you want to use the JHipster Registry to configure, monitor and scale your application? Yes
- Which other technologies would you like to use? API first development using OpenAPI-generator
- Which Framework would you like to use for the client? Vue
- Do you want to generate the admin UI? Yes
- Would you like to use a Bootswatch theme (https://bootswatch.com/)? Default JHipster
- Would you like to enable internationalization support? No
- Please choose the native language of the application English
- Besides JUnit and Jest, which testing frameworks would you like to use? Do not choose any
- Would you like to install other generators from the JHipster Marketplace? No
In the end, the application is generated after a few minutes, and the changes are committed in Git.
$ git log
commit f03bf340c15315ffbeb59c56eec2b4da777f4e53
Author: mydeveloperplanet <gunter@mydeveloperplanet.com>
Date: Sun Mar 19 13:53:18 2023 +0100
Initial version of myjhipsterplanet generated by generator-jhipster@7.9.3
Build the project.
$ ./mvnw clean verify
Run the application.
$ java -jar target/myjhipsterplanet-0.0.1-SNAPSHOT.jar
...
----------------------------------------------------------
Application 'myjhipsterplanet' is running! Access URLs:
Local: http://localhost:8080/
External: http://127.0.1.1:8080/
Profile(s): [dev, api-docs]
----------------------------------------------------------
4. Create Entities
The above-generated application is quite empty because it contains no domain entities. JHipster provides the JDL-Studio for creating the domain entities. There are also IDE plugins available for JDL-Studio. JDL stands for JHipster Domain Language, and it is quite intuitive how to model your domain. In the example application, the domain consists out of a Company with a Location. A Company has one or more Customers and a Customer also has an Address.
The JDL for this domain is the following. As you can see, it is not very complicated.
entity Company {
companyName String required
}
entity Location {
streetAddress String,
postalCode String,
city String
}
entity Customer {
customerName String required
}
entity Address {
streetAddress String,
postalCode String,
city String
}
relationship OneToOne {
Location{company} to Company
}
relationship OneToMany {
Company to Customer{company}
}
relationship OneToOne {
Address{customer} to Customer
}
Add the customer.jdl
file to the root of the repository and generate the code with JHipster. During generating the files, you will be asked to overwrite some files, you can answer these questions with yes every time.
$ jhipster jdl customer.jdl
As a result, a .jhipster
directory is created containing JSON files for the domain entities.
.jhipster/
├── Address.json
├── Company.json
├── Customer.json
└── Location.json
Besides that, quite some code is generated.
$ git status
On branch master
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git restore <file>..." to discard changes in working directory)
modified: .yo-rc.json
modified: src/main/resources/config/liquibase/master.xml
modified: src/main/webapp/app/entities/entities-menu.vue
modified: src/main/webapp/app/entities/entities.component.ts
modified: src/main/webapp/app/router/entities.ts
Untracked files:
(use "git add <file>..." to include in what will be committed)
.jhipster/
customer.jdl
src/main/java/com/mydeveloperplanet/myjhipsterplanet/domain/Address.java
src/main/java/com/mydeveloperplanet/myjhipsterplanet/domain/Company.java
src/main/java/com/mydeveloperplanet/myjhipsterplanet/domain/Customer.java
src/main/java/com/mydeveloperplanet/myjhipsterplanet/domain/Location.java
src/main/java/com/mydeveloperplanet/myjhipsterplanet/repository/AddressRepository.java
src/main/java/com/mydeveloperplanet/myjhipsterplanet/repository/CompanyRepository.java
src/main/java/com/mydeveloperplanet/myjhipsterplanet/repository/CustomerRepository.java
src/main/java/com/mydeveloperplanet/myjhipsterplanet/repository/LocationRepository.java
src/main/java/com/mydeveloperplanet/myjhipsterplanet/web/rest/AddressResource.java
src/main/java/com/mydeveloperplanet/myjhipsterplanet/web/rest/CompanyResource.java
src/main/java/com/mydeveloperplanet/myjhipsterplanet/web/rest/CustomerResource.java
src/main/java/com/mydeveloperplanet/myjhipsterplanet/web/rest/LocationResource.java
src/main/resources/config/liquibase/changelog/20230319134139_added_entity_Company.xml
src/main/resources/config/liquibase/changelog/20230319134140_added_entity_Location.xml
src/main/resources/config/liquibase/changelog/20230319134140_added_entity_constraints_Location.xml
src/main/resources/config/liquibase/changelog/20230319134141_added_entity_Customer.xml
src/main/resources/config/liquibase/changelog/20230319134141_added_entity_constraints_Customer.xml
src/main/resources/config/liquibase/changelog/20230319134142_added_entity_Address.xml
src/main/resources/config/liquibase/changelog/20230319134142_added_entity_constraints_Address.xml
src/main/resources/config/liquibase/fake-data/
src/main/webapp/app/entities/address/
src/main/webapp/app/entities/company/
src/main/webapp/app/entities/customer/
src/main/webapp/app/entities/location/
src/main/webapp/app/shared/model/address.model.ts
src/main/webapp/app/shared/model/company.model.ts
src/main/webapp/app/shared/model/customer.model.ts
src/main/webapp/app/shared/model/location.model.ts
src/test/java/com/mydeveloperplanet/myjhipsterplanet/domain/
src/test/java/com/mydeveloperplanet/myjhipsterplanet/web/rest/AddressResourceIT.java
src/test/java/com/mydeveloperplanet/myjhipsterplanet/web/rest/CompanyResourceIT.java
src/test/java/com/mydeveloperplanet/myjhipsterplanet/web/rest/CustomerResourceIT.java
src/test/java/com/mydeveloperplanet/myjhipsterplanet/web/rest/LocationResourceIT.java
src/test/javascript/spec/app/entities/
What has been generated/updated?
- Liquibase database migration scripts, including fake test data;
- Domain objects for the entities;
- Repositories for the domain objects;
- REST endpoints for the entities;
- Entities and pages for the frontend;
- Integration tests for the REST endpoints;
- Test for the frontend pages.
5. Generated Application
You have generated an application with JHipster based on a basic domain model. What does this look like? Build and run the application with the above-generated code and open the application. A welcome page is shown.
Click at the right top bottom and choose Sign In. Sign in with user admin and password admin. In the menu at the top, you choose Entities and you will see items for each entity you created. Select Companies. A page is shown with the fake data and as you can see, CRUD operations are available.
Navigate to the Customer entity and edit a Customer. An edit screen is shown. A Customer belongs to a Company. However, the generated code lets you select the Company based on the database identifier. This is not very user-friendly of course, so you will need to change that.
Because you are logged in as an administrator user, you also have the Administration pages. Let’s take a look at the different administration pages.
User Management is used for managing the users in the application.
Metrics shows all kinds of metrics, for example, the counts for each request.
Health gives information about the state of the application.
Configuration shows information how the application is configured, basically the application properties.
Logs provides easy access to the logs and their respective log levels.
API shows the Swagger documentation of the API.
Database provides access to the database. In this application, you do not need to provide any credentials. Just click the Connect button.
And now you can browse the database.
The Administration pages provide quite some information out-of-the-box. You did not need to develop anything for this.
6. Sonar Analysis
Sonar analysis is also provided. Therefore, you need to start a local Sonar server.
$ docker compose -f src/main/docker/sonar.yml up -d
And run the Sonar analysis.
$ ./mvnw -Pprod clean verify sonar:sonar
As a result, you can browse the Sonar results. As you can see, the result for the overall code is quite good, and there is a test coverage of 72.9%. That’s not bad at all.
7. Update Dependencies
The generated JHipster code used Java 11 and some older dependencies. The versions are listed in the pom file.
<properties>
<!-- Build properties -->
<maven.version>3.2.5</maven.version>
<java.version>11</java.version>
<node.version>v16.17.0</node.version>
<npm.version>8.19.1</npm.version>
...
</properties>
Change these to a more recent version.
<properties>
<!-- Build properties -->
<maven.version>3.8.7</maven.version>
<java.version>17</java.version>
<node.version>v18.5.0</node.version>
<npm.version>8.19.4</npm.version>
...
</properties>
Build and run the application (a local Maven installation was used for this instead of the Maven wrapper). Everything still worked fine after this update.
8. Conclusion
In this blog, you learned how to create a basic application generated with JHipster. Quite some code and functionality is generated, which gives you a good start for changing the application in order that it fits your needs. You only scratched the surface of JHipster in this blog, so do read the official documentation in order to get more acquainted with JHipster.
Published at DZone with permission of Gunter Rotsaert, DZone MVB. See the original article here.
Opinions expressed by DZone contributors are their own.
Comments