[Java] Visibility에서 추가했으면 하는 것….

Java visibility는 private, protected, default(package private), public 이렇게 4단계가 있다.
그런데 개인적으로 한단계 정도 더 있었으면 한다.

기능별로 block을 형성하도록 programming할 수 있어야 한다. 그게 oop의 기본이기도 하다.
하나의 class가 하나의 block을 형성할 수 있으면 좋겠지만, 보통 여러개의 class가 하나의 기능 block을 형성한다.
그리고, 이 기능 block의 내부 interface는 package private으로 하고, 외부 interface는 public으로 둔다.
이게 Java에서의 일반적인 programming방법이다.
그런데, 어떤 기능 block 자체가 더 큰 기능 block의 한 부분이게 하고 싶은 경우는 어떻게 해야 하는가?
물론, 재 사용성을 위해서 모든 기능 블럭은 자체적으로 완벽하게 동작하도록 디자인하고, 관련 interface는 public으로 해 둘 수 있게 하는것이 이상적이긴 하다.
그렇지만, 대부분의 경우, 큰 기능 블럭의 한 부분임을 가정하고 programming하는 경우가 많다.
왜냐하면, 일반적인 기능블럭(public interface를 가지는…)을 만들어 내기 위해서는 추가적인 많은 노력들이 필요하기 때문이다.
그런데, Java의 visibility는 이런 경우를 해결해 줄 수 없다.
(하나의 package로 구성된 기능 block의 interface는 public이여야만 한다.)
그래서 개인적으로 추가적인 안을 제시해 본다.

*** tree-based name space ***

name space가 tree형태를 가진다. java convention을 이용해 설명하면, ‘.’을 separator로 하고, 각 name이 tree의 path를 의미하도록 하는 것이다.
예를 들면, ‘com.java.io’라면, ‘java’는 ‘com’의 child 이고, ‘io’는 ‘java’의 child가 된다.

***  parent private ***

visibility가 자신의 parent에게만 되도록…

음.. visibility가 자꾸 많아지는 것도 안 좋긴 한데… 일단 이런게 있었으면 좋겠다… 단점도 있을 것 같은데.. 좀더 고민해 보자…

Advertisements

[Linux][C/C++] strange pipe issue in linux in ‘ylisp’.

In Linux, read or write side of pipe is automatically closed if there is no reference for the other side – file is really closed.
But I faced with strange case when implementing a ‘ylisp’ function – pipe is automatically closed even if there is still valid file descriptor that references that pipe.
Here is simpler version of issued code.

/* function */
{
    int   fd[2];
    pid_t cpid;
    pipe (fd);
    cpid = fork();
    if (cpid == 0) {
        close (fd[0]); /* close read end */
        dup2 (fd[1], STDIN_FILENO);
        /* --- (*a) --- */
        close (fd[0]); /* <-- (*1) */
        /* --- (*b) --- */
        ...
        execvp (...)
    } else {            /* Parent writes argv[1] to pipe */
        close (fd[1]); /* close write end */
        ... /* read end is used */
    }
    ...
}

ylisp is multi-threaded program. And building/running environment is

OS : Linux 2.6.35-24-generic-pae #42-Ubuntu SMP Thu Dec 2 03:21:31 UTC 2010 i686 GNU/Linux
Compiler : gcc (Ubuntu/Linaro 4.4.4-14ubuntu5) 4.4.5
libc : Ubuntu EGLIBC 2.12.1-0ubuntu10.1

For testing, I put test code to check whether STDIN_FILENO is valid file descriptor or not.
Interestingly, sometimes, STDIN_FILENO is invalid at (*b), even if it is valid at (*a).
I don’t have any idea what happens to this code.
Fortunately, commenting out (*1) seems to be a walk-around for this issue, but it’s just temporal solution.
‘fd[0]’ is never closed in this walk-around.

I need to look into this with more time… very interesting…

[Java] Some notable stuffs of VM

⚫ From VM Spec

⚬ In particular, x != x is true if and only if x is NaN, and (x<y) == !(x>=y) will be false if x or y is NaN.
⚬ round towards zero
⚬ Multibyte data items are always stored in big-endian order.

⚫ Java VM Type Signature

Signature                     Java Type
Z                             boolean
B                             byte
C                             char
S                             short
I                             int
J                             long
F                             float
D                             double
L fully-qualified-class ;     fully-qualified-class
[ type                        type[]
( arg-types ) ret-type        method type

to be continue …

[C/C++][Linux] Avoiding making zombie process

If parent doesn’t use ‘wait’ system call for it’s child, that child becomes zombie after end of execution.
(At zombie state, all allocated resources are removed, but it is still in process table for parent to get child’s exit status.)
Here is very simple example

int
main (int argc, char* argv[]) {
    if (fork ()) { /* parent */
        [*A]
        sleep(999999);
    } else { /* child */
        sleep(1);
    }
    return 0;
}

In this case, child becomes zombie.
Simplest way to avoid making zombie is get exit status of child by use ‘wait’ system call at signal handler for SIGCHLD.
The point is, “DO NOT forget about getting child’s exit status not to make zombie!”
At above example following codes should be added at [*A]

int status; wait(&status);

Done!

[C/C++][Linux] Tips about LD_PRELOAD

“LD_PRELOAD” is set to path of shared libraries. And those are loaded at first (even before C runtime).

LD_PRELOAD=./my.so:/path/to/a.so:/path/to/b.so

One good point is, “Developer can override symbols in the stock libraries, with symbols in LD_PRELOAD-specified-libraries.
For example, ‘malloc’ can be overridden with user-defined one by using LD_PRELOAD.

And another good tip is using LD_PRELOAD with ‘__attribute__((constructor))’.
‘__attribute__((constructor))’ is GCC specific syntax for C/C++.
Functions tagged ‘__attribute__((constructor))’, are located at ‘.ctors’ section of ELF and run when shared library is loaded.
(‘__attribute__((destuctor))’ functions are located at ‘.dtors’ section and run when shared library is unloaded.)
So, functions tagged ‘__attribute__((constructor))’ in LD_PRELOAD-specified-library are executed before ‘main’ function.
It is fantastic, isn’t it?

Real example is ‘stdbuf’ of gnu coreutils.
There are two main parts in ‘stdbuf’. Here are details.

libstdbuf.so :
    libstdbuf.so has stdbuf() tagged '__attribute__((destructor))'.
    In stdbuf, modes of standard buffers - stdin, stdout, stderr - are modified.

stdbuf
    stdbuf puts 'libstdbuf.so' to LD_PRELOAD.
    And then, 'exec()' to main program to execute.

==> So, modes of standard buffer of main program can be changed    

Enjoy trick of LD_PRELOAD!
For more detail example, see this post

[C/C++][linux] redirect standard io with pipe in code.

There are lot’s of articles that introduces way of using pipe and redirecting standard IO with those.
But, whenever try to do this, there is always big issue – buffer mode!
See following example.

< Tested on [Ubuntu EGLIBC 2.12.1-0ubuntu9] + [Ubuntu 2.6.35-23-generic-pae] >

#include <stdio.h>
#define _tstr "Sample Text\n"
int
main () {
    int fdp[2];
    pipe (fdp);
    if (0 != fork ()) {/* parent */
        dup2 (fdp[1],1); /* redirect standard out */
        /* fdp is not used anymore */
        close (fdp[0]);
        close (fdp[1]);
        [*A] /* <--- see below */
        sleep(99999999);
    } else {
        int  rb;
        char buf[100];
        dup2 (fdp[0],0); /* redirect standard in */
        /* fdp is not used anymore */
        close (fdp[0]);
        close (fdp[1]);
        if (0 >= (rb = [*B])) perror("IO Error\n"); /* <-- see below for [*B] */
        buf[rb] = 0; /* add trailing 0 */
        printf ("read from input:%s\n", buf);
        sleep(99999999);
    }
}

< *** [*A][*B] pair and result. *** >
OK pairs
    [*A] : write (fdp[1], ...)   |   [*B] : read (fdp[0], ...)
    [*A] : write (1, ...)        |   [*B] : read (fdp[0], ...)
    [*A] : write (1, ...)        |   [*B] : read (0, ...)
    [*A] : printf (_tstr); fflush (stdout) | [B] : read (1, ...)

NOT OK pairs - printed output is "read from input:" ('_tstr' is not printed immediately)
    [*A] : printf (_tstr);       | [*B] : read (0, ...)
        -> 'fflush' is missing here. But '\n' is at the end of test string...

Why ‘printf’ doesn’t work without ‘flush’?
‘printf’ uses standard buffer (at first IO operation, buffer is allocated by using ‘malloc’).
And because, output device is pipe – not console, buffered mode is used.
So, until flushing, all outputs are stored in buffer (NOT device).
To make pipe be REALLY like standard IO, mode of those buffer should be LINE BUFFERED mode.
So, ‘setvbuf() or setlinebuf()’ should be used at the first of [*A] as follows.

[*A] : setlinebuf (stdout); printf (_tstr);
    OR setvbuf (stdout, (char*)NULL, _IOLBF, 0); printf (_tstr);

It is simple, isn’t it?

Here is more complicated cases.
See following example.

< Tested on [Ubuntu EGLIBC 2.12.1-0ubuntu9] + [Ubuntu 2.6.35-23-generic-pae] >

< main.c >
#include <stdio.h>
int
main() {
    int fdp[2]; /* pipe */
    pipe (fdp);
    if (0 != fork()) { /* parent */
        dup2 (fdp[1], 1); /* redirect standard out */
        close (fdp[0]);
        close (fdp[1]); 
        [*C] /* <-- see below */
        execlp ("test", (char*)0); /* run test (*1) */
    } else {
        int  rb;
        char buf[100];
        dup2 (fdp[0],0); /* redirect standard in */
        /* fdp is not used anymore */
        close (fdp[0]);
        close (fdp[1]);
        if (0 >= (rb = [*B])) perror("IO Error\n");
        buf[rb] = 0; /* add trailing 0 */
        printf ("read from input:%s\n", buf);
        sleep(99999999);
    }

< test.c > => test (executable)
int
main () {
    printf("This is Test!\n");
    sleep(99999999);
}

As above case, string from ‘test’ – “This is Test!” – is not printed to console immediately because it is buffered.
(Assume that, < test.c > SHOULD NOT be modified!)
Is there solution? Yes.
Before moving next step, see this post first.

Combination of LD_PRELOAD and  __attribute__ ((constructor)) is solution.
To do this, new file is added to make share library that will be preloaded.

< mystdbuf.c > => libmystdbuf.so
#include <stdio.h>
__attribute__ ((constructor)) static void
mystdbuf () {
    setvbuf (stdout, (char*)NULL, _IOLBF, 0);
}

And add following codes to section [*C]

putenv ("LD_PRELOAD=./libmystdbuf.so");

Resolved!

Another easy and popular solution is using ‘stdbuf’ command in gnu core-utils.
Replace (*1) with

execlp ("stdbuf", "stdbuf", "-oL", "./test", (char*)0);

As described in LINK above, mechanism of ‘stdbuf’ is exactly same with above manual solution!
Done!

[Java] Simple sample codes to remind…

* Following codes is to change byte[] to integer-typed-value and vice versa.
=> Note : JavaVM uses Big-Endian. And, size of each integer-type is byte(1), short(2), int(4), long(8).

public static final int
byteArrayToLongBE(byte[] b) {
    return ((b[0]&0xff) << 56) + ((b[1]&0xff) << 48)
         + ((b[2]&0xff) << 40) + ((b[3]&0xff) << 32)
         + ((b[4]&0xff) << 24) + ((b[5]&0xff) << 16)
         + ((b[6]&0xff) << 8)  + (b[7]&0xff);
}

public static final int
byteArrayToLongLE(byte[] b) {
    return (b[0]&0xff          + ((b[1]&0xff) << 8)
         + ((b[2]&0xff) << 16) + ((b[3]&0xff) << 24)
         + ((b[4]&0xff) << 32) + ((b[5]&0xff) << 40)
         + ((b[6]&0xff) << 48) + ((b[7]&0xff) << 56));
}

public static final int
byteArrayToIntBE(byte[] b) {
    return ((b[0]&0xff) << 24) + ((b[1]&0xff) << 16)
         + ((b[2]&0xff) << 8) + (b[3]&0xff);
}

public static final int
byteArrayToIntLE(byte[] b) {
    return (b[0]&0xff) + ((b[1]&0xff) << 8)
         + ((b[2]&0xff) << 16) + ((b[3]&0xff) << 24);
}

public static final short
byteArrayToShortBE(byte[] b) {
    return (short) (((b[0]&0xff) << 8) + (b[1]&0xff));
}

public static final short
byteArrayToShortLE(byte[] b) {
    return (short) ((b[0]&0xff) + ((b[1]&0xff) << 8));
}

public static final byte[]
longToByteArrayBE(long v) {
    return new byte[] {
            (byte)(v >>> 56), (byte)(v >>> 48),
            (byte)(v >>> 40), (byte)(v >>> 32),
            (byte)(v >>> 24), (byte)(v >>> 16),
            (byte)(v >>> 8),  (byte)v};
}

public static final byte[]
longToByteArrayLE(long v) {
    return new byte[] {
            (byte)v,          (byte)(v >>> 8),
            (byte)(v >>> 16), (byte)(v >>> 24),
            (byte)(v >>> 32), (byte)(v >>> 40),
            (byte)(v >>> 48), (byte)(v >>> 56)};
}

public static final byte[]
intToByteArrayBE(int v) {
    return new byte[] {
            (byte)(v >>> 24), (byte)(v >>> 16),
            (byte)(v >>> 8),  (byte)v};
}

public static final byte[]
intToByteArrayLE(int v) {
    return new byte[] {
            (byte)v,          (byte)(v >>> 8),
            (byte)(v >>> 16), (byte)(v >>> 24)};
}

public static final byte[]
shortToByteArrayBE(short v) {
    return new byte[] {(byte)(v >>> 8), (byte)v };
}

public static final byte[]
shortToByteArrayLE(short v) {
    return new byte[] {(byte)v, (byte)(v >>> 8) };
}

* Run process

// Recommanded
// Run shell command and return it's output as string
public static String
runCmd(String... cmd) {
    String r = "";
    try {
        // execute command
        ProcessBuilder pb = new ProcessBuilder(cmds);
        // pb.redirectErrorStream(true); // if needed.
        // wait till running is done.
        Process pr = pb.start();
        pr.waitFor() ;
        String line;
        // Reader output of sub process.
        BufferedReader br = new BufferedReader(new InputStreamReader(pr.getInputStream())) ;
        // Make output String object
        while ( null != (line = br.readLine()) ) r += line + "\n";
    } catch (Exception e) {
        ; // Exception Handling!
    }
    return r;
}

// OR
public static String
    runCmd(String[] cmds) {
    String r = "";
    try {
        // execute command
        Process pr = Runtime.getRuntime().exec(cmds) ;
        // wait till running is done.
        pr.waitFor() ;
        // Reader output of sub process.
        BufferedReader br = new BufferedReader(new InputStreamReader(pr.getInputStream())) ;
        // Make output String object
        String  line;
        while ( null != (line = br.readLine()) ) r += line + "\n";
    } catch (Exception e) {
        ; // Exception Handling!
    }
    return r;
}

* Run shell command

// We should invoke SHELL (not process command directly)
// See above for 'runCmd'
String cmd = "ls -al | grep text";
runCmd("/bin/bash", "-c", cmd);
// or : runCmd(new String[]{"/bin/bash", "-c", cmd});

* Multi-lined JLabel : We can do this by using HTML directly.

JLabel jl = new JLabel("<html>1st line<br>2nd line</html>");

* Loading java property

Properties prop = new Properties();
try {
    prop.load(new FileInputStream(property_file_path));
} catch (IOException e) {
    ; // exception handling
}

* String to Integer

try {
    int v = Integer.parseInt("3456");
} catch (NumberFormatException e) {
    ; // exception handling
}

=== to be continued…