Red Hat JBoss EAP Application Migration from Jakarta EE 8 to EE 10

Updated

Overview

Red Hat JBoss Enterprise Platform 8 provide support for Jakarta EE 10. Jakarta EE 10 brings a very large change to Jakarta EE compared to the Jakarta EE 8 specifications supported by EAP 7. In this article we discuss the compatibility-impacting differences in the EE APIs that application developers should be aware of when preparing to migrate their applications from EAP 7 to EAP 8.

Note: The focus of this article is on what the differences are between EE 8 and EE 10 that an application migration to EAP 8 may need to deal with, and not on how to do the migration. For more information on EAP 7 to EAP 8 application migration in general and the tooling Red Hat provides to assist with this, see also Content from red.ht is not included.How to migrate apps from JBoss EAP 7.x to JBoss EAP 8.0.

The javax to jakarta Package Namespace Change

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, Content from blogs.eclipse.org is not included.Eclipse and Oracle agreed that the Jakarta EE community cannot evolve the javax package namespace. Therefore, in order to be able 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.*. (Note that 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 EAP 7 to EAP 8. Applications migrating to EE 10 will need to:

  • Update any import statements or other source code uses of EE API classes from the javax package to jakarta.
  • Update the names of any EE-specified system properties or other configuration properties whose names that begin with javax. to instead begin with jakarta..
  • For any application-provided implementations of EE interfaces or abstract classes that are bootstrapped using the java.util.ServiceLoader mechanism, the name of the resource that identifies the implementation class will need to be changed from META-INF/services/javax.[rest_of_name] to META-INF/services/jakarta.[rest_of_name].

Note: The Red Hat Migration Toolkit can assist in updating the namespaces in the application source code; see How to use Red Hat Migration Toolkit for Auto-Migration of an Application to the Jakarta EE 10 Namespace for more information. For cases where source code migration is not an option, the open source Content from github.com is not included.Eclipse Transformer project provides bytecode transformation tooling to transform existing Java archives from the javax namespace to jakarta.

Other Changes

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. The bulk, but not all, of these are removals of long-deprecated API elements.

Note that in the following sections, for any mentions of API elements that have been removed that use the javax namespace, the equivalent removal has also been done in the jakarta namespace that was used in Jakarta EE 9. So, if you have updated your application to replace the javax namespace with jakarta, assume that the items that mention javax apply to your application as well.

Jakarta Contexts and Dependency Injection Bean Discovery

As discussed in the second paragraph of the Content from jakarta.ee is not included.CDI 4.0 spec change notes, the default behavior for discovering CDI beans in a deployment with an empty beans.xml file has changed from all to annotated. This means for such a deployment only deployment classes with a Content from jakarta.ee is not included.bean defining annotation will be discovered by CDI. If all application classes used as beans have such an annotation, this CDI change will have no impact. Otherwise, application deployment may 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.xml file empty but add a bean defining annotation to all classes that need it.
  • Leave the classes unchanged but change the beans.xml file 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.xml files back to the EAP 7 behavior. (Note that this setting will affect all deployments on the server.) For example, with the CLI:
    /subsystem=weld:write-attribute(name=legacy-empty-beans-xml-treatment,value=true)

CDI API Changes

Jakarta Contexts and Dependency Injection 4.0 removed a number of deprecated API elements:

  • The javax.enterprise.inject.spi.Bean.isNullable() method has been removed. This method has always returned false for many years now, so applications that call it can replace the call with false or remove any branching logic and just retain the contents of the false branch.
  • The javax.enterprise.inject.spi.BeanManager.createInjectionTarget(AnnotatedType) method has been removed. Replace this method call with with BeanManager.getInjectionTargetFactory(AnnotatedType) and use the returned factory to create injection targets. See Content from jakarta.ee is not included.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. Use BeanManager.getEvent() as an entry point to a similar API. See Content from jakarta.ee is not included.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 to BeforeBeanDiscovery.addAnnotatedType(AnnotatedType, (String) null).

Jakarta Enterprise Beans

Java SE 14 has removed the java.security.Identity class, so use of it has been removed from the Jakarta Enterprise Beans 4.0 API.

  • The deprecated javax.ejb.EJBContext.getCallerIdentity() method has been removed. Use EJBContext.getCallerPrincipal() instead, which returns a java.security.Principal.
  • The deprecated javax.ejb.EJBContext.isCallerInRole(Identity role) method has been removed. Use EJBContext.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 returned a javax.xml.rpc.handler.MessageContext has been removed. The Jakarta XML RPC specification was optional in Jakarta EE 8, and Red Hat JBoss EAP 7 does not support it and any use of it would have thrown an IllegalStateException, so this EJB API change is not expected to affect any existing applications running on EAP 7.

The deprecated javax.ejb.EJBContext.getEnvironment() method has been removed. Use the JNDI naming context java:comp/env to access the enterprise bean's environment.

Jakarta Expression Language

The incorrectly spelled javax.el.MethodExpression.isParmetersProvided() method has been removed. Use MethodExpression.isParametersProvided() instead.

Jakarta JSON Binding

By default, types annotated with the jakarta.json.bind.annotation.JsonbCreator annotation no longer require all parameters to be present in the JSON content. Default values will be used if the JSON being parsed is missing one of the parameters. The EE 8 behavior of requiring that all parameters be present in the JSON can be turned on by calling jakarta.json.bind.JsonbConfig().withCreatorParametersRequired(true).

Jakarta Server Faces

There have been some significant removals of long-deprecated functionality in Faces 4.0

Faces and JSPs

The JSP support in Jakarta Server Faces has been deprecated since JSF 2.0. In its place, Facelets has been designated as the preferred View Definition Language. With Jakarta Server Faces 4.0, JSP support has been completely removed, so any applications using JSP for templating its Faces views will need to be modified to use Facelets. In most cases, these applications can be easily identified by a mapping in web.xmlof the FacesServlet to the *.jsp suffix.

Faces Managed Beans

The deprecated Jakarta Server Faces-specific managed bean concept has been removed in Faces 4.0, in favor of 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) may need to make the following changes:

  • Classes annotated with javax.faces.bean.ManagedBean or referenced in a managed-bean element in faces-config.xml should instead be annotated with jakarta.inject.Named, and any managed-bean element in faces-config.xml should be removed.
  • Members annotated with the javax.faces.bean.ManagedProperty annotation should use jakarta.faces.annotation.ManagedProperty instead, along with the jakarta.inject.Inject annotation. To get a startup semantic similar to the old javax.faces.bean.ManagedBean(name=“foo”, eager=true) add a public void xxx(@Observes jakarta.enterprise.event.Startup event)method or a public void xxx(@Observes @Initialized(ApplicationScoped.class) Object context)method. The jakarta.enterprise.event.Startup option is new in CDI 4.0.
  • Use of the javax.faces.bean.ApplicationScoped annotation should be replaced with jakarta.enterprise.context.ApplicationScoped.
  • Use of the javax.faces.bean.CustomScoped annotation should be replaced with CDI custom scopes and jakarta.enterprise.context.spi.Context. See Content from jakarta.ee is not included.Defining new scope types and Content from jakarta.ee is not included.The Context Interface in the CDI 4.0 specification for more details.
  • Use of the javax.faces.bean.NoneScoped annotation should be replaced with jakarta.enterprise.context.Dependent, which is a CDI built-in scope with approximately similar semantics.
  • Use of the javax.faces.bean.RequestScoped annotation should be replaced with jakarta.enterprise.context.RequestScoped.
  • Use of the javax.faces.bean.SessionScoped annotation should be replaced with jakarta.enterprise.context.SessionScoped.

Other Faces API Changes

The javax.faces.bean.ViewScoped annotation has been removed. 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 via in the application/resource-handler element in faces-config.xml.

Jakarta Servlet

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 should 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 strongly recommended that developers 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. Since Servlet 2.1 there have been no use cases for this interface as its implementations were required by spec 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 these methods it provided:

  • parseQueryString(String s) and parsePostData(int len, ServletInputStream in) -- Use ServletRequest.getParameterMap(). If an application needs to differentiate between query string parameters and request body parameters it will need to implement code to do that itself, perhaps by parsing the query string itself.
  • getRequestURL(HttpServletRequest req) -- Use HttpServletRequest.getRequestURL().

Finally, a number of miscellaneous methods and constructors have been removed:

Class/InterfaceRemovedUse Instead
javax.servlet.ServletContextgetServlet(String name)no replacement
getServlets()no replacement
getServletNames()no replacement
log(Exception exception, String msg)log(String message, Throwable throwable)
javax.servlet.ServletRequestgetRealPath(String path)ServletContext.getRealPath(String path)
javax.servlet.ServletRequestWrappergetRealPath(String path)ServletContext.getRealPath(String path)
javax.servlet.UnavailableExceptiongetServlet()no replacement
UnavailableException(Servlet servlet, String msg)UnavailableException(String)
UnavailableException(int seconds, Servlet servlet, String msg)UnavailableException(String, int)
javax.servlet.http.HttpServletRequestisRequestedSessionIdFromUrl()isRequestedSessionIdFromURL()
javax.servlet.http.HttpServletRequestWrapperisRequestedSessionIdFromUrl()isRequestedSessionIdFromURL()
javax.servlet.http.HttpServletResponseencodeUrl(String url)encodeURL(String url)
encodeRedirectUrl(String url)encodeRedirectURL(String url)
setStatus(int sc, String sm)sendError(int, String)
javax.servlet.http.HttpServletResponseWrapperencodeUrl(String url)encodeURL(String url)
encodeRedirectUrl(String url)encodeRedirectURL(String url)
setStatus(int sc, String sm)sendError(int, String)
javax.servlet.http.HttpSessiongetValue(String name)getAttribute(String name)
getValueNames()getAttributeNames()
putValue(String name, Object value)setAttribute(String name, Object value)
removeValue(String name)removeAttribute(String name)

Jakarta Soap with Attachments

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.SOAPFactoryfor creating SOAPElements.

SOAPElementFactory methodSOAPFactory equivalent
newInstance()newInstance()
create(Name)createElement(Name)
create(String)createElement(String)
create(String, String, String)createElement(String, String, String)

Jakarta XML Binding

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.

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 details of the current implementation discovery algorithm, see the Content from jakarta.ee is not included.Jakarta XML Binding 4.0 specification.

The generics requirements for a number of methods in the javax.xml.bind.Marshaller interface have changed:

Jakarta XML Binding 2.3 / 3.0Jakarta 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)

Beyond the changes in the Jakarta XML Binding API, there have also been significant package name changes in the implementation library EAP 8 uses, which may affect some applications that access the implementation library directly:

  • Any use of classes in the com.sun.xml.bind package should be replaced by classes in the org.glassfish.jaxb.runtime package. Classes in sub-packages of com.sun.xml.bind should be replaced with classes in corresponding org.glassfish.jaxb.runtime sub-packages.
  • For jakarta.xml.bind.Marshaller property settings, change the property constant name from com.sun.xml.bind.* to org.glassfish.jaxb.*. For example,
    marshaller.setProperty("com.sun.xml.bind.namespacePrefixMapper", mapper) becomes marshaller.setProperty("org.glassfish.jaxb.namespacePrefixMapper", mapper).
Category
Components
Article Type