<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)系 :: 聚合  :: 管理

    2014年12月10日

    1. java zip 多個文件時,如果先添加了一個excel文件,然后再想添加其他的文件時會出現(xiàn) steam is closed的錯誤。這是因?yàn)閣ork.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視圖中,右鍵點(diǎn)擊項(xiàng)目,選擇屬性,然后修改url中的地址

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

    autohotkey
    listary
    cmder可以split screen,在一個窗口中同時運(yùn)行數(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ù)類型強(qiáng)制轉(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、以管理員身份打開命令行窗口,運(yùn)行
    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.
    這是因?yàn)閙2eclipse(maven插件)要在啟動時需要進(jìn)行的一個步驟。

    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都可以實(shí)現(xiàn)這個功能,但是從pdf提取文本的一個問題是,提取出來的文本沒有固定的順序,不容易比較好的還原其格式。

    我的做法是使用pdfclown來進(jìn)行這項(xiàng)工作。官方網(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, 這樣點(diǎn)擊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

    后來才知道這是因?yàn)閿?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 主要用于查看渲染出的頁面中的信息(比如:表單項(xiàng)的名稱,節(jié)點(diǎn)ID等等)
    Burp Suite 主要用于動態(tài)攔截頁面的交互,查看Ajax的調(diào)用。
    HttpClient 用于最后程序的編制。搞清楚了網(wǎng)頁交互的過程,就可以自主決定程序需要包含的內(nèi)容。
    在實(shí)際網(wǎng)頁中,可能需要點(diǎn)開數(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 快很多。因?yàn)樗鼤С郑簭倪h(yuǎn)程胳快速加載、離線編譯以便于更快啟動、以及超快的變動檢測和為使?jié)L動更平滑的視圖緩存等等。

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

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

    4. 無縫從 AngularJS 1 升級到 2

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

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

    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)換。
    右鍵點(diǎ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)原因是因?yàn)闆]有加入commons-logging的jar文件

    幾個注意點(diǎn):
    1. commons dbcp2.x 和 commons pool需要同時升到2.x
    2. dbcp 2.x要運(yùn)行在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下載文件,其中確實(shí)有幾篇文件介紹了實(shí)現(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寫到一個文件中,就實(shí)現(xiàn)了文件下載的目的

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

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

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

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

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

    2。拷貝jcif-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)是不能成功修改表單的值的。
    因?yàn)榇藭rajaxForm已經(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 = '新的值';
                    }
                }
            }
        });
    需要使用這種方式進(jìn)行修改。

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

    今天在運(yùn)行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
    解壓,運(yùn)行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)編輯 收藏

         摘要: 解壓/生成有密碼保護(hù)的壓縮文件, 研發(fā)過程中,作者研究了壓縮文件格式文檔: http://www.pkware.com/documents/casestudies/APPNOTE.TXT,并且參考了7-zip的實(shí)現(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. 枚舉實(shí)現(xiàn)的單例
    4. 選擇參數(shù)值做為函數(shù)的返回值
    5. 在調(diào)用mock出來的方法中,改變方法參數(shù)的值

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

    1. mock構(gòu)造函數(shù), 如果有代碼沒有使用DI注入依賴實(shí)例,在單元測試中可以使用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)建實(shí)例。
    @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);
             
          // 進(jìn)行驗(yàn)證
          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ù)的例子。 注意要點(diǎn)與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枚舉實(shí)現(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之后,提供一個方便的方法來實(shí)現(xiàn)這個需要,在這之前可以使用一個匿名函數(shù)來返回一個answer來實(shí)現(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其實(shí)已經(jīng)自帶一定程度的熱加載功能,但是如果你修改了類名,方法名,或者添加了新類,新方法的話。
    Tomcat都需要重新啟動來使得剛才的更改生效。
    而JRebel和springloaded都能有效地解決這個問題。其中springloaded是開源軟件,可以免費(fèi)使用,尤其難得。
    其主頁:https://github.com/spring-projects/spring-loaded
    在官方頁面的簡單介紹中,作者只講述了如何在java程序中應(yīng)用springloaded,而沒有說明如何在tomcat中進(jìn)行配置。
    本文將簡要進(jìn)行介紹。

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

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

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

    java wrapper是一個可以用于將java應(yīng)用程序包裝成windows服務(wù)的工具。
    并且可以通過簡單的配置來允許使用visualVM進(jìn)行監(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一項(xiàng)中輸入: localhost:9898 即可。

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

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

    在一些歷史遺留代碼中,會用到j(luò)ava.util.logging. 如果在新的項(xiàng)目中引用了這些代碼,而又不希望去一個一個的修改原來的代碼。
    可以使用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();

    注意事項(xiàng):
    1、這個橋接可以會造成性能問題。
    和其他的橋接實(shí)現(xiàn)(比如:log4j, commons logging)不同,這個模塊并不真正的完全替代java.util.logging類,因?yàn)檫@個java.util.logging是java自帶的。
    所以只是把原來的日志對象進(jìn)行了轉(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中是一個非常重要的存在。它提供了強(qiáng)大的功能和便利性。

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

    2。它避免了其它框架的嵌套回調(diào)函數(shù)的缺點(diǎn)。
    -所有異步任務(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ù)的運(yùn)行結(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àng)。我們現(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ù)名稱)添加了一個依賴項(xiàng)。當(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è)計(jì)思想就是不要在函數(shù)中自己去實(shí)例化或者通過其它途徑來獲取服務(wù)的實(shí)例,而是聲明需要的對象,由AngularJS來注入具體的實(shí)例。

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

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

    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ù)鍵值進(jìn)行排序。
    b. 一些自帶的變量,$first(是否是第一個), $last(是否是最后一個), $middle(是否是中間的), $index(下標(biāo),根據(jù)鍵值排序后的下標(biāo)), $even, $odd
    08. 自己定義新變量時不要使用$$開頭。
    09. 可以使用track-by表達(dá)式來優(yōu)化對DOM的操作,對DOM對象使用從數(shù)據(jù)庫取得的ID來進(jìn)行標(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ù)集中到一個對象的方式來進(jìn)行數(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ù),前面的元素用字符串的形式指定其需要的依賴項(xiàng)。如果沒有依賴項(xiàng),那就只需要定義函數(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虛擬機(jī)規(guī)范規(guī)定JVM的內(nèi)存分為了好幾塊,比如堆,棧,程序計(jì)數(shù)器,方法區(qū)等,而Hotspot jvm的實(shí)現(xiàn)中,將堆內(nèi)存分為了三部分,新生代,老年代,持久帶,其中持久帶實(shí)現(xiàn)了規(guī)范中規(guī)定的方法區(qū),而內(nèi)存模型中不同的部分都會出現(xiàn)相應(yīng)的OOM錯誤,接下來我們就分開來討論一下。 

    棧溢出(StackOverflowError) 

    棧溢出拋出java.lang.StackOverflowError錯誤,出現(xiàn)此種情況是因?yàn)榉椒ㄟ\(yùn)行的時候棧的深度超過了虛擬機(jī)容許的最大深度所致。 

    出現(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. }  

    運(yùn)行上面的代碼,會拋出如下的異常: 
    引用

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

    堆溢出(OutOfMemoryError:java heap space) 

    堆內(nèi)存溢出的時候,虛擬機(jī)會拋出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)存大于了我們給虛擬機(jī)配置的內(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. }  

    我們通過如下的命令運(yùn)行上面的代碼: 

    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) 

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

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

    持久帶溢出(OutOfMemoryError: PermGen space) 

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

    1.使用一些應(yīng)用服務(wù)器的熱部署的時候,我們就會遇到熱部署幾次以后發(fā)現(xiàn)內(nèi)存溢出了,這種情況就是因?yàn)槊看螣岵渴鸬暮螅瓉淼腸lass沒有被卸載掉。 
    2.如果應(yīng)用程序本身比較大,涉及的類庫比較多,但是我們分配給持久帶的內(nèi)存(通過-XX:PermSize和-XX:MaxPermSize來設(shè)置)比較小的時候也可能出現(xiàn)此種問題。 
    3.一些第三方框架,比如spring,hibernate都通過字節(jié)碼生成技術(shù)(比如CGLib)來實(shí)現(xiàn)一些增強(qiáng)的功能,這種情況可能需要更大的方法區(qū)來存儲動態(tài)生成的Class文件。 
    我們知道Java中字符串常量是放在常量池中的,String.intern()這個方法運(yùn)行的時候,會檢查常量池中是否存和本字符串相等的對象,如果存在直接返回對常量池中對象的引用,不存在的話,先把此字符串加入常量池,然后再返回字符串的引用。那么我們就可以通過String.intern方法來模擬一下運(yùn)行時常量區(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. }  

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

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

    通過上面的代碼,我們成功模擬了運(yùn)行時常量池溢出的情況,從輸出中的PermGen space可以看出確實(shí)是持久帶發(fā)生了溢出,這也驗(yàn)證了,我們前面說的Hotspot jvm通過持久帶來實(shí)現(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來查看此限制。 
    給虛擬機(jī)分配的內(nèi)存過大,導(dǎo)致創(chuàng)建線程的時候需要的native內(nèi)存太少。我們都知道操作系統(tǒng)對每個進(jìn)程的內(nèi)存是有限制的,我們啟動Jvm,相當(dāng)于啟動了一個進(jìn)程,假如我們一個進(jìn)程占用了4G的內(nèi)存,那么通過下面的公式計(jì)算出來的剩余內(nèi)存就是建立線程棧的時候可以用的內(nèi)存。 線程棧總可用內(nèi)存=4G-(-Xmx的值)- (-XX:MaxPermSize的值)- 程序計(jì)數(shù)器占用的內(nèi)存 通過上面的公式我們可以看出,-Xmx 和 MaxPermSize的值越大,那么留給線程棧可用的空間就越小,在-Xss參數(shù)配置的棧容量不變的情況下,可以創(chuàng)建的線程數(shù)也就越小。因此如果是因?yàn)檫@種情況導(dǎo)致的unable to create native thread,那么要么我們增大進(jìn)程所占用的總內(nèi)存,或者減少-Xmx或者-Xss來達(dá)到創(chuàng)建更多線程的目的。

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

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

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

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

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

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

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

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

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

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

      因?yàn)?4K 和 8K 是限定了像素點(diǎn)的多少,而 Retina 是要求正常距離看不到像素點(diǎn)。

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

          可是如果給你一臺 500 寸的巨大屏幕,那么即便是 8K 也會到處是馬賽克,這時 Retina 觀感依然是高清無像素點(diǎn),必然比 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)進(jìn)行文件的加密解密 (https://www.bouncycastle.org/latest_releases.html, 需要下載: bcprov-jdk15on-151.jar, bcpg-jdk15on-151.jar).

    主要是使用bouncycastle提供的OpenPGP的庫來完成這個功能,參照了其提供的示例程序,進(jìn)行了部分改動 ( Bouncy Castle 是一種用于 Java 平臺的開放源碼的輕量級密碼術(shù)包。它支持大量的密碼術(shù)算法,并提供 JCE 1.2.1 的實(shí)現(xiàn)。因?yàn)?Bouncy Castle 被設(shè)計(jì)成輕量級的,所以從 J2SE 1.4 到 J2ME(包括 MIDP)平臺,它都可以運(yùn)行。它是在 MIDP 上運(yùn)行的唯一完整的密碼術(shù)包。)
    1. 添加循環(huán)遍歷來查找第一個可用的message
    2. 需要注意的是在main函數(shù)中的,如果不添加這一句的話 Security.addProvider(new BouncyCastleProvider()); 程序運(yùn)行中會報錯:No such Provider "BC"
    3. 
    錯誤Exception in thread "main" java.security.InvalidKeyException: Illegal key size or default parameters , 這是因?yàn)閖ava缺省的庫支持的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)編輯 收藏

    主站蜘蛛池模板: 亚洲一区二区三区免费| 黄色一级视频免费| 亚洲精品乱码久久久久久蜜桃图片| 亚洲熟妇av午夜无码不卡| 白白色免费在线视频| 久久久久久av无码免费看大片| 久久免费线看线看| 无码国产精品一区二区免费式直播| 在线免费观看中文字幕| 亚洲av无码成人精品区| 亚洲AV无码欧洲AV无码网站| 亚洲国产成人精品无码区在线秒播 | 国产在亚洲线视频观看| 黄色网页在线免费观看| 久久久久久毛片免费播放| 成年女人毛片免费播放视频m| 亚洲国产精品无码久久九九| 亚洲AV永久无码精品水牛影视| 亚洲videos| 一级做性色a爰片久久毛片免费| 最近免费视频中文字幕大全| 免费高清av一区二区三区| 中文字幕亚洲电影| 亚洲导航深夜福利| 一区二区免费国产在线观看 | 国产免费观看a大片的网站| 在线观看午夜亚洲一区| 亚洲av永久无码精品三区在线4 | 最近中文字幕大全中文字幕免费| 免费看大美女大黄大色| 亚洲αv久久久噜噜噜噜噜| 亚洲日韩国产AV无码无码精品| 国产免费黄色无码视频| 中文字幕无码不卡免费视频| 亚洲精品无码成人片在线观看| 中文字幕在线观看亚洲| 永久免费精品影视网站| 免费毛片a在线观看67194| 奇米影视亚洲春色| 久久久久亚洲国产| 日韩电影免费在线观看|