Total Pageviews

2016/08/01

[閱讀筆記] Security Analysis (Part 2)


  1. 對於Security Analysis來說,不能假設過去已經發生的事實,未來也會重複發生,這些事實只能當做是預測未來的rough index
  2. An investment is a successful speculation and a speculation is an unsuccessful investment
  3. 投資vs投機的例子:債券與股票;現金購買與融資;長期持有與短期持有;investment for income與 investment for profit;安全的標的與高風險標的
  4. 雖說債券較安全,被歸屬於投資的類別,但這不是絕對的,如垃圾債券就屬於投機,高評等的企業的股票則屬於投資
  5. 投資的行為是經過分析,了解投資標的的風險,並訂定合理的收益。如果你的行為不滿足以上條件,就稱之為投機
  6. 不要以為債券一定是安全,債券的安全與否,完全取決於債權公司是否有能力履行合約,若因某些因素導致違約,你手上的債券也會造成重大損失
  7. 證券可以分成幾類:固定價值型態的證券(如高評等債券或優先股)、變動價值型態的證券(如較安全與有獲利前景的高評等可轉換債券、如風險較高的低評等債券或優先股)、普通股
  8. 假設本金有實質風險,高票面利率(coupon rate)未必能補償你所冒的風險,如高收益債券
  9. 評斷投資成果,應該要看的是預期回報與預期風險之間的關係
  10. bond selection 是一門負面的藝術(negative art),其成功之鑰是:盡力避免成為loser,而不是一直汲汲營營想要成為winner
  11. 購買高收益債券(high yield bond)的投資組合,必須要聚焦於B-rated評等以上的債券,相較於低評等的債券,高評等債券的收益或許比較差,但是也限制了其違約的風險,大幅降低了不確定性
  12. 一家公司的credit risk(信用風險),源自於其財務槓桿操作與不穩定性。若公司是有限度的操作財務槓桿與擁有溫和的債務需求,這類的公司由於有較穩定的cash flow,故可以從激烈的上下波動中存活下來
  13. interest converge (利息覆蓋率 = EBITDA÷利息支出),用來衡量公司產生的稅前利潤能否支付當期利息的指標。利息覆蓋率是一個風險提示指標,特別是在公司經歷業績低谷,自由現金流脆弱的時期更為關鍵,當該比率低於2.5時就要注意
  14. 當一家公司的債務多到與其資產不成比例時,即便是規模很大的公司,體質也會很脆弱
  15. 記得定期檢視你的投資組合. There are no permanent investments !
  16. 不要妄想去抓market timing,也不要去預測利率變動。你應該把你的力氣花在知道你所能知道的,如瞭解產業、企業、風險等等
  17. 除非你已經做好多元化配置,不然你不要去投資高收益債券 (high yield bonds)
  18. 安全的價位不是透過精密的數學計算所計算出來的,其仰賴市場的受歡迎度來決定
  19. 投資的風險就像火災與傳染病一樣,對於火險與壽險來說,都是非常特殊且難以計算的因素
  20. 棒球打者錯失三個好球,就會被判出局。但投資人錯失無數個投資機會也不會受到懲罰
  21. 一家公司的cash flow stability 很重要,其攸關這家公司在逆境時,是否有能力去處理債務
  22. Bond Selection的主要目標是避免損失,其過程是一個負面的藝術,他是一個排除與拒絕的過程,而不是搜尋與接受的過程
  23. Bond Selection的safety,取決於發行債券的公司是否能履約,而不是衡量其抵押品或合約
  24. Bond Selection時,你要衡量的是在大蕭條時期的存活能力,而不是看景氣好的時候
  25. Bond Selection的時候要注意,高票面利率(coupon rate)是無法彌補風險的
  26. 當所購買的債券公司違約時,投資人很難透過抵押權來彌補投資損失,因為當公司經營失敗,其所抵押的資產價值會大幅縮水;債權人很難主張其所有擁有的法律權益;以及受到財務管理人的拖延
  27. 挑選債券的時候,基本原則是"避免trouble",而不是試圖在touble中保護自己
  28. 沒有產業可以完全不受不景氣的影響
  29. 債券價格崩盤,很多時候原因並不是營收消失此原因,其主因都是其無力負擔過度擴張的債務所導致
  30. 根據歷史數據顯示,中小型企業不具備穩定的獲利能力,故不適合考慮作為fixed-value investments的投資標的
  31. 投資的錯誤範例是:如果你有錢投資,那就去投資,但是當你找不到好的、安全的投資標的,那你就去買次一等級的投資標的
  32. 巴菲特認為:「一些垃圾債券發行方的管理層本身就是以欺騙為目的在發行垃圾債券。華爾街只關注發行垃圾債券能帶來多少收入,而不關心垃圾債券的後果;一些垃圾債券的買家又從不思考。所以二者一拍即合。」
  33. 作為一個謹慎的、智慧型投資者,你寧可選擇一個最好的債券(即便其收益率較不吸引人),也不要因為較高的票面利率的吸引,去購買次等級的債券,將自己的本金暴露於風險之下
  34. 根據幾次大蕭條的歷史紀錄顯示,即便是擁有良好記錄的公司,也是不可靠的,尤其是中小型企業。故挑選時要符合兩個條件:(1) 挑選績優的大型企業 ;(2) 實質獲利率大於債券利息
  35. 債券與利率的關係,與保險費率類似,其根據風險等級來計算費率。高收益與低收益的回報基本上是相等的,高收益投資的收入會有較大的本金損失的風險,低收益的投資收入的本金損失風險也較低

2016/07/31

[Travel] Kobe (神戶)

風見鶏の館
DSC09798




Starbucks Coffee 神戸北野異人館店
DSC09804

DSC09809



神戶牛
DSC09823



神戸港 Kobe Port
DSC09824

DSC09838

DSC09854

2016/07/09

[PDFBox] No ImageWriter found for 'tif' format in WebSphere

Problem
As I try to convert PDF to TIF via PDFBox in WebSphere 8, I got the error message during the conversion process:
1
2
[Line:198][org.apache.pdfbox.tools.imageio.ImageIOUtil.writeImage]No ImageWriter found for 'tif' format
[Line:206][org.apache.pdfbox.tools.imageio.ImageIOUtil.writeImage]Supported formats: BMP bmp jpg JPG wbmp jpeg png PNG JPEG WBMP GIF gif 


Lacking of jai-imageio-core jar file in your classpath must get this error message.
But I have add jai-imageio-core dependency in pom.xml.
Snippet of pom.xml looks like:
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
<!-- for generating tif file -->
<dependency>
    <groupId>org.apache.pdfbox</groupId>
    <artifactId>pdfbox-tools</artifactId>
    <version>2.0.0</version>
</dependency>

<dependency>
    <groupId>com.github.jai-imageio</groupId>
    <artifactId>jai-imageio-core</artifactId>
    <version>1.3.1</version>
</dependency>

Therefore, I try to print log to figure out the weird problem:
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
 try {
     Enumeration<URL> urls = Thread.currentThread().getContextClassLoader()
             .getResources("META-INF/services/javax.imageio.spi.ImageWriterSpi");
     while (urls.hasMoreElements()) {
         log.info("[convertToTiff] url = " + urls.nextElement().toString());
     }
 
 } catch (IOException e1) {
     e1.printStackTrace();
     throw new RuntimeException(e1);
 }

 The jar file exists in my ear file ! What happened?
1
 [convertToTiff] url = wsjar:file:/usr/IBM/WebSphere/AppServer/profiles/AppSrv03/installedApps/FDCSRA205Node03Cell/yuantalife-ecp-manage.ear/yuantalife-ecp-manage-war-0.1.0-SNAPSHOT.war/WEB-INF/lib/jai-imageio-core-1.3.1.jar!/META-INF/services/javax.imageio.spi.ImageWriterSpi

Here is my source code:
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
package albert.practice.file;

import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.util.Enumeration;

import javax.imageio.ImageIO;

import lombok.extern.slf4j.Slf4j;

import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.rendering.ImageType;
import org.apache.pdfbox.rendering.PDFRenderer;
import org.apache.pdfbox.tools.imageio.ImageIOUtil;

@Slf4j
public class PdfFileToTif {

    private final float dpi = 300f;

    public static void main(String[] args) {
        File pdfFile = new File("D:\\dropbox\\Getting Started.pdf");
        String destination = "D:\\dropbox\\";

        PdfFileToTif test = new PdfFileToTif();
        test.checkImageIoJarFile();
        test.convertPdfToTif(pdfFile, destination);
    }

    public void convertPdfToTif(File pdfFile, String destination) {
        if (!isFileExisted(pdfFile)) {
            throw new RuntimeException("File not found ! (" + pdfFile.getAbsolutePath() + ")");
        }

        String pdfFileName = pdfFile.getName();

        try {
            // load PDF document
            PDDocument document = PDDocument.load(pdfFile);

            // create PDF renderer
            PDFRenderer renderer = new PDFRenderer(document);

            // go through each page of PDF, and generate TIF for each PDF page.
            for (int i = 0; i < document.getNumberOfPages(); i++) {
                // Returns the given page as an RGB image with 300 DPI.
                BufferedImage image = renderer.renderImageWithDPI(i, dpi, ImageType.BINARY);

                // Assign the file name of TIF
                String fileName = pdfFileName + "_" + String.format("%02d", i + 1);
                log.debug("Generating  " + fileName + ".tif to " + destination);

                // Writes a buffered image to a file using the given image format.
                ImageIOUtil.writeImage(image, destination + fileName + ".tif", Math.round(dpi));
                image.flush();
            }
            log.debug("PDF to TIF conversion well done!");
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 判斷檔案是否存在
     * 
     * @param file
     * @return true - 檔案存在; false - 檔案不存在
     */
    private Boolean isFileExisted(File file) {
        Boolean isExisted = Boolean.FALSE;
        isExisted = (file.exists() && (!file.isDirectory()));
        return isExisted;
    }

    private void checkImageIoJarFile() {
        try {
            Enumeration<URL> urls = Thread.currentThread().getContextClassLoader()
                    .getResources("META-INF/services/javax.imageio.spi.ImageWriterSpi");
            while (urls.hasMoreElements()) {
                log.info("[convertToTiff] urls = " + urls.nextElement().toString());
            }

        } catch (IOException e1) {
            e1.printStackTrace();
            throw new RuntimeException(e1);
        }
    }
}


How-to
The root cause is not so clear. It may results from WebSphere's classloading problem.
Hence, I find an API to scans for plug-ins on the application class path, loads their service provider classes, and registers a service provider instance for each one found with the IIORegistry. This strange problem had been resolved as I add ImageIO.scanForPlugins();

Here is my updated source code (Line46):
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
package albert.practice.file;

import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.util.Enumeration;

import javax.imageio.ImageIO;

import lombok.extern.slf4j.Slf4j;

import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.rendering.ImageType;
import org.apache.pdfbox.rendering.PDFRenderer;
import org.apache.pdfbox.tools.imageio.ImageIOUtil;

@Slf4j
public class PdfFileToTif {

    private final float dpi = 300f;

    public static void main(String[] args) {
        File pdfFile = new File("D:\\dropbox\\Getting Started.pdf");
        String destination = "D:\\dropbox\\";

        PdfFileToTif test = new PdfFileToTif();
        test.checkImageIoJarFile();
        test.convertPdfToTif(pdfFile, destination);
    }

    public void convertPdfToTif(File pdfFile, String destination) {
        if (!isFileExisted(pdfFile)) {
            throw new RuntimeException("File not found ! (" + pdfFile.getAbsolutePath() + ")");
        }

        String pdfFileName = pdfFile.getName();

        try {
            // load PDF document
            PDDocument document = PDDocument.load(pdfFile);

            // Scans for plug-ins on the application class path, loads their service provider
            // classes, and registers a service provider instance for each one found with the
            // IIORegistry.
            ImageIO.scanForPlugins();

            // create PDF renderer
            PDFRenderer renderer = new PDFRenderer(document);

            // go through each page of PDF, and generate TIF for each PDF page.
            for (int i = 0; i < document.getNumberOfPages(); i++) {
                // Returns the given page as an RGB image with 300 DPI.
                BufferedImage image = renderer.renderImageWithDPI(i, dpi, ImageType.BINARY);

                // Assign the file name of TIF
                String fileName = pdfFileName + "_" + String.format("%02d", i + 1);
                log.debug("Generating  " + fileName + ".tif to " + destination);

                // Writes a buffered image to a file using the given image format.
                ImageIOUtil.writeImage(image, destination + fileName + ".tif", Math.round(dpi));
                image.flush();
            }
            log.debug("PDF to TIF conversion well done!");
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 判斷檔案是否存在
     * 
     * @param file
     * @return true - 檔案存在; false - 檔案不存在
     */
    private Boolean isFileExisted(File file) {
        Boolean isExisted = Boolean.FALSE;
        isExisted = (file.exists() && (!file.isDirectory()));
        return isExisted;
    }

    private void checkImageIoJarFile() {
        try {
            Enumeration<URL> urls = Thread.currentThread().getContextClassLoader()
                    .getResources("META-INF/services/javax.imageio.spi.ImageWriterSpi");
            while (urls.hasMoreElements()) {
                log.info("[convertToTiff] urls = " + urls.nextElement().toString());
            }

        } catch (IOException e1) {
            e1.printStackTrace();
            throw new RuntimeException(e1);
        }
    }
}




Reference 
[1] http://stackoverflow.com/questions/17178591/how-to-add-tiff-imagereader-to-those-registered-in-grails

2016/07/08

[JavaMail] How to send email via Microsoft Exchange Server?

Problem
I am using JavaMail to write program to send email via Microsoft Exchange Server. How to do it?

How-to
The sample code looks like:
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
package albert.practice.mail;

import java.io.File;
import java.util.Properties;

import javax.mail.MessagingException;
import javax.mail.internet.MimeMessage;

import lombok.extern.slf4j.Slf4j;

import org.springframework.core.io.FileSystemResource;
import org.springframework.mail.javamail.JavaMailSenderImpl;
import org.springframework.mail.javamail.MimeMessageHelper;

import albert.practice.mail.params.EmailParams;

@Slf4j
public class ExchangeServerMailTest {

    public static void main(String[] args) {
        // set email parameters
        EmailParams params = new EmailParams();
        params.setReceiverEmail("email address");
        params.setSubject("測試一下");
        params.setContent("測試測試測試測試");

        // call sendMail API
        new ExchangeServerMailTest().sendMail(params);
    }

    public void sendMail(EmailParams params) {
        JavaMailSenderImpl sender = getJavaMailSender();
        MimeMessage message = sender.createMimeMessage();

        try {
            MimeMessageHelper helper = new MimeMessageHelper(message, true);
            helper.setTo(params.getReceiverEmail());
            helper.setFrom("email address");
            helper.setSubject(params.getSubject());
            helper.setText(params.getContent(), false);

            // set attachment
            FileSystemResource attachment = new FileSystemResource(new File(
                    "D:\\dropbox\\退匯明細表.pdf"));
            helper.addAttachment("退匯明細表.pdf", attachment);
        } catch (MessagingException e) {
            throw new RuntimeException(e);
        }
        sender.send(message);

        log.debug("mail sent..");
    }

    private JavaMailSenderImpl getJavaMailSender() {
        Properties props = new Properties();
        props.put("mail.smtp.auth", true);
        props.put("mail.smtp.ssl.trust", "*");

        // mail server configuration
        String host = "your smtp";
        int port = 25;
        String userName = "your user name";
        String password = "your password";

        JavaMailSenderImpl sender = new JavaMailSenderImpl();
        sender.setJavaMailProperties(props);
        sender.setHost(host);
        sender.setPort(port);
        sender.setUsername(userName);
        sender.setPassword(password);
        sender.setDefaultEncoding("UTF-8");

        return sender;
    }

}




2016/07/07

[JavaMail] javax.mail.MessagingException: Could not convert socket to TLS

Problem
I am using JavaMail set send email via Microsoft Exchange Server.
When I run this program, it show this error message:
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
Exception in thread "main" org.springframework.mail.MailSendException: Mail server connection failed; nested exception is javax.mail.MessagingException: Could not convert socket to TLS;
  nested exception is:
 javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target. Failed messages: javax.mail.MessagingException: Could not convert socket to TLS;
  nested exception is:
 javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target; message exception details (1) are:
Failed message 1:
javax.mail.MessagingException: Could not convert socket to TLS;
  nested exception is:
 javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
 at com.sun.mail.smtp.SMTPTransport.startTLS(SMTPTransport.java:1907)
 at com.sun.mail.smtp.SMTPTransport.protocolConnect(SMTPTransport.java:666)
 at javax.mail.Service.connect(Service.java:295)
 at org.springframework.mail.javamail.JavaMailSenderImpl.connectTransport(JavaMailSenderImpl.java:501)
 at org.springframework.mail.javamail.JavaMailSenderImpl.doSend(JavaMailSenderImpl.java:421)
 at org.springframework.mail.javamail.JavaMailSenderImpl.send(JavaMailSenderImpl.java:345)
 at org.springframework.mail.javamail.JavaMailSenderImpl.send(JavaMailSenderImpl.java:340)
 at albert.practice.mail.ExchangeServerMailTest.sendMail(ExchangeServerMailTest.java:49)
 at albert.practice.mail.ExchangeServerMailTest.main(ExchangeServerMailTest.java:28)

The code snippet looks like:
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
   private JavaMailSenderImpl getJavaMailSender() {
        Properties props = new Properties();
        props.put("mail.smtp.auth", true);

        // mail server configuration
        String host = "your smtp";
        int port = 25;
        String userName = "your user name";
        String password = "your password";

        JavaMailSenderImpl sender = new JavaMailSenderImpl();
        sender.setJavaMailProperties(props);
        sender.setHost(host);
        sender.setPort(port);
        sender.setUsername(userName);
        sender.setPassword(password);
        sender.setDefaultEncoding("UTF-8");

        return sender;
    } 



How-To
You need to set mail.smtp.ssl.trust in your JavaMail properties.
If set, and a socket factory hasn't been specified, enables use of a MailSSLSocketFactory. 
If set to "*", all hosts are trusted. 
If set to a whitespace separated list of hosts, those hosts are trusted. Otherwise, trust depends on the certificate the server presents.


The updated code snippet looks like:
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
    private JavaMailSenderImpl getJavaMailSender() {
        Properties props = new Properties();
        props.put("mail.smtp.auth", true);
        // Fix Excpetion: Mail server connection failed; nested exception is
        // javax.mail.MessagingException: Could not convert socket to TLS
        // If set, and a socket factory hasn't been specified, enables use of a
        // MailSSLSocketFactory. If set to "*", all hosts are trusted. If set to a whitespace
        // separated list of hosts, those hosts are trusted. Otherwise, trust depends on the
        // certificate the server presents.
        props.put("mail.smtp.ssl.trust", "*");

        // mail server configuration
        String host = "your smtp";
        int port = 25;
        String userName = "your user name";
        String password = "your password";

        JavaMailSenderImpl sender = new JavaMailSenderImpl();
        sender.setJavaMailProperties(props);
        sender.setHost(host);
        sender.setPort(port);
        sender.setUsername(userName);
        sender.setPassword(password);
        sender.setDefaultEncoding("UTF-8");

        return sender;
    } 


Reference
[1] https://javamail.java.net/nonav/docs/api/com/sun/mail/smtp/package-summary.html