Saturday, February 6, 2010

Cấu hình mail server cho jira sử dụng gmail trên Linux

1. Chạy câu lệnh: openssl s_client -connect smtp.gmail.com:465(Nếu chưa có openssl bạn hãy download nó)
2. Copy đoạn bắt đầu từ "-----BEGIN CERTIFICATE-----" tới "-----END CERTIFICATE-----" (nhớ là phải có cả đoạn BEGIN và END)
3. Lưu nó vào một file gmail.pem
4. Run: keytool -import -file gmail.pem -alias smtp.gmail.com -keystore "$JAVA_HOME/jre/lib/security/cacerts"
5. keytool nằm trong $JAVA_HOME/bin
6. lib/security/cacerts nằm trong $JAVA_HOME/jre
7. Sửa $JIRA_HOME/conf/server.xml thêm đoạn sau vào:

<resource name="mail/GmailSmtpServer"

auth="Container"

type="javax.mail.Session"

mail.smtp.host="smtp.gmail.com"

mail.smtp.port="465"

mail.smtp.auth="true"

mail.smtp.user="MyGmailAccount@gmail.com"

password="MyPassword"

mail.smtp.starttls.enable="true"

mail.smtp.socketFactory.class="javax.net.ssl.SSLSocketFactory"

/>

8. Lưu file server.xml lại
9. Chuyen 2 file javamail-1.3.3.jar va activation-1.0.2.jar từ $JIRA_HOME/atlassian-jira/WEB-INF/lib
Tới $JIRA_HOME/common/lib
10. Khởi động lại jira
11. Đăng nhập vào jira với tài khoản administrator
12. Tới phần Mail Servers
13. Cấu hình SMTP
14. Sử dụng JNDI với tham số: java:comp/env/mail/GmailSmtpServer
15. Kết thúc, bạn hãy test thử và xem kết quả của mình.

Create a service for JIRA on CentOS 5 or RHEL 5

Tạo file jira trong /etc/init.d với nội dung như sau.

#!/bin/bash
#
# chkconfig: 2345 85 15
# description: jira
# processname: jira
# source function library
. /etc/init.d/functions

JAVA_HOME="/app/jdk"
JRE_HOME="/app/jdk"
CATALINA_HOME="/app/jira"

RETVAL=0

start() {
echo -n $"Starting jira services: "
. /app/jira/bin/catalina.sh start
RETVAL=$?
echo
}

stop() {
echo -n $"Shutting down jira services: "
. /app/jira/bin/catalina.sh stop
RETVAL=$?
echo
}

case "$1" in
start)
start
;;
stop)
stop
;;
restart|reload)
stop
start
;;
status)
status jira
RETVAL=$?
;;
*)
echo $"Usage: $0 {start|stop|restart|status}"
exit 1
esac
exit $RETVAL

Tiếp tới bạn vào thư mục /etc/init.d
# cd /etc/init.d
Cấp quyền execute
# chmod a+x jira
Thêm nó vào danh sách chkconfig:
# chkconfig --add jira


Ok rồi
Bạn có thể test thử
start
# /etc/init.d/jira start
stop
# /etc/init.d/jira stop
restart
# /etc/init.d/jira restart

Friday, January 15, 2010

Auto startup oracle

1, Đầu tiên bạn đăng nhập vào root và sửa file /etc/oratab: Thay đổi ký tự cuối cùng thành Y.
ORCL:/app/oracle/111:Y
Trước đó trông nó như: ORCL:/app/oracle/111:N
2, Tạo file oracle trong thư mục /etc/init.d/ với nội dung như sau:
#!/bin/bash
#
# oracle Init file for starting and stopping
# Oracle Database. Script is valid for 10g and 11g versions.
#
# chkconfig: 35 80 30
# description: Oracle Database startup script

# Source function library.

. /etc/rc.d/init.d/functions


ORACLE_OWNER="oracle"
ORACLE_HOME="/app/oracle"

case "$1" in
start)
echo -n $"Starting Oracle DB:"
su - $ORACLE_OWNER -c "$ORACLE_HOME/bin/dbstart $ORACLE_HOME"
echo "OK"
;;
stop)
echo -n $"Stopping Oracle DB:"
su - $ORACLE_OWNER -c "$ORACLE_HOME/bin/dbshut $ORACLE_HOME"
echo "OK"
;;
*)
echo $"Usage: $0 {start|stop}"
esac

3, Chạy câu lệnh:
chmod 750 /etc/init.d/oracle
chkconfig --add oracle --level 0356

Ok roài! restart thử để thấy kết quả :D!

Wednesday, January 13, 2010

Lấy địa chỉ IP của máy android của bạn!

Cũng chưa có kinh nghiệm nhiều trong lập trình android.
Nhưng mình vừa học được cách lấy ip từ máy android share cho mọi người tham khảo:
Đầu tiên bạn có thể thấy trong lớp WifiInfo có phương thức getIpAddress().
Nhưng kết quả trả về lại là một số nguyên:

WifiManager wifiManager = (WifiManager) getSystemService(WIFI_SERVICE);
WifiInfo wifiInfo = wifiManager.getConnectionInfo();
int ipAddress = wifiInfo.getIpAddress();

Hình như đây không phải là cách đúng.

Một cách khác cũng khá triển vọng là bạn có thể tạo một kết nối socket (socket connection) và dùng thể hiện của Socket để lấy địa chỉ ip của máy mình.
try {
    Socket socket = new Socket("www.androidvn.net", 80);
    Log.i("", socket.getLocalAddress().toString());
} catch (Exception e) {
    Log.i("", e.getMessage());
}

Nhưng cách này hình như lại có một số điểm bất lợi:
    + Bạn tạo ra một kết nối, tạo ra một lưu lượng vận chuyển dẫn đến người dùng có thể bị đánh vào cước :D.
    + Doạn chương trình này được quyết định bởi server mà bạn kết nối tới.
    + Tại đây có thể xảy ra Exception.

Tư tưởng đúng cho trường hợp này là tìm và lặp trên tất các các giao tiếp mạng và tất cả địa chỉ IP :D.

public String getLocalIpAddress() {
    try {
        for (Enumeration<NetworkInterface> en = NetworkInterface.getNetworkInterfaces(); en.hasMoreElements();) {
            NetworkInterface intf = en.nextElement();
            for (Enumeration<InetAddress> enumIpAddr = intf.getInetAddresses(); enumIpAddr.hasMoreElements();) {
                InetAddress inetAddress = enumIpAddr.nextElement();
                if (!inetAddress.isLoopbackAddress()) {
                    return inetAddress.getHostAddress().toString();
                }
            }
        }
    } catch (SocketException ex) {
        Log.e(LOG_TAG, ex.toString());
    }
    return null;
}

Nếu hàm trả về null có nghĩa là không có kết nối nào available.
Nếu hàm trả về một String thì đó là địa chỉ ip hiện tại của thiết bị khi kết nối wifi hay 3G.

Monday, January 11, 2010

Light Racer 2.0 - Day 9 - Adding Items

After working with the AI a bit, I realized that the game feels totally dull to me. I spent a little time thinking about game design and decided to go with levels and items. Items weren't designed in to the game at all so I have to add the whole concept in from scratch. The first item going in is the Speed Boost item. When a player picks it up, their racer will move a notch faster until the end of the round. I have a problem though, the game is coded to run at the speed of the current level, not of the current player.

Here's what I did today:

Built Project Plan
Designed Icon
Implemented basic non-working SpeedBoostItem that could just draw itself
Added SpeedBoostItem to the world
Changed the way motor sounds are handled so they will work at different speeds
Modified game to allow for different speed players
Added a method incrementSpeed() to Player
Added item collision detection
Added random item placement - needs refining
Animated SpeedBoostItem

The hardest thing was adding the concept of speed on to the Player class, which is necessary to have players run at independent speeds. The problem was that all of the AI code and collision detection was using the overall game's speed to calculate distances. I had to change several methods to use the specific player's speed in the calculations, which took about an hour. After that, it was fairly straight-forward.

I drew the images of the item in photoshop:

Speed Boost Item in PhotoshopSpeed Boost Item in Photoshop 3 Image Files3 Image Files

I created the item class and added it to the world. The main game is responsible for placing the item. After that, the item is responsible for detecting a collision and responding. When it's done, it will set a flag that it is finished and the game will remove it from the world. The collision detection is very simple. Here's how it works:

private void checkCollisions(World world) {
// check to see if a player is colliding with me, do something to that player
int top = y - (int) (height * .5) - PLAYER_ITEM_TOUCH_PADDING;
int bottom = y + (int) (height * .5) + PLAYER_ITEM_TOUCH_PADDING;
int left = x - (int) (width * .5) - PLAYER_ITEM_TOUCH_PADDING;
int right = x + (int) (width * .5) + PLAYER_ITEM_TOUCH_PADDING;
Player[] players = world.players;
Player player;
int lx, ly, cx, cy;
for (int playerIndex = 0; playerIndex < players.length; playerIndex++) {
player = players[playerIndex];
lx = player.lastX;
ly = player.lastY;
cx = player.curX;
cy = player.curY;
if (cx == lx && (cx >= left && cx <= right)) {
// moving vertical within horizontal bounds
if ((ly >= bottom && cy < bottom) || (cy > top && ly <= top)) {
// collision
doCollision(player);
}
} else if (cy == ly && (cy >= top && cy <= bottom)) {
// moving horizontal within vertical bounds
if ((lx >= right && cx < right) || (cx > left && lx <= left)) {
// collision
doCollision(player);
}
}
}
}

The animation code is the same code I always use for animations

For now the game is just randomly dropping the item all over but once I have all 3 items in, I'll work out the balance of the item drop. For now it really added a new dynamic element to the game. I can see the game getting much more fun in the next few weeks!

Here's a video of the new item working.



Friday, January 8, 2010

Bắt đầu với google maps trên android

Trước tiên bạn phải đăng ký một cái maps API key của google bằng cách vào
http://code.google.com/android/maps-api-signup.html
Trước đó bạn phải kiếm cái MD5 của máy mình đã bằng cách
Kiểm tra thư mục C:Documents and Settings<UserName>.android
Của mình cụ thể là C:Documents and SettingsTanNM.android
Bạn sẽ thấy cái file debug.keystore
copy nó vào trong C:Program FilesJavajdkbin
trên dòng lệnh command bạn cd vào thư mục C:Program FilesJavajdkbin
Chạy câu lệnh:
keytool -list -alias androiddebugkey -keystore debug.keystore -storepass android -keypass android

Sẽ được một kq giống như:
   1. androiddebugkey, Oct 27, 2009, PrivateKeyEntry,
   2. Certificate fingerprint (MD5): E1:D0:F8:0C:F7:11:F0:04:F9:F7:2F:21:49:DD:F7:B3

Sau đó vào trang
http://code.google.com/android/maps-api-signup.html
điền cái mã MD5:
E1:D0:F8:0C:F7:11:F0:04:F9:F7:2F:21:49:DD:F7:B3

vào và submit, ta sẽ có một key giống như:
09BcO4uoQ0MIS9P9FU2G2MK2imfqIE5kvrJ8JRA

Ngon roài!!!!!!

Tiếp đến ta tạo một ứng dụng đơn giản trên myeclipse
file Manifest
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
       package="com.ftl.map">
        <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
        <uses-permission android:name="android.permission.INTERNET" />
        <application android:label="@string/activity_sample_code"
               android:icon="@drawable/icon">
                <uses-library android:name="com.google.android.maps" />
                <activity android:name="com.ftl.map.view.MapViewDemo"
                       android:label="MapView">
                        <intent-filter>
                                <action android:name="android.intent.action.MAIN" />
                                <category android:name="android.intent.category.SAMPLE_CODE" />
                        </intent-filter>
                </activity>
        </application>
</manifest>

file main.xml

<?xml version="1.0" encoding="utf-8"?>

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
       android:id="@+id/main" android:layout_width="fill_parent"
       android:layout_height="fill_parent">
        <com.google.android.maps.MapView
               android:layout_width="fill_parent" android:layout_height="fill_parent"
               android:enabled="true" android:clickable="true" android:apiKey="09BcO4uoQ0MIS9P9FU2G2MK2imfqIE5kvrJ8JRA" />
</LinearLayout>


file java Activity

package com.ftl.map.view;

import android.os.Bundle;

import com.google.android.maps.MapActivity;
import com.google.android.maps.MapView;

public class MapViewDemo extends MapActivity {

        private MapView myMapView;

        @Override
        public void onCreate(Bundle savedInstanceState) {
                super.onCreate(savedInstanceState);
                setContentView(com.ftl.map.R.layout.main);
        }

        @Override
        protected boolean isRouteDisplayed() {
                return true;
        }
}

Chạy nào!!!!!