google-code-prettify

2015年1月26日 星期一

Digital Photo Professional 發生 EXC_BAD_ACCESS (SIGBUS)

在OS X上使用Canon Digital Photo Professional 一直發生Crash,
一直以來發生下面這樣的「EXC_BAD_ACCESS (SIGBUS)」的Exception,
=====

Crashed Thread:        0  Dispatch queue: com.apple.main-thread

Exception Type:        EXC_BAD_ACCESS (SIGBUS)
Exception Codes:       KERN_PROTECTION_FAILURE at 0x00000000fefff000

VM Regions Near 0xfefff000:
    Stack                  00000000bf7c3000-00000000bffc3000 [ 8192K] rw-/rwx SM=COW
--> VM_ALLOCATE            00000000fefff000-00000000ff000000 [    4K] rw-/rwx SM=COW
    Submap                 00000000ffff0000-00000000ffff1000 [    4K] r--/r-- SM=PRV  process-only VM submap

=====

一直找不到解法,
發Mail給美國Canon support,
幾次回覆提供的處理方式都無法解決問題。
後來試著幾種方式移除Canon相關軟體重裝,
還是無法解決。
但在無意間卻發現長長的Exception log有了不一樣的地方,
Crashed Thread不一樣了!

=====

Crashed Thread:        13  Dispatch queue: TFSVolumeInfo::GetSyncGCDQueue 0

Exception Type:        EXC_BAD_ACCESS (SIGBUS)
Exception Codes:       KERN_PROTECTION_FAILURE at 0x00000000fefff000

VM Regions Near 0xfefff000:
    Stack                  00000000bf723000-00000000bff23000 [ 8192K] rw-/rwx SM=COW
--> VM_ALLOCATE            00000000fefff000-00000000ff000000 [    4K] rw-/rwx SM=COW
    Submap                 00000000ffff0000-00000000ffff1000 [    4K] r--/r-- SM=PRV  process-only VM submap

======

用了這個Keyword去搜尋找到了一個處理方式,
移除下面兩個檔案:
/Library/Contextual Menu Items/SCFinderPlugin.plugin
/Library/Receipts/SCPlugin.pkg    

並且登出或是重開機,
問題就解決了!

移除的那兩個檔案是一個Subversion client軟體的檔案。
來源討論可以看這裡





2015年1月23日 星期五

簡易限制同時多執行緒數量Simple Limited Concurrent Multi-thread

因為工作常需要處理較大數量的資料,
使用單執行緒耗時較久,
所以就想寫一個多執行緒的程序來做,
但不能無限制的往Server丟,
Server恐怕也會吃不消,
所以必須控制同時多執行緒執行的數量。
另外,也為了要考量到原本已寫好的Service必須可以直接使用,
套用多執行緒後不用改Code,
保持需要時,原本只有主執行緒運算的狀況下仍可進行,
所以就利用時間寫了以下這樣一個簡易可以指定同時間多執行緒數量的程式,
並且這個控制同時執行緒數量的框架架構可以在後來其他新的程式工作直接套用即可,
不需再寫產生多執行緒、控制Concurrent Multi-thread的程式。
 

public interface BatchService {
 public Collection<!----> retrieveSource() throws Exception;
 public void doJob( Object obj ) throws Exception;
}


 
public interface Job extends Runnable {
 public void setData(Object obj);
 public void setService(BatchService service);
}

 
public class JobImpl implements Job {

 //private static Logger log = Logger.getLogger(JobImpl.class);
 
 private Object data;
 private BatchService service;
 
 @Override
 public void run() {
  Thread.currentThread().setName(Thread.currentThread().getId()+"");
  if (data == null || service == null) return;
  
  try {
   service.doJob(data);
   this.setData(null);
   this.setService(null);
   
   
  } catch (Exception e) {
   e.printStackTrace();
   //System.out.println(e.getMessage());
   //log.error(e.getMessage());
   
  }finally{
   BatchInit.infoJobFinishCount(this);
  }
 }

 @Override
 public void setData(Object obj) {
  data = obj;
  
 }

 @Override
 public void setService(BatchService service) {
  this.service = service;
 }

}

 

public class BatchInit {
 //private static Logger log = LogManager.getLogger("BatchInit");
 public static Stack<job> jobStack;

 private static int JobFinishCount = 0;

 
 public void batchJob(BatchService batchService, Stack<job> jobs) throws Exception{
  List<!----> source = (List<!---->)batchService.retrieveSource() ;
  int JobAmount = source.size();
  jobStack = jobs;
  int JobNow = 0;
  //log.info("JobAmount::"+JobAmount);
  
  while(true){
   if (JobAmount==JobFinishCount){
    //System.out.println("做完了::"+JobFinishCount);
    //log.info("做完了::"+JobFinishCount);
    break;
   }
   Job job = null;
   try{
    job = jobStack.pop();
    
   }catch(java.util.EmptyStackException ex){
  
   }catch(Exception ex){
    ex.printStackTrace();
    //log.error(ex.getMessage());
   }
   
   //log.debug("#######job ::"+job);
   if (job != null && JobNow < JobAmount ){
    loga(JobFinishCount, "");
    Object obj = source.get(JobNow);
    ++JobNow;
    job.setData(obj);
    job.setService(batchService);
    Thread t = new Thread(job, job.toString());
    t.start();
    
   }
   
  }
  
 }

 public synchronized static void infoJobFinishCount( Job job){
  ++JobFinishCount;
  jobStack.push(job);
  
 }
 
 private void loga(int i, String message){
  if (i % 500 == 0){
   System.out.println("--doing :" +i+", "+message);
   //log.info("--doing :" +i+", "+message);

  }
 }
}


上面的程式是控制同一時間執行緒的最大數量,之後不用在改(除非有Bug,或為了提升效率),
以後新的需要多執行緒進行的程式可以直接引用。
而下面的兩隻程式必須要寫,
一個是實作每一個Batch Job Service的實際工作必須implements BatchService這個interface,
另一個則是啟動程式和同一時間處理Job數量(執行緒數量)設定
 

public class MyBatchJobService implements BatchService {

 @Override
 public Collection<!----> retrieveSource() throws Exception {
  //TODO write your code
  ArrayList<String> source = new ArrayList<String>();
  source.add("Hello ");
  source.add("Ryan! ");
  source.add("How ");
  source.add("are ");
  source.add("you? ");
  
  for(int i = 0 ; i < 10 ; i++){
   source.add(""+i);
  }
  return source;
 }

 @Override
 public void doJob(Object obj) throws Exception {
  //TODO write your code 
  String data = (String) obj;
  System.out.println("ThreadId:"+ Thread.currentThread().getId() +"::"+data);
 }

}


執行BatchStart啟動程式。
 
public class BatchStart {

 private static BatchInit batchInit = new BatchInit();
 
 public static void main(String[] args) throws Exception {
  BatchService service = new MyBatchJobService();
  batchJob(service, 2);
  
 }

 private static void batchJob(BatchService service, int amountThread)
   throws Exception {
  Stack jobs = new Stack();
  
  for(int i =0; i < amountThread; i++){  //TODO Setting the amount of concurrent thread
   jobs.push(new JobImpl());
   
  }
  
  batchInit.batchJob(service, jobs);
 }
}

開放原始碼下載:GitHub

2015年1月17日 星期六

Maven設定Proxy

到一個新環境,拿到一個新Project source,
 一打開Project冒出下面這樣的錯誤:
ArtifactDescriptorException: Failed to read artifact descriptor for ......
Could not calculate build plan: Plugin org.apache.maven.plugins:maven-resources-plugin:2.6 or one of its dependencies could not be resolved: Failed to read artifact descriptor for org.apache.maven.plugins:maven-resources-plugin:jar:2.6

接著看到pom.xml冒出一堆錯誤...,
有可能是所處的網路環境會經過Proxy Server,
所以可以試著給Maven設定Proxy可以解決這樣的問題。

編寫一個settings.xml格式如下:

<settings xmlns="http://maven.apache.org/SETTINGS/1.0.0"
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0
 http://maven.apache.org/xsd/settings-1.0.0.xsd">
 <localRepository/>
 <interactiveMode/>
 <usePluginRegistry/>
 <offline/>
 <pluginGroups/>
 <servers/>
 <mirrors/>
 <proxies>
  <proxy>
   <id>myproxy</id>
   <active>true</active>
   <protocol>http</protocol>
   <host>your proxy server address</host>
   <port>your proxy server port</port>
   <username>your proxy account</username>
   <password>your proxy password</password>
   <nonProxyHosts>localhost,127.0.0.1</nonProxyHosts>
  </proxy>
 </proxies>
 <profiles/>
 <activeProfiles/>
</settings>

以Eclipse來說,到以下的選單:
Window > Preferences > Maven > User Settings
在這個畫面指定上面的settings.xml

2015年1月9日 星期五

Java在cmd環境下執行的編碼問題

編寫了call Web-service的client程式,
將資料組成JSON的格式送至Server,
在Eclipse下執行一切相安無事,
但是在cmd的環境執行時,
卻有些資料會收到Server回傳400錯誤。

將有問題的JSON資料在cmd畫面中印出來放到jsonlint驗證, 卻是一切正確。 
仔細看了發生錯誤的幾筆資料,
發現資料內容都有含一些特殊符號(例如:數學符號),
所以應該就是編碼的問題。
因為在Eclipse中編寫java時,
整個環境都是設定為UTF-8編碼,
而cmd的環境卻是Big5編碼。 

解決的方式:
1. 在執行java時,給予「-Dfile.encoding=UTF-8」參數。這樣可以解決資料處理時的編碼問題。
2. 在cmd下執行「chcp 65001」指令,65001是表示設定為UTF-8(Big5為950),並到以下的畫面設定字型。這樣可以解決cmd印出中文出現亂碼的問題。


以上的作法可以編寫成以下這樣一個.bat檔,
這樣執行程式時,就方便很多了。
chcp 65001
java -Dfile.encoding=UTF-8 你的java程式 

2015年1月8日 星期四

MongoDB使用forEach進行非固定值update

使用關聯式資料庫時,
如果只是想要簡單的以該筆資料的A欄位狀況來update它的B欄位值,
可以很簡單的用類似以下的SQL進行:
update tableA set column_B = column_A+"-new value" 
where column_C="abc";

在MongoDB中我並沒有發現有像SQL這麼簡單程式碼就可以達到相同的作法, 所以使用forEach的方式來達到同樣的目的:
db.tableA.find({"column_C":"abc"}).forEach( 
    function(myDoc) { 
        if (myDoc.column_A == null){
            return;
        }

        db.tableA.update({"column_PK":myDoc.column_PK},{ "$set": { "column_B": myDoc.column_A+"-new value"}});

    } 
);