วันเสาร์ที่ 16 กรกฎาคม พ.ศ. 2559

การใช้ Spring Boot บน Websphere 8, 8.5

เพราะว่าเป็น Enterprise เลยต้องมีเวลา Customize เพิ่มครับ

1. ต้อง Downgrade ให้ไปใช้ JPA2.0 แทนเพราะ Spring Boot ใช้ JPA2.1 (JPA จะโหลดจาก Application Server ไม่สามารถ Config ให้โหลดจาก Web  Project ได้ครับ) ทีนี่

2. Spring Boot จะ config แบบ no web.xml โดยการ extend SpringInitializer ถ้า Websphere ไม่สามารถโหลดได้ต้องเปลี่ยน Config ให้ใช้ web.xml ครับ แล้วอะไรที่ Config บน web.xml ต้องย้ายมาหมดพวก filter, ดัก error-page ที่นี่

3. สำหรับคนที่จะ Config Maven ให้ RAD ใช้งานได้ ดู ที่นี่

การ Config SpringBoot ให้ใช้งานแบบมี web.xml

การ Config แบบนี้จะต้องย้ายพวก filter ออกมาจาก annotation แล้วมา config บน web.xml ให้หมดด้วยครับ ไม่งั้นจะใช้งานไม่ได้ ใน web.xml ผมมีตัวอย่างของการ Config CXF ด้วย ว่าต้องย้ายมาไว้บน web.xml ด้วยไม่งั้นใช้งานไม่ได้
<context-param>
 <param-name>contextConfigLocation</param-name>
 <param-value>xxx.Application</param-value>
</context-param>

<listener>
 <listener-class>org.springframework.boot.legacy.context.web.SpringBootContextLoaderListener</listener-class>
</listener>

<servlet>
 <servlet-name>spring</servlet-name>
 <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
 <init-param>
  <param-name>contextAttribute</param-name>
  <param-value>org.springframework.web.context.WebApplicationContext.ROOT
  </param-value>
 </init-param>
 <load-on-startup>1</load-on-startup>
</servlet>

<!-- Servlet Mapping for CXFServlet -->
<servlet>
 <servlet-name>CXFServlet</servlet-name>
 <servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servlet-class>
</servlet>

<servlet-mapping>
 <servlet-name>CXFServlet</servlet-name>
 <url-pattern>/soap-api/*</url-pattern>
</servlet-mapping>

<servlet-mapping>
 <servlet-name>spring</servlet-name>
 <url-pattern>/*</url-pattern>
</servlet-mapping>
- จะเห็นว่าใช้ org.springframework.boot.legacy.context.web.SpringBootContextLoaderListener ตัวนี้แทนของเดิม
- contextConfigLocation เพื่อไปอ่าน Class ที่ Config ของ  SpringBoot เหมือนกับที่ต้อง config บน start-class ที่ใช้บน maven เพื่อให้มันทำานได้

วิธี Downgrade JPA จาก 2.1 เป็น 2.0 ของ SpringBoot

1. เริ่มจากเอา Config  JPA ออกจาก SpringBoot ก่อนครับ โดยใช้ exclusion org.hibernate
<dependency>
 <groupId>org.springframework.boot</groupId>
 <artifactId>spring-boot-starter-data-jpa</artifactId>
 <exclusions>
  <exclusion>  
   <groupId>org.hibernate</groupId>
  </exclusion>
 </exclusions>
</dependency>
2.ต่อไปก็เพิ่ม JPA 2.0 เข้าไป ถ้าใช้บน Websphere อาจจะต้องเอา javax.persistence ออกด้วยครับ ถ้ายังมี error อยู่
<dependency>
 <groupId>org.hibernate</groupId>
 <artifactId>hibernate-core</artifactId>
 <version>${hibernate.version}</version>
 <scope>compile</scope>
 <exclusions>
  <exclusion>
   <groupId>org.hibernate.javax.persistence</groupId>
   <artifactId>hibernate-jpa-2.0-api</artifactId>
  </exclusion>
 </exclusions>
</dependency>
<dependency>
 <groupId>org.hibernate</groupId>
 <artifactId>hibernate-entitymanager</artifactId>
 <version>${hibernate.version}</version>
 <scope>compile</scope>
 <exclusions>
  <exclusion>
   <groupId>org.hibernate.javax.persistence</groupId>
   <artifactId>hibernate-jpa-2.0-api</artifactId>
  </exclusion>
 </exclusions>
</dependency>
3. ต่อไปต้องเพิ่ม Code การโหลด entityManagerFacorry มาใหม่
 @Bean(name = "entityManagerFactory")
    public LocalContainerEntityManagerFactoryBean getEntityManagerFactory() {
     
     LocalContainerEntityManagerFactoryBean entityManagerFactory = new LocalContainerEntityManagerFactoryBean();
     entityManagerFactory.setDataSource(dataSource);
     entityManagerFactory.setPackagesToScan("xxx.entities");
     entityManagerFactory.setJpaVendorAdapter(getJPAVendor());
     entityManagerFactory.setJpaProperties(getHibernateProperties());
     
     return entityManagerFactory;
    }
    
    
    
    @Bean
    public LocalSessionFactoryBean sessionFactory() throws IOException {
     logger.debug("sessionFactory()");
     
        LocalSessionFactoryBean factoryBean = new LocalSessionFactoryBean();
        factoryBean.setHibernateProperties(getHibernateProperties());
        factoryBean.setDataSource(dataSource);
        factoryBean.setPackagesToScan("xxx.entities");
        
        return factoryBean;
    }
    

    
    @Bean
    public PersistenceExceptionTranslationPostProcessor exceptionTranslation() {
        return new PersistenceExceptionTranslationPostProcessor();
    }
    
    
    private JpaVendorAdapter getJPAVendor() {
     
     HibernateJpaVendorAdapter hibernateJpaVendorAdaptor = new HibernateJpaVendorAdapter();
     hibernateJpaVendorAdaptor.setShowSql(true);
     
     return hibernateJpaVendorAdaptor;
    }
    
    
    private Properties getHibernateProperties() {
        Properties properties = new Properties();
        
            // This is to get around a Websphere Bug
        properties.put("hibernate.dialect", Oracle10gDialect.class.getName());
        properties.put("hibernate.show_sql", "true");
        
        logger.debug("properties : {}", properties);
        return properties;
    }