Total Pageviews

2011/08/31

Example of the Strategy Design Pattern

Summary


The Strategy Design Pattern consists of a number of related algorithms encapsulated in a driver class often named Context. A user or a client program typically selects the algorithm they want to use, although the Context class may also select the algorithm automatically.


The intent of the Strategy Pattern is to make the algorithms easily interchangeable, and provide a means to choose the appropriate algorithm at a particular time.


Here is a brief summary of the Strategy Design Pattern:

  • Algorithms (strategies) are chosen at runtime.
  • A Strategy is dynamically selected by a client (a user or consuming program), or by the Context.
  • Your driver/controller class is typically named Context, though there is no requirement for this.
  • The Context class is aware of a variety of different algorithms, and each algorithm is considered a Strategy, and the name Strategy is often used as part of each class name, although again, this is only convention, and not a requirement.
  • The Context class is responsible for handling the data during the interaction with the client.

Example of the Strategy Design Pattern


NIG687提供一個介面讓使用者分別去搜尋異動記錄檔,包括

  • NIGU001 - 違章案件管制異動檔
  • NIGU005 - 案件紀錄異動檔
  • NIGU008 - 審理人員狀況維護檔(二)
  • NIGU014 - 未分配異動檔
  • NIGU015 - 已分配異動檔
  • NIGU020 - 列印參數維護檔
  • NIGU021 - 裁處書預設內容異動檔
  • NIGU036 - 違章機關代碼維護檔
  • NIGU037 - 適用法條代碼異動檔
  • NIGU038 - 違章事實代碼異動檔
  • NIGU039 - 違章作業代號異動檔
  • NIGU040 - 免議(罰)、撤銷、更裁原因代碼異動檔
  • NIGU042 - 附案證據代碼異動檔
  • NIGU050 - 違章月統計異動檔
  • NIGU081 - 法務科科室稅目對照維護檔
  • NIGU086 - 記帳士法徵銷管制異動檔
此function會有16個strategies


Class Diagram


Strategy interface: The classes that implement a concrete strategy should implement this interface.


在strategy interface中,定義其共同會使用到的algorithm or strategy
1:  package gov.fdc.nig.query.service.nig687;  
2:  import gov.fdc.common.table.Paging;  
3:  import gov.fdc.nig.query.service.params.NIG687Params;  
4:  /**  
5:  * @author albert  
6:  *  
7:  */  
8:  public interface Strategy {  
9:       Paging doQuery(NIG687Params params, final int rowsPerPage, final String sortDir);  
10:  }  





Context class: Configured with a ConcreteStrategy object and maintains a reference to a Strategy object.


負責建立與strategy class之間的關係,呼叫其相對應的strategy class method,以及接收client傳送過來的參數
1:  package gov.fdc.nig.query.service.nig687;  
2:  import gov.fdc.common.table.Paging;  
3:  import gov.fdc.nig.query.service.params.NIG687Params;  
4:  /**  
5:  * @author albert  
6:  *   
7:  */  
8:  public class Context {  
9:       private Strategy strategy;  
10:       public void setNIGU001Strategy() {  
11:            this.strategy = new NIGU001Strategy();  
12:       }  
13:       public void setNIGU005Strategy() {  
14:            this.strategy = new NIGU005Strategy();  
15:       }  
16:       public void setNIGU008Strategy() {  
17:            this.strategy = new NIGU008Strategy();  
18:       }  
19:       public void setNIGU014Strategy() {  
20:            this.strategy = new NIGU014Strategy();  
21:       }  
22:       public void setNIGU015Strategy() {  
23:            this.strategy = new NIGU015Strategy();  
24:       }  
25:       public void setNIGU020Strategy() {  
26:            this.strategy = new NIGU020Strategy();  
27:       }  
28:       public void setNIGU021Strategy() {  
29:            this.strategy = new NIGU021Strategy();  
30:       }  
31:       public void setNIGU036Strategy() {  
32:            this.strategy = new NIGU036Strategy();  
33:       }  
34:       public void setNIGU037Strategy() {  
35:            this.strategy = new NIGU037Strategy();  
36:       }  
37:       public void setNIGU038Strategy() {  
38:            this.strategy = new NIGU038Strategy();  
39:       }  
40:       public void setNIGU039Strategy() {  
41:            this.strategy = new NIGU039Strategy();  
42:       }  
43:       public void setNIGU040Strategy() {  
44:            this.strategy = new NIGU040Strategy();  
45:       }  
46:       public void setNIGU042Strategy() {  
47:            this.strategy = new NIGU042Strategy();  
48:       }  
49:       public void setNIGU050Strategy() {  
50:            this.strategy = new NIGU050Strategy();  
51:       }  
52:       public void setNIGU081Strategy() {  
53:            this.strategy = new NIGU081Strategy();  
54:       }  
55:       public void setNIGU086Strategy() {  
56:            this.strategy = new NIGU086Strategy();  
57:       }  
58:       public Paging executeStrategy(NIG687Params params,final int rowsPerPage, final String sortDir) {  
59:            return strategy.doQuery(params, rowsPerPage, sortDir);  
60:       }  
61:  }  





Concrete Strategy class implementations shown below here.


定義Strategy class的細部運作細節


NIGU001 Strategy class
1:  package gov.fdc.nig.query.service.nig687;  
2:  import gov.fdc.common.dao.wherecon.SimpleCriteria;  
3:  import gov.fdc.common.table.Paging;  
4:  import gov.fdc.nig.dao.Nigu001Dao;  
5:  import gov.fdc.nig.domain.Nigu001;  
6:  import gov.fdc.nig.domain.Nigu001PK;  
7:  import gov.fdc.nig.query.service.params.NIG687Params;  
8:  import org.apache.commons.lang.StringUtils;  
9:  import org.springframework.beans.factory.annotation.Autowired;  
10:  /**  
11:  * @author albert  
12:  *  
13:  */  
14:  public class NIGU001Strategy implements Strategy {  
15:       @Autowired  
16:       private transient Nigu001Dao nigu001Dao;  
17:       /* (non-Javadoc)  
18:       * @see gov.fdc.nig.query.service.nig687.Strategy#doQuery(gov.fdc.nig.query.service.params.NIG687Params)  
19:       */  
20:       @Override  
21:       public Paging doQuery(NIG687Params params, final int rowsPerPage, final String sortDir) {  
22:            final SimpleCriteria whereCondition = new SimpleCriteria();  
23:            Nigu001PK primaryKey = (Nigu001PK)params.getPrimaryKey();  
24:            if(StringUtils.isNotEmpty(primaryKey.getDlvUnit()) &&  
25:               StringUtils.isNotEmpty(primaryKey.getTaxCd()) &&  
26:              StringUtils.isNotEmpty(primaryKey.getDlvYr()) &&  
27:              StringUtils.isNotEmpty(primaryKey.getFlgTp()) &&  
28:              StringUtils.isNotEmpty(primaryKey.getSerialNo())){  
29:                 whereCondition.eq("id.dlvUnit", primaryKey.getDlvUnit());  
30:                 whereCondition.eq("id.taxCd", primaryKey.getTaxCd());  
31:                 whereCondition.eq("id.dlvYr", primaryKey.getDlvYr());  
32:                 whereCondition.eq("id.flgTp", primaryKey.getFlgTp());  
33:                 whereCondition.eq("id.serialNo", primaryKey.getSerialNo());  
34:            }  
35:            // 取得排序方向, 如果有的話代表是要排序  
36:            if (sortDir != null){  
37:                 whereCondition.orderBy("id", sortDir.equals("asc"));  
38:            }else{  
39:                 whereCondition.orderBy("id", true); // 預設照seqNo由小到大排  
40:            }  
41:            // 執行查詢  
42:            return new Paging(new Nigu001(), null, whereCondition, rowsPerPage, 100, nigu001Dao);  
43:       }  
44:  }  





NIGU005 Strategy Class
1:  package gov.fdc.nig.query.service.nig687;  
2:  import gov.fdc.common.dao.wherecon.SimpleCriteria;  
3:  import gov.fdc.common.table.Paging;  
4:  import gov.fdc.nig.dao.Nigu005Dao;  
5:  import gov.fdc.nig.domain.Nigu005;  
6:  import gov.fdc.nig.domain.Nigu005PK;  
7:  import gov.fdc.nig.query.service.params.NIG687Params;  
8:  import org.apache.commons.lang.StringUtils;  
9:  import org.springframework.beans.factory.annotation.Autowired;  
10:  /**  
11:  * @author albert  
12:  *   
13:  */  
14:  public class NIGU005Strategy implements Strategy {  
15:       @Autowired  
16:       private transient Nigu005Dao nigu005Dao;  
17:       /*  
18:       * (non-Javadoc)  
19:       *   
20:       * @see  
21:       * gov.fdc.nig.query.service.nig687.Strategy#doQuery(gov.fdc.nig.query.service  
22:       * .params.NIG687Params, int, java.lang.String)  
23:       */  
24:       @Override  
25:       public Paging doQuery(NIG687Params params, int rowsPerPage, String sortDir) {  
26:            final SimpleCriteria whereCondition = new SimpleCriteria();  
27:            Nigu005PK primaryKey = (Nigu005PK) params.getPrimaryKey();  
28:            if (StringUtils.isNotEmpty(primaryKey.getDlvUnit())     &&   
29:              StringUtils.isNotEmpty(primaryKey.getTaxCd()) &&   
30:                 StringUtils.isNotEmpty(primaryKey.getDlvYr()) &&   
31:                 StringUtils.isNotEmpty(primaryKey.getFlgTp()) &&   
32:                 StringUtils.isNotEmpty(primaryKey.getSerialNo())) {  
33:                   whereCondition.eq("id.dlvUnit", primaryKey.getDlvUnit());  
34:                  whereCondition.eq("id.taxCd", primaryKey.getTaxCd());  
35:                  whereCondition.eq("id.dlvYr", primaryKey.getDlvYr());  
36:                  whereCondition.eq("id.flgTp", primaryKey.getFlgTp());  
37:                  whereCondition.eq("id.serialNo", primaryKey.getSerialNo());  
38:            }  
39:            // 取得排序方向, 如果有的話代表是要排序  
40:            if (sortDir != null) {  
41:                 whereCondition.orderBy("id", sortDir.equals("asc"));  
42:            } else {  
43:                 whereCondition.orderBy("id", true); // 預設照seqNo由小到大排  
44:            }  
45:            // 執行查詢  
46:            return new Paging(new Nigu005(), null, whereCondition, rowsPerPage, 100, nigu005Dao);  
47:       }  
48:  }  





this is our "driver" method to demonstrate our Java Strategy Design Pattern example
1:  public static void main(String[] args){  
2:       Context context;  
3:       //搜尋NIGU001 table的資料  
4:       context = new Context();  
5:       context.setNIGU001Strategy();  
6:       context.executeStrategy(params, rowsPerPage, sortDir);  
7:       //搜尋NIGU005 table的資料  
8:       context = new Context();  
9:       context.setNIGU005Strategy();  
10:      context.executeStrategy(params, rowsPerPage, sortDir);  
11:  }  


2011/08/24

illegal character: \65279 when using file encoding UTF8

Problem
As I try to compile classes in my workspace, it show this error message "illegal character: \65279 when using file encoding UTF8".

Root Cause
Some Java class has BOM(Byte-Order Mark) character, so you need to remove it.

Solution
Use notepad++ to remove it.



JasperWave - designer for JasperReports




Another report designer tool choice for JasperReports: http://jasperwave.com/docs/introduction.html

Ease Your Effort of Putting Data into History Table


2011/08/23

had objects of type "gov.fdc.nig.domain.Nigt038PK" but expected signature "gov.fdc.nig.domain.Nigu038PK"

Problem
As I utilize Appche commons PropertyUtils.copyProperties API, it show this error message in runtime

Cannot invoke gov.fdc.nig.domain.Nigu038.setId on bean class 'class gov.fdc.nig.domain.Nigu038' - had objects of type "gov.fdc.nig.domain.Nigt038PK" but expected signature "gov.fdc.nig.domain.Nigu038PK"


Root Cause
Here is Nigt038's attributes
1:  @Entity   
2:  @EntityListeners({EntityListener.class})   
3:  @Table(name = "NIGT038")   
4:  public class Nigt038 extends DomainBase {   
5:       // Fields   
6:       private Nigt038PK id;   
7:       private String vioFactNm;   
8:       private Timestamp timeStamp;   
9:       private String updateCd;   
10:       private String userId;   
11:       private String updateDate;   
12:       //..........   



Here is Nigu038's attributes
1:  @Entity   
2:  @EntityListeners({EntityListener.class})   
3:  @Table(name = "NIGU038")   
4:  public class Nigu038 extends DomainBase {   
5:       // Fields   
6:       private Nigu038PK id;   
7:       private String vioFactNm;   
8:       private Timestamp timeStamp;   
9:       private String userId;   
10:       private String updateDate;   
11:       //........   

The two class the same attrbute name, but have different type. It's the reason why it fails to do object copy.
And in our case, we don't need to copy id attributes.

Solution
We need to igore the "id" attribute, so we use this way to do property copy.


1:    /**  
2:     * Copy properties.  
3:     *  
4:     * @param dest  
5:     *      the dest  
6:     * @param source  
7:     *      the source  
8:     */  
9:    public void copyProperties(Object dest, Object source) {  
10:      try {  
11:        PropertyDescriptor[] destDesc = PropertyUtils.getPropertyDescriptors(dest);  
12:        for (int i = 0; i < destDesc.length; i++) {  
13:          Class<?> destType = destDesc[i].getPropertyType();  
14:          Class<?> origType = PropertyUtils.getPropertyType(source, destDesc[i].getName());  
15:          if ((destType != null && destType.equals(origType) && !destType.equals(Class.class) && !"id"  
16:            .equals(destDesc[i].getName()))) {  
17:            Object value = PropertyUtils.getProperty(source, destDesc[i].getName());  
18:            PropertyUtils.setProperty(dest, destDesc[i].getName(), value);  
19:          }  
20:        }  
21:      } catch (IllegalAccessException e) {  
22:        e.printStackTrace();  
23:      } catch (InvocationTargetException e) {  
24:        e.printStackTrace();  
25:      } catch (NoSuchMethodException e) {  
26:        e.printStackTrace();  
27:      }  
28:    }  

2011/08/18

org.springframework.beans.factory.NoSuchBeanDefinitionException: No matching bean of type [gov.fdc.nig.controlop.NIG225Manager] found for dependency

Problem
As I execute my function, it show this error message
 Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No matching bean of type [gov.fdc.nig.controlop.NIG225Manager] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}   
 at org.springframework.beans.factory.support.DefaultListableBeanFactory.raiseNoSuchBeanDefinitionException(DefaultListableBeanFactory.java:920)   
 at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:789)   
 at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:703)   
 at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:478)   
 ... 42 more   


Controller class is as bellowing
 /**   
 *   
 */   
 package gov.fdc.nig.web.controlop.controller;   
 /**   
 * @author albert   
 *   
 */   
 @Controller   
 @RequestMapping("/front/NIG225W")   
 public class NIG225Controller extends AbstractController {   
      @Autowired   
      private transient NIG225Manager nig225Manager;   
 }  

Root Cause
I forgot to add @Service to my service implementation


Solution
 @Service   
 public class NIG225ManagerImpl implements NIG225Manager {   
 }  

2011/08/12

How to specify the time limit to complete server operations in WAS


Problem
As I start up WAS (WebSphere Application Server) in Eclipse, it will show timeout error dialog sometimes.

Solution
Increase start timeout value, and save your configuration value. Then restart WAS (WebSphere Application Server).

Install jquerywtp to Make Eclipse WTP's JavaScript Content Assistance Support jQuery

1. Go to download jar file, jqueryWTP1.00foEN.jar, from http://code.google.com/a/eclipselabs.org/p/jquerywtp/downloads/list

2. execute java -jar jqueryWTP1.20foEN.jar in command line

3. Jar File --> Browse --> Choose org.eclipse.wst.jsdt.core_1.1.4.v201102102045.jar


4. Output Dir --> Browse

5. Click Generate Button


6. You can get new jar file, org.eclipse.wst.jsdt.core_1.1.4.v201102102045.jar, in C:\

7. Overwrite jar file in eclipse\plugins

8. Then restart eclipse with -clean to clear plug-in cache.

9. Check the result

Remember to remove -clean after you launch eclipse

ADMA0176E: Application installation of {0} faild with PrivilegedActionException. Ear file path is {1}.

Problem


When I try to deploy an ear file to my WAS (WebSphere Application Server)



I get the following error:

ADMA0176E: Application installation of {0} faild with PrivilegedActionException. Ear file path is {1}.



Solution


right click on project --> Properties --> Dependecncy Management --> Check "Automatically update dependencies from Maven pom.xml" checkbox




And do "Update Project Configuration" on your project



See....my ear file had been deployed to WAS successfully.

And can open my jsp successfully.

The name "Ybdt010" is not a recognized entity or identifier

Problem
As I do query via OpenJPA in WAS(WebSphere Application Server), it complains this error message
 org.apache.openjpa.persistence.ArgumentException: An error occurred while parsing the query filter "select t from Ybdt010 t where t.emplCd = ?1". Error message: The name "Ybdt010" is not a recognized entity or identifier. Perhaps you meant Nigt010, which is a close match. Known entity names: [Nigw001, Nigt010, Nigt055, Nigt011, Nigt012, JUTSysParam, Nigt013, Nigt036, Nigt037, Nigt038, Nigt039, JUTMsg, Nigt080, Nigt081, Nigt082, Nigt040, Nigt063, Nigt041, Nigt042, Nigt020, Nigt064, Nigt021, Nigt043, Nigt044, Nigt088, Nigt001, Nigt045, Nigt005, Nigt006, Nigt007, Nigt008, JUTCode]   
 at org.apache.openjpa.kernel.exps.AbstractExpressionBuilder.parseException(AbstractExpressionBuilder.java:118) ~[com.ibm.ws.jpa.jar:1.0.1-SNAPSHOT]   
 at org.apache.openjpa.kernel.jpql.JPQLExpressionBuilder.getClassMetaData(JPQLExpressionBuilder.java:177) ~[com.ibm.ws.jpa.jar:1.0.1-SNAPSHOT]   
 at org.apache.openjpa.kernel.jpql.JPQLExpressionBuilder.resolveClassMetaData(JPQLExpressionBuilder.java:150) ~[com.ibm.ws.jpa.jar:1.0.1-SNAPSHOT]   
 at org.apache.openjpa.kernel.jpql.JPQLExpressionBuilder.getCandidateMetaData(JPQLExpressionBuilder.java:225) ~[com.ibm.ws.jpa.jar:1.0.1-SNAPSHOT]   
 at org.apache.openjpa.kernel.jpql.JPQLExpressionBuilder.getCandidateMetaData(JPQLExpressionBuilder.java:195) ~[com.ibm.ws.jpa.jar:1.0.1-SNAPSHOT]   


Why it happened?
There was a problem if the first time you accessed an Entity type (ie. Ybdt010) via a Query instead of some other access.
It should be WebSphere's bug, need to install fixpack to fix this problem.

Solution
Here has a workaround solution to fix this problem. Before executing your query, you just insert something simple like...
 Ybdt010 ybdt010 = new Ybdt010();  


2011/08/08

員工失去幹勁,主管做錯了什麼?

  • 不斷的批評
  • 無法達成的目標
  • 不斷改變目標
  • 未提供相關資訊使目標難以達成
  • 當大問題發生的時候,主管卻只責備一個人
  • 侵入式的監督他人工作
  • 低估已經完成的工作
  • 主管將別人的努力據為己有

org.apache.openjpa.persistence.NoResultException


Problem
As we do search via primary key, it will show this exception message if JPA does not search any matched data
1:  org.apache.openjpa.persistence.NoResultException: The query on candidate type "class gov.fdc.nig.domain.Nigt020" with filter "select t1 from Nigt020 t1, Nigt022 t2 where t2.id.dlvUnit = ?1 and t2.id.taxCd = ?2 and t2.id.dlvYr = ?3 and t2.id.flgTp = ?4 and t2.id.serialNo = ?5 and t2.paraTp <> ?6 and t2.paraTp = t1.paraTp" was configured to have a unique result, but no instance matched the query.   
2:  at org.apache.openjpa.kernel.QueryImpl.singleResult(QueryImpl.java:1299) ~[com.ibm.ws.jpa.jar:1.0.1-SNAPSHOT]   
3:  at org.apache.openjpa.kernel.QueryImpl.toResult(QueryImpl.java:1221) ~[com.ibm.ws.jpa.jar:1.0.1-SNAPSHOT]   
4:  at org.apache.openjpa.kernel.QueryImpl.execute(QueryImpl.java:990) ~[com.ibm.ws.jpa.jar:1.0.1-SNAPSHOT]   
5:  at org.apache.openjpa.kernel.QueryImpl.execute(QueryImpl.java:805) ~[com.ibm.ws.jpa.jar:1.0.1-SNAPSHOT]   
6:  at org.apache.openjpa.kernel.QueryImpl.execute(QueryImpl.java:775) ~[com.ibm.ws.jpa.jar:1.0.1-SNAPSHOT]   
7:  at org.apache.openjpa.kernel.DelegatingQuery.execute(DelegatingQuery.java:533) ~[com.ibm.ws.jpa.jar:1.0.1-SNAPSHOT]   
8:  at org.apache.openjpa.persistence.QueryImpl.execute(QueryImpl.java:252) ~[com.ibm.ws.jpa.jar:1.0.1-SNAPSHOT]   
9:  at org.apache.openjpa.persistence.QueryImpl.getSingleResult(QueryImpl.java:317) ~[com.ibm.ws.jpa.jar:1.0.1-SNAPSHOT]   


The original approach is to call getSingleResult method:
1:  public Object createQueryForSingleResult(String jpql, Object[] params, Dao.PersistenceUnit persistenceUnitName) {   
2:       EntityManager em = getEntityManager(persistenceUnitName);   
3:       Query query = em.createQuery(jpql);   
4:       for (int i = 0; i &lt; params.length; i++) {   
5:            query.setParameter(i + 1, params[i]);   
6:       }   
7:       return query.getSingleResult();   
8:  }  

Solution
Just change to this way, then the exception will not take place again:
1:  public Object createQueryForSingleResult(String jpql, Object[] params, Dao.PersistenceUnit persistenceUnitName) {   
2:       Object result = null;   
3:       EntityManager em = getEntityManager(persistenceUnitName);   
4:       Query query = em.createQuery(jpql);   
5:       for (int i = 0; i < params.length; i++) {   
6:            query.setParameter(i + 1, params[i]);   
7:       }   
8:       List list = query.getResultList();   
9:       if(!CollectionUtils.isEmpty(list)){   
10:            result = list.get(0);   
11:       }   
12:       return result;   
13:  }   

2011/08/05

2011/08/04

How to Change WebSphere Console to English

Problem
As I start up WebSphere, the console show Traditional Chinese in default.
But it's difficult for us to figure out solutions as we face problems.

Solution
Please login WAS administration console: https://localhost:9043/ibm/console
Go to 伺服器 > 伺服器類型 > WebSphere Application Server > 應用程式伺服器 > server1 > 伺服器基礎架構 > Java 和程序管理 > 程序定義 > Java 虛擬機器 > 自訂內容

Create a new property:
  • name: user.language
  • value: en



Then restart WAS, and check the console

Taking Over a Project

Reference: http://kaczanowscy.pl/tomek/2011-08/taking-over-a-project

Team

  • who? + characteristics + how long they work with the team + strong/weak points + maturity level / how independent they are? + maybe there is some BSC mechanism, if so, take a look at the previous records
  • language skills
  • contact - mail, skype/jabber nick etc.
  • working hours? anyone working half-time? anyone with unusual working hours?
  • where? one room or many places
  • some people from other teams involved? independent consultants? some project partners (external companies) that we cooperate with?
  • what are the roles of people
  • who knows what?
  • are team members involved in other projects?
  • questions to ask to each team member:
    • what are you proud/angry/annoyed about? what (de)motivates you?
    • please draw the architecture of the system
    • please write down the "definition of done"
    • what issues do you think we have? what is the most common source of bugs? which bugs are the most annoying for us / for clients?

Meetings / Telcos

  • internal (only the team is involved) - Scrum - daily / sprint / backlog ?
  • with clients
  • with higher-ups?
  • traveling? where? for how long?
  • how are the invitations send? who sends them? who sets the agenda? who sends minutes (if any)? who attends?
  • how long is the meeting? who participates?

Documents

  • where can I find them, how are they generated, who maintains them?
  • technical documentation
  • user documentation
  • developers documentation
  • reporting - internal / external
  • templates - documents? mails? reports? presentations?
  • bug tracker - how are issues commented?
  • where is the database schema?

Infrastructure

  • SCM, FTP/WebDavs, Sonar, CI, bug tracker, artifacts repository, wiki
  • keystores, certificates
  • mailing lists (internal, external)
  • adresses, credentials, who creates accounts? who administrates?
  • environments - local, testing, production?
  • Can anyone, besides the team, access any of these (e.g. client reading bug tracker issues) ?

Processes

  • SCRUM? how does it really look like? how are user stories sized - hours or t-shirts (M, S, XL)? what meetings, how often etc., are daily standups held regularly
  • code reviews - formalized, informal, who does them? peer reviews? external audits of code?
  • any visualization tools? (well, these are the easiest to notice, aren't they?)
  • what is the "definition of done" of this team?
  • any special recruiting process for this team?
  • build process - automated?
  • How are versions/releases created? What is a naming pattern? Are there different internal (for team) and external (for client) versions? How can one learn about the changes between versions X and Y?
  • statuses of issues on issue tracker (e.g. todo, in progree, done, accepted etc.)
  • production deploy & rollback, tools used - Puppet, Liquidbase?
  • code conventions - format (Eclipse formatter?), checkstyle etc, but also use of TODO/FIXME tags in code
  • SCM (SVN/git) - branches? how/when created, when merged?
  • CI - schedules, how are they set?

Testing

  • unit
  • integration
  • end2end
  • does client test?
  • automation? which requirements functional and non functional are being automatically tested?
  • code coverage - how high, is it automatically calculated, is code coverage of different tests merged?

Development Tools

  • what tools/software is being used by team members
  • OS? IDE? build tools? testing libraries? mocking libraries? code review tools?
  • specific applications for Win (Visio?, Outlook?)

Problems

  • what we know? what are the main problems from our point of view? (e.g. internal code quality, our build process, client?), does client is aware of this?
  • recent problems, what were the causes, are they fixed?
  • what is the main concern of client?
  • common bugs, how many critical bugs, are they added to the current sprint?

Client(s)

  • communication - how do we communicate with clients? with whom exactly should I talk about certain topics? who has the right to make decisions?
  • communication - how does client communicates with us?
  • communication - what hours is he available? does he answer emails immediately?
  • what does he value, what are his goals?
  • does he own the code?
  • does he has a say in technologies we used, should we ask him for approval for new libraries/tools that we plan to use?
  • is it possible to negotiate the scope?

Next steps

  • What is the most pressing matter? Are we late with anything?
  • Any meetings/telcos ahead?

Architecture

  • software
  • hardware