用 Hibernet Tool 自動產生的 Domain Code,對於 FOREIGN KEY 會以 annotation:  @ManyToMany(fetch = FetchType.LAZY) 來作註,但執行時會發生下列的錯誤

Struts Problem Report

Struts has detected an unhandled exception:

Messages:
  • failed to lazily initialize a collection of role: com.mis.model.Admin.roles, could not initialize proxy - no Session
File: org/hibernate/collection/internal/AbstractPersistentCollection.java
 

Stacktraces

org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: com.mis.model.Admin.roles, could not initialize proxy - no Session

 

解決方法: 由 FetchType.LAZY 改成 FetchType.EAGER

    //@ManyToMany(fetch = FetchType.LAZY)
    @ManyToMany(fetch = FetchType.EAGER)
    @JoinTable(name = "admin_roles", catalog = "weixin", joinColumns = {
            @JoinColumn(name = "aid", nullable = false, updatable = false) }, inverseJoinColumns = {
                    @JoinColumn(name = "rid", nullable = false, updatable = false) })
    public Set<Role> getRoles() {
        return this.roles;
    }

 

或者是在 applicationContext.xml 加入 <prop key="hibernate.enable_lazy_load_no_trans">true</prop> 如下

    <!-- Configure the entity manager factory bean : Step02-Start-->    
    <bean id="emfLocalDS"    class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">        
        <property name="dataSource" ref="LocalDS"></property>         
        <property name="persistenceUnitName" value="emfLocalPU"/>
        <!-- Set base package of your entities -->
        <property name="packagesToScan" value="com.mis.model"/>
        <!-- Set share cache mode -->
        <property name="sharedCacheMode" value="ENABLE_SELECTIVE"/>
        <!-- Set validation mode -->
        <property name="validationMode" value="NONE"/>         
        <property name="jpaVendorAdapter">
            <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
                <property name="database" value="MYSQL" />
                <property name="showSql" value="true" />
            </bean>
        </property>

        <!-- Set JPA properties -->
        <property name="jpaProperties">
            <props>
                 <prop key="hibernate.dialect">org.hibernate.dialect.MySQL5InnoDBDialect</prop>
                 <prop key="hibernate.enable_lazy_load_no_trans">true</prop>
            </props>
        </property>       
    </bean>
    <!-- Configure the entity manager factory bean : Step02-End-->

參考:

http://stackoverflow.com/questions/11746499/solve-failed-to-lazily-initialize-a-collection-of-role-exception

http://www.lostinsoftware.com/2015/08/reverse-engineering-and-code-generation/

文章標籤

MIS 發表在 痞客邦 留言(0) 人氣()

作法如下:

http://stackoverflow.com/questions/26616723/java-lang-nosuchmethoderror-javax-persistence-table-indexesljavax-persistenc

If you are using Jboss 7.1.1, jboss already has hibernate-jpa-2.0 in its classpath, so during runtime it uses the one in its classpath, not the one you've deployed with your app , to point jboss to the hibernate-jpa-2.1 do the following:

  1. copy hibernate-jpa-2.1-api-1.0.0.final.jar to the following directory : jboss-as-7.1.1.Final/modules/javax/persistence/api/main

  2. open module.xml and change the resource-root as follows : resource-root path="hibernate-jpa-2.1-api-1.0.0.final.jar" (pointing it to jpa 2.1)

  3. re-compile and re-deploy your app, then you are good to go.

module.xml 檔案內容, 置換成 hibernate-jpa-2.1-api-1.0.0.Final.jar :

<?xml version="1.0" encoding="UTF-8"?>

<!--
  ~ JBoss, Home of Professional Open Source.
  ~ Copyright 2010, Red Hat, Inc., and individual contributors
  ~ as indicated by the @author tags. See the copyright.txt file in the
  ~ distribution for a full listing of individual contributors.
  ~
  ~ This is free software; you can redistribute it and/or modify it
  ~ under the terms of the GNU Lesser General Public License as
  ~ published by the Free Software Foundation; either version 2.1 of
  ~ the License, or (at your option) any later version.
  ~
  ~ This software is distributed in the hope that it will be useful,
  ~ but WITHOUT ANY WARRANTY; without even the implied warranty of
  ~ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  ~ Lesser General Public License for more details.
  ~
  ~ You should have received a copy of the GNU Lesser General Public
  ~ License along with this software; if not, write to the Free
  ~ Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
  ~ 02110-1301 USA, or see the FSF site: http://www.fsf.org.
  -->

<module xmlns="urn:jboss:module:1.1" name="javax.persistence.api">
    <dependencies>
        <!-- PersistenceUnitInfo needs javax.sql.DataSource -->
        <module name="javax.api" export="true"/>
    </dependencies>

    <resources>
        <resource-root path="hibernate-jpa-2.1-api-1.0.0.Final.jar"/>
        <!-- Insert resources here -->
    </resources>
</module>

 

文章標籤

MIS 發表在 痞客邦 留言(0) 人氣()

所需軟體

1. OS: windows 7

2. xampp-portable-win32-5.5.38-3-VC11.zip

3. FreeRADIUS.net-1.1.7-r0.0.2.exe - 6.74 MB - Licence: GNU/LGPL

4. NTRadPing 測試工具

安裝:

Step 1: 主機端(192.168.1.1):安裝 FreeRADIUS.net-1.1.7-r0.0.2.exe 完後,執行 C:\FreeRADIUS.net\bin\radtest.bat,應該本機測試會正常

Step 2: 修改 C:\FreeRADIUS.net\etc\raddb\clients.conf

## 增加 client 電腦端 test
client 192.168.1.4 {
    secret        = testing123
    shortname    = private-network-3
}

Step 3: 修改 C:\FreeRADIUS.net\etc\raddb\users.conf

## 增加一筆測試帳號

polinwei    User-Password == "password"

Step 4: 用 NTRadPing  測試,填入資訊如下。應該可以測試正常

 

整合 MySQL

Step1: 用 XAMPP 建立 MySQL DB: "radius",並匯入 C:\FreeRADIUS.net\share\doc\freeradius\examples\mysql.sql

Step2: 建立測試資料

INSERT INTO `radgroupreply` (`id`, `GroupName`, `Attribute`, `op`, `Value`) VALUES
(1, 'user', 'Auth-Type', ':=', 'Local'),
(2, 'user', 'Service-Type', ':=', 'Framed-User'),
(3, 'user', 'Framed-IP-Address', ':=', '255.255.255.254'),
(4, 'user', 'Framed-IP-Netmask', ':=', '255.255.255.0');


INSERT INTO `radcheck` (`id`, `UserName`, `Attribute`, `op`, `Value`) VALUES
(1, 'sqltest', 'User-Password', ':=', 'testpwd'),
(2, 'polinwei', 'User-Password', ':=', '12345');

Step3: 修改 radius.conf

#第1784行
authorize {
    #
    #  Read the 'users' file
#    files

    #
    #  Look in an SQL database.  The schema of the database
    #  is meant to mirror the "users" file.
    #
    #  See "Authorization Queries" in sql.conf
    sql

#第1989行
accounting {
    #
    #  Log traffic to an SQL database.
    #
    #  See "Accounting queries" in sql.conf
    sql

Step4: 修改 radius.conf,注意:windows 7 因為有 ipv6 ,所以用 127.0.0.1 代替 localhost 。這樣 FreeRADIUS 連結 mysql 才不會有問題。

sql {
    # Database type
    # Current supported are: rlm_sql_mysql, rlm_sql_postgresql,
    # rlm_sql_iodbc, rlm_sql_oracle, rlm_sql_unixodbc, rlm_sql_freetds
    driver = "rlm_sql_mysql"

    # Connect info
    server = "127.0.0.1"
    login = "radius"
    password = "password"

    # Database table configuration
    radius_db = "radius"

這樣就大工告成了。

 

 

 

 

文章標籤

MIS 發表在 痞客邦 留言(1) 人氣()

在目錄 %JBOSS_HOME%\modules\com\microsoft\sqlserver\jdbc\main 下放入 module.xml & sqljdbc42.jar

module.xml 的內容

<?xml version="1.0" encoding="UTF-8"?>
<module xmlns="urn:jboss:module:1.1" name="com.microsoft.sqlserver.jdbc">
 <resources>
  <resource-root path="sqljdbc42.jar"/>
 </resources>
 <dependencies>
  <module name="javax.api"/>
  <module name="javax.xml.bind.api"/>
  <module name="javax.transaction.api"/>
 </dependencies>
</module>

編輯 %JBOSS_HOME%\standalone\configuration\standalone.xml

<datasource jndi-name="java:/mssqlDS" pool-name="LansweeperDS" enabled="true">
    <connection-url>jdbc:sqlserver://mssql_IP\SQLEXPRESS;DatabaseName=mydb</connection-url>
    <driver-class>com.microsoft.sqlserver.jdbc.SQLServerDriver</driver-class>
    <driver>sqlserver</driver>
    <security>
        <user-name>sa</user-name>
        <password>password</password>
    </security>
    <validation>
        <valid-connection-checker class-name="org.jboss.jca.adapters.jdbc.extensions.mssql.MSSQLValidConnectionChecker"/>
    </validation>
</datasource>

<driver name="sqlserver" module="com.microsoft.sqlserver.jdbc">
    <xa-datasource-class>com.microsoft.sqlserver.jdbc.SQLServerXADataSource</xa-datasource-class>
</driver>

這樣就可以了

MIS 發表在 痞客邦 留言(0) 人氣()

Sql Server Express

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC
        "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
        "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
    <session-factory>
        <property name="hibernate.connection.driver_class">com.microsoft.sqlserver.jdbc.SQLServerDriver</property>
        <property name="hibernate.connection.url">jdbc:sqlserver://localhost\SQLEXPRESS;databaseName=master;user=sa;password=password</property>
        <property name="hibernate.dialect">org.hibernate.dialect.SQLServerDialect</property>
    </session-factory>
</hibernate-configuration>

Oracle DB

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC
        "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
        "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
    <session-factory>
        <property name="hibernate.connection.driver_class">oracle.jdbc.driver.OracleDriver</property>
        <property name="hibernate.connection.password">manager</property>
        <property name="hibernate.connection.url">jdbc:oracle:thin:@localhost:1521:xe</property>
        <property name="hibernate.connection.username">system</property>
        <property name="hibernate.default_schema">system</property>
        <property name="hibernate.dialect">org.hibernate.dialect.Oracle10gDialect</property>
    </session-factory>
</hibernate-configuration>
 

MySQL DB

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC
        "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
        "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
    <session-factory>
        <property name="hibernate.connection.driver_class">org.gjt.mm.mysql.Driver</property>
        <property name="hibernate.connection.password">password</property>
        <property name="hibernate.connection.url">jdbc:mysql://localhost/mydb</property>
        <property name="hibernate.connection.username">root</property>
        <property name="hibernate.dialect">org.hibernate.dialect.MySQL5Dialect</property>
    </session-factory>
</hibernate-configuration>
 

 

 

 

 

MIS 發表在 痞客邦 留言(0) 人氣()

Step 01: 準備 table : TEST_GROUP & TEST_MEMBERS

 

table : TEST_GROUP

CREATE TABLE JAPPS.TEST_GROUP
(
  ID    VARCHAR2(10 BYTE),
  NAME  VARCHAR2(10 BYTE)
)

 

table :  JAPPS.TEST_MEMBERS

CREATE TABLE JAPPS.TEST_MEMBERS
(
  GID   VARCHAR2(10 BYTE),
  ID    VARCHAR2(10 BYTE),
  NAME  VARCHAR2(10 BYTE)
)

 

Step 02 : JAVA 程式段的作法

註:

1. EntityManager 的 getTransaction().begin();   不支援 //Not allowed to create transaction on shared EntityManager - use Spring transactions or EJB CMT

2. 使用 JpaTransactionManager 搭配 TransactionStatus 來控制

3. 只要作 JpaTransactionManager 的 commit(status) , 在 catch 中判斷  if (!status.isCompleted()) 作  baseService.getTxmBpm().rollback(status); 

package com.bpm;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.hibernate.Session;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.DefaultTransactionDefinition;

import com.bpm.dao.japps.TestGroupDao;
import com.bpm.dao.japps.TestMembersDao;
import com.bpm.model.japps.TestGroup;
import com.bpm.model.japps.TestMembers;
import com.bpm.model.japps.TestMembersId;
import com.util.services.BaseService;

public class SingleMultiTable {
    private static final long serialVersionUID = 1L;
    private static final Logger logger = LogManager.getLogger(SingleMultiTable.class);
    
    
    public static void main(String[] args) {
        // TODO Auto-generated method stub

        testSingleTable();
        testMultiTable();
    }

    public static void testSingleTable(){
        ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("spring-demo-cfg.xml");
        BaseService baseService = ctx.getBean("baseService",BaseService.class);
        TestGroupDao testGroupDao = ctx.getBean("testGroupDao", TestGroupDao.class);
        
        try {
            TestGroup testGroup = new TestGroup();
            testGroup.setId("A");
            testGroup.setName("Group 2");
            testGroupDao.save(testGroup);
            
            //testGroupDao.delete(testGroup);
        } catch (Exception e) {
            System.out.println("寫入資料庫有錯");
        }
        
    }
    
    public static void testMultiTable(){
        ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("spring-demo-cfg.xml");
        BaseService baseService = ctx.getBean("baseService",BaseService.class);
        TestGroupDao testGroupDao = ctx.getBean("testGroupDao", TestGroupDao.class);
        TestMembersDao testMembersDao  = ctx.getBean("testMembersDao", TestMembersDao.class);
        
        TestGroup testGroup = new TestGroup();
        TestMembers testMembers = new TestMembers();
        TestMembersId testMembersId = new TestMembersId();
        
        DefaultTransactionDefinition def = new DefaultTransactionDefinition();        
        def.setName("rootTransaction");        
        def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);
        TransactionStatus status = baseService.getTxmBpm().getTransaction(def);        
        try {            
            testGroup.setId("3");
            testGroup.setName("C");
            testGroupDao.save(testGroup);
            int a;
            a = 1/0;
            testMembersId.setGid("3");
            testMembersId.setId("1");
            testMembers.setId(testMembersId);
            testMembers.setName("G3U2-2");            
            testMembersDao.save(testMembers);
            baseService.getTxmBpm().commit(status);
            
        } catch (Exception e) {
            //Session session = baseService.getSfBpmDS().getCurrentSession();
            if (!status.isCompleted()){                
                baseService.getTxmBpm().rollback(status);
            }            
            System.out.println("寫入資料庫有錯");                        
        }
        
    }

    
}


文章標籤

MIS 發表在 痞客邦 留言(0) 人氣()

使用 EasyUI 的 Datagrid 選擇到一筆記錄後,將這一筆完整的資料要送到後端 Java 接收,可以先轉換成 JSON 的格式再後送。

UI 的圖示如下,可以用 FireBug 去查看 JavaScript 裡的資料

datagrid

 

作法如下:

HTML 的 Java Script Code:

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ taglib prefix="s" uri="/struts-tags" %>
<%@    taglib prefix="i" uri="/esayui-tags" %>

<i:html title="easyui-datagrid & EasyUI Demo" >

<div class="col-sm-1"></div>
<div class="col-sm-10">
<i:form id="fmEmpIDLogin" action="Login"  method="post" isExtraPara="false">
                
                    <input name="reqCode" value="" type="hidden" />

    <table id="dg" class="easyui-datagrid" title="CheckBox Selection on DataGrid" style="width:100%;height:400px;padding:10px;"
            data-options="url:'Login_multiEmpID?reqCode=EmpIDList',method:'get',rownumbers:true,pagination:true,singleSelect:true,toolbar: '#tb'">
        <thead>
            <tr>
                <th data-options="field:'ck',checkbox:true"></th>
                <th data-options="field:'empId',sortable:true"> <s:property value="getText('display.sc004.empid')"/> </th>
                <th data-options="field:'realName',sortable:true"> <s:property value="getText('display.sc004.alternatename')"/> </th>
                <th data-options="field:'companyName',sortable:true"> <s:property value="getText('display.sc006.name')"/> </th>
                <th data-options="field:'deptName',sortable:true"> <s:property value="getText('display.sc007.name')"/> </th>
                <th data-options="field:'deptsManagerId',hidden:true">MANAGER_ID</th>
                <th data-options="field:'userId',hidden:true">USER_ID</th>
            </tr>
        </thead>
    </table>

    <div id="tb" style="height:auto">
        <a href="javascript:void(0)" class="easyui-linkbutton" data-options="iconCls:'icon-add',plain:true" onclick="submitForm()">Submit</a>
    </div>

</i:form>
</div>
<div class="col-sm-1"></div>
</i:html>

<script type="text/javascript">
    function submitForm(){
        $("#fmEmpIDLogin input[name='reqCode']").val("empIdLogin");
        var rowData = $('#dg').datagrid('getSelected');
        var cellRow = $("<input>").attr("type", "hidden").attr("name", "cellRow").val(JSON.stringify(rowData));
        $('#fmEmpIDLogin').append($(cellRow));
        $('#fmEmpIDLogin').submit();       
    }    
</script>

 

Java Code: 利用 String[] cellRow 接收,並用 Gson().fromJson(cellRow[0], Map.class); 作轉換即可

public class LoginAction extends BaseSupport {
    
    private String[] cellRow;    

    public String empIdLogin() throws Exception {
        String loginResult=SUCCESS;
        Userinfo userInfo = null;
        logger.debug(cellRow[0]);
        Map<String,Object> result = new Gson().fromJson(cellRow[0], Map.class);
        
        String userEmpID = result.get("empId") == null ? "" : result.get("empId").toString();
        
        return loginResult;
    }
        

    public String[] getCellRow() {
        return cellRow;
    }

    public void setCellRow(String[] cellRow) {
        this.cellRow = cellRow;
    }

}
文章標籤

MIS 發表在 痞客邦 留言(0) 人氣()

Struts2 的 logger 是與 log4j2 作整合,同樣是 Apache Project 專案之一。為了瞭解一下與架構 Java 專案時的偵錯機制,所以花了半天的時間來實作。

Maven 對 log4j2 相依性

    <properties>
        <struts2.version>2.3.24.1</struts2.version>
        <log4j2.version>2.2</log4j2.version>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>

        <dependency>
            <groupId>org.apache.logging.log4j</groupId>
            <artifactId>log4j-api</artifactId>
            <version>${log4j2.version}</version>
        </dependency>
        <dependency>
            <groupId>org.apache.logging.log4j</groupId>
            <artifactId>log4j-core</artifactId>
            <version>${log4j2.version}</version>
        </dependency>

 

 log4j2.xml (在 src/main/resources 目錄下)

<?xml version="1.0" encoding="UTF-8"?>

<!-- 優先等級: FATAL > ERROR > WARN >INFO > DEBUG -->
<Configuration>
    <properties>  
        <property name="LOG_HOME">/log/mis</property>
        <property name="FILE_NAME">mis</property>    
    </properties>  
    <Appenders>
        <Console name="STDOUT" target="SYSTEM_OUT">
            <PatternLayout pattern="%d %-5p [%t] %C{2} (%F:%L) - %m%n"/>
        </Console>
        <File name="FILE" fileName="${LOG_HOME}/logfile_fileMode.log" append="true">
            <PatternLayout pattern="%d %-5p [%t] %C{2} (%F:%L) - %m%n"/>
        </File>
        <RollingRandomAccessFile name="MIS_PROJECT"
            fileName="${LOG_HOME}/${FILE_NAME}.log"
            filePattern="${LOG_HOME}/$${date:yyyy-MM}/${FILE_NAME}-%d{yyyy-MM-dd}-%i.log.gz">
            
            <PatternLayout pattern="%d %-5p [%t] %C{2} (%F:%L) - %m%n" />
            <Policies>
                <TimeBasedTriggeringPolicy />
                <SizeBasedTriggeringPolicy size="10 MB" />
            </Policies>
            <DefaultRolloverStrategy max="20" />
        </RollingRandomAccessFile>
        
    </Appenders>
    <Loggers>
        <Logger name="com.opensymphony.xwork2" level="info"/>
        <Logger name="org.apache.struts2" level="info"/>
        
        <Logger name="com.mis.demo" level="DEBUG" additivity="true">
            <AppenderRef ref="STDOUT"/>
        </Logger>

        <Root level="info">
            <AppenderRef ref="STDOUT"/>                  
        </Root>      
        <Root level="WARN">
            <AppenderRef ref="MIS_PROJECT" />
        </Root>        
    </Loggers>
</Configuration>

參數說明

1. monitorInterval="1800" 指 log4j2 每隔1800秒(半小時),自動監控該設定檔是否有變化,如果變化,則自動根據檔內容重新配置(很不錯的功能!)

2. RollingRandomAccessFile  即表示以檔方式記錄,注意一下 filePattern 的設置,它與 SizeBasedTriggeringPolicy (表示單個檔最大多少容量)結合在一起,非常有用,以這段配置為例,當單個文件達到10M後,會自動將以前的內容,先創建類似 2014-09(年-月)的目錄,然後按 "xxx-年-月-日-序號"命名,打成壓縮包(很體貼的設計,即省了空間,又不丟失以前的日誌資訊)

3. DefaultRolloverStrategy max="20"表示壓縮包,最多保留20個

4. 定義了一個 <Logger name="com.mis.demo" level="DEBUG" additivity="true"> ,使用 Console 方式來觀察日誌,additivity="true" 這裡注意一下,因為下面還有一個root logger,任何其它的logger最終都相當於繼承自root logger。

所以<Root level="WARN"> 這個 root logger中,記錄了 WARN 以上級別的日誌,會寫入日誌 mis.log 檔案內;當 <Logger name="com.mis.demo" level="DEBUG" additivity="true"> 有 DEBUG 以上級別的日誌時,也會寫入檔案日誌 mis.log 檔案內。。如果把additivity="true" 中的true,改成false,root logger就不會再起作用,即只會控制台輸出,日誌不會記錄在檔案中。

 

程式 Log4j2Example.java

package com.mis.demo;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
public class Log4j2Example {

    private static final Logger LOG = LogManager.getLogger(Log4j2Example.class.getName());
    public static void main(String[] args) {
        LOG.debug("This will be printed on debug");        
        LOG.info("This will be printed on info");
        LOG.warn("This will be printed on warn");
        LOG.error("This will be printed on error");
        LOG.fatal("This will be printed on fatal");

        LOG.info("Appending string: {}.", "Hello, World");

    }

}

 

 輸出的格式內容

2016-03-11 10:43:52,260 DEBUG [main] demo.Log4j2Example (Log4j2Example.java:9) - This will be printed on debug
2016-03-11 10:43:52,261 INFO  [main] demo.Log4j2Example (Log4j2Example.java:10) - This will be printed on info
2016-03-11 10:43:52,262 WARN  [main] demo.Log4j2Example (Log4j2Example.java:11) - This will be printed on warn
2016-03-11 10:43:52,262 ERROR [main] demo.Log4j2Example (Log4j2Example.java:12) - This will be printed on error
2016-03-11 10:43:52,262 FATAL [main] demo.Log4j2Example (Log4j2Example.java:13) - This will be printed on fatal
2016-03-11 10:43:52,263 INFO  [main] demo.Log4j2Example (Log4j2Example.java:15) - Appending string: Hello, World.

 

 參考:

http://www.cnblogs.com/yjmyzz/p/3988114.html

http://blog.csdn.net/jiangguilong2000/article/details/11397557

http://memorynotfound.com/log4j2-with-log4j2-xml-configuration-example/

https://logging.apache.org/log4j/2.x/manual/configuration.html

文章標籤

MIS 發表在 痞客邦 留言(0) 人氣()

當 struts2 加入 struts2-spring-plugin 的 JAR 檔後,執行 JUnit 或 Maven build 時發生 

SEVERE:   [50:59.081] ********** FATAL ERROR STARTING UP STRUTS-SPRING INTEGRATION **********
Looks like the Spring listener was not configured for your web app!
Nothing will work until WebApplicationContextUtils returns a valid ApplicationContext.
You might need to add the following to web.xml:
    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>
SEVERE:   [50:59.089] Dispatcher initialization failed

 

這時候 JUnit 程式的 extends 要由 StrutsTestCase 變為 StrutsSpringTestCase ,這樣才不會出錯。程式碼如下

package com.mis.example;

import com.opensymphony.xwork2.ActionSupport;

import org.apache.struts2.StrutsSpringTestCase;
import org.apache.struts2.StrutsTestCase;

//public class HelloWorldTest extends StrutsTestCase{
public class HelloWorldTest extends StrutsSpringTestCase {

    public void testHelloWorld() throws Exception {
        HelloWorld hello_world = new HelloWorld();
        String result = hello_world.execute();
        assertTrue("Expected a success result!",
                ActionSupport.SUCCESS.equals(result));
        assertTrue("Expected the default message!",
                hello_world.getText(HelloWorld.MESSAGE).equals(hello_world.getMessage()));
    }
}

 

參考:

http://blog.csdn.net/zj133520/article/details/12620763

http://kang36897.blog.163.com/blog/static/170473732010710101238126/

http://openhome.cc/Gossip/JUnit/

http://linuschien.blogspot.tw/2013/01/unit-test-to-struts2-action-with-spring.html

 

文章標籤

MIS 發表在 痞客邦 留言(0) 人氣()

上次介紹 Spring Quartz Job Schedule Simple Example 工作排程器 ,現在再來使用 Spring 原生的 Task Execution and Scheduling,首先來瞭解一下 @Scheduled annotation 的意思

This annotation is used for task scheduling. The trigger information needs to be provided along with this annotation. You can use the properties fixedDelay/fixedRate/cron to provide the triggering information.

1. fixedRate: makes Spring run the task on periodic intervals even if the last invocation may be still running. 固定時間執行,不管上一次是否結束
2. fixedDelay: specifically controls the next execution time when the last execution finishes. 上一次執行結束後,再依設定的固定時間執行
3. cron: is a feature originating from Unix cron utility and has various options based on your requirements. BJ4(就不解釋了)

 

方法 1) Task scheduling using fixed delay attribute in @Scheduled annotation

Step 01: 設定 applicationContext.xml,將 task 選取

applicationContext  

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:aop="http://www.springframework.org/schema/aop"
    xmlns:cache="http://www.springframework.org/schema/cache"
    xmlns:context="http://www.springframework.org/schema/context"
    xmlns:tx="http://www.springframework.org/schema/tx"
    xmlns:jpa="http://www.springframework.org/schema/data/jpa"
    xmlns:jee="http://www.springframework.org/schema/jee"
    xmlns:task="http://www.springframework.org/schema/task"
    xsi:schemaLocation="http://www.springframework.org/schema/cache http://www.springframework.org/schema/cache/spring-cache.xsd
        http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-4.2.xsd
        http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-4.2.xsd
        http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
        http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd
        http://www.springframework.org/schema/data/jpa http://www.springframework.org/schema/data/jpa/spring-jpa-1.8.xsd
        http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd">

    <!-- Spring Task using Annotation-->
    <task:annotation-driven/>
    <bean id="SpringTask-Annotation" class="com.mis.demo.SpringTaskAnnotationDemo"/>
    

</beans>   

 

Step 02: 建立 SpringTaskAnnotationDemo.java

package com.mis.demo;

import java.util.Date;
import org.springframework.scheduling.annotation.Scheduled;
public class SpringTaskAnnotationDemo {
    @Scheduled(fixedDelay = 5000)
    //@Scheduled(fixedRate = 5000)
    public void demoServiceMethod()
    {
        System.out.println("Method executed at every 5 seconds. Current time is :: "+ new Date());
    }
}

這樣就可以運作了,簡單吧 !!

 

方法 2) Task scheduling using cron expression in @Scheduled annotation

Step 01: 在 applicationContext.xml 設定 class 的 task:scheduled 執行方法,所以在 SpringTaskExecutorDemo.java 的執行 method 為 execute。

    <!-- Spring Task Using cron -->
    <bean id="SpringTask-Cron" class="com.mis.demo.SpringTaskExecutorDemo"/>
    <task:scheduled-tasks>
        <task:scheduled ref="SpringTask-Cron" method="execute" cron="*/5 * * * * ?"/>
    </task:scheduled-tasks>

 

Step 02:  建立 SpringTaskExecutorDemo.java

package com.mis.demo;

import java.util.Calendar;


public class SpringTaskExecutorDemo {
    public void execute () {
        System.out.println("SpringTaskExecutorDemo: Run at " + Calendar.getInstance().getTimeInMillis() );
    }
}

 

這樣就可以運作了,也很簡單吧 !!

 

 

 

 

參考:

http://howtodoinjava.com/spring/spring-core/4-ways-to-schedule-tasks-in-spring-3-scheduled-example/

http://jimwayne.blogspot.tw/2014/04/spring-framework.html

http://docs.spring.io/spring/docs/current/spring-framework-reference/html/scheduling.html

MIS 發表在 痞客邦 留言(0) 人氣()