<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    云自無心水自閑

    天平山上白云泉,云自無心水自閑。何必奔沖山下去,更添波浪向人間!
    posts - 288, comments - 524, trackbacks - 0, articles - 6
      BlogJava :: 首頁 :: 新隨筆 :: 聯(lián)系 :: 聚合  :: 管理

    2013年8月15日

    1. java zip 多個文件時,如果先添加了一個excel文件,然后再想添加其他的文件時會出現(xiàn) steam is closed的錯誤。這是因為work.write(outputSteam)后,出調(diào)用outputSteam.close(),關(guān)閉輸出流。
    解決方法:
    將原來的程序:
                ZipEntry entry = new ZipEntry( "file3.txt" );
                zos.putNextEntry( entry );
                workbook.write( zos );
                zos.closeEntry();
    改為:
                ZipEntry entry = new ZipEntry( "file3.txt" );
                zos.putNextEntry( entry );
                workbook.write( new NonCloseableOutputStream( zos ) );
                zos.closeEntry();

    其中 NonCloseableOutputStream 定義如下:
    public class NonCloseableOutputStream extends java.io.FilterOutputStream {
        public NonCloseableOutputStream(OutputStream out) {
            super(out);
        }
        @Override public void close() throws IOException {
            flush();
        }
    }



    2. 使用binary使得mysql區(qū)分大小寫
    select * from table1 where binary field1 = 'abc';

    posted @ 2017-08-09 19:52 云自無心水自閑 閱讀(428) | 評論 (0)編輯 收藏

    https://notepad-plus-plus.org/community/topic/13661/plugin-manager-x64-available-submit-your-plugins

    posted @ 2017-06-26 09:33 云自無心水自閑 閱讀(396) | 評論 (0)編輯 收藏

    move Git Server to a new IP/URL:

    you can just edit 
    .git/config and change the URLs there

    也可以在git視圖中,右鍵點擊項目,選擇屬性,然后修改url中的地址

    posted @ 2017-06-15 08:40 云自無心水自閑 閱讀(320) | 評論 (0)編輯 收藏

    autohotkey
    listary
    cmder可以split screen,在一個窗口中同時運行數(shù)個cmd

    posted @ 2017-05-24 07:13 云自無心水自閑 閱讀(17853) | 評論 (0)編輯 收藏

    官網(wǎng)地址:autohotkey.com

    ; fill password
    ^Numpad2::
    Send, root{tab}root{enter}
    Return
    ^Numpad3::
    IfWinExist, ahk_exe OUTLOOK.EXE
    {
        WinActivate ahk_exe OUTLOOK.EXE ; Automatically uses the window found above.
        ; WinMaximize  ; same
        ;Send, Some text.{Enter}
    msgbox Outlook is running.
    }
    Return

    posted @ 2017-03-08 13:06 云自無心水自閑 閱讀(368) | 評論 (0)編輯 收藏

    <html>
    <head>
        <script src="https://unpkg.com/vue/dist/vue.js"></script>
        <script>
            window.onload = function () {
                var app = new Vue({
                    el: '#app',
                    data: {
                        message: 'Hello Vue!'
                    }
                });
            }    
        </script>
    </head>

    <body>
        <div id="app">
          {{ message }}
        </div>
    </body>
    </html>

    posted @ 2017-02-09 07:41 云自無心水自閑 閱讀(402) | 評論 (0)編輯 收藏


    String[] splits=someString.split("a,b,c,d", ",");
    logger.debug( "array: {}", (Object) splits );

    這里要注意的就是要把數(shù)組的數(shù)據(jù)類型強制轉(zhuǎn)換為Object 

    posted @ 2016-12-29 11:51 云自無心水自閑 閱讀(1619) | 評論 (0)編輯 收藏

    在windows環(huán)境中,可以用如下方法重置root密碼

    1、先停止mysql數(shù)據(jù)庫

    2、保存密碼重置sql文件
         5.7.6(包括)以后的版本:ALTER USER 'root'@'localhost' IDENTIFIED BY 'MyNewPass';
         5.7.5(包括)以前的版本:SET PASSWORD FOR 'root'@'localhost' = PASSWORD('MyNewPass');
    假設(shè)保存到文件: c:\reset.txt

    3、以管理員身份打開命令行窗口,運行
    C:\> cd "C:\Program Files\MySQL\MySQL Server 5.5\bin"
    C:\> mysqld --init-file=C:\reset.txt

    4、啟動后,還不能馬上用新密碼連接數(shù)據(jù)庫,需要重啟mysql數(shù)據(jù)庫

    posted @ 2016-12-21 07:12 云自無心水自閑 閱讀(370) | 評論 (0)編輯 收藏

    This is a general step that happens when m2e/m2eclipse (Maven integration for Eclipse) is installed, whether projects are actively using it or not.
    這是因為m2eclipse(maven插件)要在啟動時需要進行的一個步驟。

    This step can be disabled through the Eclipse preferences: Window / Preferences / Maven / "Download repository index updates on startup". This option is on the main "Maven" preference page (not a child page). Just uncheck the box to prevent this from happening.
    我們可以停止這個動作。方法:Windows -> Preferences -> Maven 取消勾選 Download repository index updates on startup

    posted @ 2016-11-29 08:38 云自無心水自閑 閱讀(1310) | 評論 (0)編輯 收藏

    有好幾個java library都可以實現(xiàn)這個功能,但是從pdf提取文本的一個問題是,提取出來的文本沒有固定的順序,不容易比較好的還原其格式。

    我的做法是使用pdfclown來進行這項工作。官方網(wǎng)站是:https://pdfclown.org/ 先下載其最新版本。
    參考其示例代碼:https://pdfclown.org/2010/01/02/upcoming-0-0-8-whats-going-to-be-new/#more-30

    使用這段代碼,我們不僅可以得到文本的字符串,還能得到文本的頁數(shù)和相對坐標(biāo)。
    我的思路是先把所有文本的字符串和坐標(biāo)提取出來。然后排序,排序的順序是縱坐標(biāo),然后橫坐標(biāo)。
    這樣排序完畢后,就能比較好的解決文本格式問題。

    posted @ 2016-11-28 11:03 云自無心水自閑 閱讀(385) | 評論 (0)編輯 收藏


    1, 先定義一個input, 做為datepicker的容器。
    <input type='text' class="form-control" id="dateTo" name="dateTo" required/>

    2, 在后面加上glyphicon, 注意關(guān)鍵是label 中的for的id需要是前面定義的容器的id, 這樣點擊glyphicon的時候就會觸發(fā)彈出日期選擇框。
    <label for="dateTo" class="input-group-addon"><span class="glyphicon glyphicon-time"></span></label>

    posted @ 2016-10-10 19:57 云自無心水自閑 閱讀(219) | 評論 (0)編輯 收藏

    在日志文件中看到這個錯誤信息
    Cause: java.sql.SQLException: #HY000

    后來才知道這是因為數(shù)據(jù)庫中有個別字段要求不能為空, 但是insert語句中沒有提供數(shù)據(jù),造成了這個錯誤。

    關(guān)鍵是錯誤信息不明確直觀,不容易知道是這個原因


    posted @ 2016-09-28 13:13 云自無心水自閑 閱讀(1067) | 評論 (0)編輯 收藏

        public void afterJFinalStart(){
            Configuration config = FreeMarkerRender.getConfiguration();
            config.setTemplateUpdateDelayMilliseconds( 2 );
            config.setAPIBuiltinEnabled( true );
        }

    posted @ 2016-09-21 14:02 云自無心水自閑 閱讀(239) | 評論 (0)編輯 收藏


    中文版地址  https://angular.cn/

    posted @ 2016-09-16 13:13 云自無心水自閑 閱讀(2108) | 評論 (0)編輯 收藏

    1, call ##002# to cancel "call diversion"

    2, call 121600, choose option "2" to cancel "Active call catcher"

    posted @ 2016-08-25 12:58 云自無心水自閑 閱讀(154) | 評論 (0)編輯 收藏

    1. 格式化XML的插件
    可以安裝“XML Tools", 安裝完畢后,選擇 插件->XML Tools->Pretty Print(XML Only - with line breaks)

    2. 格式化JSON的插件
    可以安裝”JSON Viewer", 安裝完畢后,選擇 插件->JSON Viewer->Format JSON

    3. 格式化SQL的插件
    可以安裝“Poor man's T-Sql Formatter", 選擇 插件->Poor man's T-Sql Formatter->Format T-Sql Code

    posted @ 2016-08-12 15:14 云自無心水自閑 閱讀(1052) | 評論 (0)編輯 收藏

     
    使用的工具

    1. Apache HttpClient
    2. Firefox + FireBug
    3. Burp Suite ( https://portswigger.net/burp ) + Firefox FoxyProxy

    Firefox + FireBug 主要用于查看渲染出的頁面中的信息(比如:表單項的名稱,節(jié)點ID等等)
    Burp Suite 主要用于動態(tài)攔截頁面的交互,查看Ajax的調(diào)用。
    HttpClient 用于最后程序的編制。搞清楚了網(wǎng)頁交互的過程,就可以自主決定程序需要包含的內(nèi)容。
    在實際網(wǎng)頁中,可能需要點開數(shù)級菜單,才能最后看到需要的內(nèi)容。
    但是在程序中,可以直接跳到最后一步。

    posted @ 2016-06-05 19:00 云自無心水自閑 閱讀(198) | 評論 (0)編輯 收藏

    1. 表格文字右對齊 
     <table>
    <tr>
        <td><p style="text-align:right;margin:0;padding:0">文字右對齊</p></td>
        <td>文字左對齊</td>
    </tr>
    </table>

    2. 表格邊緣的margin 需要在表格外再套一個div
    <div style="margin:10px">
        <table>
        ......
        </table>
    </div>

    3. btn-toolbar class can put a margin between 2 "pull-right" buttons
            <div class="row">
                <div class="col-md-2"></div>
                <div class="col-md-8 btn-toolbar">
                    <input type="submit" class="btn btn-warning pull-right" value="Submit">
                    <input type="button" id="profilePassBackBtn" class="btn btn-info pull-right" value="Back">
                </div>
                <div class="col-md-2">
                </div>
            </div>

    posted @ 2016-05-31 11:39 云自無心水自閑 閱讀(378) | 評論 (0)編輯 收藏

     AngularJS 2.0 已經(jīng)發(fā)布了Beta版本,相信正式版不久以后就會發(fā)布了。

    下面是官網(wǎng)上的新功能介紹:

    1. 更快更高效。AngularJS 2 將會比 AnuglarJS 1 快很多。因為它會支持:從遠(yuǎn)程胳快速加載、離線編譯以便于更快啟動、以及超快的變動檢測和為使?jié)L動更平滑的視圖緩存等等。

    2. 更加簡單清晰。語法將會顯得更加自然,易于編寫

    3. 跨越平臺。無論是臺式機、手機瀏覽器、安卓、IOS平臺,AngularJS都能提供相應(yīng)的支持。

    4. 無縫從 AngularJS 1 升級到 2

    5. 簡便的開發(fā)。支持各種開發(fā)語言,ES5, TypeScript, Dart

    6. 全面完備的路由。 方便地映射URL到應(yīng)用組件,并提供多種高級功能,比如:嵌套和鄰接路由,支持卡片棧導(dǎo)航、動畫過渡、手機用戶延遲加載等等

    7. 依賴注入。

    8. 舊瀏覽器的良好支持

    9. 動畫效果 (仍在開發(fā)中)

    10. 國際化支持(仍在開發(fā)中)

    posted @ 2016-04-18 20:09 云自無心水自閑 閱讀(265) | 評論 (0)編輯 收藏

    1. Go to web project properties.
    2. Deployment Assembly (Left).
    3. Add > Select project > Select your lib project > Check "Assemble projects into the WEB-INF/lib folder of the web application" if not checked > Finish.

    posted @ 2016-04-13 10:35 云自無心水自閑 閱讀(171) | 評論 (0)編輯 收藏

     使用酷狗就可以轉(zhuǎn)換。
    右鍵點擊歌曲 ,工具,格式轉(zhuǎn)換。
    唯一要注意的是要先登錄。

    posted @ 2016-03-17 20:20 云自無心水自閑 閱讀(1595) | 評論 (0)編輯 收藏

    今天把commons dbcp 和 pool都升級到2.x, 結(jié)果發(fā)現(xiàn)不能正常的工作,卡在new BasicDataSource()上了.
    后來才發(fā)現(xiàn)原因是因為沒有加入commons-logging的jar文件

    幾個注意點:
    1. commons dbcp2.x 和 commons pool需要同時升到2.x
    2. dbcp 2.x要運行在java 7以上 
    3. mysql connector要5.1.11以上
    4. 需要有commons-logging的包,我使用的是slf4j, 就需要加一個jcl-over-slf4j

    posted @ 2016-02-09 11:44 云自無心水自閑 閱讀(615) | 評論 (0)編輯 收藏

    Error
    com.jcraft.jsch.JSchException: The cipher 'aes256-cbc' is required, but it is not available.
    or
    Caused by: java.security.InvalidKeyException: Illegal key size


    posted @ 2016-02-05 13:51 云自無心水自閑 閱讀(270) | 評論 (0)編輯 收藏


    我在網(wǎng)上搜索了一下如何使用Selenium下載文件,其中確實有幾篇文件介紹了實現(xiàn)的方法。
    但是其主要思想都是使用httpClient或者URL獲得InputStream, 然后保存到文件中。
    但是,其中的問題是用戶登錄的Session不能維持。

    我發(fā)現(xiàn)了一個簡單的方法。
    直接使用WebDriver.get, 示例如下:

    webDriver.get("https://website.com/login");
    WebElement element = driver.findElement( By.id( "userID" ) );
    element.sendKeys( "user01" );

    element = driver.findElement( By.id( "passwd" ) );
    element.sendKeys( "password" );

    element = driver.findElement( By.name( "Login" ) );
    element.submit();

    webDriver.get("https://website.cm/download.do?start=xx&end=yy");
    String source = webDriver.getPageSource();

    這個source就是我們想保存的要下載的內(nèi)容。
    只要把這個String寫到一個文件中,就實現(xiàn)了文件下載的目的

    posted @ 2016-01-28 18:06 云自無心水自閑 閱讀(470) | 評論 (0)編輯 收藏

         摘要: 在我的上一篇文章中介紹了如何進行GPG加密解密。
    加密解密的基本操作流程是,用戶使用公鑰對明文進行加密,解密方使用私鑰對密文進行解密。

    在實際應(yīng)用中,除了加密保證文本內(nèi)容不泄露外,同時還要考慮能夠驗證密文發(fā)送方的身份,比較普遍使用的方法就是簽名。
    本文主要對具體的方法進行介紹并附上源代碼。  閱讀全文

    posted @ 2015-12-11 21:40 云自無心水自閑 閱讀(1268) | 評論 (0)編輯 收藏

    Java程序中訪問擁有全部讀寫權(quán)限的目錄相對比較簡單,和普通的目錄沒有什么差別。
    但是要訪問一個需要用戶和密碼驗證的目錄就需要一點點小技巧了。
    這里介紹一個開源的庫能夠比較容易的實現(xiàn)這一需求。
    1。 下載庫文件:
     https://jcifs.samba.org/
    下載的zip文件中, 不僅包含了jar文件,還有文檔和示例。

    2??截恓cif-1.3.18.jar到類路徑中。

    3。代碼示例:
     1     String user = "your_user_name";
     2     String pass ="your_pass_word";
     3 
     4     String sharedFolder="shared";
     5     String path="smb://ip_address/"+sharedFolder+"/test.txt";
     6     NtlmPasswordAuthentication auth = new NtlmPasswordAuthentication("",user, pass);
     7     SmbFile smbFile = new SmbFile(path,auth);
     8     SmbFileOutputStream smbfos = new SmbFileOutputStream(smbFile);
     9     smbfos.write("testing.and writing to a file".getBytes());
    10     System.out.println("completed nice !");
    說明: 如果有一個共享目錄,比如: \\192.168.1.2\testdir\
    那么smb的路徑就是:smb://192.168.1.2/testdir/
    NtlmPasswordAuthentication需要三個參數(shù), 第一個是名,沒有的話,填null, 第二個是用戶名,第三個是密碼

    得到SmbFile之后,操作就和java.io.File基本一樣了。
    另外還有一些功能比如:
    SmbFile.copyTo
    SmbFile.renameTo
    等等

    posted @ 2015-11-20 14:03 云自無心水自閑 閱讀(12984) | 評論 (0)編輯 收藏

    先將my.default.ini改名為my.ini放到bin目錄
    命令行執(zhí)行: mysqld --initialize --user=mysql --console
    先執(zhí)行以上命令, 生成庫. 注意有個臨時密碼, 要記下來.

    安裝服務(wù):mysqld.exe --install MySql5.7 --defaults-file=c:\mysql\mysql5.7\my.ini

    然后啟動服務(wù). 
    然后再命令行:
    mysql -uroot -p
    輸入密碼,
    再輸入: 
    set password = password('root')
    改密碼成功, 然后就可以操作了.

    posted @ 2015-11-09 15:25 云自無心水自閑 閱讀(736) | 評論 (0)編輯 收藏

    如果只是在beforeSubmit()中 調(diào)用$('#fieldname').val(2)是不能成功修改表單的值的。
    因為此時ajaxForm已經(jīng)把表單中所有的內(nèi)容存儲在arr之中了。

        $('#form1').ajaxForm({
            beforeSubmit: function(arr){
                for ( var i = 0; i < arr.length; i ++ ) {
                    if ( arr[i].name == "fieldName1" ) {
                        arr[i].value = '新的值';
                    }
                }
            }
        });
    需要使用這種方式進行修改。

    posted @ 2015-11-02 19:13 云自無心水自閑 閱讀(1218) | 評論 (0)編輯 收藏

    今天在運行myeclipse的時候,突然報nullPointerException.

    具體的錯誤信息如下:

    Message: Errors running builder ‘DeploymentBuilder’ on project XXX’.
    Exception Stack Trace
    java.lang.NullPointerException

    解決方法:

    1. Shut down the workspace.

    2. Delete the file com.genuitec.eclipse.ast.deploy.core.prefs which is located at <workspace dir>/.metadata/.plugins/org.eclipse.core.runtime/.settings/com.genuitec.eclipse.ast.deploy.core.prefs

    3. Start the IDE.

    posted @ 2015-10-21 09:21 云自無心水自閑 閱讀(364) | 評論 (0)編輯 收藏

     
    ipconfig /flushdns
    ipconfig /registerdns
    netsh winsock reset

    重新啟動電腦。

    posted @ 2015-10-13 16:31 云自無心水自閑 閱讀(1787) | 評論 (0)編輯 收藏

    今天下載了Apache James 3.0 Beta 5, 文件名:james-server-app-3.0.0-beta5-20150627.102412-1076-app.zip
    解壓,運行run.bat

    然后,注冊domain
    james-cli --host localhost adddomain example.com
    添加用戶
    james-cli.bat --host localhost adduser test@example.com password

    然后測試發(fā)送郵件,客戶端顯示發(fā)送成功,但是james服務(wù)器報錯,找不到MimeConfig的無參數(shù)構(gòu)造函數(shù)。
    解決方法:
    使用舊的mime4j的jar包替換james 3.0 beta5中自帶的最新包。
    beta5中自帶的是0.8.0版,apache網(wǎng)站中可以下載到0.7.2
    下載apache-mime4j-0.7.2-bin.zip, 將其中的apache-mime4j-core-0.7.2.jar, apache-mime4j-dom-0.7.2.jar復(fù)制到j(luò)ames\lib目錄,
    并將其更名覆蓋原有的
    apache-mime4j-core-0.8.0-20150617.024907-738.jar
    apache-mime4j-dom-0.8.0-20150617.024927-735.jar
    重新啟動james, 發(fā)送郵件, 成功。

    posted @ 2015-10-08 08:45 云自無心水自閑 閱讀(3277) | 評論 (0)編輯 收藏

         摘要: 解壓/生成有密碼保護的壓縮文件, 研發(fā)過程中,作者研究了壓縮文件格式文檔: http://www.pkware.com/documents/casestudies/APPNOTE.TXT,并且參考了7-zip的實現(xiàn)。
      閱讀全文

    posted @ 2015-08-19 10:16 云自無心水自閑 閱讀(9954) | 評論 (0)編輯 收藏

         摘要: 花了兩天時間終于把windows10安裝好了,以下是我的一些個人的體會
      閱讀全文

    posted @ 2015-08-03 18:56 云自無心水自閑 閱讀(6251) | 評論 (0)編輯 收藏

    在JfinalConfig的繼承類中,
    configConstant() 需要設(shè)置me.setDevMode(true);

    1. 只有在DevMode下,才能禁止freeMarker的緩存。
    Configuration config = FreeMarkerRender.getConfiguration();
    config.setTemplateUpdateDelayMilliseconds(0);
    才會生效


    2. 這時才會有JFinal Action Report日志輸出

    posted @ 2015-07-24 19:58 云自無心水自閑 閱讀(416) | 評論 (0)編輯 收藏

    本文將簡單介紹如何使用PowerMock和Mockito來mock
    1. 構(gòu)造函數(shù)
    2. 靜態(tài)函數(shù)
    3. 枚舉實現(xiàn)的單例
    4. 選擇參數(shù)值做為函數(shù)的返回值
    5. 在調(diào)用mock出來的方法中,改變方法參數(shù)的值

    一點簡要說明:Mockito其實已經(jīng)可以滿足大部分的需求,但是它的實現(xiàn)機制是使用cglib來動態(tài)創(chuàng)建接口的類的實例。但是這種實現(xiàn)方式不能用于構(gòu)造函數(shù)和靜態(tài)函數(shù),因為那需要使用類的字節(jié)碼(比如使用javassist). 所以我們才需要結(jié)合使用PowerMock.

    1. mock構(gòu)造函數(shù), 如果有代碼沒有使用DI注入依賴實例,在單元測試中可以使用PowerMock來模擬創(chuàng)建對象。
    注意的開始兩行的2個注解 @RunWith 和 @PrepareForTest
    @RunWith比較簡單,后面始終是PowerMockRunner.class
    @PrepareForText后面需要加的是調(diào)用構(gòu)造函數(shù)的類名,而不是有構(gòu)造函數(shù)的類本身。
    在下面的例子中,我們要測試的類是:Helper, 在Helper類中調(diào)用了Somthing類的構(gòu)造函數(shù)來創(chuàng)建實例。
    @RunWith(PowerMockRunner.class)
    @PrepareForTest(Helper.
    class)
    public class HelperTest {
      @Mock
      
    private Something mockSomething;
          
      @InjectMocks
      
    private Helper helper;
          
      @Test
      
    public void doSomething() throws Exception {
          String argument 
    = "arg";
              
          PowerMockito.whenNew(Something.
    class).withArguments(argument).thenReturn(mockSomething);
             
          // 調(diào)用需要測試方法
          helper.doSomething(argument);
             
          // 進行驗證
          verify(mockSomething).doIt();
      }
    }


    public class Helper {
      public void doSomething(String arg) {
          Something something = new Something(arg);
          something.doit();
      }
    }


    2,mock 靜態(tài)函數(shù), 單例模式就是一個典型的會調(diào)用靜態(tài)函數(shù)的例子。 注意要點與mock構(gòu)造函數(shù)相同。
    class ClassWithStatics {
      
    public static String getString() {
        
    return "String";
      }

      
    public static int getInt() {
        
    return 1;
      }
    }

    @RunWith(PowerMockRunner.
    class)
    @PrepareForTest(ClassWithStatics.
    class)
    public class StubJustOneStatic {
      @Test
      
    public void test() {
        PowerMockito.mockStatic(ClassWithStatics.
    class);

        when(ClassWithStatics.getString()).thenReturn(
    "Hello!");

        System.out.println(
    "String: " + ClassWithStatics.getString());
        System.out.println(
    "Int: " + ClassWithStatics.getInt());
      }
    }

    3。mock枚舉實現(xiàn)的單例
    SingletonObject.java
    public enum SingletonObject { 
        INSTANCE
    ;
        private
    int num;
        protected
    void setNum(int num) {
            this.num = num;
        }
        public int getNum() {
            return
    num;
        }

    }
    SingletonConsumer.java

    public class SingletonConsumer {
        public String consumeSingletonObject() { 
            return
    String.valueOf(SingletonObject.INSTANCE.getNum());
        }
    }
    SingletonConsumerTest.java
    @RunWith(PowerMockRunner.class) 
    @PrepareForTest({SingletonObject.class})
    public class SingletonConsumerTest {
        @Test public void testConsumeSingletonObject() throws Exception {
            SingletonObject
    mockInstance = mock(SingletonObject.class);
            Whitebox
    .setInternalState(SingletonObject.class, "INSTANCE", mockInstance);
            when
    (mockInstance.getNum()).thenReturn(42);
            assertEquals
    ("42", new SingletonConsumer().consumeSingletonObject());
        }
    }
    4。返回參數(shù)值做為函數(shù)返回值。
    mockito 1.9.5之后,提供一個方便的方法來實現(xiàn)這個需要,在這之前可以使用一個匿名函數(shù)來返回一個answer來實現(xiàn)。
    when(myMock.myFunction(anyString())).then(returnsFirstArg());
    其中returnsFirstArg()是org.mockito.AdditionalAnswers中的一個靜態(tài)方法。
    在這個類中還有其他的一些類似方法
    returnsSecondArg()
    returnsLastArg()
    ReturnsArgumentAt(int position)

    5. 在調(diào)用mock出來的方法中,改變方法參數(shù)的值
    when( myMock.someMethod( any( List.class ) ) ).thenAnswer( ( new Answer<Void>() {
        @Override
        
    public Void answer( InvocationOnMock invocation )
                
    throws Throwable {
            Object[] args 
    = invocation.getArguments();
            List arg1 
    = (List)args[0];
            arg1.add(
    "12345");
            
    return null;
        }
    } ) );



    Verifying with generic parameters
    verify(someService).process(Matchers.<Collection<Person>>any());
    verify(adunoMasterBaseProcessor).processBinFiles( anyListOf(File.class) );

    posted @ 2015-06-16 21:27 云自無心水自閑 閱讀(18458) | 評論 (0)編輯 收藏

    Oracle提供的JDK其實已經(jīng)自帶一定程度的熱加載功能,但是如果你修改了類名,方法名,或者添加了新類,新方法的話。
    Tomcat都需要重新啟動來使得剛才的更改生效。
    而JRebel和springloaded都能有效地解決這個問題。其中springloaded是開源軟件,可以免費使用,尤其難得。
    其主頁:https://github.com/spring-projects/spring-loaded
    在官方頁面的簡單介紹中,作者只講述了如何在java程序中應(yīng)用springloaded,而沒有說明如何在tomcat中進行配置。
    本文將簡要進行介紹。

    1,下載springloaded到本地目錄,比如:c:\temp\springloaded-1.2.3.RELEASE.jar

    2. 修改tomcat的應(yīng)用,禁止tomcat自己的熱加載,方法是在META-INF目錄下創(chuàng)建context.xml文件,里面包含如下語句,關(guān)鍵便是其中設(shè)置reloadable為false
    <?xml version="1.0" encoding="UTF-8"?>
    <Context antiResourceLocking="false" privileged="true" useHttpOnly="true" reloadable="false" />

    3.在運行環(huán)境中添加springloaded的jar文件,在eclipse中右鍵點擊項目,run as->run configuration
    在彈出的窗口中,選擇Arguments標(biāo)簽,在vm arguments的末尾添加:
    -javaagent:C:\temp\springloaded-1.2.3.RELEASE.jar -noverify
    點擊應(yīng)用按鈕。

    以上便完成了所有的配置,步驟并不復(fù)雜。

    posted @ 2015-06-11 21:59 云自無心水自閑 閱讀(7714) | 評論 (0)編輯 收藏

    java wrapper是一個可以用于將java應(yīng)用程序包裝成windows服務(wù)的工具。
    并且可以通過簡單的配置來允許使用visualVM進行監(jiān)控。

    配置方法:
    在wrapper.conf中添加如下3行

    wrapper.java.additional.1=-Dcom.sun.management.jmxremote.port=9898 #這里的端口號可以自行選擇。
    wrapper.java.additional.2=-Dcom.sun.management.jmxremote.ssl=false
    wrapper.java.additional.3=-Dcom.sun.management.jmxremote.authenticate=false

    修改完畢保存后重新啟動服務(wù)。

    打開visualVM, 在菜單中選擇 file->Add JMX Connection。
    在彈出窗口中,connection一項中輸入: localhost:9898 即可。

    此配置對于jconsole也同樣有效。

    posted @ 2015-06-11 14:09 云自無心水自閑 閱讀(4817) | 評論 (0)編輯 收藏

    在一些歷史遺留代碼中,會用到j(luò)ava.util.logging. 如果在新的項目中引用了這些代碼,而又不希望去一個一個的修改原來的代碼。
    可以使用slf4j提供的類來轉(zhuǎn)接這部分的日志輸出。

    方法:
    1、類路徑中添加
        slf4j-api-1.7.10.jar
        jul-to-slf4j.1.7.10.jar ( 用于將java.util.logging的日志橋接到slf4j中)
        logback-core.1.1.2.jar
        logback-classic-1.1.2.jar

    2、在代碼中添加:
             // Optionally remove existing handlers attached to j.u.l root logger
             SLF4JBridgeHandler.removeHandlersForRootLogger();  // (since SLF4J 1.6.5)

             // add SLF4JBridgeHandler to j.u.l's root logger, should be done once during
             // the initialization phase of your application
             SLF4JBridgeHandler.install();

    注意事項:
    1、這個橋接可以會造成性能問題。
    和其他的橋接實現(xiàn)(比如:log4j, commons logging)不同,這個模塊并不真正的完全替代java.util.logging類,因為這個java.util.logging是java自帶的。
    所以只是把原來的日志對象進行了轉(zhuǎn)換,簡單的說,這個轉(zhuǎn)換過程是有開銷的。
    關(guān)鍵在于,不管日志語句有沒有根據(jù)日志級別被關(guān)閉,這個轉(zhuǎn)換無法避免。

    2、不能在類路徑中放入
    slf4j-jkd14.jar
    jul-toslf4j.jar

    posted @ 2015-04-27 15:31 云自無心水自閑 閱讀(1551) | 評論 (0)編輯 收藏

     1. Text Editor: Notepad++/Syncplify.me Notepad!
     2. Browser: Chrome/Firefox
     3. 文件管理: XYplorer Lite/Explorer++/Q-Dir
     4. Mind map: XMind Free
     5. Video player: PotPlayer
     6. Music player: Kugou
     7. Mysql client: HeidiSql
     8. PDF reader: Foxit Reader
     9. File/Folder synchronize : FreeFileSync
    10. MP3 tools: Audacity/MP3 Gain
    11. Zip: 7-zip
    12. Partition Management: EaseUS Partition Master Free / MiniTool Free Partition Manager 
    13. Data Recovery: EaseUS Data Recovery Wizard Free / MiniTool Free Data Recovery
    14. PDF Printer: PDF reDirect v2
    15. 個人信息管理: EssentialPIM Free Edition
    16. 遠(yuǎn)程登錄: Terminals
    17. 文本比較合并: winmerge
    18. (s)FTP client: WinSCP
    19. 圖像處理: GIMP

    posted @ 2015-04-14 21:21 云自無心水自閑 閱讀(726) | 評論 (0)編輯 收藏

    Ember 是一個旨在創(chuàng)建大型web應(yīng)用的JavaScript框架,它消除了樣板(boilerplate)并提供了標(biāo)準(zhǔn)的應(yīng)用程序架構(gòu)。

    Manning: Ember.js in action 第一章
    Manning: Ember.js in action 第五章

    posted @ 2015-03-23 12:37 云自無心水自閑 閱讀(3707) | 評論 (1)編輯 收藏

    先給一個例子:
    $http. get('/remote/item' ). then(function(response) {
    console.log('成功。');
    }, function(errResponse) {
    console. error('出錯.' );
    });

    一。介紹Promise
    在這個例子中,$http.get()函數(shù)返回了一個Promise對象, 有了這個對象,我們才能很方便地直接在后面添加then函數(shù)的定義。
    Promise對象在AngularJS中是一個非常重要的存在。它提供了強大的功能和便利性。

    1。異步性
    從定義的語法上看,操作似乎是同步的,但是Promise的工作其實是異步的,只有在服務(wù)端返回數(shù)據(jù)后,后續(xù)的函數(shù)才會被調(diào)用。這是一個事件驅(qū)動,非阻塞式的框架。

    2。它避免了其它框架的嵌套回調(diào)函數(shù)的缺點。
    -所有異步任務(wù)都會返回一個Promise對象
    -每個Promise對象都有一個then函數(shù),then函數(shù)有兩個參數(shù),分別是成功處理函數(shù)和失敗處理函數(shù)
    -失敗處理函數(shù)和成功處理函數(shù)都只會在異步處理完成后被調(diào)用一次
    -then函數(shù)也會返回Promise對象,這樣,我們可以把多個函數(shù)串連起來成為一個函數(shù)鏈
    -成功處理函數(shù)和失敗處理函數(shù)的返回值可以被傳遞到函數(shù)鏈下一個的函數(shù)中
    -如果在成功(或者失敗)處理函數(shù)中,又開始了一個異步調(diào)用,那么函數(shù)鏈中的函數(shù)將會在這個異步調(diào)用結(jié)束后才開始

    二。異步鏈?zhǔn)秸{(diào)用的后續(xù)處理
    假如我們定義了如下的函數(shù)鏈:
    $http.get('/item').then(s1, e1).then(s2, e2).then(s3, e3);
    我們?nèi)绾巫灾鞯母鶕?jù)函數(shù)鏈中每個函數(shù)的運行結(jié)果,決定觸發(fā)后續(xù)函數(shù)的成功處理函數(shù)或者失敗處理函數(shù)呢?
    比如說,在s1處理過程中,發(fā)生問題,于是我們觸發(fā)了e2, 但是在e2處理完后,我們又想觸發(fā)s3.
    AnguarJS提供了$q來滿足這樣的需求。
    如果我們想觸發(fā)函數(shù)鏈中下一個函數(shù)的成功處理,我們只需要最后給出一個返回值,有了返回值,AngularJS會認(rèn)為函數(shù)執(zhí)行正確,自動調(diào)用下一個函數(shù)中的成功處理
    如果想觸發(fā)失敗處理,那么可以簡單地返回$q.reject(data),這樣就會觸發(fā)下一個函數(shù)的失敗處理

    posted @ 2015-02-27 18:39 云自無心水自閑 閱讀(2616) | 評論 (1)編輯 收藏



    在前文(http://www.tkk7.com/usherlight/archive/2015/02/01/422633.html)中我們曾經(jīng)介紹過,定義controller時,需要2個參數(shù),第一個參數(shù)是controller的名稱,第二個參數(shù)是一個數(shù)組,數(shù)組的最后一個元素將是controller的函數(shù),前面的參數(shù)是controller的依賴項。我們現(xiàn)在就來仔細(xì)分析一下其中的具體過程。

    先給一個例子:
    angular. module('notesApp' , [])
     . controller('MainCtrl' , ['$log' , function($log) {
     var self = this;
     self. logStuff = function() {
     $log. log('The button was pressed' );
     };
     }])

    在這個例子中可以看到,我們在第一個參數(shù)中用字符串(服務(wù)名稱)添加了一個依賴項。當(dāng)我們通過字符串聲明了這一個服務(wù)之后,我們就可以把它當(dāng)作一個變量注入到函數(shù)中。AngularJS會自動查找字符串名稱對應(yīng)的服務(wù)名,按照順序?qū)⑵渥⑷氲胶瘮?shù)中。
    myModule.controller("MainCtrl",  ["$log", "$window", function($l, $w) {}]);
    在這個例子中,$log, $windows是AngularJS自帶的兩個服務(wù),在數(shù)組中通過名稱聲明后,會被注入到函數(shù)的兩個參數(shù)中。
    比較常用的AngularJS自帶的服務(wù)有:$window, $location, $http等

    從上面的例子中可以看出,AngularJS的設(shè)計思想就是不要在函數(shù)中自己去實例化或者通過其它途徑來獲取服務(wù)的實例,而是聲明需要的對象,由AngularJS來注入具體的實例。

    創(chuàng)建自己的服務(wù)
    什么時候應(yīng)該創(chuàng)建服務(wù),而不是controller呢?
    1。 需要重用的時候
    2。需要保留應(yīng)用級的狀態(tài)。這是非常重要的一點,controller是會不斷地被創(chuàng)建和銷毀的,如果需要保存應(yīng)用級的狀態(tài),就需要使用service
    3。和頁面顯示無關(guān)
    4。需要和第三方服務(wù)整合
    5。緩存

    服務(wù)是會被延遲加載的,也就是說只有在第一次被引用的時候,才會被創(chuàng)建。
    服務(wù)將會被定義一次,也只會被實例化一次。

    posted @ 2015-02-09 19:28 云自無心水自閑 閱讀(7281) | 評論 (0)編輯 收藏

         摘要: 默認(rèn)情況下,每隔一秒種,SpringLoaded就會掃描類路徑,自動加載改變過的類, 而不需要重新啟動應(yīng)用  閱讀全文

    posted @ 2015-02-07 09:16 云自無心水自閑 閱讀(11098) | 評論 (4)編輯 收藏

    07. ng-repeart
    a. 在循環(huán)map的時候,會自動根據(jù)鍵值進行排序。
    b. 一些自帶的變量,$first(是否是第一個), $last(是否是最后一個), $middle(是否是中間的), $index(下標(biāo),根據(jù)鍵值排序后的下標(biāo)), $even, $odd
    08. 自己定義新變量時不要使用$$開頭。
    09. 可以使用track-by表達式來優(yōu)化對DOM的操作,對DOM對象使用從數(shù)據(jù)庫取得的ID來進行標(biāo)記,這樣的話,當(dāng)我們重復(fù)多次從數(shù)據(jù)庫中取出相同的數(shù)據(jù)的時候,DOM對象就能夠被重用。
    10. 數(shù)據(jù)雙向綁定的好處
    a. 如果我們想改變頁面Form中的數(shù)值,我們不需要在Javascript中,根據(jù)ID或者名稱來查找相應(yīng)的Form控件,只需要改變Controller變量的值,不需要JQuery的Selector,也不需要findElementByID
    b. 如果我們想在javascript中獲取Form控件的值,在控件的變量中就能直接獲得。
    11. 使用ng-submit比在button上使用ng-click要好一些。HTML的表單的提交有多種方式,比如在輸入域中按回車鍵就會觸發(fā)ng-submit,而不會觸發(fā)button的ng-click事件。
    12. 在ng-model中,可以直接引用一個對象,比如:<input type="text" ng-model="ctrl.user.name">,而不需要事先在model中以self.user={}定義。在AngularJS中,使用了ng-model的話,AngularJS在初始化數(shù)據(jù)綁定的時候,自動創(chuàng)建其中的對象和鍵值。在剛才的例子中,一旦用戶開始在輸入域中鍵入第一個字母,用戶user就會被自動創(chuàng)建。
    13. 推薦使用將相關(guān)數(shù)據(jù)集中到一個對象的方式來進行數(shù)據(jù)綁定,比如,用戶名和密碼,推薦使用:
    <input type="text" ng-model="ctrl.user.name">
    <input type="text" ng-model="ctrl.user.password">
    而不是:
    <input type="text" ng-model="ctrl.name">
    <input type="text" ng-model="ctrl.password">

    posted @ 2015-02-03 19:36 云自無心水自閑 閱讀(2638) | 評論 (1)編輯 收藏

    1. AngularJS的module函數(shù)有兩種用法,
    a. 定義一個module, 需要傳入2個參數(shù),module('moduleName', []), 第一個參數(shù)是新的module名稱,第二個參數(shù)是新module所依賴的module數(shù)組。
    b. 載入一個module, 只需要1個參數(shù),module('moduleName'), 唯一的一個參數(shù)指定要載入的module名稱。
    2. 使用controller函數(shù)來定義一個控制器(controller), 用ng-controller將控制器綁定到具體的HTML組件上。定義控制器的controller函數(shù)也需要2個參數(shù),第一個是控制器名稱,第二個參數(shù)同樣也是一個數(shù)組,數(shù)組的最后一個元素就是controller本身的函數(shù),前面的元素用字符串的形式指定其需要的依賴項。如果沒有依賴項,那就只需要定義函數(shù)。比如:
    angular.module('app1', [])
    .controller('mainControl', [function() {
    console.log('controller created.');
    }]);
    3. 在controller函數(shù)中用var定義的局部變量,在HTML中是不可見的。
    4. 推薦在controller函數(shù)中盡量避免直接引用this, 比較好的做法是使用代理。原因是一個函數(shù)中的this關(guān)鍵詞在被外部調(diào)用的時候,是會被覆蓋掉的。這樣的話,在函數(shù)內(nèi)部和外部的this會是完全不同兩個對象。
    代理用法示例:
    angular.module('app1', [])
    .controller('mainControl', [function() {
    var self = this;
    self.message = 'Hello world';
    self.changeMessage = function() {
    self.message = 'Goodbye.';
    };
    }]);
    5. ng-bind與雙大括號的區(qū)別, ng-bind和{{}}可以說基本上是可以互相替換的,但是也有區(qū)別。區(qū)別在于:AngularJS在啟動的時候就會執(zhí)行ng-bind, 而{{}}的替換時間會稍晚一些。有可能發(fā)現(xiàn)頁面在加載的時候,雙括號被一閃而過地替換掉(只在頁面初次加載的時候發(fā)生)。但是ng-bind就沒有這個問題。
    6. ng-cloak可以用于解決雙括號閃現(xiàn)的問題。

    posted @ 2015-02-01 19:19 云自無心水自閑 閱讀(5029) | 評論 (1)編輯 收藏

    1. HTML頁面的加載,這會觸發(fā)加載頁面包含的所有JS (包括 AngularJS)
    2. AngularJS啟動,搜尋所有的指令(directive)
    3. 找到ng-app,搜尋其指定的模塊(Module),并將其附加到ng-app所在的組件上。
    4. AnguarJS遍歷所有的子組件,查找指令和bind命令
    5. 每次發(fā)現(xiàn)ng-controller或者ng-repeart的時候,它會創(chuàng)建一個作用域(scope),這個作用域就是組件的上下文。作用域指明了每個DOM組件對函數(shù)、變量的訪問權(quán)。
    6. AngularJS然后會添加對變量的監(jiān)聽器,并監(jiān)控每個變量的當(dāng)前值。一旦值發(fā)生變化,AngularJS會更新其在頁面上的顯示。
    7. AngularJS優(yōu)化了檢查變量的算法,它只會在某些特殊的事件觸發(fā)時,才會去檢查數(shù)據(jù)的更新,而不是簡單地在后臺不停地輪詢。

    posted @ 2015-01-31 20:36 云自無心水自閑 閱讀(4779) | 評論 (2)編輯 收藏

    Java虛擬機規(guī)范規(guī)定JVM的內(nèi)存分為了好幾塊,比如堆,棧,程序計數(shù)器,方法區(qū)等,而Hotspot jvm的實現(xiàn)中,將堆內(nèi)存分為了三部分,新生代,老年代,持久帶,其中持久帶實現(xiàn)了規(guī)范中規(guī)定的方法區(qū),而內(nèi)存模型中不同的部分都會出現(xiàn)相應(yīng)的OOM錯誤,接下來我們就分開來討論一下。 

    棧溢出(StackOverflowError) 

    棧溢出拋出java.lang.StackOverflowError錯誤,出現(xiàn)此種情況是因為方法運行的時候棧的深度超過了虛擬機容許的最大深度所致。 

    出現(xiàn)這種情況,一般情況下是程序錯誤所致的,比如寫了一個死遞歸,就有可能造成此種情況。 下面我們通過一段代碼來模擬一下此種情況的內(nèi)存溢出。 
    Java代碼 
    1. import java.util.*;  
    2. import java.lang.*;  
    3. public class OOMTest{  
    4.    
    5.   public void stackOverFlowMethod(){  
    6.       stackOverFlowMethod();  
    7.   }  
    8.    
    9.   public static void main(String... args){  
    10.       OOMTest oom = new OOMTest();  
    11.       oom.stackOverFlowMethod();  
    12.   }  
    13.    
    14. }  

    運行上面的代碼,會拋出如下的異常: 
    引用

    Exception in thread "main" java.lang.StackOverflowError 
            at OOMTest.stackOverFlowMethod(OOMTest.java:6) 

    堆溢出(OutOfMemoryError:java heap space) 

    堆內(nèi)存溢出的時候,虛擬機會拋出java.lang.OutOfMemoryError:java heap space,出現(xiàn)此種情況的時候,我們需要根據(jù)內(nèi)存溢出的時候產(chǎn)生的dump文件來具體分析(需要增加-XX:+HeapDumpOnOutOfMemoryErrorjvm啟動參數(shù))。出現(xiàn)此種問題的時候有可能是內(nèi)存泄露,也有可能是內(nèi)存溢出了。 
    如果內(nèi)存泄露,我們要找出泄露的對象是怎么被GC ROOT引用起來,然后通過引用鏈來具體分析泄露的原因。 
    如果出現(xiàn)了內(nèi)存溢出問題,這往往是程序本生需要的內(nèi)存大于了我們給虛擬機配置的內(nèi)存,這種情況下,我們可以采用調(diào)大-Xmx來解決這種問題。 

    下面我們通過如下的代碼來演示一下此種情況的溢出: 
    Java代碼 
    1. import java.util.*;  
    2. import java.lang.*;  
    3. public class OOMTest{  
    4.    
    5.         public static void main(String... args){  
    6.                 List<byte[]> buffer = new ArrayList<byte[]>();  
    7.                 buffer.add(new byte[10*1024*1024]);  
    8.         }  
    9.    
    10. }  

    我們通過如下的命令運行上面的代碼: 

    Java代碼 
    1. java -verbose:gc -Xmn10M -Xms20M -Xmx20M -XX:+PrintGC OOMTest  


    程序輸入如下的信息: 
    引用

    [GC 1180K->366K(19456K), 0.0037311 secs] 
    [Full GC 366K->330K(19456K), 0.0098740 secs] 
    [Full GC 330K->292K(19456K), 0.0090244 secs] 
    Exception in thread "main" java.lang.OutOfMemoryError: Java heap space 
            at OOMTest.main(OOMTest.java:7) 

    從運行結(jié)果可以看出,JVM進行了一次Minor gc和兩次的Major gc,從Major gc的輸出可以看出,gc以后old區(qū)使用率為134K,而字節(jié)數(shù)組為10M,加起來大于了old generation的空間,所以拋出了異常,如果調(diào)整-Xms21M,-Xmx21M,那么就不會觸發(fā)gc操作也不會出現(xiàn)異常了。 

    通過上面的實驗其實也從側(cè)面驗證了一個結(jié)論:當(dāng)對象大于新生代剩余內(nèi)存的時候,將直接放入老年代,當(dāng)老年代剩余內(nèi)存還是無法放下的時候,出發(fā)垃圾收集,收集后還是不能放下就會拋出內(nèi)存溢出異常了 

    持久帶溢出(OutOfMemoryError: PermGen space) 

    我們知道Hotspot jvm通過持久帶實現(xiàn)了Java虛擬機規(guī)范中的方法區(qū),而運行時的常量池就是保存在方法區(qū)中的,因此持久帶溢出有可能是運行時常量池溢出,也有可能是方法區(qū)中保存的class對象沒有被及時回收掉或者class信息占用的內(nèi)存超過了我們配置。當(dāng)持久帶溢出的時候拋出java.lang.OutOfMemoryError: PermGen space。 
    我在工作可能在如下幾種場景下出現(xiàn)此問題。 

    1.使用一些應(yīng)用服務(wù)器的熱部署的時候,我們就會遇到熱部署幾次以后發(fā)現(xiàn)內(nèi)存溢出了,這種情況就是因為每次熱部署的后,原來的class沒有被卸載掉。 
    2.如果應(yīng)用程序本身比較大,涉及的類庫比較多,但是我們分配給持久帶的內(nèi)存(通過-XX:PermSize和-XX:MaxPermSize來設(shè)置)比較小的時候也可能出現(xiàn)此種問題。 
    3.一些第三方框架,比如spring,hibernate都通過字節(jié)碼生成技術(shù)(比如CGLib)來實現(xiàn)一些增強的功能,這種情況可能需要更大的方法區(qū)來存儲動態(tài)生成的Class文件。 
    我們知道Java中字符串常量是放在常量池中的,String.intern()這個方法運行的時候,會檢查常量池中是否存和本字符串相等的對象,如果存在直接返回對常量池中對象的引用,不存在的話,先把此字符串加入常量池,然后再返回字符串的引用。那么我們就可以通過String.intern方法來模擬一下運行時常量區(qū)的溢出.下面我們通過如下的代碼來模擬此種情況: 
    Java代碼 
    1. import java.util.*;  
    2. import java.lang.*;  
    3. public class OOMTest{  
    4.    
    5.         public static void main(String... args){  
    6.                 List<String> list = new ArrayList<String>();  
    7.                 while(true){  
    8.                         list.add(UUID.randomUUID().toString().intern());  
    9.                 }  
    10.         }  
    11.    
    12. }  

    我們通過如下的命令運行上面代碼: 
    java -verbose:gc -Xmn5M -Xms10M -Xmx10M -XX:MaxPermSize=1M -XX:+PrintGC OOMTest 
    運行后的輸入如下圖所示: 
    引用

    Exception in thread "main" java.lang.OutOfMemoryError: PermGen space 
            at java.lang.String.intern(Native Method) 
            at OOMTest.main(OOMTest.java:8) 

    通過上面的代碼,我們成功模擬了運行時常量池溢出的情況,從輸出中的PermGen space可以看出確實是持久帶發(fā)生了溢出,這也驗證了,我們前面說的Hotspot jvm通過持久帶來實現(xiàn)方法區(qū)的說法。 

    OutOfMemoryError:unable to create native thread 

    最后我們在來看看java.lang.OutOfMemoryError:unable to create natvie thread這種錯誤。 出現(xiàn)這種情況的時候,一般是下面兩種情況導(dǎo)致的: 

    1.程序創(chuàng)建的線程數(shù)超過了操作系統(tǒng)的限制。對于Linux系統(tǒng),我們可以通過ulimit -u來查看此限制。 
    給虛擬機分配的內(nèi)存過大,導(dǎo)致創(chuàng)建線程的時候需要的native內(nèi)存太少。我們都知道操作系統(tǒng)對每個進程的內(nèi)存是有限制的,我們啟動Jvm,相當(dāng)于啟動了一個進程,假如我們一個進程占用了4G的內(nèi)存,那么通過下面的公式計算出來的剩余內(nèi)存就是建立線程棧的時候可以用的內(nèi)存。 線程棧總可用內(nèi)存=4G-(-Xmx的值)- (-XX:MaxPermSize的值)- 程序計數(shù)器占用的內(nèi)存 通過上面的公式我們可以看出,-Xmx 和 MaxPermSize的值越大,那么留給線程棧可用的空間就越小,在-Xss參數(shù)配置的棧容量不變的情況下,可以創(chuàng)建的線程數(shù)也就越小。因此如果是因為這種情況導(dǎo)致的unable to create native thread,那么要么我們增大進程所占用的總內(nèi)存,或者減少-Xmx或者-Xss來達到創(chuàng)建更多線程的目的。

    posted @ 2015-01-20 07:12 云自無心水自閑 閱讀(872) | 評論 (0)編輯 收藏

    現(xiàn)在的顯示屏都在飚像素,商家的宣傳一個比一個噱頭大,什么 Retina、4K、8K 這種名詞一個接一個的出來, 這些到底都是啥意思?
     
    首先,Retina 和 4K 以及 8K 并不是同一層面的定義。屏幕一般是以像素點做單位的,4K 和 8K 就是直接限定了像素點的多少,而 Retina 則是沒有硬性的規(guī)范。

    Retina 屏幕的概念最早由蘋果公司執(zhí)行長史蒂夫·喬布斯(Steve Jobs)于 WWDC2010 發(fā)布 iPhone 4 時提出的。

      定義是:要求在正常觀看距離下,足以使人肉眼無法分辨其中的單獨像素。因此它并沒有限定像素值多少。

    4K 就是水平方向每一行的像素值達到或是接近 1024 的 4 倍,8K 就是達到或接近 8 倍。

      以此為標(biāo)準(zhǔn),4K 一般圖像就是指 4096*2160 的分辨率。當(dāng)然,這也不是硬性要求,像市場上很多 4K 屏幕其實是 3840*2160 或是 3656*2664,這些都是 4K 圖像分辨率的范疇。

      8K 就是分辨率在 7680*4320 左右。

    順便說一下,720p 則是指豎直方向的像素點達到 720 個,1080p 則是 1080 個,“P”是逐行掃描的意思

    問:那到底 Retina 和 4K 或是 Retina 和 8K 哪個更清楚呢?

      答:不一定,二者不能平行比較。

      因為 4K 和 8K 是限定了像素點的多少,而 Retina 是要求正常距離看不到像素點。

      舉個例子:如果放到正常的 42 寸屏幕上,4K 和 8K 在正常距離觀看下都看不到像素點,那么兩者都可以被稱作“Retina 屏幕”。

          可是如果給你一臺 500 寸的巨大屏幕,那么即便是 8K 也會到處是馬賽克,這時 Retina 觀感依然是高清無像素點,必然比 8K 和 4K 清楚的多。

    posted @ 2015-01-15 07:17 云自無心水自閑 閱讀(651) | 評論 (0)編輯 收藏


    Last_SQL_Error: Error 'Lock wait timeout exceeded; try restarting transaction' on query. Default database: 'test'. Query: 'DELETE FROM table1 WHERE id = 361'
    1 row in set (0.00 sec)

    solution:
    restart slave;

    stop slave;
    start slave;

    posted @ 2015-01-13 08:01 云自無心水自閑 閱讀(596) | 評論 (0)編輯 收藏

    1. server.xml
    在<engine>中添加
    <Realm className="org.apache.catalina.realm.MemoryRealm" />
    2. tomcat-user.xml
    <role rolename="manager"/>   
    <role rolename="manager-gui"/>

    <user username="admin" password="tomcat" roles="manager"/>

    posted @ 2015-01-09 09:32 云自無心水自閑 閱讀(667) | 評論 (0)編輯 收藏


    1. 自動掃描配置文件改動
    <configuration scan="true" scanPeriod="30 seconds">
    ....
    </configuration

    2. 日志每天歸檔,同時目錄名包含相應(yīng)的年份和月份
    <fileNamePattern>F:\Programs\GlobalPos\GatewayCiti\logs\%d{yyyy/MM,aux}\G%d{dd}-%i.log</fileNamePattern>
    注意其中aux的使用,在fileNamePatter中如果出現(xiàn)多個%d的情況下,只能有一個為主配置,其他都需要使用aux標(biāo)記為附屬配置
    其中的%i請參看下節(jié)的介紹

    3. 文件同時根據(jù)日期和大小滾動創(chuàng)建
            <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
                <!-- rollover daily -->
                <!-- 
                <fileNamePattern>F:\Programs\GlobalPos\NetReport\logs\Portal-%d{yyyyMMdd}.log</fileNamePattern>
                
    -->
                
                <!-- Size and time based archiving -->
                <fileNamePattern>D:\logs\%d{yyyy/MM,aux}\L%d{dd}-%i.log</fileNamePattern>
                <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
                    <maxFileSize>100MB</maxFileSize>
                </timeBasedFileNamingAndTriggeringPolicy>            
            </rollingPolicy>

    fileNamePattern在上一節(jié)已經(jīng)介紹,這里主要介紹timeBasedFileNamingAndTriggeringPolicy,此處配置對文件大小的限定,由fileNamePattern的%i在確定下標(biāo)在文件名中的位置
    此示例產(chǎn)生的日志文件將會是:
    D:\logs\2015\01\L05-0.log 
    如果該文件大于100M,就會生成D:\logs\2015\01\L05-1.log

    posted @ 2015-01-07 09:40 云自無心水自閑 閱讀(7365) | 評論 (0)編輯 收藏

    OpenPGP 號稱是世界上使用最廣泛的郵件加密標(biāo)準(zhǔn).  OpenPGP is the most widely used email encryption standard in the world. ( http://www.openpgp.org/ )
    這篇例子介紹如何使用這個標(biāo)準(zhǔn)進行文件的加密解密 (https://www.bouncycastle.org/latest_releases.html, 需要下載: bcprov-jdk15on-151.jar, bcpg-jdk15on-151.jar).

    主要是使用bouncycastle提供的OpenPGP的庫來完成這個功能,參照了其提供的示例程序,進行了部分改動 ( Bouncy Castle 是一種用于 Java 平臺的開放源碼的輕量級密碼術(shù)包。它支持大量的密碼術(shù)算法,并提供 JCE 1.2.1 的實現(xiàn)。因為 Bouncy Castle 被設(shè)計成輕量級的,所以從 J2SE 1.4 到 J2ME(包括 MIDP)平臺,它都可以運行。它是在 MIDP 上運行的唯一完整的密碼術(shù)包。)
    1. 添加循環(huán)遍歷來查找第一個可用的message
    2. 需要注意的是在main函數(shù)中的,如果不添加這一句的話 Security.addProvider(new BouncyCastleProvider()); 程序運行中會報錯:No such Provider "BC"
    3. 
    錯誤Exception in thread "main" java.security.InvalidKeyException: Illegal key size or default parameters , 這是因為java缺省的庫支持的key長度比較短,需要到oracle的網(wǎng)站上去下載一個支持更長key的庫覆蓋原有的庫文件
    <JAVA_HOME>/lib/securty/ 目錄下的兩個jar文件
    local_policy.jar and US_export_policy.jar
    搜索這個文件: Java Cryptography Extension (JCE) Unlimited Strength Jurisdiction Policy Files

    package org.bouncycastle.openpgp.examples;

    import java.io.BufferedInputStream;
    import java.io.BufferedOutputStream;
    import java.io.File;
    import java.io.FileInputStream;
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.io.InputStream;
    import java.io.OutputStream;
    import java.security.NoSuchProviderException;
    import java.security.SecureRandom;
    import java.security.Security;
    import java.util.Iterator;

    import org.bouncycastle.bcpg.ArmoredOutputStream;
    import org.bouncycastle.bcpg.CompressionAlgorithmTags;
    import org.bouncycastle.jce.provider.BouncyCastleProvider;
    import org.bouncycastle.openpgp.PGPCompressedData;
    import org.bouncycastle.openpgp.PGPEncryptedData;
    import org.bouncycastle.openpgp.PGPEncryptedDataGenerator;
    import org.bouncycastle.openpgp.PGPEncryptedDataList;
    import org.bouncycastle.openpgp.PGPException;
    import org.bouncycastle.openpgp.PGPLiteralData;
    import org.bouncycastle.openpgp.PGPOnePassSignatureList;
    import org.bouncycastle.openpgp.PGPPrivateKey;
    import org.bouncycastle.openpgp.PGPPublicKey;
    import org.bouncycastle.openpgp.PGPPublicKeyEncryptedData;
    import org.bouncycastle.openpgp.PGPSecretKeyRingCollection;
    import org.bouncycastle.openpgp.PGPSignatureList;
    import org.bouncycastle.openpgp.PGPUtil;
    import org.bouncycastle.openpgp.jcajce.JcaPGPObjectFactory;
    import org.bouncycastle.openpgp.operator.jcajce.JcaKeyFingerprintCalculator;
    import org.bouncycastle.openpgp.operator.jcajce.JcePGPDataEncryptorBuilder;
    import org.bouncycastle.openpgp.operator.jcajce.JcePublicKeyDataDecryptorFactoryBuilder;
    import org.bouncycastle.openpgp.operator.jcajce.JcePublicKeyKeyEncryptionMethodGenerator;
    import org.bouncycastle.util.io.Streams;

    /**
     * A simple utility class that encrypts/decrypts public key based
     * encryption files.
     * <p>
     * To encrypt a file: KeyBasedFileProcessor -e [-a|-ai] fileName publicKeyFile.<br>
     * If -a is specified the output file will be "ascii-armored".
     * If -i is specified the output file will be have integrity checking added.
     * <p>
     * To decrypt: KeyBasedFileProcessor -d fileName secretKeyFile passPhrase.
     * <p>
     * Note 1: this example will silently overwrite files, nor does it pay any attention to
     * the specification of "_CONSOLE" in the filename. It also expects that a single pass phrase
     * will have been used.
     * <p>
     * Note 2: if an empty file name has been specified in the literal data object contained in the
     * encrypted packet a file with the name filename.out will be generated in the current working directory.
     
    */
    public class KeyBasedFileProcessor
    {
        private static void decryptFile(
            String inputFileName,
            String keyFileName,
            char[] passwd,
            String defaultFileName)
            throws IOException, NoSuchProviderException
        {
            InputStream in = new BufferedInputStream(new FileInputStream(inputFileName));
            InputStream keyIn = new BufferedInputStream(new FileInputStream(keyFileName));
            decryptFile(in, keyIn, passwd, defaultFileName);
            keyIn.close();
            in.close();
        }

        /**
         * decrypt the passed in message stream
         
    */
        private static void decryptFile(
            InputStream in,
            InputStream keyIn,
            char[]      passwd,
            String      defaultFileName)
            throws IOException, NoSuchProviderException
        {
            in = PGPUtil.getDecoderStream(in);
            
            try
            {
                JcaPGPObjectFactory pgpF = new JcaPGPObjectFactory(in);
                PGPEncryptedDataList    enc;

                Object                  o = pgpF.nextObject();
                //
                
    // the first object might be a PGP marker packet.
                
    //
                if (o instanceof PGPEncryptedDataList)
                {
                    enc = (PGPEncryptedDataList)o;
                }
                else
                {
                    enc = (PGPEncryptedDataList)pgpF.nextObject();
                }
                
                //
                
    // find the secret key
                
    //
                Iterator                    it = enc.getEncryptedDataObjects();
                PGPPrivateKey               sKey = null;
                PGPPublicKeyEncryptedData   pbe = null;
                PGPSecretKeyRingCollection  pgpSec = new PGPSecretKeyRingCollection(
                    PGPUtil.getDecoderStream(keyIn), new JcaKeyFingerprintCalculator());

                while (sKey == null && it.hasNext())
                {
                    pbe = (PGPPublicKeyEncryptedData)it.next();
                    
                    sKey = PGPExampleUtil.findSecretKey(pgpSec, pbe.getKeyID(), passwd);
                }
                
                if (sKey == null)
                {
                    throw new IllegalArgumentException("secret key for message not found.");
                }
        
                InputStream         clear = pbe.getDataStream(new JcePublicKeyDataDecryptorFactoryBuilder().setProvider("BC").build(sKey));
                
                JcaPGPObjectFactory    plainFact = new JcaPGPObjectFactory(clear);
                
                Object              message = plainFact.nextObject();
        
                while ( true ) {
                    if (message instanceof PGPCompressedData)
                    {
                        PGPCompressedData   cData = (PGPCompressedData)message;
                        JcaPGPObjectFactory    pgpFact = new JcaPGPObjectFactory(cData.getDataStream());
                        
                        message = pgpFact.nextObject();
                    }
                    
                    if (message instanceof PGPLiteralData)
                    {
                        PGPLiteralData ld = (PGPLiteralData)message;

                        String outFileName = ld.getFileName();
                        if (outFileName.length() == 0)
                        {
                            outFileName = defaultFileName;
                        }

                        InputStream unc = ld.getInputStream();
                        OutputStream fOut = new BufferedOutputStream(new FileOutputStream(outFileName));

                        Streams.pipeAll(unc, fOut);

                        fOut.close();
                        break;
                    }
                    else if (message instanceof PGPOnePassSignatureList)
                    {
                        System.out.println("encrypted message contains a signed message - not literal data.");
                    }
                    else if (message instanceof PGPSignatureList)
                    {
                        System.out.println("encrypted message contains a signed message - not literal data.");
                    }
                    else
                    {
                        throw new PGPException("message is not a simple encrypted file - type unknown.");
                    }
                    message = plainFact.nextObject();
                }
                
                if (pbe.isIntegrityProtected())
                {
                    if (!pbe.verify())
                    {
                        System.err.println("message failed integrity check");
                    }
                    else
                    {
                        System.err.println("message integrity check passed");
                    }
                }
                else
                {
                    System.err.println("no message integrity check");
                }
            }
            catch (PGPException e)
            {
                System.err.println(e);
                if (e.getUnderlyingException() != null)
                {
                    e.getUnderlyingException().printStackTrace();
                }
            }
        }

        private static void encryptFile(
            String          outputFileName,
            String          inputFileName,
            String          encKeyFileName,
            boolean         armor,
            boolean         withIntegrityCheck)
            throws IOException, NoSuchProviderException, PGPException
        {
            OutputStream out = new BufferedOutputStream(new FileOutputStream(outputFileName));
            PGPPublicKey encKey = PGPExampleUtil.readPublicKey(encKeyFileName);
            encryptFile(out, inputFileName, encKey, armor, withIntegrityCheck);
            out.close();
        }

        private static void encryptFile(
            OutputStream    out,
            String          fileName,
            PGPPublicKey    encKey,
            boolean         armor,
            boolean         withIntegrityCheck)
            throws IOException, NoSuchProviderException
        {
            if (armor)
            {
                out = new ArmoredOutputStream(out);
            }

            try
            {
                byte[] bytes = PGPExampleUtil.compressFile(fileName, CompressionAlgorithmTags.ZIP);

                PGPEncryptedDataGenerator encGen = new PGPEncryptedDataGenerator(
                    new JcePGPDataEncryptorBuilder(PGPEncryptedData.CAST5).setWithIntegrityPacket(withIntegrityCheck).setSecureRandom(new SecureRandom()).setProvider("BC"));

                encGen.addMethod(new JcePublicKeyKeyEncryptionMethodGenerator(encKey).setProvider("BC"));

                OutputStream cOut = encGen.open(out, bytes.length);

                cOut.write(bytes);
                cOut.close();

                if (armor)
                {
                    out.close();
                }
            }
            catch (PGPException e)
            {
                System.err.println(e);
                if (e.getUnderlyingException() != null)
                {
                    e.getUnderlyingException().printStackTrace();
                }
            }
        }

        public static void main(
            String[] args)
            throws Exception
        {
            Security.addProvider(new BouncyCastleProvider());

            if (args.length == 0)
            {
                System.err.println("usage: KeyBasedFileProcessor -e|-d [-a|ai] file [secretKeyFile passPhrase|pubKeyFile]");
                return;
            }

            if (args[0].equals("-e"))
            {
                if (args[1].equals("-a") || args[1].equals("-ai") || args[1].equals("-ia"))
                {
                    encryptFile(args[2] + ".asc", args[2], args[3], true, (args[1].indexOf('i') > 0));
                }
                else if (args[1].equals("-i"))
                {
                    encryptFile(args[2] + ".bpg", args[2], args[3], falsetrue);
                }
                else
                {
                    encryptFile(args[1] + ".bpg", args[1], args[2], falsefalse);
                }
            }
            else if (args[0].equals("-d"))
            {
                decryptFile(args[1], args[2], args[3].toCharArray(), new File(args[1]).getName() + ".out");
            }
            else
            {
                System.err.println("usage: KeyBasedFileProcessor -d|-e [-a|ai] file [secretKeyFile passPhrase|pubKeyFile]");
            }
        }
    }


    asdf

    posted @ 2014-12-10 06:50 云自無心水自閑 閱讀(11804) | 評論 (5)編輯 收藏

     Netty作為一個異步非阻塞式的框架,是不允許在ChannelHandler中長時間處理事務(wù)(比如數(shù)據(jù)庫的操作),阻塞I/O的讀寫處理的。

    在Netty in Action中是這樣描述的:
    While the I/O thread must not be blocked at all, thus prohibiting any direct blocking operations within your ChannelHandler, there is a way to implement this requirement. 
    You can specify an EventExecutorGroup when adding ChannelHandlers to the ChannelPipeline. 
    This EventExecutorGroup will then be used to obtain an EventExecutor, which will execute all the methods of the ChannelHandler. 
    This EventExecutor will use a different thread from the I/O thread, thus freeing up the EventLoop.
    I/O線程是不允許被阻塞的,也就是不能在ChannelHandler中進行任何阻塞式的處理,但是對此我們也有相應(yīng)的解決方法.
    就是在把ChannelHanders添加到ChannelPipeline的時候,指定一個EventExecutorGroup,ChannelHandler中所有的方法都將會在這個指定的EventExecutorGroup中運行。
    而這個EVentExecutorGroup運行的線程與I/O線程不同,達到不阻塞I/O的目的。 
    程序示例如下:
    Channel ch = ...;
    ChannelPipeline p = ch.pipeline();
    EventExecutor e1 = new DefaultEventExecutorGroup(16);
    EventExecutor e2 = new DefaultEventExecutorGroup(8);
     
    p.addLast(new MyProtocolCodec());
    p.addLast(e1, new MyDatabaseAccessingHandler());
    p.addLast(e2, new MyHardDiskAccessingHandler());
    需要補充說明一下,上面的示例程序似乎有點問題。使用上述方法添加ChannelHandler到pipeline中以后,channelHandler的所有方法確實什么在一個單獨的線程中被處理。
    但是,每次DefaultEventExcutorGroup線程池中的線程不能被重用,每次都會生成一個新的線程,然后在新的線程中調(diào)用ChannelHandler, 在visualvm可以看到線程數(shù)量直線增長。

    解決的方法是:不能使用局部變量形式的DefaultEventExecutorGroup。而使用類靜態(tài)成員變量:
    static final EventExecutor e1 = new DefaultEventExecutorGroup(16);

    我分析原因可能是:在新的連接到來,創(chuàng)建ChannelPipeline給新Channel的時候,如果不使用靜態(tài)的共享變量,而使用局部變量的話,就造成DefaultEventExecutorGroup被多次重復(fù)創(chuàng)建。因此,雖然一個DefaultEventExecutorGroup中的Thread數(shù)量是固定的,但是卻產(chǎn)生了多余的DefaultEventExecutorGroup。從VisualVM中也可以看到,DefaultEventExecutorGroup線程的名字會是:
    xxx-2-1
    xxx-3-1
    xxx-4-1
    xxx-n-1
    說明是Group的數(shù)量(第一個數(shù)字)在增多,而不是Group中的線程數(shù)量(第二個數(shù)字)在增多
    改成靜態(tài)變量后,線程名會是:
    xxx-2-1
    xxx-2-2
    xxx-2-3
    xxx-2-n
    最后一個n就是在創(chuàng)建DefaultEventExecutorGroup時候,傳入的線程個數(shù)參數(shù)的大小。

    posted @ 2014-11-27 07:36 云自無心水自閑 閱讀(9864) | 評論 (0)編輯 收藏

    Netty
    1. there're 2 EventLoopGroup in netty, bossGroup and workerGroup, (1 implementation NioEventLoopGroup is a kind of thread pool)
    2. bossGroup is Acceptor,is responsible for creating Channels for incoming connection requests
    3. workerGroup is the Reactor/Selector?, handling I/O requests. 
    4. a thread in bossGroup will be listening in the port, Once a connection has been accepted workerGroup assigns an EventLoop to its Channel
    5. multiple channels can be registered into 1 EventLoop, multiple EventLoops will exist in workerGroup
    6. workerGroup will iterate all the EventLoop, and iterate all the channels in EventLoop, if any of the channel is ready to execute/process
    7. it will invoke all the channelHandlers in the channelPipeline
    8. ChannelPipelines are containers for chains of ChannelHandlers which executed in order
    9. There are, in fact, two ways of sending messages in Netty. You can write directly to the Channel or write to the ChannelHandlerContext object. The main difference is that the former approach causes the message to start from the tail of the ChannelPipeline, while the latter causes the message to start from the next handler in the ChannelPipeline.
    10. While the I/O thread must not be blocked at all, thus prohibiting any direct blocking operations within your ChannelHandler, there is a way to implement this requirement.
    You can specify an EventExecutorGroup when adding ChannelHandlers to the ChannelPipeline.
    This EventExecutorGroup will then be used to obtain an EventExecutor, which will execute all the methods of the ChannelHandler.
    This EventExecutor will use a different thread from the I/O thread, thus freeing up the EventLoop.

    Channel ch = ...;
    ChannelPipeline p = ch.pipeline();
    EventExecutor e1 = new DefaultEventExecutor(16);
    EventExecutor e2 = new DefaultEventExecutor(8);
     
    p.addLast(new MyProtocolCodec());
    p.addLast(e1, new MyDatabaseAccessingHandler());
    p.addLast(e2, new MyHardDiskAccessingHandler());

    http://stackoverflow.com/questions/12928723/netty-4-eventloopgroup-eventloop-eventexecutor-thread-affinity

    posted @ 2014-11-21 14:18 云自無心水自閑 閱讀(527) | 評論 (0)編輯 收藏

    http://denis.doublebuffer.net/lablog/2012/11/19/fixing-the-screen-flickering-on-a-dell-inspiron-n5720-and-maybe-many-others/
    A Dell Inspiron N5720 has a nVidia GT 630M and an Intel HD Graphics 4000. Let’s see what the Intel Graphics Control panel looks like. To open it, follow these instructions.
    Select Advanced mode.
    Go to the Power menu and change the power source to “On battery”. Now uncheck the little check box that says “Display Refresh Rate Switch”. Apply. OK. And you’re done.

    posted @ 2014-02-14 19:58 云自無心水自閑 閱讀(547) | 評論 (0)編輯 收藏

    Where are the Database Files Stored?

    When using database URLs like jdbc:h2:~/test, the database is stored in the user directory. For Windows, this is usually C:\Documents and Settings\<userName> or C:\Users\<userName>. If the base directory is not set (as in jdbc:h2:test), the database files are stored in the directory where the application is started (the current working directory). When using the H2 Console application from the start menu, this is<Installation Directory>/bin. The base directory can be set in the database URL. A fixed or relative path can be used. When using the URL jdbc:h2:file:data/sample, the database is stored in the directory data(relative to the current working directory). The directory is created automatically if it does not yet exist. It is also possible to use the fully qualified directory name (and for Windows, drive name). Example:jdbc:h2:file:C:/data/tes

    posted @ 2014-01-29 18:58 云自無心水自閑 閱讀(683) | 評論 (0)編輯 收藏

     在主動模式下,F(xiàn)TP客戶端隨機開啟一個大于1024的端口N向服務(wù)器的21號端口發(fā)起連接,然后開放N+1號端口進行監(jiān)聽,并向服務(wù)器發(fā)出PORT N+1命令。服務(wù)器接收到命令后,會用其本地的FTP數(shù)據(jù)端口(通常是20)來連接客戶端指定的端口N+1,進行數(shù)據(jù)傳輸。     
    在被動模式下,F(xiàn)TP庫戶端隨機開啟一個大于1024的端口N向服務(wù)器的21號端口發(fā)起連接,同時會開啟N+1號端口。然后向服務(wù)器發(fā)送PASV命令,通知服務(wù)器自己處于被動模式。服務(wù)器收到命令后,會開放一個大于1024的端口P進行監(jiān)聽,然后用PORT P命令通知客戶端,自己的數(shù)據(jù)端口是P??蛻舳耸盏矫詈?,會通過N+1號端口連接服務(wù)器的端口P,然后在兩個端口之間進行數(shù)據(jù)傳輸。    
     總的來說,主動模式的FTP是指服務(wù)器主動連接客戶端的數(shù)據(jù)端口,被動模式的FTP是指服務(wù)器被動地等待客戶端連接自己的數(shù)據(jù)端口。     

    被動模式的FTP通常用在處于防火墻之后的FTP客戶訪問外界FTp服務(wù)器的情況,因為在這種情況下,防火墻通常配置為不允許外界訪問防火墻之后主機,而只允許由防火墻之后的主機發(fā)起的連接請求通過。
    因此,在這種情況下不能使用主動模式的FTP傳輸,而被動模式的FTP可以良好的工作。

     Standard模式FTP 客戶端首先和FTP Server的TCP 21端口建立連接,通過這個通道發(fā)送命令,客戶端需要接收數(shù)據(jù)的時候在這個通道上發(fā)送PORT命令。 PORT命令包含了客戶端用什么端口接收數(shù)據(jù)。
    在傳送數(shù)據(jù)的時候,服務(wù)器端通過自己的TCP 20端口發(fā)送數(shù)據(jù)。 FTP server必須和客戶端建立一個新的連接用來傳送數(shù)據(jù)。     
     Passive模式在建立控制通道的時候和Standard模式類似,當(dāng)客戶端通過這個通道發(fā)送PASV 命令的時候,F(xiàn)TP server打開一個位于1024和5000之間的隨機端口并且通知客戶端在這個端口上傳送數(shù)據(jù)的請求, 然后FTP server 將通過這個端口進行數(shù)據(jù)的傳送,這個時候FTP server不再需要建立一個新的和客戶端之間的連接。 

    posted @ 2014-01-28 08:54 云自無心水自閑 閱讀(585) | 評論 (0)編輯 收藏


    java.awt.Desktop is the class you're looking for.

    import java.awt.Desktop; 
    import java.net.URI;
    // ...
    if(Desktop.isDesktopSupported()) {
    Desktop.getDesktop().browse(new URI("http://www.example.com"));
    }


    If you're using Java 6 or above, see the Desktop API, in particular browse. Use it like this (not tested):

    // using this in real life, you'd probably want to check that the desktop
    // methods are supported using isDesktopSupported()...
    
    String htmlFilePath = "path/to/html/file.html"; // path to your new file
    File htmlFile = new File(htmlFilePath);
    
    // open the default web browser for the HTML page
    Desktop.getDesktop().browse(htmlFile.toURI());
    
    // if a web browser is the default HTML handler, this might work too
    Desktop.getDesktop().open(htmlFile);

    posted @ 2014-01-27 21:09 云自無心水自閑 閱讀(414) | 評論 (0)編輯 收藏

    例子:
    java -cp bin;lib/* org.kevin.task.RunJobA f:\temp\jobs


    1.路徑中需要使用/,而不是\\,
    2.只能用一個*,不需要添加后綴, 

    posted @ 2013-12-09 14:22 云自無心水自閑 閱讀(468) | 評論 (0)編輯 收藏

    P66
    1. components:
        a. Message
            a.1 Header
    a.1.1 Destination
    a.1.2 DeliveryMode: persistent, non-persistent
    a.2 Body
        b. Queue
        c. Client
            c.1 Producer
            c.2 Consumer - Message Selector
    d. Domain, 2 styles of messaging
    d.1 point-to-point
    d.1.1 destination known as QUEUE
    d.1.2 similar to person to person email sent through a mail server
    d.1.3 multiple consumers can be registered on a single queue
    but only one consumer will receive a a given messge 
    and it's upt to that consumer to acknowledge the message
    d.2 publish-subscribe
    d.2.1 destination known as TOPICS
    d.2.2 publishers send messages to the topic 
    and subscribers register to receive messages from the topic
    d.2.3 durable subscriptions allow for subscriber disconnection without missing any messages

    posted @ 2013-10-14 20:35 云自無心水自閑 閱讀(497) | 評論 (0)編輯 收藏

    最近在開發(fā)中遇到一個問題,就是如何判斷遠(yuǎn)端服務(wù)器是否已經(jīng)斷開連接,如果斷開那么需要重新連接。 

    首先想到socket類的方法isClosed()、isConnected()、isInputStreamShutdown()、isOutputStreamShutdown()等,但經(jīng)過試驗并查看相關(guān)文檔,這些方法都是本地端的狀態(tài),無法判斷遠(yuǎn)端是否已經(jīng)斷開連接。 

    然后想到是否可以通過OutputStream發(fā)送一段測試數(shù)據(jù),如果發(fā)送失敗就表示遠(yuǎn)端已經(jīng)斷開連接,類似ping,但是這樣會影響到正常的輸出數(shù)據(jù),遠(yuǎn)端無法把正常數(shù)據(jù)和測試數(shù)據(jù)分開。 

    最后又回到socket類,發(fā)現(xiàn)有一個方法sendUrgentData,查看文檔后得知它會往輸出流發(fā)送一個字節(jié)的數(shù)據(jù),只要對方Socket的SO_OOBINLINE屬性沒有打開,就會自動舍棄這個字節(jié),而SO_OOBINLINE屬性默認(rèn)情況下就是關(guān)閉的,太好了,正是我需要的! 

    于是,下面一段代碼就可以判斷遠(yuǎn)端是否斷開了連接: 

    Java代碼  收藏代碼
    1. try{  
    2.       socket.sendUrgentData(0xFF);  
    3. }catch(Exception ex){  
    4.       reconnect();  
    5. }  

    posted @ 2013-08-15 20:09 云自無心水自閑 閱讀(2690) | 評論 (0)編輯 收藏

    主站蜘蛛池模板: www.免费在线观看| 每天更新的免费av片在线观看 | 中国性猛交xxxxx免费看| 成人亚洲综合天堂| 中国内地毛片免费高清| 亚洲一区精品伊人久久伊人| 日本一区二区在线免费观看| 99热这里有免费国产精品| 亚洲精品字幕在线观看| 嫩草在线视频www免费观看| 亚洲成色在线影院| 亚洲美女视频免费| 亚洲日韩中文字幕一区| 波多野结衣视频在线免费观看| 一区二区三区精品高清视频免费在线播放| 亚洲精品免费网站| 亚洲欧洲免费无码| 亚洲国产精品综合久久网络| a级成人免费毛片完整版| 久久水蜜桃亚洲av无码精品麻豆| 久久w5ww成w人免费| 中文字幕在线日亚洲9| 免费国产不卡午夜福在线| 久久久久久av无码免费看大片| 国产v亚洲v天堂无码网站| 7x7x7x免费在线观看| 亚洲欧美黑人猛交群| 亚洲乱码日产精品a级毛片久久| 怡红院免费全部视频在线视频| 亚洲黄色网址大全| 四虎永久在线精品免费影视 | 日本一区二区三区在线视频观看免费 | 亚洲网站在线免费观看| 成av免费大片黄在线观看| 亚洲最新永久在线观看| 成人免费在线视频| 中文字幕免费在线看线人动作大片| 久久亚洲中文字幕精品有坂深雪 | 在线观看片免费人成视频播放| 亚洲日韩在线视频| 免费人成视频在线观看不卡|