成都网站建设设计

将想法与焦点和您一起共享

从JbossEAP6.4迁移到EAP7.1

建站服务器 POM 升级JavaEE


org.jboss.bom
jboss-eap-javaee7
7.1.1.GA
pom
import


org.jboss.eap
wildfly-ejb-client-bom
7.1.1.GA-redhat-2
pom
import


org.jboss.eap
wildfly-jms-client-bom
7.1.1.GA-redhat-2
pom
import
升级dependency

org.jboss.spec.javax.servlet
jboss-servlet-api_3.1_spec
provided


org.jboss.remoting
jboss-remoting
provided


org.jboss.spec.javax.ejb
jboss-ejb-api_3.2_spec
provided


org.jboss.spec.javax.jms
jboss-jms-api_2.0_spec
provided

...
WEB 设置默认编码

...

    
    

...
配置ajp-listener和instance-id



    
    
    
    ...

...
JSF 1.2

EAP 7不支持JSF 1.2,可从EAP 6将JSF 1.2 Module(包含javax.faces.api,com.sun.jsf-impl,org.jboss.as.jsf-injection)迁移过来,module.xml内容无需更改,建议修改一下module版本urn:jboss:module:1.5
如部署使用的ear包,在jboss-deployment-structure.xml中增加如下配置:

成都创新互联公司服务项目包括香河网站建设、香河网站制作、香河网页制作以及香河网络营销策划等。多年来,我们专注于互联网行业,利用自身积累的技术优势、行业经验、深度合作伙伴关系等,向广大中小型企业、政府机构等提供互联网行业的解决方案,香河网站推广取得了明显的社会效益与经济效益。目前,我们服务的客户以成都为中心已经辐射到香河省份的部分城市,未来相信会继续扩大服务区域并继续获得客户的支持与信任!


    
        
        
        
    
    
        
        
        
    


    
        
        
        
    
    
        
        
        
    


    
        
        
        
    
    
        
        
        
    

Richfaces 3.3

因EAP 7的servlet版本是3.1,fileUpload组件不能使用,需要使用getParts方法重写MultipartRequest实现。

package org.ajax4jsf.request;

import org.ajax4jsf.exception.FileUploadException;
import org.ajax4jsf.webapp.BaseXMLFilter;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.richfaces.component.FileUploadConstants;
import org.richfaces.model.UploadItem;

import javax.faces.context.ExternalContext;
import javax.faces.context.FacesContext;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import javax.servlet.http.Part;
import java.io.*;
import java.rmi.server.UID;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * Request wrapper for supporting multipart requests, used for file uploading.
 *
 * @author Shane Bryzak
 */
public class MultipartRequest extends HttpServletRequestWrapper {
    private static final Log logger = LogFactory.getLog(MultipartRequest.class);
    private static final int BUFFER_SIZE = 2048;

    private boolean createTempFiles;

    private Part filePart;
    private ByteArrayOutputStream bOut = null;
    private FileOutputStream fOut = null;
    private File tempFile = null;

    private String uid;

    private Integer contentLength = 0;

    private int bytesRead = 0;

    private int read = 0;

    private byte[] buffer;

    private InputStream input;

    //we shouldn\'t allow to stop until request reaches PhaseListener because of portlets
    private boolean canStop = false;

    private Map percentMap = null;

    private Map requestSizeMap = null;

    private Map requestKeysMap = null;

    private String requestKey = null;

    private MultipartRequestRegistry requestRegistry;

    boolean initialized = false;

    private boolean shouldStop = false;
    private boolean canceled;

    public MultipartRequest(HttpServletRequest request, boolean createTempFiles, int maxRequestSize, String uid) {
        super(request);
        this.createTempFiles = createTempFiles;
        this.uid = uid;
        this.contentLength = Integer.parseInt(request.getHeader(Content-Length));
    }

    public void cancel() {
        this.canceled = true;

        deleteFile();
    }

    private void deleteFile() {
        try {
            if (fOut != null) {
                fOut.close();
                if (tempFile != null) {
                    tempFile.delete();
                }
            }
        } catch (Exception e) {
            throw new FileUploadException(Could not delete temporary file);
        }
    }

    private void fillBuffer() throws IOException {
        read = input.read(buffer);

        if (read > 0) {
            bytesRead += read;
        }

        fillProgressInfo();
    }

    private void readData() throws IOException {
        while (read > 0) {
            appendData(buffer, 0, read);
            fillBuffer();
        }
    }

    private void initialize() throws IOException {
        if (initialized) {
            return;
        }

        initialized = true;
        buffer = new byte[BUFFER_SIZE];
        getFilePart();
        input = getFileInputStream();

        setupProgressData();
        fillBuffer();
    }

    private void getFilePart() {
        try {
            filePart = null;
            Collection parts = getParts();
            for (Part part : parts) {
                if (part.getName().endsWith(:file)) {
                    filePart = part;
                    if (createTempFiles) {
                        createTempFile();
                    }
                    break;
                }
            }
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
        }
    }

    public void createTempFile() {
        try {
            tempFile = File.createTempFile(new UID().toString().replace(:, -), .upload);
            fOut = new FileOutputStream(tempFile);
        } catch (IOException ex) {
            throw new FileUploadException(Could not create temporary file);
        }
    }

    private void appendData(byte[] data, int start, int length) throws IOException {
        if (fOut != null) {
            fOut.write(data, start, length);
            fOut.flush();
        } else {
            if (bOut == null) {
                bOut = new ByteArrayOutputStream();
            }
            bOut.write(data, start, length);
        }
    }

    public void parseRequest() {
        canStop = true;

        setupProgressData();

        try {
            initialize();

            readData();
        } catch (IOException e) {
            this.cancel();

            if (!this.shouldStop) {
                throw new FileUploadException(IO Error parsing multipart request, e);
            }
        }
    }

    public static MultipartRequest lookupRequest(FacesContext context, String uploadId) {
        Map sessionMap = context.getExternalContext().getSessionMap();
        Map requestKeys = (Map) sessionMap.get(FileUploadConstants.REQUEST_KEYS_BEAN_NAME);
        if (requestKeys != null) {
            String requestKey = requestKeys.get(uploadId);
            if (requestKey != null) {
                MultipartRequestRegistry requestRegistry = MultipartRequestRegistry.getInstance(context);
                if (requestRegistry != null) {
                    MultipartRequest request = requestRegistry.getRequest(requestKey);
                    if (request != null) {
                        return request;
                    }
                }
            }
        }

        return null;
    }

    @SuppressWarnings(unchecked)
    private void setupProgressData() {
        if (percentMap == null || requestSizeMap == null || requestKeysMap == null) {
            FacesContext facesContext = FacesContext.getCurrentInstance();
            if (facesContext != null) {
                ExternalContext externalContext = facesContext.getExternalContext();
                if (externalContext != null) {
                    Map sessionMap = externalContext.getSessionMap();
                    if (sessionMap != null) {
                        String uploadId = getUploadId();

                        synchronized (sessionMap) {
                            if (percentMap == null) {
 percentMap = (Map) sessionMap.get(FileUploadConstants.PERCENT_BEAN_NAME);
 if (percentMap == null) {
     percentMap = new ConcurrentHashMap();
     sessionMap.put(FileUploadConstants.PERCENT_BEAN_NAME, percentMap);
 }
                            }

                            if (requestSizeMap == null) {
 requestSizeMap = (Map) sessionMap.get(FileUploadConstants.REQUEST_SIZE_BEAN_NAME);
 if (requestSizeMap == null) {
     requestSizeMap = new ConcurrentHashMap();
     sessionMap.put(FileUploadConstants.REQUEST_SIZE_BEAN_NAME, requestSizeMap);
 }
                            }

                            if (requestKeysMap == null) {
 requestKeysMap = (Map) sessionMap.get(FileUploadConstants.REQUEST_KEYS_BEAN_NAME);
 if (requestKeysMap == null) {
     requestKeysMap = new ConcurrentHashMap();
     sessionMap.put(FileUploadConstants.REQUEST_KEYS_BEAN_NAME, requestKeysMap);
 }
                            }
                        }

                        percentMap.put(uploadId, Double.valueOf(0));
                        requestSizeMap.put(uploadId, getSize());

                        requestRegistry = MultipartRequestRegistry.getInstance(facesContext);
                        requestKey = requestRegistry.registerRequest(this);
                        requestKeysMap.put(uploadId, requestKey);
                    }
                }
            }
        }
    }

    private void fillProgressInfo() {
        setupProgressData();

        if (percentMap != null) {
            Double percent = (100.0 * this.bytesRead / this.contentLength);
            percentMap.put(uid, percent);
        }
    }

    public Integer getSize() {
        return contentLength;
    }

    public byte[] getFileBytes(String name) {
        if (filePart == null) {
            return null;
        }

        if (fOut != null) {
            try {
                fOut.close();
            } catch (IOException ex) {
            }
            fOut = null;
        }

        if (bOut != null) {
            return bOut.toByteArray();
        }

        if (tempFile != null && tempFile.exists()) {
            try {
                FileInputStream inputStream = new FileInputStream(tempFile);
                ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
                byte[] buf = new byte[BUFFER_SIZE];
                int read = inputStream.read(buf);
                while (read != -1) {
                    outputStream.write(buf, 0, read);
                    read = inputStream.read(buf);
                }
                outputStream.flush();
                inputStream.close();
                tempFile.delete();
                return outputStream.toByteArray();
            } catch (IOException ex) {
            }
        }
        return null;
    }

    public InputStream getFileInputStream() throws IOException {
        return filePart == null ? null : filePart.getInputStream();
    }

    public String getFileContentType() {
        return filePart != null ? filePart.getContentType() : null;
    }

    public Object getFile() {
        if (filePart == null) {
            return null;
        }

        if (tempFile != null) {
            if (fOut != null) {
                try {
                    fOut.close();
                } catch (IOException ex) {
                }
                fOut = null;
            }
            return tempFile;
        }
        if (bOut != null) {
            return bOut.toByteArray();
        }

        return null;
    }

    public String getFileName() {
        return filePart != null ? filePart.getSubmittedFileName() : null;
    }

    public int getFileSize() {
        return filePart != null ? (int) filePart.getSize() : -1;
    }

    public List getUploadItems() {
        List uploadItems = new ArrayList<>();
        if (filePart != null) {
            uploadItems.add(new UploadItem(getFileName(), getFileSize(), getFileContentType(), getFile()));
        }
        return uploadItems;
    }

    public boolean isFormUpload() {
        return _richfaces_form_upload.equals(uid);
    }

    @Override
    public String getHeader(String name) {
        if (!Accept.equals(name)) {
            return super.getHeader(name);
        } else {
            return BaseXMLFilter.TEXT_HTML;
        }
    }

    public void stop() {
        if (canStop) {
            shouldStop = true;
        }
    }

    public boolean isStopped() {
        return this.shouldStop;
    }

    public boolean isDone() {
        return !(this.shouldStop && (this.canceled || this.contentLength != null && this.contentLength.intValue() != this.bytesRead));
    }

    @Override
    public String getContentType() {
        return application/x-www-form-urlencoded;
    }

    protected String getUploadId() {
        return uid;
    }

    public void clearRequestData() {
        String uploadId = getUploadId();

        if (percentMap != null) {
            percentMap.remove(uploadId);
        }

        if (requestSizeMap != null) {
            requestSizeMap.remove(uploadId);
        }

        if (requestKeysMap != null) {
            requestKeysMap.remove(uploadId);
        }

        if (requestRegistry != null) {
            requestRegistry.removeRequest(requestKey);
        }
    }
}

另外,Richfaces 3.3.4.Final fileupload组件页面显示有中文乱码问题,需要修改FileUploadRendererBase的initLabels方法,删除value = dumpingWriter.toString();这一行。

Hibernate 3.5

强烈建议升级到Hibernate 5,如确实不能升级,需创建一个3.5 module,放入依赖包,module配置如下:




    



    
    
    
    
    
    



    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
          

jboss-deployment-structure.xml中排除org.hibernate,引入3.5


    
        
    
    
        
        
        
    


    
        
    
    
        
        
    

修改persistence.xml



    org.hibernate.ejb.HibernatePersistence
    java:jboss/datasources/scheduleDatasource
    ...
    
        
        
        ...
    

HornetQ

EAP 7 使用了ActiveMQ Artemis取代了HornetQ,原Message-Driven Bean不需更改,需更改配置和客户端调用代码。

jms-destinations
EAP 6中jms-destinations配置如下:

...

 
    
     
  

...

更改为:



 ...
 
 ...

security
如不启用security,增加如下配置:


 
 ...

Dependency

org.apache.activemq
artemis-jms-client
provided


org.jboss.spec.javax.jms
jboss-jms-api_2.0_spec
provided


org.jboss.spec.javax.json
jboss-json-api_1.0_spec
provided
org.apache.activemq.artemis module取代org.hornetq 客户端代码
EAP 7,默认connector从remote改为http-remoting,使用undertow default http-listener、http端口,这也是推荐的方式:


...


...


...

   
   
   ...

...

客户端代码要做以下修改:remote connection port从4447改为8080,PROVIDER_URL从remote://localhost:4447改为http-remoting://localhost:8080。INITIAL_CONTEXT_FACTORY从org.jboss.naming.remote.client.InitialContextFactory改为org.wildfly.naming.client.WildFlyInitialContextFactory。
EAP 6:

java.naming.factory.initial=org.jboss.naming.remote.client.InitialContextFactory
java.naming.provider.url=remote://localhost:4447

EAP 7:

java.naming.factory.initial=org.wildfly.naming.client.WildFlyInitialContextFactory
java.naming.provider.url=http-remoting://localhost:8080
EJB Connector
EAP 7,默认connector从remote改为http-remoting,使用undertow default http-listener、http端口。
EAP 6:


EAP 7:




Dependency

org.jboss
jboss-ejb-client
provided


org.jboss.remoting
jboss-remoting
provided


org.wildfly
wildfly-naming-client
provided


org.jboss.spec.javax.ejb
jboss-ejb-api_3.2_spec
provided


org.jboss.spec.javax.transaction
jboss-transaction-api_1.2_spec
provided


org.jboss.marshalling
jboss-marshalling-river
provided


org.jboss.xnio
xnio-api
provided


org.jboss.xnio
xnio-nio
provided
jboss-ejb-client.properties
EAP 6:
remote.connectionprovider.create.options.org.xnio.Options.SSL_ENABLED=false
remote.connections=default
remote.connection.default.protocol=remote
remote.connection.default.host=localhost
remote.connection.default.port=4447
remote.connection.default.connect.options.org.xnio.Options.SASL_POLICY_NOANONYMOUS=false
remote.connection.default.username=quickuser
remote.connection.default.password=quick-123

EAP 7:

remote.connectionprovider.create.options.org.xnio.Options.SSL_ENABLED=false
remote.connections=default
remote.connection.default.protocol=http-remoting
remote.connection.default.host=localhost
remote.connection.default.port=8080
remote.connection.default.connect.options.org.xnio.Options.SASL_POLICY_NOANONYMOUS=false
remote.connection.default.username=quickuser
remote.connection.default.password=quick-123
客户端代码
EAP 6:
java.naming.factory.initial=org.jboss.naming.remote.client.InitialContextFactory
java.naming.provider.url=remote://localhost:4447

EAP 7:

java.naming.factory.initial=org.wildfly.naming.client.WildFlyInitialContextFactory
java.naming.provider.url=http-remoting://localhost:8080
Standalone Client
EAP 7.1引入新的配置文件wildfly-config.xml,统一了所有客户端的配置,在standalone client中推荐使用这种方式。wildfly-config.xml放在classpath或META-INF目录下,也可用-Dwildfly.config.url指定路径(优先级:wildfly.config.url > classpath > META-INF)。
wildfly-config.xml:



    
        
    
    
        
            
            
            
                
            
            
                
            
            
        
    

使用wildfly-config.xml时的Java代码:

Properties properties = new Properties();
properties.put(Context.INITIAL_CONTEXT_FACTORY, WildFlyInitialContextFactory.class.getName());
properties.put(Context.PROVIDER_URL, http-remoting://localhost:8080);
Context context = new InitialContext(properties);
Object theRemote = context.lookup(jndiName);
...

代码很简单,多个PROVIDER_URL时用逗号分隔。注意运行之前要添加ApplicationRealm用户:

add-user.sh -a -u quickuser -p quick-123
Server-to-Server
利用remote-outbound-connection,在standalone.xml中增加如下配置:
增加security-realm,密码需经Base64编码


    
        
            
        
    
    ...

...

配置remote-outbound-connection





    
        
            
            
        
    

配置Socket


...

    

在war的WEB-INF或ear的META-INF中新建文件jboss-ejb-client.xml:

  
      
  

Java代码

Properties props = new Properties();  
props.put(Context.URL_PKG_PREFIXES, org.jboss.ejb.client.naming);  
Context context = new javax.naming.InitialContext(props);  
Object theRemote = context.lookup(jndiName);
Seam 2.2.2.Final

seam 2.2可以运行在Jboss EAP 7,同在EAP 6中一样,需修改org.jboss.seam.transaction.Transaction:

protected javax.transaction.UserTransaction getUserTransaction() throws NamingException
{
  InitialContext context = Naming.getInitialContext();
  try
  {
     return (javax.transaction.UserTransaction) context.lookup(java:comp/UserTransaction);
  }
  catch (NamingException ne)
  {
     try
     {
        //Embedded JBoss has no java:comp/UserTransaction
        javax.transaction.UserTransaction ut = (javax.transaction.UserTransaction) context.lookup(UserTransaction);
        ut.getStatus(); //for glassfish, which can return an unusable UT
        return ut;
     }
     catch (NamingException nnfe2) {
         // Try the other JBoss location in JBoss AS7
         return (javax.transaction.UserTransaction) context.lookup(java:jboss/UserTransaction);
     }
     catch (Exception e)
     {
        throw ne;
     }
  }
}

如使用了seam-resteasy,需排除jaxrs子系统,使用EAP 6中的resteasy版本即可。



    
        
    
    ...

PicketLink 配置Subsystem

EAP 7默认是不支持picketlink的,需要配置picketlink subsystem。
增加extension


...

...

配置subsystem


...

...
配置security-domain

将EAP 6中相应配置迁移过来即可。



    




    
        
        
    

配置jboss-deployment-structure


    
        ...
        
    

注意:必须要添加services="import"。

配置Federation

EAP 7,valve不再使用:



sp

    org.picketlink.identity.federation.bindings.tomcat.sp.ServiceProviderAuthenticator
    
        characterEncoding
        UTF-8
    


idp
idp-sig

    org.picketlink.identity.federation.bindings.tomcat.idp.IDPWebBrowserSSOValve

删除valve,参数需迁移到web.xml中:


org.picketlink.federation.saml.CHARACTER_ENCODING
UTF-8

web.xml中必须配置login-config


...

FORM

注意:idp、sp都要配置auth-method
picketlink.xml sample:



    http://localhost:8080/idp-sig/
    https://localhost:8443/sso/
    
        
        
        
        
        
    


    
    
        
    
    
    

注意:

如果升级到EAP 7.1.2后使用picketlink可能会报如下错误:
Error during the logout.: java.lang.NullPointerException
at org.picketlink.identity.federation.bindings.wildfly.sp.SPFormAuthenticationMechanism.lambda$authenticate$0(SPFormAuthenticationMechanism.java:275)
建议7.1.3发布后再升级。 Undertow Servlet Container有一属性proactive-authentication,默认为true,会拦截所有含有SAMLResponse参数的请求。当项目中使用了其他custom portal时,将其设为"false";



Patching EAP

使用CLI应用、回滚、清除Patch

Applying a Patch
patch apply /path/to/downloaded-patch.zip --override-all
shutdown --restart=true
Rolling Backe a Patch

先使用patch history查询出patch id,然后调用rollback命令:

patch history
patch rollback --patch-id=PATCH_ID --reset-configuration=TRUE
shutdown --restart=true
Clearing Patch History

多次打Patch后会占用磁盘空间,可进行清理,但当前应用的Patch是不能删除的。

/core-service=patching:ageout-history
参考文档

Jboss EAP 7.1 Migration Guide
Using the JBoss Server Migration Tool
Configuration Guide
Configuring Messaging
Developing EJB Applications
How to Configure Identity Management
How to Configure Server Security
How To Set Up SSO with SAML v2
Patching and Upgrading Guide


分享标题:从JbossEAP6.4迁移到EAP7.1
分享链接:http://chengdu.cdxwcx.cn/article/cjeoje.html