rmi 서버를 종료했다가 rmi를 실행할 때, 유의할 점이 있다.

실행시, 

처음 실행할 때는 createRegistry를 사용한다.
 LocateRegistry.createRegistry(rmiPort);

rmi 서버를 종료하고 다시 실행할 때는 getRegistry를 사용하면 된다.

코드는 다음과 같다.



 


/**

 * A RMI Server class binds or unbinds <code>NetworkDataBase</code> class.   

 * 

 * @author Kim, Yong Hwan

 * @version 1.0

 * 

 */

public class RMIServer {

/**

* <code>NetworkDataBase</code> object to bind or unbind

*/

private static NetworkDataBase ndb;

/**

* RMI Server port

*/

private static int port;

/**

* Checks if connection is valid

*/

private static boolean isConnected;

/**

* Checks if rmi server is running in first time

*/

private static boolean firstTime = true;

 

    /**

     * Binds the remote RMI database on the specified port.

     * 

     * @param dbLocation 

     *   database file location.

     * @param rmiPort

     *            port on the server.

     * @throws RemoteException

     *            Thrown if the remote database, <code>NetworkDataBase</code> 

     *            class could not be accessed.

     */

    public static void register(String dbLocation, int rmiPort) throws RemoteException {

    Registry registry;

    port = rmiPort;

    ndb = new NetworkDataBase(dbLocation); 

    if (firstTime) {

    registry = LocateRegistry.createRegistry(rmiPort);

    firstTime = false;

    } else {

    registry = LocateRegistry.getRegistry(rmiPort);

    }

        registry.rebind("database", ndb);


        isConnected = true;

    }

    

    /**

     * Unbinds and unexports the remote RMI database 

     * 

     * @throws RemoteException

     *            Thrown if the rmi server is not shutdown.

     */

    public static void exit() throws RemoteException {

    try {

Naming.unbind("rmi://127.0.0.1:" + port + "/database");

} catch (Exception e){

throw new RemoteException(e.getMessage());

}

        ndb = null;

        port = 0;

        isConnected = false;

    }

    

    /**

     * Gets if connection is valid;

     * @return return true, if connection is alive. Otherwise return false.

     */

    public static boolean isConnected() {

    return isConnected;

    }

}

Posted by '김용환'
,


 concurrency bug patterns for multicore systems
http://www.ibm.com/developerworks/java/library/j-concurrencybugpatterns/index.html?ca=drs-


1. An antipattern from Jetty

volatile 변수를 쓸 데 없는 곳에 사용하지 마라, Optimization에 관련된 필드 선언이기 때문에 잘 모르면 쓰지 말고, java.util.concurrent 패키지의 AtomicXX 클래스를 사용해라 .


2. Synchronization on mutable fields

변하지 않는 객체로만 동기화 객체로 써라, 객체의 인스턴스가 여러 개로 나누어지면 동기화를 보장할 수 있다. 동기화는 인스턴스 단위이다.


3. java.util.concurrent lock leak
java.util.concurrent.Lock 사용시에는 finally로 반드시 lock을 처리한다.
Lock의 생성과 해지를 늘 기억해라. 이런 게 귀찮다고 생각하지 말자. c/c++은 끔직했다...


4. Performance tuning synchronized blocks
동기화 블럭은 최소단위로 써라


5. Multi-stage access
상황에 잘 맞게 써야 하는데, 무조건 이렇게 바꾸라는 것은 아니다.
thread-safe한 메소드를 잘 구현하고 싶을 때, 클래스안의 변수는 동기화 타입(ConcurrentHashMap)이긴 하지만, return 또는 선언하는 곳에서 문제가 될 수 있다. 
무조건 동기화 변수만 쓴다고 해서 모든 곳에서 다 동기화가 이루어진다고 생각하지 말자.


6. Symmetric lock deadlock
중첩으로 동기코드를 작성시에는 순서를 잘 고려하면서 사용해야 한다.


기술지원하다보면, 사람들은 가끔씩 3, 5번 정도가 조금 걸리는 것 같다.
요즘에 framework가 thread-safe한 인스턴스 기반이라서 framework 기반이 아닐 때만 이슈인듯.. 지금은 framework을 쓰다보니.. 문제는 생기지는 않지만, frameowork없이 개발을 못한다는 한계가 있다.

Posted by '김용환'
,


어디서 문제가 되었나 했더니..
아파치 루씬/Solr 쪽에서 테스트하다가 문제 발견되었다.
jdk7 뿐 아니라 jdk6 에서도 영향이 있을 수 있으니. 조심히 jvm option 체크할 것!
(아래 빨강 색칠)

http://www.lucidimagination.com/blog/2011/07/28/dont-use-java-7-for-anything/


From: Uwe Schindler
Date: Thu, 28 Jul 2011 23:13:36 +0200
Subject: [WARNING] Index corruption and crashes in Apache Lucene Core / Apache Solr with Java 7

Hello Apache Lucene & Apache Solr users,
Hello users of other Java-based Apache projects,

Oracle released Java 7 today. Unfortunately it contains hotspot compiler
optimizations, which miscompile some loops. This can affect code of several
Apache projects. Sometimes JVMs only crash, but in several cases, results
calculated can be incorrect, leading to bugs in applications (see Hotspot
bugs 7070134 [1], 7044738 [2], 7068051 [3]).

Apache Lucene Core and Apache Solr are two Apache projects, which are
affected by these bugs, namely all versions released until today. Solr users
with the default configuration will have Java crashing with SIGSEGV as soon
as they start to index documents, as one affected part is the well-known
Porter stemmer (see LUCENE-3335 [4]). Other loops in Lucene may be
miscompiled, too, leading to index corruption (especially on Lucene trunk
with pulsing codec; other loops may be affected, too – LUCENE-3346 [5]).

These problems were detected only 5 days before the official Java 7 release,
so Oracle had no time to fix those bugs, affecting also many more
applications. In response to our questions, they proposed to include the
fixes into service release u2 (eventually into service release u1, see [6]).
This means you cannot use Apache Lucene/Solr with Java 7 releases before
Update 2! If you do, please don’t open bug reports, it is not the
committers’ fault! At least disable loop optimizations using the
-XX:-UseLoopPredicate JVM option to not risk index corruptions.

Please note: Also Java 6 users are affected, if they use one of those JVM
options, which are not enabled by default: -XX:+OptimizeStringConcat or
-XX:+AggressiveOpts

It is strongly recommended not to use any hotspot optimization switches in
any Java version without extensive testing!

In case you upgrade to Java 7, remember that you may have to reindex, as the
unicode version shipped with Java 7 changed and tokenization behaves
differently (e.g. lowercasing). For more information, read
JRE_VERSION_MIGRATION.txt in your distribution package!

On behalf of the Lucene project,
Uwe

[1] http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=7070134
[2] http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=7044738
[3] http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=7068051
[4] https://issues.apache.org/jira/browse/LUCENE-3335
[5] https://issues.apache.org/jira/browse/LUCENE-3346
[6] http://s.apache.org/StQ

Posted by '김용환'
,
loop 관련 코드를 최적화하면서 for, while 문에 문제가 있다고 알려진 버그들.

http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=7070134
http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=7044738
http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=7068051



open jdk7에서는 관련 코드(loop predicate)를 삭제를 했음
http://hg.openjdk.java.net/hsx/hotspot-comp/hotspot/rev/c96c3eb1efae
 
해결을 위해서는 아래 옵션을 jvm에 추가해야 함.

 -XX:-UseLoopPredicate
Posted by '김용환'
,
Posted by '김용환'
,
Posted by '김용환'
,
Posted by '김용환'
,



javap.exe 또는 이클립트 플러그인을 이용하는 방법이 있다. 나는 그냥 javap를 활용한다.

그냥 javap.exe 파일 을 쓰지 않고...

E:\jdk1.7\test\bin>"c:\Program Files\Java\jdk1.7.0\bin\javap.exe" HelloWorld.class
Compiled from "HelloWorld.java"
public class HelloWorld {
  public HelloWorld();
  public static void main(java.lang.String[]);
}



"javap.exe -c 클래스이름" 이란 명령어를 내린다.

E:\jdk1.7\test\bin>"c:\Program Files\Java\jdk1.7.0\bin\javap.exe" -c HelloWorld.class
Compiled from "HelloWorld.java"
public class HelloWorld {
  public HelloWorld();
    Code:
       0: aload_0
       1: invokespecial #8                  // Method java/lang/Object."<init>":()V
       4: return

  public static void main(java.lang.String[]);
    Code:
       0: ldc           #16                 // String Hello World
       2: astore_1
       3: getstatic     #18                 // Field java/lang/System.out:Ljava/io/PrintStream;
       6: aload_1
       7: invokevirtual #24                 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
      10: return
}





Posted by '김용환'
,

http://www.youtube.com/watch?v=hcY8cYfAEwU




Effective java 의 저자로 유명한 Josh Bloch의 발표동영상이다.

발로 적은 내용을 공유한다. 

성공할 수 없었던 자바의 특징을 먼저 설명하였다. (장점은 아래 PPT 참조) 특별히, 다른 언어에서 사용하는 일부 기능 생략도 성공 중의 하나였다.(lexical macros, multiple implementation inheritance, operator overloading, 헤더 파일, 다큐먼트).  

이 분이 얘기한 자바의 단점 또는 추한 부분을 얘기했다.
1. int->float, long->double형으로 형을 변환(conversion)하면서 생기는 문제(widening)
2. compound 할당 연산자가 작은 타입으로 변환하는 casting 문제 (narrowing)
3. equals를 구현(override)하였지만, ==, != 연산자는 주소를 가지고 비교한다. 
4. constant 변수가 inline된다. 
5. 
불필요한 비안정성을 이끌었던 디폴트 생성자는 처음부터 없어야 한다
6. 생성자에서 override된 메소드를 호출하는 것이 가능(legal)하면 안된다. 미묘한 버그를 생산할 수 있다.
7. unsigned 타입의 부재
8. 단일화된 Exception 상속개념이 없다.
9. switch 문이 잘 구조화되지 않았다.
10. Arrays의 toString을 잘 구현해야 내용물이 출력한다. 자바를 처음 배우는 친구들이 매번 실수한다.
11. Exception이 막 발생한 (pending) exception을 제거하고 새로운 것으로 만들 수 있다.
12. Cloneable 인터페이스에 clone 이라는 함수가 없다. 




발표자료가 웹에 없어서 캡쳐해서 공유한다. 

























Posted by '김용환'
,

language 레벨에서 concurrent 이슈와 Parallel 이슈를 나누어서 해결할 수 있도록 하는 컨셉으로 발표한 자료이다. 둘의 이슈를 자바보다는 스칼라로 해결하는 게 쉬울 수 있다는 얘기이다. 





발표자료는 다음과 같다. 

Oscon keynote: Working hard to keep it simple


기억에 남는 부분을 남겨둔다.













Posted by '김용환'
,