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. Note 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 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 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. Change the name of the resource that identifies the implementation class from META-INF/services/javax.[rest_of_name] to META-INF/services/jakarta.[rest_of_name] for any application-provided implementations of EE interfaces or abstract classes that are bootstrapped using the java.util.ServiceLoader mechanism. Note 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 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 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.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 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 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 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 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 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) . 4.2.3. Jakarta Enterprise Beans 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 use EJBContext.getCallerPrincipal() instead, which returns java.security.Principal . The deprecated javax.ejb.EJBContext.isCallerInRole(Identity role) method has been removed. You can 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 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. 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 context java:comp/env to access the enterprise bean's environment. 4.2.4. Jakarta Expression Language The incorrectly spelled javax.el.MethodExpression.isParmetersProvided() method has been removed. You can use MethodExpression.isParametersProvided() instead. 4.2.5. Jakarta JSON Binding 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 The following deprecated functionality has been removed in Jakarta Faces 4.0. 4.2.6.1. Jakarta Faces and Java Server Pages 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 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.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 Defining new scope types and 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 . 4.2.6.3. Other Faces API Changes 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 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) and parsePostData(int len, ServletInputStream in) - Use ServletRequest.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) - Use HttpServletRequest.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 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 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.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) .

Commands: