Chapter 4. Red Hat JBoss Enterprise Application Platform application migration from Jakarta EE 8 to 10
JBoss EAP 8.0 provides support for Jakarta EE 10. Jakarta EE 10 brings a large change to Jakarta EE compared to the Jakarta EE 8 specifications supported by JBoss EAP 7. In this chapter, the compatibility-impacting differences in the Jakarta EE APIs that application developers must be aware of when preparing to migrate their applications from JBoss EAP 7 to JBoss EAP 8.0 are discussed.
The focus of this chapter is on the differences between Jakarta EE 8 and Jakarta EE 10 that an application developer migrating their application to JBoss EAP 8.0 might need to deal with, and not on how to do the migration. For more information on JBoss EAP 7 to JBoss EAP 8.0 application migration and the tools provided by Red Hat to assist with this, see Simplify your JBoss EAP 8.0 migration with effective tools and Understanding application migration changes.
4.1. The javax to jakarta Package Namespace change Copy linkLink copied to clipboard!
By far the largest compatibility-impacting difference between Jakarta EE 8 and EE 10 is the renaming of the EE API Java packages from javax.* to jakarta.*.
Following the move of Java EE to the Eclipse Foundation and the establishment of Jakarta EE, Eclipse and Oracle agreed that the Jakarta EE community cannot evolve the javax. package namespace. Therefore, in order to continue to evolve the EE APIs, beginning with Jakarta EE 9, the packages used for all EE APIs have changed from javax.* to jakarta.*. This change does not affect javax packages that are part of Java SE.
Adapting to this namespace change is the biggest change involved in migrating an application from JBoss EAP 7 to JBoss EAP 8. Applications migrating to Jakarta EE 10 need to:
-
Update any import statements or other source code uses of EE API classes from the
javaxpackage tojakarta -
Update the names of any EE-specified system properties or other configuration properties whose names that begin with
javax.to instead begin withjakarta. -
Change the name of the resource that identifies the implementation class from
META-INF/services/javax.[rest_of_name]toMETA-INF/services/jakarta.[rest_of_name]for any application-provided implementations of EE interfaces or abstract classes that are bootstrapped using thejava.util.ServiceLoadermechanism.
The Red Hat Migration Toolkit can assist in updating the namespaces in the application source code. For more information, see How to use Red Hat Migration Toolkit for Auto-Migration of an Application to the Jakarta EE 10 Namespace. For cases where source code migration is not an option, the open source Eclipse Transformer project provides bytecode transformation tooling to transform existing Java archives from the javax namespace to jakarta.
4.2. Other Changes Copy linkLink copied to clipboard!
Besides the package namespace change, applications written for earlier EE versions may need to adapt to changes made in a number of specifications included in Jakarta EE 10. The following sections describe these changes, which are mostly removals of long-deprecated API elements.
In the following sections, for any instances of API elements that have been removed that use the javax namespace, the equivalent removal has been done in the jakarta namespace used in Jakarta EE 9. Therefore, if you have updated your application to replace the javax namespace with jakarta, assume that the items that mention javax are applicable for your application.
4.2.1. Jakarta Contexts and Dependency Injection Bean Discovery Copy linkLink copied to clipboard!
As per the CDI 4.0 spec change notes, the default behavior for discovering Contexts and Dependency Injection or CDI beans in a deployment with an empty beans.xml file has changed from all to annotated. This means that for such a deployment only deployment classes with a bean defining annotation is discovered by CDI. If all application classes using beans have such an annotation, this CDI change will have no impact. Otherwise, an application deployment might fail when CDI cannot find a type that provides a particular bean.
If your application is impacted by this change, you have several options:
-
Leave the
beans.xmlfile empty but add a bean defining annotation to all classes that need it. -
Leave the classes unchanged but change the
beans.xmlfile from being empty to one with the following content:<beans bean-discovery-mode="all"></beans> -
Leave the application unchanged, but change the server’s weld subsystem configuration to restore handling of empty
beans.xmlfiles back to the JBoss EAP 7 behavior. This setting affects all deployments on the server. For example, with the CLI:/subsystem=weld:write-attribute(name=legacy-empty-beans-xml-treatment,value=true)
4.2.2. CDI API Changes Copy linkLink copied to clipboard!
Jakarta Contexts and Dependency Injection 4.0 removed the following deprecated API elements:
-
The
javax.enterprise.inject.spi.Bean.isNullable()method has been removed. This method has always returnedfalsefor many years now, so applications that call it can replace the call withfalseor remove any branching logic and just retain the contents of thefalsebranch. -
The
javax.enterprise.inject.spi.BeanManager.createInjectionTarget(AnnotatedType)method has been removed. Replace this method call with withBeanManager.getInjectionTargetFactory(AnnotatedType)and use the returned factory to create injection targets. See Obtaining an InjectionTarget for a class in the Jakarta Contexts and Dependency injection specification for more information. -
The
javax.enterprise.inject.spi.BeanManager.fireEvent(Object, Annotation)method has been removed. UseBeanManager.getEvent()as an entry point to a similar API. See Firing an event in the Jakarta Contexts and Dependency injection specification for more information. -
The
javax.enterprise.inject.spi.BeforeBeanDiscovery.addAnnotatedType(AnnotatedType)method has been removed. If your application is calling this method, you can replace it with a call toBeforeBeanDiscovery.addAnnotatedType(AnnotatedType, (String) null).
4.2.3. Jakarta Enterprise Beans Copy linkLink copied to clipboard!
Java SE 14 has removed the java.security.Identity class, so it’s usage has been removed from the Jakarta Enterprise Beans 4.0 API.
-
The deprecated
javax.ejb.EJBContext.getCallerIdentity()method has been removed. You can useEJBContext.getCallerPrincipal()instead, which returnsjava.security.Principal. -
The deprecated
javax.ejb.EJBContext.isCallerInRole(Identity role)method has been removed. You can useEJBContext.isCallerInRole(String roleName)instead. -
The Jakarta XML RPC specification has been removed from the Jakarta EE 10 Full Platform, so the
javax.ejb.SessionContext.getMessageContext()method that returnedjavax.xml.rpc.handler.MessageContexthas been removed. -
The Jakarta XML RPC specification was optional in Jakarta EE 8, and Red Hat JBoss EAP 7 does not support it. Any usage of this specification would have thrown an
IllegalStateException, so this EJB API change is not expected to affect any existing applications running on JBoss EAP 7. -
The deprecated
javax.ejb.EJBContext.getEnvironment()method has been removed. Use the JNDI naming contextjava:comp/envto access the enterprise bean’s environment.
4.2.4. Jakarta Expression Language Copy linkLink copied to clipboard!
The incorrectly spelled javax.el.MethodExpression.isParmetersProvided() method has been removed. You can use MethodExpression.isParametersProvided() instead.
4.2.5. Jakarta JSON Binding Copy linkLink copied to clipboard!
By default, types annotated with the jakarta.json.bind.annotation.JsonbCreator annotation does not require all parameters to be available in the JSON content. Default values will be used if the JSON being parsed is missing one of the parameters. The EE 8 behavior that requires all the parameters to be present in the JSON can be turned on by calling jakarta.json.bind.JsonbConfig().withCreatorParametersRequired(true).
4.2.6. Jakarta Faces Copy linkLink copied to clipboard!
The following deprecated functionality has been removed in Jakarta Faces 4.0.
4.2.6.1. Jakarta Faces and Java Server Pages Copy linkLink copied to clipboard!
Jakarta Server Pages (JSP) support is deprecated in Jakarta Faces 2.0 and later versions. JSP support is removed in Jakarta Faces 4.0. Facelets replaces JSP as the preferred View Definition Language (VDL). Applications using JSP for Faces views can be modified using Facelets. You can identify the applications by mapping FacesServlet to the *.jsp suffix in web.xml.
4.2.6.2. Faces Managed-Beans Copy linkLink copied to clipboard!
The deprecated Jakarta Faces-specific managed-bean concept has been removed in Faces 4.0, for Jakarta Contexts and Dependency Injection (CDI) beans. Applications using Faces managed-beans (i.e. classes annotated with javax.faces.bean.ManagedBean or referenced in a managed-bean element in faces-config.xml) might need to make the following changes:
-
Classes annotated with
javax.faces.bean.ManagedBeanor referenced in a managed-bean element infaces-config.xmlshould instead be annotated withjakarta.inject.Named, and any managed-bean element infaces-config.xmlshould be removed. -
Members annotated with the
javax.faces.bean.ManagedPropertyannotation should usejakarta.faces.annotation.ManagedPropertyinstead, along with thejakarta.inject.Injectannotation. To get a startup semantic similar to the oldjavax.faces.bean.ManagedBean(name=“foo”, eager=true), add apublic void xxx(@Observes jakarta.enterprise.event.Startup event)method or apublic void xxx(@Observes @Initialized(ApplicationScoped.class) Object context)method. Thejakarta.enterprise.event.Startupoption is new in CDI 4.0. -
Use of the
javax.faces.bean.ApplicationScopedannotation should be replaced withjakarta.enterprise.context.ApplicationScoped. -
Use of the
javax.faces.bean.CustomScopedannotation should be replaced with CDI custom scopes andjakarta.enterprise.context.spi.Context. See Defining new scope types and The Context Interface in the CDI 4.0 specification for more details. -
Use of the
javax.faces.bean.NoneScopedannotation should be replaced withjakarta.enterprise.context.Dependent, which is a CDI built-in scope with approximately similar semantics. -
Use of the
javax.faces.bean.RequestScopedannotation should be replaced withjakarta.enterprise.context.RequestScoped. -
Use of the
javax.faces.bean.SessionScopedannotation should be replaced withjakarta.enterprise.context.SessionScoped.
4.2.6.3. Other Faces API Changes Copy linkLink copied to clipboard!
The javax.faces.bean.ViewScoped annotation has been removed. You can use jakarta.faces.view.ViewScoped instead.
The javax.faces.view.facelets.ResourceResolver and javax.faces.view.facelets.FaceletsResourceResolver annotations have been removed. For any ResourceResolvers in your application, implement the jakarta.faces.application.ResourceHandler interface and register the fully qualified class name of the implementation in the application/resource-handler element in faces-config.xml.
4.2.7. Jakarta Servlet Copy linkLink copied to clipboard!
Jakarta Servlet 6.0 removes a number API classes and methods that were deprecated in Servlet 5.0 and earlier, mostly in the Servlet 2.x releases.
The javax.servlet.SingleThreadModel marker interface has been removed and servlets that implement this interface must remove the interface declaration and ensure that the servlet code properly guards state and other resource access against concurrent access. For example, by avoiding the usage of an instance variable or synchronizing the block of code accessing resources. However, it is recommended that developers do not synchronize the service method (or methods like doGet and doPost that it dispatches to) because of the detrimental effect of such synchronization on performance.
The javax.servlet.http.HttpSessionContext interface has been removed, along with the javax.servlet.http.HttpSession.getSessionContext() method. There have been no use cases for this interface since Servlet 2.1 as its implementations were required by specifications not to provide any usable data.
The javax.servlet.http.HttpUtils utility class has been removed. Applications should use the ServletRequest and HttpServletRequest interfaces instead of the following methods:
-
parseQueryString(String s)andparsePostData(int len, ServletInputStream in)- UseServletRequest.getParameterMap(). If an application needs to differentiate between query string parameters and request body parameters, the application must implement the code to do that by parsing the query string itself. -
getRequestURL(HttpServletRequest req)- UseHttpServletRequest.getRequestURL().
Also, the following miscellaneous methods and constructors have been removed:
| Class/Interface | Removed | Use Instead |
|---|---|---|
| javax.servlet.ServletContext | getServlet(String name) | no replacement |
| getServlets() | no replacement | |
| getServletNames() | no replacement | |
| log(Exception exception, String msg) | log(String message, Throwable throwable) | |
| javax.servlet.ServletRequest | getRealPath(String path) | ServletContext.getRealPath(String path) |
| javax.servlet.ServletRequestWrapper | getRealPath(String path) | ServletContext.getRealPath(String path) |
| javax.servlet.UnavailableException | getServlet() | no replacement |
| UnavailableException(Servlet servlet, String msg) | UnavailableException(String) | |
| UnavailableException(int seconds, Servlet servlet, String msg) | UnavailableException(String, int) | |
| javax.servlet.http.HttpServletRequest | isRequestedSessionIdFromUrl() | isRequestedSessionIdFromURL() |
| javax.servlet.http.HttpServletRequestWrapper | isRequestedSessionIdFromUrl() | isRequestedSessionIdFromURL() |
| javax.servlet.http.HttpServletResponse | encodeUrl(String url) | encodeURL(String url) |
| encodeRedirectUrl(String url) | encodeRedirectURL(String url) | |
| setStatus(int sc, String sm) | sendError(int, String) | |
| javax.servlet.http.HttpServletResponseWrapper | encodeUrl(String url) | encodeURL(String url) |
| encodeRedirectUrl(String url) | encodeRedirectURL(String url) | |
| setStatus(int sc, String sm) | sendError(int, String) | |
| javax.servlet.http.HttpSession | getValue(String name) | getAttribute(String name) |
| getValueNames() | getAttributeNames() | |
| putValue(String name, Object value) | setAttribute(String name, Object value) | |
| removeValue(String name) | removeAttribute(String name) |
4.2.8. Jakarta Soap with Attachments Copy linkLink copied to clipboard!
Support for provider lookup through a jaxm.properties file has been removed.
The deprecated javax.xml.soap.SOAPElementFactory class has been removed. Use jakarta.xml.soap.SOAPFactory for creating SOAPElements.
| SOAPElementFactory method | SOAPFactory equivalent |
|---|---|
| newInstance() | newInstance() |
| create(Name) | createElement(Name) |
| create(String) | createElement(String) |
| create(String, String, String) | createElement(String, String, String) |
4.2.9. Jakarta XML Binding Copy linkLink copied to clipboard!
The XML namespace that should be used in xml binding files has changed. The http://java.sun.com/xml/ns/jaxb namespace should be replaced with https://jakarta.ee/xml/ns/jaxb.
The deprecated javax.xml.bind.Validator interface has been removed, as has the associated javax.xml.bind.JAXBContext.createValidator() method. To validate marshalling and unmarshalling operations, provide a javax.xml.validation.Schema to jakarta.xml.bind.Marshaller.setSchema(Schema).
Support for compatibility with JAXB 1.0 has been removed.
Some of the deprecated steps in the JAXBContext implementation lookup algorithm have been removed. Searches for implementation class names through jaxb.properties files, javax.xml.bind.context.factory or jakarta.xml.bind.JAXBContext properties and /META-INF/services/javax.xml.bind.JAXBContext resource files have been dropped. For more informatoin about the current implementation discovery algorithm, see the Jakarta XML Binding 4.0 specification.
The generic requirements for a number of methods in the javax.xml.bind.Marshaller interface have changed as follows:
| Jakarta XML Binding 2.3 / 3.0 | Jakarta XML Binding 4.0 |
|---|---|
| <A extends XmlAdapter> void setAdapter(A adapter) | <A extends XmlAdapter<?, ?>> void setAdapter(A adapter) |
| <A extends XmlAdapter> void setAdapter(Class<A> type, A adapter) | <A extends XmlAdapter<?, ?>> void setAdapter(Class<A> type, A adapter) |
| <A extends XmlAdapter> A getAdapter(Class<A> type) | <A extends XmlAdapter<?, ?>> A getAdapter(Class<A> type) |
Apart from the changes in the Jakarta XML Binding API, there have been significant package name changes in the implementation library EAP 8, which might affect some applications that access the implementation library directly:
-
Any use of classes in the
com.sun.xml.bindpackage should be replaced by classes in theorg.glassfish.jaxb.runtimepackage. Classes in sub-packages ofcom.sun.xml.bindshould be replaced with classes in correspondingorg.glassfish.jaxb.runtimesub-packages. -
For
jakarta.xml.bind.Marshallerproperty settings, change the property constant name fromcom.sun.xml.bind.*toorg.glassfish.jaxb.*. For example,marshaller.setProperty("com.sun.xml.bind.namespacePrefixMapper", mapper)becomesmarshaller.setProperty("org.glassfish.jaxb.namespacePrefixMapper", mapper).