Red Hat Training
A Red Hat training course is available for Red Hat JBoss Enterprise Application Platform
第 5 章 应用程序迁移的修改
5.1. Web Service 的应用程序修改
JBossWS 5 为 JBoss EAP 7 Web Services 带来了新的功能和性能改进,这主要是通过升级 Apache CXF、Apache WSS4J 和 Apache Santuario 完成的。
5.1.1. JAX-RPC 支持的修改
基于 XML 的 RPC(JAX-RPC)的 Java API 在 Java EE 6 已被舍弃,在 Java EE 7 里是可选的。在 JBoss EAP 7 里它不再可用也不被支持。使用 JAX-RPC 的应用程序必须迁移以使用目前 Java EE 的标准 Web Service 框架 JAX-WS。
JAX-RPC Web Service 可以用下列途径确认:
-
使用 JAX-RPC 映射文件,它是一个 XML 文件,其根元素是
<java-wsdl-mapping>
。 使用包含
<webservice-description>
元素(包含<jaxrpc-mapping-file>
子元素)的webservices.xml
XML 描述符文件。下面是一个定义 JAX-RPC web service 的webservices.xml
描述符文件示例。<webservices xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://www.ibm.com/webservices/xsd/j2ee_web_services_1_1.xsd" version="1.1"> <webservice-description> <webservice-description-name>HelloService</webservice-description-name> <wsdl-file>WEB-INF/wsdl/HelloService.wsdl</wsdl-file> <jaxrpc-mapping-file>WEB-INF/mapping.xml</jaxrpc-mapping-file> <port-component> <port-component-name>Hello</port-component-name> <wsdl-port>HelloPort</wsdl-port> <service-endpoint-interface>org.jboss.chap12.hello.Hello</service-endpoint-interface> <service-impl-bean> <servlet-link>HelloWorldServlet</servlet-link> </service-impl-bean> </port-component> </webservice-description> </webservices>
-
使用
ejb-jar.xml
文件,它包含引用 JAX-RPC 映射文件的<service-ref>
元素。
5.1.2. Apache CXF Spring Web Services 的修改
在以前的 JBoss EAP 版本里,您可以通过在端点部署归档里包含 jbossws-cxf.xml
配置文件来自定义 JBossWS 和 Apache CXF 集成。其中已一个例子是为 Apache CXF 总线上的 Web Service 客户和服务器端点配置连接器链。这个集成要求在 JBoss EAP 服务器里部署 Spring。
JBoss EAP 7 不再支持 Spring 集成。任何包含 jbossws-cxf.xml
描述符配置文件的应用程序必须进行修改,替换该文件里定义的自定义配置。虽然您仍可以直接访问 Apache CXF API,请注意应用程序将会是不可迁移的。
我们建议的方法是尽量用新的 JBossWS 描述符配置选项替换 Spring 自定义配置。基于 JBossWS 描述符的方法提供了类似的功能而无需修改客户端点代码。在某些情况下,您可以用 Context Dependency Injection (CDI) 替代 Spring。
Apache CXF 拦截器
JBossWS 描述符提供了新的配置选项,允许您声明拦截器而无需修改客户端点代码。通过指定 cxf.interceptors.in
和 cxf.interceptors.out
属性的拦截器类名,您可以在预定义的客户和端点配置里声明拦截器。
下面是一个 jaxws-endpoint-config.xml
文件示例,它用这些属性声明拦截器。
<?xml version="1.0" encoding="UTF-8"?> <jaxws-config xmlns="urn:jboss:jbossws-jaxws-config:4.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:javaee="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="urn:jboss:jbossws-jaxws-config:4.0 schema/jbossws-jaxws-config_4_0.xsd"> <endpoint-config> <config-name>org.jboss.test.ws.jaxws.cxf.interceptors.EndpointImpl</config-name> <property> <property-name>cxf.interceptors.in</property-name> <property-value>org.jboss.test.ws.jaxws.cxf.interceptors.EndpointInterceptor,org.jboss.test.ws.jaxws.cxf.interceptors.FooInterceptor</property-value> </property> <property> <property-name>cxf.interceptors.out</property-name> <property-value>org.jboss.test.ws.jaxws.cxf.interceptors.EndpointCounterInterceptor</property-value> </property> </endpoint-config> </jaxws-config>
Apache CXF 功能
JBossWS 描述符允许您通过指定 cxf.features
属性的功能类名列表,在预定义的客户和端点配置里声明功能。
下面是一个 jaxws-endpoint-config.xml
文件示例,它用这些属性声明了一个功能。
<?xml version="1.0" encoding="UTF-8"?> <jaxws-config xmlns="urn:jboss:jbossws-jaxws-config:4.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:javaee="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="urn:jboss:jbossws-jaxws-config:4.0 schema/jbossws-jaxws-config_4_0.xsd"> <endpoint-config> <config-name>Custom FI Config</config-name> <property> <property-name>cxf.features</property-name> <property-value>org.apache.cxf.feature.FastInfosetFeature</property-value> </property> </endpoint-config> </jaxws-config>
Apache CXF 的 HTTP 传输
在 Apache CXF 里,HTTP 传输配置是通过 org.apache.cxf.transport.http.HTTPConduit
属性实现的。JBoss WS 集成允许在程序里使用 Apache CXF API 修改 Conduit。
import org.apache.cxf.frontend.ClientProxy; import org.apache.cxf.transport.http.HTTPConduit; import org.apache.cxf.transports.http.configuration.HTTPClientPolicy; // Set chunking threshold before using a JAX-WS port client ... HTTPConduit conduit = (HTTPConduit)ClientProxy.getClient(port).getConduit(); HTTPClientPolicy client = conduit.getClient(); client.setChunkingThreshold(8192); ...
您也通过设置系统属性来控制和覆盖 Apache CXF HTTPConduit
的默认值。
属性 | 类型 | 描述 |
---|---|---|
cxf.client.allowChunking |
布尔值 |
指定是否用分块发送请求。 |
cxf.client.chunkingThreshold |
整数 |
设置从非分块切模式切换至分块模式时的极限值。 |
cxf.client.connectionTimeout |
长整数 |
设置连接超时(毫秒)。 |
cxf.client.receiveTimeout |
长整数 |
设置接收超时(毫秒)。 |
cxf.client.connection |
字符串 |
指定是否使用 |
cxf.tls-client.disableCNCheck |
布尔值 |
指定是否禁用 CN 主机名称检查。 |
5.1.3. WS-Security 修改
-
如果您的应用程序包含了自定义的访问
org.apache.ws.security.WSPasswordCallback
类的回调处理程序,请注意这个类已经移至org.apache.wss4j.common.ext
软件包。 -
org.apache.ws.security.saml.ext
软件包里大多数 SAML bean 对象已经移至org.apache.wss4j.common.saml package
。 - 使用 RSA v1.5 关键字传输并默认禁用所有相关的算法。
-
安全令牌服务(Security Token Service,STS)之前只检验
onBehalfOf
令牌。它现在可以检验ActAs
令牌。因此,您必须在为ActAs
令牌提供的UsernameToken
里指定有效的用户名和密码。 -
SAML Bearer 令牌现在要求具有内部签名。
org.apache.wss4j.dom.validate.SamlAssertionValidator
类现在有一个setRequireBearerSignature()
方法来启用或禁用签名验证。
5.1.4. JBoss 模块结构的修改
cxf-api
和 cxf-rt-core
JAR 已合并到一个 cxf-core
JAR。因此,JBoss EAP 里的 org.apache.cxf
模块现在包含了 cxf-core
JAR 并较之以前的版本开放了更多的类。
5.1.5. Bouncy Castle 的要求和修改
如果您想对 XML/WS-Security 里的对称加密使用 AES 加密和 Galois/Counter Mode (GCM),您需要 BouncyCastle 安全提供者。
JBoss EAP 7 附带了 org.bouncycastle
模块,JBossWS 现在能够依赖自己的类加载来获取和使用 BouncyCastle 安全提供者。因此不再需要再当前 JMV 里静态地安装 BouncyCastle。对于运行在容器外而要访问安全提供者的应用程序,你可以添加 BouncyCastle 库到 classpath 里。
您可以通过设置 jaxws-endpoint-config.xml
(服务器)或 jaxws-client-config.xml
(客户)里的 org.jboss.ws.cxf.noLocalBC
属性值为 true
来禁用这个行为。
如果您不想使用 JBoss EAP 附带的版本,您仍可以将 BouncyCastle 静态地安装到 JVM 里。在这种情况下,静态安装的 BouncyCastle 将优先于 classpth 的安全提供者。要避免这种情况,您必须使用 BouncyCastle 1.49、1.51 或更高的版本。
5.1.6. Apache CXF 总线选择策略
容器里运行的客户的默认总线选择策略已从 THREAD_BUS
改为 TCCL_BUS
。对于在容器外运行的客户,默认的策略仍是 THREAD_BUS
。您可以用下列方法来恢复之前版本里的设置。
-
将系统属性
org.jboss.ws.cxf.jaxws-client.bus.strategy
设置为THREAD_BUS
来引导 JBoss EAP 服务器。 - 显性地在客户代码里设置选择策略。
5.1.7. WebServiceRef 对 JAX-WS 2.2 的要求
容器必须使用JAX-WS 2.2 风格的构造器,它使用 WebServiceFeature 类来构建注入到 Web service 引用里的客户。这意味着用户提供的服务类(由容器注入)必须实现 JAX-WS 2.2 或更高规格。
5.1.8. 忽略 HttpsHost CN 检查
在以前的版本里,通过设置系统属性 org.jboss.security.ignoreHttpsHost
为 true
,您可以禁用对证书里服务器的公共名称(Common Name,CN) 的 HTTPS URL 主机名检查。这个系统属性名称已被 cxf.tls-client.disableCNCheck
所替代。
5.1.9. 服务器端的配置和类加载
As a consequence of enabling injections into service endpoint and service client handlers, it is no longer possible to automatically load handler classes from the org.jboss.as.webservices.server.integration
JBoss module. If your application depends on a given predefined configuration, you might need to explicitly define new module dependencies for your deployment. For more information, see Migrate Explicit Module Dependencies
5.1.10. 舍弃 Java Endorsed Standards Override Mechanism
JDK 1.8_40 已舍弃 Java Endorsed Standards Override Mechanism 而 JDK 9 将删除它。这个机制允许开发人员将 JAR 放入 JRE 里支持的目录,从而使这些库为所有部署的应用程序所用。
如果您的应用程序使用了 Apache CXF 的 JBossWS 实现,JBoss EAP 7 会确保以正确的顺序添加所需的依赖关系,所以您不会受这些改动的影响。如果您的应用程序直接访问 Apache CXF,作为应用程序部署的一部分,在 JBossWS 依赖关系之后您现在必须提供 Apache CXF 依赖关系。
5.1.11. EAR 归档里的描述符规格
在以前的 JBoss EAP 版本里,您可以为 JAR 归档的 META-INF/
里的 EJB Web Service 部署或 WEB-INF/
里的 POJO Web Service 部署及 WAR 归档捆绑的 EJB Web Service 端点配置 jboss-webservices.xml
部署描述符文件。
在 JBoss EAP 7 里,您现在可以在 EAR 归档的 META-INF/
目录里配置 jboss-webservices.xml
部署描述符文件。如果 EAR 归档和 JAR 或 WAR 归档里都有 jboss-webservices.xml
文件,JAR 或 WAR 的 jboss-webservices.xml
里的配置数据会覆盖 EAR 描述符文件里对应的数据。
5.2. 更新远程 URL 连接器和端口
在 JBoss EAP 7 里,默认的连接器已从 remote
改为 http-remoting
,且默认的远程连接端口已从 4447
改为 8080
。默认配置的 JNDI 供应商 URL 已从 remote://localhost:4447
改为 http-remoting://localhost:8080
。
If you use the JBoss EAP 7 migrate
operation to update your configuration, you do not need to modify the remote connector, remote port, or JNDI provider URLs because the migration operation preserves the JBoss EAP 6 remoting connector and 4447
port configuration settings in the subsystem configuration. For more information about the migrate
operation, see Management CLI Migration Operation.
如果您没有使用 migrate
操作而用新的 JBoss EAP 7 默认配置来运行,你必须修改远程连接、远程端口以及 JNDI 供应商 URL 来使用上述新的设置。
5.3. 消息应用程序的修改
5.3.1. 替换或更新 JMS 部署描述符
JBoss EAP 7 舍弃了用命名模式 -jms.xml
标识的私有 JMS 资源部署描述符文件。下面是一个 JBoss EAP 6 的 JMS 资源部署描述符示例。
<?xml version="1.0" encoding="UTF-8"?> <messaging-deployment xmlns="urn:jboss:messaging-deployment:1.0"> <hornetq-server> <jms-destinations> <jms-queue name="testQueue"> <entry name="queue/test"/> <entry name="java:jboss/exported/jms/queue/test"/> </jms-queue> <jms-topic name="testTopic"> <entry name="topic/test"/> <entry name="java:jboss/exported/jms/topic/test"/> </jms-topic> </jms-destinations> </hornetq-server> </messaging-deployment>
在以前的版本里,如果您的应用程序使用了 -jms.xml
JMS 部署描述符,您可以按照 Java EE 7 规格的 EE.5.18 章节转成使用标准 Java EE 7 部署描述符,或者升级部署描述符来使用 JBoss EAP 7 里的 messaging-activemq
子系统。
如果您选择更新描述符,您需要进行下列修改。
- 修改命名空间 "urn:jboss:messaging-deployment:1.0" 为 "urn:jboss:messaging-activemq-deployment:1.0"。
-
修改
<hornetq-server>
元素名为<server>
。
修改后的文件应该类似于下面的例子。
<?xml version="1.0" encoding="UTF-8"?> <messaging-deployment xmlns="urn:jboss:messaging-activemq-deployment:1.0"> <server> <jms-destinations> <jms-queue name="testQueue"> <entry name="queue/test"/> <entry name="java:jboss/exported/jms/queue/test"/> </jms-queue> <jms-topic name="testTopic"> <entry name="topic/test"/> <entry name="java:jboss/exported/jms/topic/test"/> </jms-topic> </jms-destinations> </server> </messaging-deployment>
关于和消息相同相关的服务器配置修改,请参考 Messaging Server Configuration Changes。
5.3.2. 更新外部的 JMS 客户
JBoss EAP 7 仍支持 JMS 1.1 API,所以您不需要修改您的代码。
JBoss EAP 7 修改了默认的远程连接器和端口。关于这种改动的细节,请参考更新远程 URL 连接器和端口。
如果您用 migrate
操作移您的服务器配置,旧的设置将被保留,您不需要更新 PROVIDER_URL
。然而,如果您用新的 JBoss EAP 7 的默认配置来运行,您必须在客户代码里修改 PROVIDER_URL
并使用新的 http-remoting://localhost:8080
设置。更多信息请参考迁移远程命名客户代码。
如果您计划将您的代码迁移至 JMS 2.0 API,请参考 helloworld-jms
quickstart 里的用法。
5.3.3. 替代 HornetQ API
JBoss EAP 6 包含 org.hornetq
模块,它允许您在代码里使用 HornetQ API。
JBoss EAP 7 里 Apache ActiveMQ Artemis 替代了 HornetQ,所以您必须迁移任何使用 HornetQ API 的代码,使其使用 Apache ActiveMQ Artemis API。这个 API 库包含在 org.apache.activemq.artemis
模块里。
ActiveMQ Artemis 是 HornetQ 的演化版本,所以许多概念仍然适用。
5.4. JAX-RS 和 RESTEasy 应用程序的修改
之前的 JBoss EAP 版本捆绑了实现 JAX-RS 1.x 的 RESTEasy 2。JBoss EAP 7 附带实现 JAX-RS 2.0(由 JSR 339: JAX-RS 2.0: The Java API for RESTful Web Services 规格定义)的 RESTEasy 3。关于用于 RESTful Web Service 的 Java API 的更多信息,请参考 JAX-RS 2.0 API 规格。
JBoss EAP 7 里包含的 Jackson 版本已有改变。之前的 JBoss EAP 包含的是 Jackson 1.9.9,而 JBoss EAP 7 现在包含 Jackson 2.6.3 或更高的版本。
This section describes how these changes might impact applications that use RESTEasy or JAX-RS.
5.4.1. RESTEasy 已舍弃的类
Interceptor 和 MessageBody 类
JSR 311: JAX-RS: The Java™ API for RESTful Web Services did not include an interceptor framework, so RESTEasy 2 provided one. JSR 339: JAX-RS 2.0: The Java API for RESTful Web Services introduced an official interceptor and filter framework, so the interceptor framework included in RESTEasy 2 is now deprecated, and is replaced by the JAX-RS 2.0 compliant interceptor facility in RESTEasy 3.x. The relevant interfaces are defined in the javax.ws.rs.ext
package of the jaxrs-api
module.
RESTEasy 3.x 里舍弃了下列拦截器接口。
-
在 RESTEasy 3.x 里
org.jboss.resteasy.spi.interception.PreProcessInterceptor
接口被javax.ws.rs.container.ContainerRequestFilter
接口所替代。 RESTEasy 3.x 里也舍弃了下列接口和类。
-
org.jboss.resteasy.spi.interception.MessageBodyReaderInterceptor
-
org.jboss.resteasy.spi.interception.MessageBodyWriterInterceptor
-
org.jboss.resteasy.spi.interception.MessageBodyWriterContext
-
org.jboss.resteasy.spi.interception.MessageBodyReaderContext
-
org.jboss.resteasy.core.interception.InterceptorRegistry
-
org.jboss.resteasy.core.interception.InterceptorRegistryListener
-
org.jboss.resteasy.core.interception.ClientExecutionContextImpl
-
-
org.jboss.resteasy.spi.interception.MessageBodyWriterInterceptor
接口已被javax.ws.rs.ext.WriterInterceptor
接口替代。 In addition, some changes to the
javax.ws.rs.ext.MessageBodyWriter
interface might not be backward compatible with respect to JAX-RS 1.x. If your application used JAX-RS 1.x, review your application code to make sure you define@Produces
or@Consumes
for your endpoints. Failure to do so might result in an error similar to the following.org.jboss.resteasy.core.NoMessageBodyWriterFoundFailure: Could not find MessageBodyWriter for response object of type: <OBJECT> of media type:
下面是可能导致这个错误的 REST 端点示例。
@Path("dates") public class DateService { @GET @Path("daysuntil/{targetdate}") public long showDaysUntil(@PathParam("targetdate") String targetDate) { DateLogger.LOGGER.logDaysUntilRequest(targetDate); final long days; try { final LocalDate date = LocalDate.parse(targetDate, DateTimeFormatter.ISO_DATE); days = ChronoUnit.DAYS.between(LocalDate.now(), date); } catch (DateTimeParseException ex) { // ** DISCLAIMER **. This example is contrived. throw new WebApplicationException(Response.status(400).entity(ex.getLocalizedMessage()).type(MediaType.TEXT_PLAIN) .build()); } return days; } }
要修复这个问题,请添加对
javax.ws.rs.Produces
和@Produces
注解的导入。... import javax.ws.rs.Produces; ... @Path("dates") public class DateService { @GET @Path("daysuntil/{targetdate}") @Produces(MediaType.TEXT_PLAIN) public long showDaysUntil(@PathParam("targetdate") String targetDate) { DateLogger.LOGGER.logDaysUntilRequest(targetDate); final long days; try { final LocalDate date = LocalDate.parse(targetDate, DateTimeFormatter.ISO_DATE); days = ChronoUnit.DAYS.between(LocalDate.now(), date); } catch (DateTimeParseException ex) { // ** DISCLAIMER **. This example is contrived. throw new WebApplicationException(Response.status(400).entity(ex.getLocalizedMessage()).type(MediaType.TEXT_PLAIN) .build()); } return days; } }
之前 RESTEasy 版本的所有拦截器都可以和新的 JAX-RS 2.0 过滤器和拦截器接口并行运行。
For more information about interceptors, see RESTEasy Interceptors in Developing Web Services Applications for JBoss EAP.
关于新的替代 API 的更多信息,请参考 RESTEasy JAX-RS 3.0.13.Final API 或更新的版本。
Client API
resteasy-jaxrs
里的 RESTEasy 客户框架已被兼容 JAX-RS 2.0 的 resteasy-client
模块替代。因此,某些 RESTEasy Client API 类和方法已被舍弃。
下面的类已被舍弃。
-
org.jboss.resteasy.client.ClientResponseFailure
异常、org.jboss.resteasy.client.ClientExecutor
及org.jboss.resteasy.client.EntityTypeFactory
接口已被舍弃。 您必须用
org.jboss.resteasy.client.jaxrs.ResteasyClient
和javax.ws.rs.core.Response
分别替代org.jboss.resteasy.client.ClientRequest
和org.jboss.resteasy.client.ClientResponse
类。下面是一个在 RESTEasy 2.3.x 里发送链接头部和 RESTEasy 客户的例子。
ClientRequest request = new ClientRequest(generateURL("/linkheader/str")); request.addLink("previous chapter", "previous", "http://example.com/TheBook/chapter2", null); ClientResponse response = request.post(); LinkHeader header = response.getLinkHeader();
下面是一个在 RESTEasy 3 里如何用 RESTEasy 客户实现相同任务的例子。
ResteasyClient client = new ResteasyClientBuilder().build(); Response response = client.target(generateURL("/linkheader/str")).request() .header("Link", "<http://example.com/TheBook/chapter2>; rel=\"previous\"; title=\"previous chapter\"").post(Entity.text(new String())); javax.ws.rs.core.Link link = response.getLink("previous");
关于与 JAX-RS Web service 交互的外部 JAX-RS RestEasy 客户,请参考
resteasy-jaxrs-client
quickstart 示例。-
org.jboss.resteasy.client.cache
软件包里的类和接口也已被舍弃。它们被org.jboss.resteasy.client.jaxrs.cache
软件包里对应的类和接口替代。
关于 org.jboss.resteasy.client.jaxrs
API 类的更多信息,请参考 RESTEasy JAX-RS JavaDoc。
StringConverter
RESTEasy 3.x 已舍弃了 org.jboss.resteasy.spi.StringConverter
类。这个功能可以用 JAX-RS 2.0 jax.ws.rs.ext.ParamConverterProvider 类替代。
5.4.2. 已删除或变成 protected 权限的 RESTEasy 类
ResteasyProviderFactory 的 Add 系列方法
在 RESTEasy 3.0 里,大部分 org.jboss.resteasy.spi.ResteasyProviderFactory
add()
方法已被删除或权限变为 protected。例如,addBuiltInMessageBodyReader{}
和 addBuiltInMessageBodyWriter()
方法已被删除而 addMessageBodyReader()
和 addMessageBodyWriter()
方法的权限已变成 protected。
现在您应该使用 registerProvider()
和 registerProviderInstance()
方法。
RESTEasy 3 里删除的其他类
指定 JAX-RS 方法的响应应该在服务器上缓存的 @org.jboss.resteasy.annotations.cache.ServerCached
注解,已从 RESTEasy 3 删除且必须从应用程序代码里删除。
5.4.3. 其他 RESTEasy 修改
SignedInput 和 SignedOuput
-
用于
resteasy-crypto
的SignedInput
和SignedOutput
必须将Request
或Response
对象里的Content-Type
设置为multipart/signed
,或者使用@Consumes
或@Produces
注解。 -
通过在
@Produces
或@Consumes
注解里设置application/pkcs7-signature
MIME 类型,SignedOutput
和SignedInput
可以用来以二进制形式返回 "application/pkcs7-signature" MIME 类型。 -
如果
@Produces
或@Consumes
是text/plain
MIME 类型,SignedOutput
将用 base64 编码并作为 String 发送。
安全过滤器
@RolesAllowed
、@PermitAll
和 @DenyAll
的安全过滤器现在返回 "403 Forbidden" 而不是 "401 Unauthorized"。
客户端过滤器
当您使用之前版本的 RESTEasy client API 时,新的 JAX-RS 2.0 客户端过滤器不会被绑定和运行。
对异步 HTTP 的支持
Because the JAX-RS 2.0 specification adds asynchronous HTTP support using the @Suspended
annotation and the AsynResponse
interface, the RESTEasy proprietary API for asynchronous HTTP has been deprecated and might be removed as soon as RESTEasy 3.1. The asynchronous Tomcat and asynchronous JBoss Web modules have also been removed from the server installation. If you are not using the Servlet 3.0 container or higher, asynchronous HTTP server-side processing will be simulated and run synchronously in same request thread.
服务器端的缓存
服务器端的缓存设置已经改变,更多信息请参考 RESTEasy Documentation 。
5.4.4. 对 RESTEasy SPI 的修改
SPI 异常
我们已舍弃所有的 SPI 失败异常,不再在内部使用它们。它们已被对应的JAX-RS 2.0 异常所替代。
已舍弃的异常 | jaxrs-api 模块里的替代异常 |
---|---|
org.jboss.resteasy.spi.ForbiddenException |
javax.ws.rs.ForbiddenException |
org.jboss.resteasy.spi.MethodNotAllowedException |
javax.ws.rs.NotAllowedException |
org.jboss.resteasy.spi.NotAcceptableException |
javax.ws.rs.NotAcceptableException |
org.jboss.resteasy.spi.NotFoundException |
javax.ws.rs.NotFoundException |
org.jboss.resteasy.spi.UnauthorizedException |
javax.ws.rs.NotAuthorizedException |
org.jboss.resteasy.spi.UnsupportedMediaTypeException |
javax.ws.rs.NotSupportedException |
InjectorFactory 和 Registry
InjectorFactory
和 Registry
SPI 已有改动。如果您按照文档和支持来使用 RESTEasy,这不应该成为问题。
5.4.5. Jackson 提供者的变动
JBoss EAP 7 里包含的 Jackson 版本已有改变。之前的 JBoss EAP 包含的是 Jackson 1.9.9,而 JBoss EAP 7 现在包含 Jackson 2.6.3 或更高的版本。因此,Jackson 提供者已从 resteasy-jackson-provider
变为 resteasy-jackson2-provider
。
升级至 resteasy-jackson2-provider
要求修改一些软件包。例如,Jackson 注解软件包已从 org.codehaus.jackson.annotate
改成 com.fasterxml.jackson.annotation
。
To switch your application to use the default provider that was included in the previous release of JBoss EAP, see Switching the Default Jackson Provider in Developing Web Services Applications for JBoss EAP.
5.4.6. Spring RESTEasy 集成的修改
Spring 4.0 框架引入了对 Java 8 的支持。如果您计划集成 RESTEasy 3.x 和 Spring,请确保在部署里指定最低的 Spring 版本为 4.2.x,因为这是 JBoss EAP 7 支持的最早的稳定版本。
5.4.7. RESTEasy Jettison JSON 提供者的修改
JBoss EAP 7 已舍弃了 RESTEasy Jettison JSON 提供者,默认不再将其添加到部署里。我们鼓励您切换至我们推荐的 RESTEasy Jackson 提供者。如果您宁愿继续使用 Jettison 提供者,您必须在 jboss-deployment-descriptor.xml
文件里为其定义一个显性依赖关系,如下例所示。
<?xml version="1.0" encoding="UTF-8"?> <jboss-deployment-structure> <deployment> <exclusions> <module name="org.jboss.resteasy.resteasy-jackson2-provider"/> <module name="org.jboss.resteasy.resteasy-jackson-provider"/> </exclusions> <dependencies> <module name="org.jboss.resteasy.resteasy-jettison-provider" services="import"/> </dependencies> </deployment> </jboss-deployment-structure>
For more information about how to define explicit dependencies, see Add an Explicit Module Dependency to a Deployment in the JBoss EAP Development Guide.
5.5. CDI 1.2 应用程序的修改
JBoss EAP 7 includes support for CDI 1.2. As a result, applications written using CDI 1.0 might see some changes in behavior when migrated to JBoss EAP 7. This section summarizes only a few of those changes.
您可以在下列引用里找到关于 Weld 和 CDI 1.2 的更多信息:
Bean 归档
已启用的 bean 的 Bean 类必须部署在 bean 归档里以确保被 CDI 扫描并发现和处理 bean 类。
在 CDI 1.0 里,对于应用程序客户、EJB 或库 JAR,如果归档的 META-INF/
目录包含了 beans.xml
,或者是 WAR 的 WEB-INF/
目录包含了 beans.xml
文件,这个就被定义为显性的 bean 归档。
CDI 1.1 引入了隐性的 bean 归档,也就是包含一个或多个带有 bean 定义注解 bean 类或者会话 bean 的归档。隐性的 bean 归档会被 CDI 扫描,在类型发现过程中,只有带有 bean 定义注解的类会被发现。详情请参考Java EE 平台的上下文和依赖关系注入里的类型和 Bean 的发现。
Bean 归档具有 all
、annotated
或 none
发现模式。包含不带版本的 beans.xml
文件的 bean 归档的默认发现模式是 all
。包含 1.1
或更高版本的 beans.xml
文件的 bean 归档必须指定 bean-discovery-mode
属性。这个属性的默认值是 annotated
。
在下列情况下归档不是 Bean 归档:
-
它包含
bean-discovery-mode
为none
的beans.xml
文件。 -
它包含不带有
beans.xml
文件的 CDI 扩展。
在下列情况下归档是显性的 Bean 归档:
-
归档包含版本为 1.1 或更高的
beans.xml
文件,且bean-discovery-mode
模式为all
。 -
归档包含没有版本号的
beans.xml
文件。 -
归档包含空的
beans.xml
文件。
在下列情况下归档是隐性的 Bean 归档:
-
归档包含一个或多个带有 bean 定义注解 bean 类或者会话 bean,即使它没有包含
beans.xml
文件。 -
归档包含
bean-discovery-mode
为annotated
的beans.xml
文件。
CDI 1.2 将 bean 定义注解限制为:
-
@ApplicationScoped
、@SessionScoped
、@ConversationScoped
和@RequestScoped
注解。 - 所有其他的普通作用域类型
-
@Interceptor
和@Decorator
注解 -
使用
@Stereotype
的所有原型注解 -
@Dependent
作用域注解
关于 Bean 归档的更多信息,请参考Java EE 平台的上下文和依赖关系注入里的 Bean 归档。
会话解析(Conversation Resolution)的说明
会话上下文生命周期已被修改以防止和 CDI Specification Issue CDI-411 里描述的 Servlet 规格冲突。会话作用域在所有 Servlet 请求期间都时是活动的,它不应该阻止其他 Serlet 或 Servlet 过滤器设置请求主体或字符编码。
Observer 解析
CDI 1.2 已部分地重写了事件解析(Event resolution)。在 CDI 1.0 里,如果一个 observer 方法具有所有的事件限定符,事件将被递送给它。在 CDI 1.2 里,如果一个 observer 方法没有事件限定符或只有一个子集,事件将被递送给它。
5.6. 迁移显性模块依赖关系
之前 JBoss EAP 版本里引入模块化类加载系统和 JBoss Modules 允许对应用程序可用的类进行细颗粒度的控制。这个功能允许您用应用程序的 MANIFEST.MF
或 jboss-deployment-structure.xml
部署描述符文件配置显性的模块依赖关系。
如果您在应用程序里定义了显性的模块依赖关系,您应该意识到 JBoss EAP 7 里下列的变化。
复查依赖关系的可用性
JBoss EAP 里包含的模块已经改动。当您迁移应用程序至 JBoss EAP 7 时,请复查您的 MANIFEST.MF
和 jboss-deployment-structure.xml
文件以确保它们没有引用本版本已删除的模块。
要求注解扫描的依赖关系
在之前 JBoss EAP 版本里,如果依赖关系包含了在注解扫描时需要处理的注解,如声明 EJB 拦截器时,您会被要求在新的 JAR 文件里生成和包括 Jandex 索引并在 MANIFEST.MF
或 jboss-deployment-structure.xml
部署描述符文件里设置一个标记。
JBoss EAP 7 现在为静态模块提供了注解索引的运行时自动生成,所以您不再需要手动生成它们。然而,您仍需要添加 annotations
标记到应用程序的 MANIFEST.MF
或 jboss-deployment-structure.xml
文件(如下所示)。
MANIFEST.MF 文件里的注解标记示例
Dependencies: com.company.my-ejb annotations, com.company.other
jboss-deployment-structure.xml 文件里的注解标记示例
<jboss-deployment-structure> <deployment> <dependencies> <module name="com.company.my-ejb" annotations="true"/> <module name="com.company.other"/> </dependencies> </deployment> </jboss-deployment-structure>
5.7. Hibernate 和 JPA 迁移的修改
5.7.1. Hibernate ORM 3.0
The integration classes that made it easier to use Hibernate ORM 3 in the previous release were removed from JBoss EAP 7. If your application still uses Hibernate ORM 3 libraries, it is strongly recommended that you migrate your application to use Hibernate ORM 5 as Hibernate ORM 3 will no longer work in JBoss EAP without a lot of effort. If you can not migrate to Hibernate ORM 5, you must define a custom JBoss Module for the Hibernate ORM 3 JARs and exclude the Hibernate ORM 5 classes from your application.
5.7.2. Hibernate ORM 4.0 - 4.3
If your application needs second-level cache enabled, you should migrate to Hibernate ORM 5, which is integrated with Infinispan 8.x.
Applications written with Hibernate ORM 4.x can still use Hibernate ORM 4.x. You must define a custom JBoss module for the Hibernate ORM 4.x JARs and exclude the Hibernate ORM 5 classes from your application. However, it is strongly recommended that you rewrite your application code to use Hibernate ORM 5. For information about migrating to Hibernate ORM 5, see Migrating to Hibernate ORM 5.
5.7.3. Hibernate ORM 5
If your application contains a persistence.xml
file or the code uses the @PersistenceContext
or @PersistenceUnit
annotations, JBoss EAP 7 detects this during deployment and assumes the application uses JPA. It implicitly adds the Hibernate ORM 5 libraries plus a few other dependencies to your application class path and defaults to using these libraries.
5.7.4. Migrating to Hibernate ORM 5
This section highlights the changes you need to make when migrating from Hibernate ORM version 4.3 to version 5. For more information about the changes implemented between Hibernate ORM 4 and Hibernate ORM 5, see the Hibernate ORM 5.0 Migration Guide.
Removed and Deprecated Classes
The following deprecated classes were removed from Hibernate ORM 5.
Other Changes to Classes and Packages
-
The
org.hibernate.integrator.spi.Integrator
interface changed to account for bootstrap redesign. -
A new package
org.hibernate.engine.jdbc.env
package was created. It contains theorg.hibernate.engine.jdbc.env.spi.JdbcEnvironment
interface, which was extracted fromorg.hibernate.engine.jdbc.spi.JdbcServices
interface. -
A new
org.hibernate.boot.model.relational.ExportableProducer
interface was introduced that will affectorg.hibernate.id.PersistentIdentifierGenerator
implementations. -
The signature of
org.hibernate.id.Configurable
was changed to acceptorg.hibernate.service.ServiceRegistry
rather than justorg.hibernate.dialect.Dialect
. -
The
org.hibernate.metamodel.spi.TypeContributor
interface has migrated toorg.hibernate.boot.model.TypeContributor
. -
The
org.hibernate.metamodel.spi.TypeContributions
interface has migrated toorg.hibernate.boot.model.TypeContributions
.
Type Handling
-
Built-in
org.hibernate.type.descriptor.sql.SqlTypeDescriptor
implementations no longer auto-register themselves withorg.hibernate.type.descriptor.sql.SqlTypeDescriptorRegistry
. Applications using customSqlTypeDescriptor
implementations that extend the built-in implementations and rely on that behavior must be updated to callSqlTypeDescriptorRegistry.addDescriptor()
themselves. -
For IDs defined as generated UUIDs, some databases require you to explicitly set the
@Column(length=16)
in order to generateBINARY(16)
so that comparisons work properly. -
For
EnumType
mappings defined in thehbm.xml
, where you wantjavax.persistence.EnumType.STRING
name-mapping
, this configuration must be explicitly stated by using either theuseNamed(true)
setting or by specifying a VARCHAR value of12
.
Transaction Management
-
The transaction SPI underwent a major redesign in Hibernate ORM 5. In Hibernate ORM 4.3, you used the
org.hibernate.Transaction
API to directly access different back-end transaction strategies. Hibernate ORM 5 introduced a level of indirection. On the back end, theorg.hibernate.Transaction
implementation now talks to aorg.hibernate.resource.transaction.TransactionCoordinator
, which represents the transactional context for a given session according to the back-end strategy. While this does not have a direct impact on developers, it could affect the bootstrap configuration. Previously applications would specifyhibernate.transaction.factory_class
property, which is now deprecated, and refer to aorg.hibernate.engine.transaction.spi.TransactionFactory
FQN (fully qualified name). With Hibernate ORM 5, you specify thehibernate.transaction.coordinator_class
setting and refer to aorg.hibernate.resource.transaction.TransactionCoordinatorBuilder
. Seeorg.hibernate.cfg.AvailableSettings.TRANSACTION_COORDINATOR_STRATEGY
for additional details. The following short names are now recognized.
-
jdbc: Manage transactions using the JDBC
java.sql.Connection
. This is the default for non-JPA transactions. jta: Manage transactions using JTA.
重要If a JPA application does not provide a setting for the
hibernate.transaction.coordinator_class
property, Hibernate will automatically build the proper transaction coordinator based on the transaction type for the persistence unit.If a non-JPA application does not provide a setting for the
hibernate.transaction.coordinator_class
property, Hibernate will default tojdbc
to manage the transactions. This default will cause problems if the application actually uses JTA-based transactions. A non-JPA application that uses JTA-based transactions should explicitly set thehibernate.transaction.coordinator_class
property value tojta
or provide a customorg.hibernate.resource.transaction.TransactionCoordinatorBuilder
that builds aorg.hibernate.resource.transaction.TransactionCoordinator
that properly coordinates with JTA-based transactions.
-
jdbc: Manage transactions using the JDBC
Other Hibernate ORM 5 Changes
-
The
cfg.xml
files are again fully parsed and integrated with events, security, and other functions. -
The properties loaded from the
cfg.xml
using theEntityManagerFactory
did not previously prefix names withhibernate
. This has now been made consistent. - The configuration is no longer serializable.
-
The
org.hibernate.dialect.Dialect.getQuerySequencesString()
method now retrieves catalog, schema, and increment values. -
The
AuditConfiguration
modifier was removed fromorg.hibernate.envers.boot.internal.EnversService
. -
The
AuditStrategy
method parameters were changed to remove the obsoleteAuditConfiguration
and use the newEnversService
. -
Various classes and interfaces in the
org.hibernate.hql.spi
package and subpackages have been moved to the neworg.hibernate.hql.spi.id
package. This includes theMultiTableBulkIdStrategy
class and theAbstractTableBasedBulkIdHandler
,TableBasedDeleteHandlerImpl
, andTableBasedUpdateHandlerImpl
interfaces and their subclasses. - There was a complete redesign of property access contracts.
-
Valid
hibernate.cache.default_cache_concurrency_strategy
setting values are now defined using theorg.hibernate.cache.spi.access.AccessType.getExternalName()
method rather than theorg.hibernate.cache.spi.access.AccessType
enum constants. This is more consistent with other Hibernate settings.
5.8. Hibernate Search 的修改
JBoss EAP 7 附带的 Hibernate Search 版本已被修改。之前版本的 JBoss EAP 附带 Hibernate Search 4.6.x,而 JBoss EAP 7 附带 Hibernate Search 5.5.x。
Hibernate Search 5.5 is built upon Apache Lucene 5.3.1. If you use any native Lucene APIs, be sure to align with this version. The Hibernate Search 5.5 API wraps and hides the complexity of many of the Lucene API changes made between version 3 and version 5, however, some classes are now deprecated, renamed, or repackaged. This section describes how these changes might impact your application code.
Hibernate Search Mapping 的修改
内嵌关系的 ID 字段的索引
当使用 @IndexedEmbedded
注解来包含相关实体的字段时,相关实体的 id
字段不再被包含。您可以用 @IndexedEmbedded
注解的 includeEmbeddedObjectId
属性启用对 id
的包含。
@IndexedEmbedded(includeEmbeddedObjectId=true)
数字和日期索引格式的修改
数字和日期现在默认用数值型字段作为索引。int
、long
、float
、double
类型的属性及对应的 Wrapper 类都不再用字符串进行索引了。它们现在改为使用 Lucene 的数字编码来索引。id
字段是这个规则的一个例外。即使它们用数字类型来表达,它们的索引默认仍使用字符串键值。@NumericField
现在已废弃,除非您希望为数字编码定制精度。您可以通过制定一个字符串编码的字段桥(field bridge)来保留旧的基于字符串的索引格式。对于整型,它就是 org.hibernate.search.bridge.builtin.IntegerBridge。关于其他可用的公用字段桥,请参考org.hibernate.search.bridge.builtin软件包。
Date
和 Calendar
不再以字符串为索引。它们改为用长整型来代表自 1970 年 1 月1 日 00:00:00 GMT 以来的毫秒数。您可以用新的EncodingType 枚举来切换索引格式。例如:
@DateBridge(encoding=EncodingType.STRING) @CalendarBridge(encoding=EncodingType.STRING)
数字和日期的编码修改是很重要的,这对应用程序的行为有重大影响。如果以字段为目标的查询之前是用字符串编码,而现在是数字编码,您就必须更新这个查询。数字型的字段必须用 NumericRangeQuery
进行搜索。您也必须确保所有按目标分类的字段都是用字符串编码的。如果您使用 Search 查询 DSL,正确的查询应该会自动创建。
其他的 Hibernate Search 修改
-
我们改进了排序选项,排序选项的错误字段编码现在会导致 runtime 异常抛出。如果预先知道排序使用的字段,Lucene 也提供了更高性能的排序方式。Hibernate Search 5.5 提供了新的
@SortableField
注解及其多值选项@SortableFields
。更多信息请参考《从 Hibernate Search 5.4 到 5.5 的迁移指南》。 Lucene
SortField
API 要求进行下列程序代码的修改。在以前的 JBoss EAP 6 版本里,您可以像下面这样设置排序字段的类型。
fulltextQuery.setSort(new Sort(new SortField("title", SortField.STRING)));
下面是在 JBoss EAP 7 进行设置的例子。
fulltextQuery.setSort(new Sort(new SortField("title", SortField.Type.STRING)));
-
既然
SearchFactory
只应被 ORM 集成使用,它从hibernate-search-engine
模块移至hibernate-search-orm
模块。其他集成应该专门地依赖于SearchIntegrator
,它替代了已舍弃的SearchFactoryIntegrator
。 -
枚举值
SpatialMode.GRID
被重命名为SpatialMode.HASH
。 -
FullTextIndexEventListener
现在是 final 类。如果您目前继承了这个类,您必须找到替代方案来实现相同的功能。 -
hibernate-search-analyzers
模块已删除。我们推荐的方法是直接使用合适的 Lucene 工件,例如org.apache.lucene:lucene-analyzers-common
。 -
The JMS controller API has changed. The JMS back-end dependency on Hibernate ORM was removed so that it could be used in other non-ORM environments. A consequence is that implementors of
org.hibernate.search.backend.impl.jms.AbstractJMSHibernateSearchController
must adjust to the new signature. This class is an internal class and it is recommended to use it as an example instead of extending it. -
org.hibernate.search.spi.ServiceProvider
SPI 已被重构。如果您要集成旧的服务合约,新合约的细节请参考ServiceManager
、Service
、Startable
和Stoppable
的 Hibernate Search 5.5 Javadoc。 -
如果您已保留了 Lucene 3.x 生成的索引且没有用 Hibernate Search 5.0 或更新的版本进行重构,您将遇到
IndexFormatTooOldException
。我们推荐您用 mass indexer 重构索引。如果您不能这样做,请试图使用 Lucene 的IndexUpgrader
。如果默认行为已修改,您必须小心地更新 Hibernate Search 映射。更多的信息请参考《Apache Lucene 迁移指南》。 - JBoss EAP 7 已将 Apache Lucene 升级为 3.6 到 5.3。如果您的代码直接导入了 Lucene 代码,相关细节请参考《Apache Lucene 迁移指南》。其他信息可以在 Lucene 更新日志里找到。
-
当使用
@Field(indexNullAs=)
来对索引里的空 marker 值编码时,这个 marker 的类型必须和在相同字段里其他索引值兼容。例如,之前可能对数值型字段用字符串 "null" 编码空的值。现在这是不允许的。相反,您必须选择一个数字来表示null
值,如-1
。 -
我们对 faceting 引擎进行了重大改进。多数改动不会影响 API。一个值得注意的例外是您必须注解任何要用
@Facet
或@Facets
注解进行 faceting 的字段。
Hibernate Search 重命名和重打包的类
下面是被重新打包或重命名的 Hibernate Search 类的列表。
之前的软件包和类 | 新的软件包和类 |
---|---|
org.hibernate.search.Environment |
org.hibernate.search.cfg.Environment |
org.hibernate.search.FullTextFilter |
org.hibernate.search.filter.FullTextFilter |
org.hibernate.search.ProjectionConstants |
org.hibernate.search.engine.ProjectionConstants |
org.hibernate.search.SearchException |
org.hibernate.search.exception.SearchException |
org.hibernate.search.Version |
org.hibernate.search.engine.Version |
Lucene - 重命名和重打包的类
查询解析器已移至新的模块,所在软件包从 org.apache.lucene.queryParser.QueryParser
改为 org.apache.lucene.queryparser.classic.QueryParser
。
许多 Lucene 分析器都已重构,导致软件包的变动。要寻找替代的软件包,请查看 Apache Lucene 文档。
某些 Apache Solr 工具类,如 TokenizerFactory
或 TokenFilterFactory
,都已移至 Apache Lucence。如果您的应用程序使用了这些工具或自定义的分析器,您必须找到 Apache Lucene 里新的软件包名称。
更多的信息请参考《Apache Lucene 迁移指南》。
Hibernate Search 已舍弃的 API
关于 Hibernate Search 已舍弃的接口、类、枚举、注解类型、方法、构造器和枚举常量的完整列表,请参考 Hibernate Search 已舍弃的 API 文档。
Hibernate Search 已舍弃的接口
接口 | 描述 |
---|---|
org.hibernate.search.store.IndexShardingStrategy |
从 Hibernate Search 4.4 开始已舍弃,可能在 Search 5 里删除。现在请使用 ShardIdentifierProvider 。 |
org.hibernate.search.store.Workspace |
This interface will be moved and should be considered non-public API. For more information, see HSEARCH-1915. |
Hibernate Search 已舍弃的类
类 | 描述 |
---|---|
org.hibernate.search.filter.FilterKey |
自定义的过滤器键已舍弃且在 Hibernate Search 6 里将被删除。从 Hibernate Search 5.1 开始,用于缓存 Lucene 过滤器的键将基于给定的过滤器参数自动计算。 |
org.hibernate.search.filter.StandardFilterKey |
自定义的过滤器键已舍弃且在 Hibernate Search 6 里将被删除。从 Hibernate Search 5.1 开始,用于缓存 Lucene 过滤器的键将基于给定的过滤器参数自动计算。 |
Hibernate Search 已舍弃的枚举
枚举 | 描述 |
---|---|
org.hibernate.search.annotations.FieldCacheType |
请删除已舍弃的 |
Hibernate Search 已舍弃的注解
注解 | 描述 |
---|---|
org.hibernate.search.annotations.CacheFromIndex |
请删除这个注解,不需要其他接替者。 |
org.hibernate.search.annotations.Key |
自定义的过滤器缓存键已舍弃且在 Hibernate Search 6 里将被删除。从 Hibernate Search 5.1 开始,过滤器缓存键将基于过滤器参数自动确定,所以不再需要提供键对象。 |
Hibernate Search 已舍弃的方法
方法 | 描述 |
---|---|
org.hibernate.search.FullTextSharedSessionBuilder.autoClose() |
没有接替者 |
org.hibernate.search.FullTextSharedSessionBuilder.autoClose(boolean) |
没有接替者 |
org.hibernate.search.cfg.IndexedMapping.cacheFromIndex(FieldCacheType…) |
它将被删除且没有接替者。 |
org.hibernate.search.cfg.EntityDescriptor.getCacheInMemory() |
它将被删除且没有接替者。 |
org.hibernate.search.cfg.ContainedInMapping.numericField() |
请改为调用 |
org.hibernate.search.cfg.EntityDescriptor.setCacheInMemory(Map<String, Object>) |
它将被删除且没有接替者。 |
org.hibernate.search.MassIndexer.threadsForSubsequentFetching(int) |
这个方法将被删除。 |
org.hibernate.search.query.dsl.FuzzyContext.withThreshold(float) |
请使用 |
Hibernate Search 已舍弃的构造器
构造器 | 描述 |
---|---|
org.hibernate.search.cfg.NumericFieldMapping(PropertyDescriptor, EntityDescriptor, SearchMapping) |
请改为使用 |
影响高级集成器的修改
本节描述了非公用 API 的修改。它们不应该影响普通开发人员,因为这些工件只应该由继承 Hibernate Search 框架的集成者访问。
-
IndexWriterSetting.MAX_THREAD_STATES
和IndexWriterSetting.TERM_INDEX_INTERVAL
枚举常量已被舍弃。它们影响从配置读取哪些属性,它们的缺失意味着忽略一些配置属性如hibernate.search.Animals.2.indexwriter.term_index_interval = default
,所以唯一的副作用是不会应用这些属性。 -
SearchFactoryIntegrator
接口已被舍弃。您应该立即迁移所有的代码以使用SearchIntegrator
。 -
SearchFactoryBuilder
类已被舍弃。请改为使用SearchIntegrationBuilder
。 -
The
HSQuery.getExtendedSearchIntegrator()
method has been deprecated. It might be possible to useSearchIntegrator
, but it is preferable to remove it altogether. -
DocumentBuilderIndexedEntity.getFieldCacheOption()
方法已被舍弃。目前还没有接替者。 -
BuildContext.getIndexingStrategy()
方法已被舍弃。请改为使用BuildContext.getIndexingMode()
。 -
DirectoryHelper.getVerifiedIndexDir(String, Properties, boolean)
方法已被舍弃。请改为使用DirectoryHelper.getVerifiedIndexPath(java.lang.String, java.util.Properties, boolean)
。 下面是被重新打包或重命名的 Hibernate Search 类的列表。
之前的软件包和类 新的软件包和类 org.hibernate.search.engine.impl.SearchMappingBuilder
org.hibernate.search.engine.spi.SearchMappingHelper
org.hibernate.search.indexes.impl.DirectoryBasedIndexManager
org.hibernate.search.indexes.spi.DirectoryBasedIndexManager
org.hibernate.search.spi.MassIndexerFactory
org.hibernate.search.batchindexing.spi.MassIndexerFactory
org.hibernate.search.spi.SearchFactoryBuilder
org.hibernate.search.spi.SearchIntegratorBuilder
org.hibernate.search.spi.SearchFactoryIntegrator
org.hibernate.search.spi.SearchIntegrator
5.9. 迁移 Entity Bean 至 JPA
Java EE 7 对 EJB Entity Bean 的支持是可选的,它们不再受到支持。这意味着迁移到 JBoss EAP 7 时,您必须重写 CMP(container-managed persistence)和 BMP(bean-managed persistence)来使用 Java Persistence API (JPA) 实体。
在以前的 JBoss EAP 版本里,Entity Bean 是通过应用程序代码继承 javax.ejb.EntityBean
类并实现所需方法来创建的。它们然后在 ejb-jar.xml
文件里进行配置,CMP Entity Bean 用包含值为 Container 的 <persistence-type>
子元素的 <entity>
元素来指定。BMP entity bean 用包含值为 Bean 的子元素 <persistence-type>
的 <entity>
元素来指定。
在 JBoss EAP 7 里,您必须用 Java Persistence API (JPA) 实体替换任何 CMP 和 BMP Entity Bean。JPA 实体使用 javax.persistence.* 类创建并在 persistence.xml
文件里定义的。
下面是一个 JPA 实体类示例。
import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.Id; import javax.persistence.Table; @Entity // User is a keyword in some SQL dialects! @Table(name = "MyUsers") public class MyUser { @Id @GeneratedValue private Long id; @Column(unique = true) private String username; private String firstName; private String lastName; public Long getId() { return id; } public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public String getFirstName() { return firstName; } public void setFirstName(String firstName) { this.firstName = firstName; } public String getLastName() { return lastName; } public void setLastName(String lastName) { this.lastName = lastName; }
下面是一个 persistence.xml
文件示例。
<persistence version="2.1" xmlns="http://xmlns.jcp.org/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation=" http://xmlns.jcp.org/xml/ns/persistence http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd"> <persistence-unit name="my-unique-persistence-unit-name"> <properties> // properties... </properties> </persistence-unit> </persistence>
关于 JPA 实体的示例,请参考 JBoss EAP 7 附带的 bmt
、cmt
和 hibernate5
Quickstarts 例程。
5.10. JPA 持久化属性的修改
我们添加了新的持久性属性 jboss.as.jpa.deferdetach
来提供对之前版本的 JBoss EAP 里的持久性行为的支持。
jboss.as.jpa.deferdetach
属性控制每次 EntityManager
调用后非 JTA 事务线程里使用的事务作用域的持久化上下文是否分离加载的实体,或者等待至持久化上下文关闭。例如,当 Session Bean 调用结束时。这个属性值默认是 false
,表示实体在每次 EntityManager
调用后被分离或清除。这是 JPA 规格里定义的正确的默认行为。如果属性被设置为 true
,实体在持久化上下文关闭前不会被分离。
在 JBoss EAP 5 里,持久化的行为就像将 jboss.as.jpa.deferdetach
属性设置为 true
一样。要在迁移至 JBoss EAP 7 时获得相同的行为,您必须在 persistence.xml
里将 jboss.as.jpa.deferdetach
属性设置为 true
,如下例所示。
<?xml version="1.0" encoding="UTF-8"?> <persistence xmlns="http://java.sun.com/xml/ns/persistence" version="1.0"> <persistence-unit name="EAP5_COMPAT_PU"> <jta-data-source>java:jboss/datasources/ExampleDS</jta-data-source> <properties> <property name="jboss.as.jpa.deferdetach" value="true" /> </properties> </persistence-unit> </persistence>
在 JBoss EAP 6 里,持久化的行为就像将 jboss.as.jpa.deferdetach
属性设置为 false
一样。这在 JBoss EAP 7 里是相同的,所以迁移应用程序时不需要进行修改。
5.11. 迁移 EJB 客户代码
JBoss EAP 7 修改了默认的远程连接器和端口。关于这种改动的细节,请参考更新远程 URL 连接器和端口。
如果您使用了 migrate
操作来迁移服务器配置,旧的设置将被保留,您不需要修改下面的细节。然而,如果您用新的 JBoss EAP 7 默认配置运行,您必须进行下列修改。
5.11.1. 更新默认的远程连接端口
在 jboss-ejb-client.properties
文件里将远程连接端口值从 4447
改为 8080
。
下面是之前和当前版本里的 jboss-ejb-client.properties
文件示例。
示例:JBoss EAP 6 jboss-ejb-client.properties 文件
remote.connectionprovider.create.options.org.xnio.Options.SSL_ENABLED=false remote.connections=default remote.connection.default.host=localhost remote.connection.default.port=4447 remote.connection.default.connect.options.org.xnio.Options.SASL_POLICY_NOANONYMOUS=false
示例:JBoss EAP 7 jboss-ejb-client.properties 文件
remote.connectionprovider.create.options.org.xnio.Options.SSL_ENABLED=false remote.connections=default remote.connection.default.host=localhost remote.connection.default.port=8080 remote.connection.default.connect.options.org.xnio.Options.SASL_POLICY_NOANONYMOUS=false
5.11.2. 更新默认的连接器
如果您使用新的 JBoss EAP 7 配置运行,默认的连接器已从 remote
改为 http-remoting
。这次改动影响了使用某个版本里的库并连接不同版本的服务器的客户。
-
如果客户应用程序使用 JBoss EAP 6 里的 EJB 客户库并希望连接至 JBoss EAP 7 服务器,您必须配置服务器通过
8080
之外的端口开放remote
连接器。然后客户必须使用新配置的连接器进行连接。 使用 JBoss EAP 7 里的 EJB 客户库并希望连接至 JBoss EAP 6 服务器的客户应用程序必须意识到服务器实例没有使用
http-remoting
而是remoting
连接器。这是通过定义新的客户端连接属性来实现的。remote.connection.default.protocol=remote
5.11.3. 迁移远程命名客户代码
如果您用新的默认 JBoss EAP 7 配置运行,你必须修改客户代码以使用新的默认远程端口和连接器。
下面是 JBoss EAP 6 里如何在客户代码里指定远程命名属性的例子。
java.naming.factory.initial=org.jboss.naming.remote.client.InitialContextFactory java.naming.provider.url=remote://localhost:4447
下面是 JBoss EAP 7 里如何在客户代码里指定远程命名属性的例子。
java.naming.factory.initial=org.jboss.naming.remote.client.InitialContextFactory java.naming.provider.url=http-remoting://localhost:8080
5.12. 迁移部署计划配置
The Java EE Application Deployment specification (JSR-88) was intended to define a standard contract to enable tools from multiple providers to configure and deploy applications on any Java EE platform product. The contract required Java EE Product Providers to implement the DeploymentManager
and other javax.enterprise.deploy.spi
interfaces to be accessed by the Tool Providers. In case of JBoss EAP 6, a deployment plan is identified by an XML descriptor named deployment-plan.xml
that is bundled in a ZIP or JAR archive.
我们已很少采用这个规格,因为多数应用服务器产品提供了自己更“功能丰富”的部署方案。出于这个原因,Java EE 7 取消了对 JSR-88 的支持,所以 JBoss EAP 7 也不再支持。
If you used JSR-88 to deploy your application, you must now use another method to deploy the application. The JBoss EAP management CLI deploy
command provides a standard way to deploy archives to standalone servers or to server groups in a managed domain. For more information about the management CLI, see the Management CLI Guide.
5.13. 迁移自定义应用程序阀
您必须手动迁移自定义阀或任何在 jboss-web.xml
XML 文件里定义的阀。这包含通过继承 org.apache.catalina.valves.ValveBase
类创建以及在 jboss-web.xml
描述符文件的 <valve>
元素里配置的阀。
自定义阀和 jboss-web.xml
文件里定义的阀必须被重写或用对应的 Undertow 内置处理程序替代。关于映射阀到 Undertow 处理程序的更多信息,请参考迁移 JBoss Web 阀。
验证阀必须用 Undertow 内嵌的验证机制手动替换。
迁移部署里配置的阀
在 JBoss EAP 6,您可以在 jboss-web.xml
描述符文件里进行配置来定义应用程序级别的自定义阀。而在 JBoss EAP 7 里,您可以用 Undertow 处理程序来实现。
下面是 JBoss EAP 6 里的 jboss-web.xml
文件配置的阀的示例。
<jboss-web> <valve> <class-name>org.jboss.examples.MyValve</class-name> <param> <param-name>myParam</param-name> <param-value>foobar</param-value> </param> </valve> </jboss-web>
For more information about how to create and configure custom handlers in JBoss EAP, see Creating Custom Handlers in the JBoss EAP Development Guide.
迁移自定义验证器阀
关于如何迁移验证器阀的信息,请参考安全性应用程序的修改。
5.14. 安全性应用程序的修改
用 Undertow 替代 JBoss Web 要求修改 JBoss EAP 7 的安全性配置。
5.14.1. 迁移
验证器阀(Authenticator Valve)必须用 Undertow 内置的验证机制手动替代。关于如何迁移验证器阀的信息,请阅读下面的章节。
5.14.2. PicketLink 的修改
For information about the changes required for SSO with SAML v2 configuration, see Changes from Previous Versions of JBoss EAP in How to Set Up SSO with SAML v2 for JBoss EAP.
5.14.3. 其他安全性应用程序的修改
For information about the differences in SSO configuration with Kerberos, see Differences from Configuring Previous Versions JBoss EAP in How to Set Up SSO with Kerberos for JBoss EAP.
5.15. JBoss Logging 的修改
如果您的应用程序使用了 JBoss Logging,请注意 JBoss EAP 7 已舍弃在 org.jboss.logging
软件包里进行注解。它们被移至 org.jboss.logging.annotations
软件包,所以您必须更新源码来导入新的软件包。
这些注解也已移至单独的 Maven groupId:artifactId:version
(GAV) ID,所以您需要在 pom.xml
文件里为 org.jboss.logging:jboss-logging-annotations
添加一个新的依赖关系。
只移动了日志注解。org.jboss.logging.BasicLogger
和 org.jboss.logging.Logger
仍存在于 org.jboss.logging
软件包里。
下表列出已舍弃的注解类和对应的接替者。
表 5.1. 已舍弃的 Logging 注解的接替者
已舍弃的类 | 替代的类 |
---|---|
org.jboss.logging.Cause |
org.jboss.logging.annotations.Cause |
org.jboss.logging.Field |
org.jboss.logging.annotations.Field |
org.jboss.logging.FormatWith |
org.jboss.logging.annotations.FormatWith |
org.jboss.logging.LoggingClass |
org.jboss.logging.annotations.LoggingClass |
org.jboss.logging.LogMessage |
org.jboss.logging.annotations.LogMessage |
org.jboss.logging.Message |
org.jboss.logging.annotations.Message |
org.jboss.logging.MessageBundle |
org.jboss.logging.annotations.MessageBundle |
org.jboss.logging.MessageLogger |
org.jboss.logging.annotations.MessageLogger |
org.jboss.logging.Param |
org.jboss.logging.annotations.Param |
org.jboss.logging.Property |
org.jboss.logging.annotations.Property |
5.16. JavaServer Faces (JSF) 代码的修改
取消对 JSF 1.2 的支持
JBoss EAP 6 允许您通过创建 jboss-deployment-structure.xml
文件继续使用 JSF 1.2。
JBoss EAP 7 包含 JSF 2.2 且不再支持 JSF 1.2 API。如果您的应用程序使用 JSF 1.2,您必须重写代码以使用 JSF 2.2。
JSF 2.1 和 JSF 2.2 间的兼容性问题
JSF 2.1 和 JSF 2.2 API 不是完全兼容的。FACELET_CONTEXT_KEY
常量从 com.sun.faces.facelets.FACELET_CONTEXT
改成了 javax.faces.FACELET_CONTEXT
。编译器内联这个值,根据某个版本编译的代码将无法在其他版本里使用。
用 JSF 2.1 API 编译的包含和下面例子相似的代码的应用程序,如果在使用 JSF 2.2 API 的 JBoss EAP 7 里运行会导致 NullPointerException
。要修复这个问题,您必须用 JSF 2.2 API 重新编译应用程序。
Object obj = FacesContext.getCurrentInstance().getAttributes().get(FaceletContext.FACELET_CONTEXT_KEY);
5.17. 模块类加载的修改
在 JBoss EAP 7 里,多个模块包含相同的类或软件包时的类加载行为已修改。
假设有两个模块 MODULE_A
和 MODULE_B
,彼此依赖并包含一些相同的软件包。在 JBoss EAP 6 里,从依赖关系加载的类或软件包优先于 module.xml
文件的 resource-root
元素里指定的。这意味着 MODULE_A
可以看到 MODULE_B
的软件包而 MODULE_B
可以看到 MODULE_A
的软件包。这种行为让人困惑且可能导致冲突。而 JBoss EAP 7 已修改了这种行为。现在 module.xml
文件的 resource-root
元素指定的类或软件包优先于依赖关系所指定的。这意味着 MODULE_A
只可以看到 MODULE_A
的软件包而 MODULE_B
可以看到 MODULE_B
的软件包。这防止了冲突并提供了更合适的行为。
If you have defined custom modules that include resource-root
libraries or packages that contain classes that are duplicated in their module dependencies, you might see ClassCastException
, LinkageError
, class loading errors, or other changes in behavior when you migrate to JBoss EAP 7. To resolve these issues, you must configure your module.xml
file to ensure only one version of a class is used. This can be accomplished by using either of the following approaches.
-
您可以避免指定在模块依赖关系里重复类的
resource-root
。 您可以使用
imports
和exports
的include
和exclude
子元素来控制module.xml
文件里的类加载。下面是使用 export 元素排除指定软件包里的类的例子。<exports> <exclude path="com/mycompany/duplicateclassespath/"/> </exports>
如果您希望保留现有的行为,你必须通过 filter
元素在过滤 module.xml
文件里 resource-root
的依赖关系软件包。这允许您保留现有的行为而不会看到 JBoss EAP 6 里看到的奇怪的循环。下面是通过 root-resource
过滤指定软件包里的类的例子。
<resource-root path="mycompany.jar"> <filter> <exclude path="com/mycompany/duplicateclassespath"/> </filter> </resource-root>
For more information about modules and class loading, see Class Loading and Modules in the JBoss EAP Development Guide.
5.18. 应用程序群集的修改
5.18.1. 新的群集功能概述
下面描述了从 JBoss EAP 6 迁移至 JBoss EAP 7 时要注意的新的群集功能。
- JBoss EAP 7 introduces a new public API for building singleton services that significantly simplifies the process. For more information, see Implement an HA Singleton in Developing EJB Applications for JBoss EAP.
- A singleton deployment can be configured to deploy and start on only a single node in the cluster at a time. For more information, see HA Singleton Deployments in the JBoss EAP Development Guide.
- You can now define clustered singleton MDBs. For more information, see Clustered Singleton MDBs in Developing EJB Applications for JBoss EAP.
- JBoss EAP 7 includes the Undertow mod_cluster implementation. This offers a pure Java load balancing solution that does not require an httpd web server. For more information, see Configuring JBoss EAP as a Front-end Load Balancer in the JBoss EAP Configuration Guide.
The remainder of this section describes how clustering changes might impact the migration of your applications to JBoss EAP 7.
5.18.2. Web 会话群集的修改
JBoss EAP 7 引入了新的 Web 会话群集实现。它替代了之前和旧的 JBoss Web 子系统紧耦合的实现。
新的 Web 会话群集实现影响了如何在 jboss-web.xml
描述符文件里配置应用程序。下面是这个文件里保留的群集配置元素。
<jboss-web> ... <max-active-sessions>...</max-active-sessions> ... <replication-config> <replication-granularity>...</replication-granularity> <cache-name>...</cache-name> </replication-config> ... </jboss-web>
下表描述了如何实现和 jboss-web.xml
里现已舍弃的元素类似的行为。
配置元素 | 对修改的描述 |
---|---|
<max-active-sessions/> |
以前,如果活动会话的数量超过了
在新的实现里, |
<passivation-config/> |
JBoss EAP 7 不再使用这个配置元素及其子元素。 |
<use-session-passivation/> |
以前,钝化是用这个属性启用的。
在新的实现里,钝化是通过为 |
<passivation-min-idle-time/> |
以前,会话在成为钝化候选者之前,需要处于活动状态一段最短的时间。这可能导致创建会话失败,即使已启用了钝化。 新的实现不支持这个逻辑,所以避免了拒绝服务(Denial of Service,DoS)漏洞。 |
<passivation-max-idle-time/> |
以前,会话将处于空闲状态一段时间后将被钝化。
新的实现只支持 lazy 钝化。它不支持 eager 钝化。会话只有在需要遵从 |
<replication-config/> |
新的实现舍弃了大量的子元素。 |
<replication-trigger/> |
Previously, this element was used to determine when session replication was triggered. The new implementation replaces this configuration option with a single, robust strategy. For more information, see Immutable Session Attributes in the JBoss EAP Development Guide. |
<use-jk/> |
以前,处理给定请求的节点的
在新的实现里,如果定义了 |
<max-unreplicated-interval/> |
以前,这个配置选项的目的是防止没有修改会话属性时会话时间戳的重复。虽然这听起来不错,但事实上它没有防止任何 RPC,因为无论是否修改了任何会话属性,访问会话都要求缓存事务 RPC。 在新的实现里,会话的时间戳在每次请求时进行复制。这防止了失效切换后的过时的会话元数据。 |
<snapshot-mode/> |
Previously, one could configure |
<snapshot-interval/> |
它只和 |
<session-notification-policy/> |
以前,这个属性指定的值定义了触发会话事件的策略。 在新的实现里,这个行为是规格驱动的且是不可配置的。 |
This new implementation also supports write-through cache stores as well as passivation-only cache stores. Typically, a write-through cache store is used in conjunction with an invalidation cache. The web session clustering implementation in JBoss EAP 6 did not operate correctly when used with an invalidation cache.
5.18.3. Stateful Session EJB 群集的修改
在 JBoss EAP 6 里,您被要求以下列方式之一启用 stateful session beans (SFSBs) 的群集行为。
您可以在 session bena 里添加
org.jboss.ejb3.annotation.Clustered
注解。@Stateful @Clustered public class MyBean implements MySessionInt { public void myMethod() { // } }
您可以将
<clustered>
元素添加到jboss-ejb3.xml
文件里。<c:clustering> <ejb-name>DDBasedClusteredSFSB</ejb-name> <c:clustered>true</c:clustered> </c:clustering>
JBoss EAP 7 不再要求您启用群集行为。在默认情况下,如果服务器用 HA 配置集启动,SFSB 的状态将自动复制。
您可以用下列方式之一禁用默认的行为。
-
您可以使用 EJB 3.2 规格里新的
@Stateful(passivationCapable=false)
来禁用单个 stateful session bean 的默认行为。 -
你也可以通过服务器配置的
ejb3
子系统来在全局禁用这个行为。
如果没有从应用程序里删除 @Clustered
注解,它会被忽略且不会影响到应用程序的部署。
5.18.4. 群集服务的修改
在 JBoss EAP 6,用于群集服务的 API 位于私有模块且不被支持。
JBoss EAP 7 引入了公用群集 API。新的服务被设计为轻量级的、易于注入的且没有外部依赖关系。
-
新的
org.wildfly.clustering.group.Group
接口提供了对当前群集状态的访问并允许侦听群集成员的变动。 -
新的
org.wildfly.clustering.dispatcher.CommandDispatcher
接口允许在群集、所有或选择的节点子集里运行代码。
这些服务替代了之前版本里类似的 API,也就是 JBoss EAP 5 的 HAPartition
,JBoss EAP 6 里的 GroupCommunicationService
、GroupMembershipNotifier
和 GroupRpcDispatcher
。
For more information, see Public API for Clustering Services in the JBoss EAP Development Guide.
5.18.5. 迁移群集 HA 单点登录
在 JBoss EAP 6 里,群集范围的 HA 单点登录服务没有可用的公用 API。如果您使用了私有 org.jboss.as.clustering.singleton.*
类,在迁移应用程序至 JBoss EAP 7 时,您必须修改代码以使用新的公用 org.wildfly.clustering.singleton.*
软件包。
For more information about how to implement an HA singleton, see HA Singleton Service in the Development Guide for JBoss EAP.