This document describes the steps to install and configure XWiki as a knowledge base site. The production information can be found in https://www.xwiki.org/.
Thursday, August 21, 2025
Installation and Configuration XWiki
Tuesday, January 28, 2025
Wildfly upgrade for Java Server Faces
applications
Background
This document describes the basic changes for migrating JSF 2 applications from Wildfly v20 (JBOSS Enterprise Application Platform 7) to v30+ (or JBOSS EAP 8) – for version mapping between Wildfly and Jboss EAP, please refer to Appendix. The main changes in the later versions of Wildfly/Jboss EAP are package rename and deprecation. For example, the old javax.faces.* packages are renamed to jakarta.faces.*. This will need the Java library dependency changes and the reference updates in the application source code. Also some changes are required in the application configuration and web application deployment descriptors (eg web.xml).
Preparation
Download and install Wildfly 35, WildFly Downloads
Configure the application server supporting libraries if needed. Like the previous application server, ojdbc libraries may need to be copied to the application server, %JBOSS_HOME%\modules\system\layers\base.
Set up admin account (use %JBOSS_HOME%\bin\add-user.bat) for accessing the Wildfly/Jboss EAP admin console: http://localhost:9990
Basic Changes
replace the library references in project configuration file (eg pom.xml in Apache Maven)
update the references in the source code based on the new libraries. If no new libraries to use, may need to consider to rewrite certain application functions.
compile and package the application and fix any compile errors
deploy the application package to the running application server and fix any deployment errors
test the application and fix the runtime errors
Maven project file, pom.xml
Update the library dependencies as the following. Find updated 3rd party library dependencies from Maven Repository: Search/Browse/Explore. For the new versions, look at what’s bundled with the wildfly. Eg in %JBOSS_HOME%\modules\system\layers\base\*
Name |
Old Library (to be replaced) |
New Library |
jUnit |
3.x |
4.x |
JAXB API |
javax.xml.bind > jaxb-api |
jakarta.xml.bind > jakarta.xml.bind-api |
JSF API |
com.sun.faces > jsf-api |
jakarta.platform > jakarta.jakartaee-api |
JSF IMPL |
com.sun.faces > jsf-api |
|
CDI Support |
|
jakarta.enterprise > jakarta.enterprise.cdi-api |
Java Servlet |
javax.servlet > javax.servlet-api |
jakarta.servlet > jakarta.servlet-api |
Expression Language |
javax.el > javax.el-api |
jakarta.el > jakarta.el-api |
JSTL (taglib) |
javax.servlet.jsp.jstl > jstl-api |
jakarta.servlet.jsp.jstl > jakarta.servlet.jsp.jstl-api |
JEE API |
Javax > javaee-api |
(upgrade the version only if needed) |
JMS |
(the libs with JEE API may not work) |
jakarta.jms > jakarta.jms-api
|
RESTful WS API |
javax.ws.rs > javax.ws.rs-api |
jakarta.ws.rs > jakarta.ws.rs-api |
OJDBC |
com.oracle > ojdbc |
(upgrade the version only if needed) |
Hibernate |
org.hibernate > hibernate-core |
org.hibernate.orm > hibernate-core |
Plugins update with new versions |
||
org.apache.maven.plugins > maven-compiler-plugin |
||
org.apache.maven.plugins > maven-resources-plugin |
||
org.apache.maven.plugins > maven-war-plugin |
||
Package reference rename in application source code
Change imports with the new package names from the above new libraries
The following list contains the new references:
import jakarta.annotation.PostConstruct;
import jakarta.el.ELResolver;
import jakarta.enterprise.context.ApplicationScoped;
import jakarta.enterprise.context.RequestScoped;
import jakarta.enterprise.context.SessionScoped;
import jakarta.enterprise.inject.Disposes;
import jakarta.enterprise.inject.Produces;
import jakarta.faces.application.FacesMessage;
import jakarta.faces.context.FacesContext;
import jakarta.faces.event.AjaxBehaviorEvent;
import jakarta.faces.event.PhaseEvent;
import jakarta.faces.event.PhaseId;
import jakarta.faces.event.PhaseListener;
import jakarta.faces.model.SelectItem;
import jakarta.inject.Inject;
import jakarta.inject.Named;
import jakarta.jms.BytesMessage;
import jakarta.jms.Queue;
import jakarta.jms.QueueConnection;
import jakarta.jms.QueueConnectionFactory;
import jakarta.jms.QueueSender;
import jakarta.jms.QueueSession;
import jakarta.persistence.CascadeType;
import jakarta.persistence.Column;
import jakarta.persistence.ElementCollection;
import jakarta.persistence.Entity;
import jakarta.persistence.EntityManager;
import jakarta.persistence.EntityManagerFactory;
import jakarta.persistence.EntityTransaction;
import jakarta.persistence.FetchType;
import jakarta.persistence.Id;
import jakarta.persistence.JoinColumn;
import jakarta.persistence.JoinTable;
import jakarta.persistence.ManyToMany;
import jakarta.persistence.MapKeyColumn;
import jakarta.persistence.NamedQueries;
import jakarta.persistence.NamedQuery;
import jakarta.persistence.OrderBy;
import jakarta.persistence.Table;
import jakarta.persistence.Transient;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.servlet.http.HttpSession;
import jakarta.ws.rs.client.Client;
import jakarta.ws.rs.client.ClientBuilder;
import jakarta.ws.rs.client.Entity;
import jakarta.ws.rs.client.WebTarget;
import jakarta.ws.rs.Consumes;
import jakarta.ws.rs.core.Context;
import jakarta.ws.rs.core.MediaType;
import jakarta.ws.rs.core.Response;
import jakarta.ws.rs.core.UriInfo;
import jakarta.ws.rs.DELETE;
import jakarta.ws.rs.ext.ParamConverter;
import jakarta.ws.rs.ext.Provider;
import jakarta.ws.rs.GET;
import jakarta.ws.rs.HeaderParam;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.PathParam;
import jakarta.ws.rs.POST;
import jakarta.ws.rs.Produces;
import jakarta.ws.rs.PUT;
import jakarta.ws.rs.QueryParam;
import jakarta.jms.BytesMessage;
import jakarta.jms.Queue;
import jakarta.jms.QueueConnection;
import jakarta.jms.QueueConnectionFactory;
import jakarta.jms.QueueSender;
import jakarta.jms.QueueSession;
Update WEB-INF\web.xml
find the old class types defined there and rename if available. For example of the following new names:
<servlet>
<servlet-name>Faces Servlet</servlet-name>
<servlet-class>jakarta.faces.webapp.FacesServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<error-page>
<exception-type>jakarta.faces.application.ViewExpiredException</exception-type>
<location>/m_login.xhtml</location>
</error-page>
@NamedQuery with implicit ‘SELECT’ not allowed, so add “SELECT <object alias> ” before “FROM”
@Type(type = "yes_no") replaced by @Convert(converter = YesNoConverter.class). Note: when referring to it in NativeQueries, you may need to pass a true/false query parameter instead of hard-coded Y/N in the query.
@Singlton may need to be replaced with @ApplicationScoped because the @PostConstructed method in @Singlton may not be executed.
Potential Issues
Some old 3rd party libraries (eg Richfaces) may be out-of-support with using the old packages, and they will need to be replaced with the similar well-supported/updated libraries. For example, if the JSF applications are using Richfaces (UI components or AJAX), consider to replace with PrimeFaces for example. For possible Richfaces component replacements, refer to Appendix.
Appendix
Version Mapping between JBoss EAP and Wildfly
JBoss EAP Version |
WildFly Version |
8 |
28 |
7.4 |
23 |
7.3 |
18 |
7.2 |
14 |
7.1 |
11 |
7 |
10 |
Richfaces to Primefaces Migration References
|
RichFaces (change from) |
PrimeFaces (change to) |
|
||
Listener |
a4j:actionListener |
f:setPropertyActionListener |
AJAX |
a4j:ajax |
p:ajax |
Button |
a4j:commandButton render |
p:commandButton update= |
Link |
a4j:commandLink |
p:commandLink |
JS function |
a4j:jsFunction |
p:remoteCommand |
Media output |
a4j:mediaOutput |
p:graphicImage, ... |
Output area |
a4j:outputPanel |
div or p:tab or p:outputPanel |
Parameter |
a4j:param |
f:param |
Region |
a4j:region |
h:panelGroup or p:fragment |
Repeat |
a4j:repeat |
p:repeat |
Status |
a4j:status |
p:ajaxStatus |
Accordion |
rich:accordion |
p:accordionPanel |
Accord. item |
rich:accordionItem |
p:tab |
Autocomplete |
rich:autocomplete |
p:autocomplete |
Calendar |
rich:calendar |
p:calendar |
Sub-table |
rich:collapsibleSubTable |
p:dataTable (nested) |
Column |
rich:column |
p:column |
Button |
rich:commandButton |
p:commandButton ajax="false" |
Command link |
rich:commandLink |
p:commandLink ajax="false" |
Control |
rich:componentControl |
JS function |
Data grid |
rich:dataGrid |
p:dataGrid |
Data scroll |
rich:dataScroller |
remove (use paginator) |
Data table |
rich:dataTable |
p:dataTable |
Sub-menu |
rich:dropDownMenu |
p:submenu |
Editor |
rich:editor |
p:editor(p:textEditor in PF 6) |
File upload |
rich:fileUpload |
p:fileUpload |
Focus |
rich:focus |
p:focus |
Google map |
rich:gmap (RF3) |
p:gmap |
Hot key |
rich:hotKey |
p:hotkey |
Spinner |
rich:inputNumberSpinner |
p:spinner |
List |
rich:list |
p:dataList |
Menu item |
rich:menuItem |
p:menuitem |
Message |
rich:message |
p:message |
Messages |
rich:messages |
p:messages |
Panel |
rich:panel |
p:panel |
Panel menu |
rich:panelMenu |
p:panelMenu or p:menu |
Menu item |
rich:panelMenuItem |
p:menuitem |
Pick list |
rich:pickList |
p:pickList |
Popup |
rich:popup |
p:dialog |
Select one |
rich:select |
p:selectOneMenu |
Tab |
rich:tab |
p:tab |
Menu bar |
rich:toolbar |
p:menubar or p:toolbar |
Menu group |
rich:toolbarGroup |
remove |
Tooltip |
rich:tooltip |
p:tooltip |
Tree |
rich:tree |
p:tree |
Tree node |
rich:treeNode |
p:treeNode |
Label |
h:outputLabel |
p:outputLabel |
Input text |
h:inputText |
p:inputText |
Input secret |
h:inputSecret |
p:password |
Message |
h:message |
p:message |
Messages |
h:messages |
p:messages |
Text area |
h:inputTextarea |
p:inputTextarea |
Dropdown |
h:selectOneListbox |
p:selectOneMenu |
Select one |
h:selectOneMenu |
p:selectOneMenu |
Multi-select |
h:selectManyListbox |
p:selectManyMenu |
Check box |
h:selectBooleanCheckbox |
p:selectBooleanCheckbox |
Check boxes |
h:selectManyCheckbox |
p:selectManyCheckbox |
Radio button |
h:selectOneRadio |
p:selectOneRadio |
Button |
h:commandButton |
p:commandButton ajax="false |
Regular link |
h:commandLink |
p:commandLink ajax="false" |
Image link |
h:commandLink |
p:menuitem |
Link |
h:link |
p:link |
Column |
h:column |
p:column |
Repeat |
ui:repeat |
p:repeat |
Field set |
fieldset |
p:fieldset |
References
Migration Guide 3.0: Hibernate ORM 5 to 6 migration · quarkusio/quarkus Wiki
Getting Started With Jakarta EE 10 - Jakarta CDI
Alternative of richfaces components in primefaces - Stack Overflow
Wednesday, September 18, 2024
Common Git Commands
# initialize local Git repository
git init
# create the main branch
git checkout -b main
# add local file (eg README.md) to staging
git add README.md
# commit the staging changes with comments (eg first commit)
git commit -m "first commit"
# add a remote repository (Git HTTPS or SSH URL: git@git.abc.com:company-name/Temp_Test_Repo.git)
git remote add origin git@git.abc.com:company-name/Temp_Test_Repo.git
# push the staging changes to the (remote) repository
git push origin main
# create the new branch (eg FY23-01) from main
git checkout -b FY23-01 main
# push the latest changes from the branch (eg FY23-01)
git push origin FY23-01
# revert local commits - for SHA, only need first 5 or 6 characters to differentiate
git revert <new commit SHA>
# undo the above revert
git revert <commit SHA of the previous revert>
# or, make a copy of the original commit
git cherry-pick <original commit SHA>
# check untracked files
git diff
# check local git status for uncommitted files etc
git status
# check git history
git log
# check git history by range
git log --online <start commit SHA>..<end commit SHA>
# cherry-pick multiple commits
git cherry-pick <start commit SHA>..<end commit SHA>
# delete a new local branch (eg FY23-01) in case of recreating
git branch -D FY23-01
# delete a remote branch
git push origin --delete FY23-01
# merge branch FY23-01 back to main
# switch to the target branch (eg main)
git switch main # or git checkout main
# merge from the source branch (eg FY23-01) without fast-forward
git merge --no-ff FY23-01
# push the merged changes back to the target branch (eg main) of the (remote) repository
git push origin main
# rebase from main to the branch created before some updates in main - merged from another branch - later
git switch main
git pull origin main
git switch out-of-date-branch
git rebase main
Wednesday, May 8, 2024
Common Oracle DDLs
-- Table
CREATE TABLE <table name>
( <field name> <data type> NOT NULL,
-- ... ...
CONSTRAINT <primary key name> PRIMARY KEY (field name)
);
COMMENT ON COLUMN <table name.field name> IS 'comments...';
ALTER TABLE <table name> ADD <field name> <data type>
-- Index
CREATE INDEX <index name> ON <table name> (<field name>);
DROP INDEX <index name>;
-- View
CREATE OR REPLACE FORCE VIEW <view name> (<field name>,...)
SELECT <field name>,...
FROM <table/view name>;
-- Sequence
CREATE SEQUENCE <sequence name> MINVALUE 1 MAXVALUE 1000000000 INCREMENT BY 1 START WITH 1;
-- Stored Function
CREATE OR REPLACE FUNCTION <function name> (<parameter name> IN <data type>, ...)
RETURN <data type>
IS
<local variable name> <data type>;
BEGIN
IF <condition> THEN
<local variable name> := <value>;
ELSE
-- ... ...
END IF;
RETURN <local variable name>;
EXCEPTION
WHEN OTHERS THEN
RETURN NULL;
END <function name>;
-- Stored procedure
CREATE OR REPLACE PROCEDURE <procedure name> (<parameter name> IN <data type, ...)
IS
<local variable> <data type>;
CURSOR <cursor name> IS
<select query statement>;
BEGIN
OPEN <cursor name>;
LOOP
FETCH <cursor name> INTO <local variable>, ...;
EXIT WHEN <cursor name>%NOTFOUND;
-- iterator cursor
END LOOP;
CLOSE <cursor name>;
EXCEPTION
WHEN OTHERS THEN
<local vairable> := <value>;
DBMS_OUTPUT.PUT_LINE('SQL Error: ...');
END <procedure name>;
/
-- Package
-- Specification
CREATE OR REPLACE <package name>
AS
FUNCTION <function name> (<parameter name> IN <data type>, ...) RETURN <data type>;
PROCEDURE <procedure name> (<parameter name> IN <data type>, ...);
-- ...
END <package name>;
/
-- Body
CREATE OR REPLACE BODY <package name>
AS
FUNCTION <function name> (<parameter name> IN <data type>, ...)
IS
<local variable> <data type>;
BEGIN
END <function name>;
-- ... ...
RETURN <data type>
END <package name>
-- Trigger
CREATE OR REPLACE <trigger name>
BEFORE INSERT ON <table name> REFERENCING NEW AS NEW OLD AS OLD
-- or AFTER INSERT OR UPDATE ON <table name> ...s
FOR EACH ROW
DECLARE
<local variable> <data type>;
BEGIN
<local variable> := <value>;
IF :NEW.id IS NULL THEN
SELECT <sequence name>.NEXTVAL INTO <local variable> FROM DUAL;
:NEW.id := <local variable>;
END IF;
END;
-- Scheduled jobs
BEGIN
DBMS_SCHEDULER.CREATE_JOB (
job_name => '<job name>',
job_type => 'PLSQL_BLOCK';
job_action => 'BEGIN <stored procedure name(parameters...)> END;',
start_date => TRUNC(SYSDATE, 'DD') + 23/24, -- starting at 23:00
repeat_interval => 'FREQ=MONTHLY;BYMONTHDAY=22;'
-- on 22nd every month; or FREQ=DAILY;BYHOUR=23, or FREQ=WEEKLY;BYDAY=FRI...s
);
END;
/
-- Grant permission
GRANT SELECT,UPDATE,DELETE,INSERT,EXECUTE ON <table name> TO <user name>;
REVOKE SELECT,UPDATE,DELETE,INSERT,EXECUTE ON <table name> FROM <user name>;
-- Get environment information using system functions
SELECT SYS_CONTEXT('USERENV','OS_USER'), SYS_CONTEXT('USERENV','MODULE'), SYS_CONTEXT('USERENV','HOST') FROM DUAL;
Saturday, May 9, 2020
Create Docker Container for SpringBoot Application
- understand how to use Docker
- understand how to create SpringBoot applications
- Package your SpringBoot application using Maven - "mvn clean package".
- Create a DockerFile
- FROM openjdk:11-slim
- COPY ./target/KnowledgeBase-1.0.jar /usr/app/KnowledgeBase-1.0.jar
- WORKDIR /usr/app
- RUN sh -c "touch KnowledgeBase-1.0.jar"
- ENTRYPOINT ["java", "-jar", "KnowledgeBase-1.0.jar"]
- Modify pom.xml to add repackage target to have a runnable .jar and maven-jar-plugin to specify mainClass in manifest.
- Note: if your SpringBoot access a database (e.g. PostgreSQL) in another Docker container, need to change JDBC from localhost to the IP address of the database container (in application.properties).
- Build Docker container using "docker build -t <image_name> ."
- Verify the newly build image using "docker images"
- Run the Docker container using "docker run --name <container_name> -p 8090:8080 <image_name>". Note: the trigger port can be different from the original one (e.g. 8090:8080)
- the container can be stop and start using "docker container stop <container_name>" and "docker container start <container_name>" respectively.
- check container logs using "docker container logs <container_name>"
Friday, May 8, 2020
Example of a SpringBoot data service
- create a Maven project template using "mvn archetype:generate".
- fill in the application information.
- groupId, artifactId, version, package
- open Maven project file - pom.xml and add SpringBoot and PostgreSQL dependencies.
- create application.properties in src/main/resources with the application name, port and database connection information.
- set up database and table(s) in PostgreSQL - scripts.
- create SpringBoot entry application class (with @SpringBootApplication)
- create a data model entity class (e.g. Article.java) mapping to the corresponding table (e.g. t_article).
- create a repository interface extends from CrudRepository from Spring Data with the common method declarations (e.g. findAll(), save() and etc.).
- create a controller class with org.springframework.web.bind.annotation.RestController.
- autowire the repository in the controller.
- create the HTTP RESTful methods in the controller.
- build and run the SpringBoot application by running "mvn spring-boot:run"
- test the controller method (e.g. http://<server>:<port>/<path>).
- curl -X GET http://localhost:8080/articles/
- curl -X GET http://localhost:8080/articles/Test
- curl -X POST -H "Content-Type: application/json" -d "{"""title""":"""2nd Article for testing purpose""","""category""":"""Test""","""description""":"""This is a test record added from SpringBoot RestController again."""}" http://localhost:8080/articles/add
- curl -X DELETE http://localhost:8080/articles/10008
Wednesday, May 6, 2020
How to create a Docker container for PostgreSQL
- install Docker Desktop from https://www.docker.com/get-started based on your OS.
- create your Docker account at https://hub.docker.com and log on.
- open a command window (in Windows), and type docker --version to check the docker version.
- c:\users\testuser>docker --version
- Docker version 19.03.8, build afacb8b
- start Docker Desktop and log on your Docket account.
- search postgres from https://hub.docker.com and click postgres Office Image.
- in the command window, type "docker pull postgres" to get the latest PostgreSQL image. Note: by default, the PostgreSQL version is the latest. To get a particular version, execute "docker pull postgres:12.2".
- in the command window, type the following to create and start a PostgreSQL container (-p for port number <trigger port #:port# in container>):
- docker run --name containername -h localhost -p 5435:5432 -e POSTGRES_PASSWORD=mypassword -d postgres:12.2
- use "docker ps" or "docker container ls" to show the running container status. "docker ps -a" lists all existing containers.
- to stop a docket container, type "docker stop containername"
- to restart an existing container, type "docker start containername"
- get in the docker container by typing "docker exec -it containername bash"
- within the container bash shell, you can then log in PostgreSQL as usual
- psql -U postgres postgres
- if you specified host and port numbers when creating the docker postgres container, you can access from the local machine using postgres client
- psql -h localhost -p 5435 -U postgres -W
- to remove the container, use "docker rm -f containername"
- to list docker images, type "docker images" or "docker image ls"
- to remove an image by name, use "docker image rm -f imagename", or by id using "docker image rmi -f 93d5585e579d"