Jshell 启动错误 build 9-ea+121


Exception in thread "main" java.lang.InternalError: Launching execution engine threw: Failed remote launch: com.sun.jdi.CommandLineLaunch (defaults: home=/Library/Java/JavaVirtualMachines/jdk-9.jdk/Contents/Home, options=, main=, suspend=true, quote=", vmexec=java) -- {home=home=/Library/Java/JavaVirtualMachines/jdk-9.jdk/Contents/Home, options=options=, main=main=jdk.internal.jshell.remote.RemoteAgent 57696, suspend=suspend=true, quote=quote=", vmexec=vmexec=java}
at jdk.jshell.JShell.executionControl(jdk.jshell@9-ea/JShell.java:714)
at jdk.jshell.Unit.classesToLoad(jdk.jshell@9-ea/Unit.java:275)
at jdk.jshell.Eval.lambda$compileAndLoad$15(jdk.jshell@9-ea/Eval.java:580)
at java.util.stream.ReferencePipeline$7$1.accept(java.base@9-ea/ReferencePipeline.java:269)
at java.util.ArrayList$ArrayListSpliterator.forEachRemaining(java.base@9-ea/ArrayList.java:1477)
at java.util.stream.AbstractPipeline.copyInto(java.base@9-ea/AbstractPipeline.java:484)
at java.util.stream.AbstractPipeline.wrapAndCopyInto(java.base@9-ea/AbstractPipeline.java:474)
at java.util.stream.ReduceOps$ReduceOp.evaluateSequential(java.base@9-ea/ReduceOps.java:913)
at java.util.stream.AbstractPipeline.evaluate(java.base@9-ea/AbstractPipeline.java:234)
at java.util.stream.ReferencePipeline.collect(java.base@9-ea/ReferencePipeline.java:511)
at jdk.jshell.Eval.compileAndLoad(jdk.jshell@9-ea/Eval.java:581)
at jdk.jshell.Eval.declare(jdk.jshell@9-ea/Eval.java:441)
1 127.0.0.1 Hais-MacBook-Pro
at jdk.jshell.Eval.processMethod(jdk.jshell@9-ea/Eval.java:372)
at jdk.jshell.Eval.eval(jdk.jshell@9-ea/Eval.java:127)
at jdk.jshell.JShell.eval(jdk.jshell@9-ea/JShell.java:393)
at jdk.internal.jshell.tool.JShellTool.processCompleteSource(jdk.jshell@9-ea/JShellTool.java:2114)
at jdk.internal.jshell.tool.JShellTool.processSource(jdk.jshell@9-ea/JShellTool.java:2102)
at jdk.internal.jshell.tool.JShellTool.processSourceCatchingReset(jdk.jshell@9-ea/JShellTool.java:789)
at jdk.internal.jshell.tool.JShellTool.run(jdk.jshell@9-ea/JShellTool.java:769)
at jdk.internal.jshell.tool.JShellTool.startUpRun(jdk.jshell@9-ea/JShellTool.java:706)
at jdk.internal.jshell.tool.JShellTool.resetState(jdk.jshell@9-ea/JShellTool.java:663)
at jdk.internal.jshell.tool.JShellTool.start(jdk.jshell@9-ea/JShellTool.java:483)
at jdk.internal.jshell.tool.JShellTool.start(jdk.jshell@9-ea/JShellTool.java:462)
at jdk.internal.jshell.tool.JShellTool.main(jdk.jshell@9-ea/JShellTool.java:452)
Caused by: java.lang.InternalError: Failed remote launch: com.sun.jdi.CommandLineLaunch (defaults: home=/Library/Java/JavaVirtualMachines/jdk-9.jdk/Contents/Home, options=, main=, suspend=true, quote=", vmexec=java) -- {home=home=/Library/Java/JavaVirtualMachines/jdk-9.jdk/Contents/Home, options=options=, main=main=jdk.internal.jshell.remote.RemoteAgent 57696, suspend=suspend=true, quote=quote=", vmexec=vmexec=java}
at jdk.internal.jshell.jdi.JDIConnection.reportLaunchFail(jdk.jshell@9-ea/JDIConnection.java:353)
at jdk.internal.jshell.jdi.JDIConnection.launchTarget(jdk.jshell@9-ea/JDIConnection.java:319)
at jdk.internal.jshell.jdi.JDIConnection.open(jdk.jshell@9-ea/JDIConnection.java:120)
at jdk.internal.jshell.jdi.JDIEnv.init(jdk.jshell@9-ea/JDIEnv.java:49)
at jdk.internal.jshell.jdi.JDIExecutionControl.jdiGo(jdk.jshell@9-ea/JDIExecutionControl.java:425)
at jdk.internal.jshell.jdi.JDIExecutionControl.start(jdk.jshell@9-ea/JDIExecutionControl.java:95)
at jdk.jshell.JShell.executionControl(jdk.jshell@9-ea/JShell.java:712)
... 23 more
Caused by: com.sun.jdi.connect.VMStartException: VM initialization failed for: /Library/Java/JavaVirtualMachines/jdk-9.jdk/Contents/Home/bin/java -Xdebug -Xrunjdwp:transport=dt_socket,address=Hais-MacBook-Pro:57697,suspend=y jdk.internal.jshell.remote.RemoteAgent 57696
at com.sun.tools.jdi.AbstractLauncher$Helper.launchAndAccept(jdk.jdi@9-ea/AbstractLauncher.java:193)
at com.sun.tools.jdi.AbstractLauncher.launch(jdk.jdi@9-ea/AbstractLauncher.java:132)
at com.sun.tools.jdi.SunCommandLineLauncher.launch(jdk.jdi@9-ea/SunCommandLineLauncher.java:225)
at jdk.internal.jshell.jdi.JDIConnection.launchTarget(jdk.jshell@9-ea/JDIConnection.java:312)
... 28 more

https://bugs.openjdk.java.net/browse/JDK-8131029
这个问题在新版的已经被修复了,但是如果碰到了,可以修改 /etc/hosts 来绕过(增加一个本地计算机名字的 loop ip)

本地计算机名字可以用
uname -n
来查看

参考这个文章找到的 workaround

怎样为Android添加一个系统级服务

内容均来自于网络资料,源码以及自己的理解,如有错误的地方还请指出!示例源码可以随意使用。

我这里使用的环境如下

PLATFORM_VERSION_CODENAME=AOSP
PLATFORM_VERSION=4.0.9.99.999.9999.99999
TARGET_PRODUCT=full_panda
TARGET_BUILD_VARIANT=userdebug
TARGET_BUILD_TYPE=release

Android提供了一些基础服务,但是如果你想给它添加一些特定的服务的话,也是可以的(比如在一直到某些特定的平台下,需要增加/裁剪一些服务)

比如我们都知道Android上用的最广泛的应该是多媒体服务,其对应的有一个mediaserver进程,然后比如我们的
AudioFlinger/MediaPlayerService/CameraService/AudioPolicyService
都是跑在这个进程里面的

那如果我们想自己增加一个类似的东西可不可以呢?答案当然是可以的。

很简单的几点就可以帮你完成

启动进程

/path/to/aosp/frameworks/base/customized_service/server

具体服务实现

/path/to/aosp/frameworks/base/customized_service/libcustomizedservice

系统开机启动

/path/to/aosp/system/core/rootdir/init.rc

添加如下内容到init.rc文件

service customized /system/bin/customizedserver
    class main
    user media
    group audio camera

我是用的Pandaboard
编译整个ROM,然后fastboot flashall

I/        ( 1080): ServiceManager: 0x40ce4f00
D/        ( 1080): CustomizedService instantiate
D/        ( 1080): CustomizedService created
E/ServiceManager(   94): add_service('test.customized',0x44) uid=xxxx - PERMISSION DENIED
D/        ( 1080): CustomizedService r = -1
D/        ( 1080): CustomizedService destroyed

或者你想从shell当中启动这个服务的进程也会出现类似权限不足的问题,追一下log就很快会发现问题

int do_add_service(struct binder_state *bs,
                   uint16_t *s, unsigned len,
                   void *ptr, unsigned uid, int allow_isolated)
{
    struct svcinfo *si;

    if (!ptr || (len == 0) || (len > 127))
        return -1;

    if (!svc_can_register(uid, s)) {
        ALOGE("add_service('%s',%p) uid=%d - PERMISSION DENIED\n",
             str8(s), ptr, uid);
        return -1;
    }

    si = find_svc(s, len);
 
    ......

    binder_acquire(bs, ptr);
    binder_link_to_death(bs, ptr, &si->death);
    return 0;
}
int svc_can_register(unsigned uid, uint16_t *name)
{
    unsigned n;
    
    if ((uid == 0) || (uid == AID_SYSTEM))
        return 1;

    for (n = 0; n < sizeof(allowed) / sizeof(allowed[0]); n++)
        if ((uid == allowed[n].uid) && str16eq(name, allowed[n].name))
            return 1;

    return 0;
}

可以看出能注册service的用户的uid只能是0即ROOT或者是AID_SYSTEM,或者是allowed列表当中的服务,最简单的就是把所要添加的服务加到列表当中

{ AID_MEDIA, "test.customized" },

而服务allowed列表位于

/path/to/aosp/frameworks/base/cmds/servicemanager/service_manager.c

重新编译ROM,烧完之后启动看到customizedservice这个进程起来的话,就多半表明服务加好了

App端怎么调用?

写个Activity利用android.os.ServiceManager的getService获取到指定的服务,然后调用就可以了。
这里需要说明下的就是目前android.os.ServiceManager对于app来说是hide掉的,我们暂且可以不管,用个反射先用着。
至于为什么要hide掉,难道Android不想让我们自己定义系统级别的service来使用?还是说用其他的方式可以完成,目前我也不清楚!

目前结果就是通过getService能获取到我们的服务,并且成功调用,但是因为我返回的参数有String有int,而String没有获取出来,都知道Parcel的参数顺序是很重要的,可能是这个的原因,后面再来看看到底是什么原因,目前就是把customized service这一套先跑通。

P.S. 后来一次发现可能是我每次编译的so档案没有进到ROM当中去,所以烧到设备的so档案不是最新的,就没有把后面加的String获取出来(之前是两个int型数据)。
另外我还做了个实验,就是在service端通过ServiceManager的getService(…)方法再次访问当前service,这个就相当于在当前代码中通过一个指针或者引用访问的效果是一样的,这就是Binder的强大之处吧!此改动可以参见以下commit:

commit 1875ad41d5f8e505cb4c26599e4626944005f26b
Date: Tue Jun 25 12:10:59 2013 +0800

Symptom: test invoking getService in same process with service
Issue ID: NA
Root Cause: NA
Solution: NA

完整代码参见
https://github.com/guohai/and-customized-service.git

这里是Java端调用native端的服务,其实也可以native调用native的服务,这里暂时就不再去具体实现了,需要的话,会再来写。

无图无真相
add-customized-service-for-android
add-customized-service-for-android-1

Java知识脉络

Java知识庞大而复杂,所以有必要标记下自己学过哪些东西,让自己更清楚

Java Language Partition

I 基本数据类型引用类型

String
常量池(Constant Pool)存在于.class文件中,运行时被加载,可以扩充,String.intern()方法就可以扩充常量池

String变量是有长度限制的,最大长度为Integer.MAX_VALUE
但String常量(string literals)的最大长度却不为这么多,参考地(http://java.sun.com/docs/books/jvms/second_edition/html/ClassFile.doc.html#7963)和

关于

String s = new String("hello");

创建几个对象的问题,参见这里

会有字符串对象只在Heap中,但是Constant Pool中不存在对应的字面表示吗?Constant Pool中的内容会不会被GC?

II 常用对象

III

IV

V

VI

VII 一些错误或者异常
java.lang.OutOfMemoryError: Requested array size exceeds VM limit

VIII

Java Virtual Machine Partition

I Feature
Stack based
Symbolic reference
Garbage collection
Explicitly defining the primitive data type
Network byte order

II Class Format
Methods in Java are restricted to 64k
http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4309152

III GC
根集合是什么,怎么确定根集合?
HotSpot虚拟机中垃圾对象的扫描是采用的路径搜索方法,从根集合开始没有路径可到达的被认为是垃圾对象,可以回收
根集合包括,栈帧当中

IV Instruction Set
invokeinterface: Invokes an interface method
invokespecial: Invokes an initializer, private method, or superclass method
invokestatic: Invokes static methods
invokevirtual: Invokes instance methods

PS.
update 2012-02-09 写的这个破玩意在草稿箱躺了6个月了,发出来边看,边补充吧。

面试题之多线程数组求和

想换工作的,平时还是要做些面试题,因为冷不丁的被面一下,会感觉突然,当然结果也是很糟糕。
这是一道老题目“一个非常非常大的int类型数组,用多线程计算和。假设数组长度M线程数量N”。
思想是分而治之,跟快速排序MapReduce思想有些类似。

这里是一个实现的一个简单版本,根据有多少线程,然后把数组分为多少段,因为求和的过程都是读取数组元素,涉及不到锁等等。
所以只要段划分正确,计算就是简单的事情了。

有空再来用Future实现一个版本

Java多线程消费者问题

有一个简单的场景:一个Queue,包含很多Task,现在的程序要去Queue中取Task来执行
取的时候是多线程去取的,但是一旦有个线程拿到Queue中的某个Task,其他线程就必须退出

拿到Task的线程根据Task里面的内容,将具体工作(因为一个Task中可能存在多个具体的工作)分发给最终的工作执行线程(ProductionLineA或者ProductionLineB)去执行,工作执行线程执行完一个具体的工作后就把信息更新到Task中去,拿到Task的线程会不断检测当前Task里面的具体工作是否都执行完毕,如果完毕,拿到Task的线程退出,Task也会从队列中销毁

通俗的来讲也就是多线程抢任务,抢到一个任务后,把具体的工作分给多个线程去执行,它还可以回来继续抢其他的任务

注意点
1、抢任务的时候可以有多个线程去抢,但是最终一个任务只能有一个线程拿到,也就是执行任务分发的那段代码只能由某个线程执行一次,否则到后面具体的工作可能被执行多次
所以对已经抢到的任务打标记要只能打一次,不能存在A线程判断的时候标记没有被打上,B线程判断也没有,A打标记,B也打标记,这个到后面肯定就乱了,用double check来实现?
2、工作执行线程需要把执行完的情况更新到Task中去,如果第1点中具体工作分正确了,这里应该能保证不会有多个线程执行同样的具体工作,所以把执行完的情况写回Task的时候不用同步保证也行

目前任务标记用的是Thread,这个是不是不合适?
检测是否执行完毕的代码是单线程的,见WatchDog类,目前还缺超时检测,多线程的检测有没有必要?
锁加的恰不恰当?

多线程的代码确实比较难编写和调试

目前我实现了一个代码,看似没有问题,通过测试,分析日志,发现都还正常

			Lock lock = new ReentrantLock();
			lock.tryLock();
			// critical area start
			if (null != task.getExclusive()
					&& task.getExclusive() != Thread.currentThread()) {
				// 如果有人占了,那么自动退出
				// 这里怎么实现比较好?
				continue;
			} else {
				if (null == task.getExclusive()) {
					task.setExclusive(Thread.currentThread());
				}
			}
			// critical area end
			lock.unlock();

关键代码中,目前这一段因该还有修改的空间

运行文件run.sh
日志分析LogAnalyzer.java,目前只能说是大概的分析有没有明显出错的地方,比如执行的数量对不对

日志:

queue has 60 wks
can only be executed 10 times...
can only be executed 10 times...
can only be executed 10 times...
can only be executed 10 times...
can only be executed 10 times...
can only be executed 10 times...
can only be executed 10 times...
can only be executed 10 times...
can only be executed 10 times...
shan$evol in task[2] is executing by ProductionLineB...
shan$love in task[8] is executing by ProductionLineA...
shan$love in task[3] is executing by ProductionLineA...
can only be executed 10 times...
shan$love in task[0] is executing by ProductionLineA...
shan$vole in task[3] is executing by ProductionLineB...
shan$elvo in task[8] is executing by ProductionLineB...
shan$ovel in task[8] is executing by ProductionLineB...
shan$vole in task[8] is executing by ProductionLineB...
shan$love in task[5] is executing by ProductionLineA...
shan$love in task[5] is executing by ProductionLineA...
shan$love in task[4] is executing by ProductionLineA...
shan$love in task[7] is executing by ProductionLineA...
shan$leov in task[8] is executing by ProductionLineB...
shan$elvo in task[4] is executing by ProductionLineB...
shan$ovel in task[4] is executing by ProductionLineB...
shan$vole in task[4] is executing by ProductionLineB...
shan$leov in task[4] is executing by ProductionLineB...
shan$ovel in task[5] is executing by ProductionLineB...
shan$evol in task[5] is executing by ProductionLineB...
shan$elvo in task[5] is executing by ProductionLineB...
shan$vole in task[1] is executing by ProductionLineB...
shan$ovel in task[1] is executing by ProductionLineB...
shan$leov in task[1] is executing by ProductionLineB...
shan$evol in task[1] is executing by ProductionLineB...
shan$vole in task[6] is executing by ProductionLineB...
shan$evol in task[3] is executing by ProductionLineB...
shan$elvo in task[7] is executing by ProductionLineB...
shan$ovel in task[7] is executing by ProductionLineB...
shan$leov in task[7] is executing by ProductionLineB...
shan$love in task[9] is executing by ProductionLineA...
shan$evol in task[7] is executing by ProductionLineB...
shan$ovel in task[6] is executing by ProductionLineB...
task0 is done...
shan$evol in task[6] is executing by ProductionLineB...
shan$vole in task[9] is executing by ProductionLineB...
shan$leov in task[6] is executing by ProductionLineB...
shan$evol in task[9] is executing by ProductionLineB...
shan$ovel in task[5] is executing by ProductionLineB...
shan$leov in task[4] is executing by ProductionLineB...
shan$leov in task[8] is executing by ProductionLineB...
shan$leov in task[1] is executing by ProductionLineB...
task2 is done...
shan$elvo in task[7] is executing by ProductionLineB...
shan$evol in task[5] is executing by ProductionLineB...
shan$ovel in task[7] is executing by ProductionLineB...
shan$elvo in task[5] is executing by ProductionLineB...
shan$evol in task[3] is executing by ProductionLineB...
shan$evol in task[6] is executing by ProductionLineB...
shan$vole in task[1] is executing by ProductionLineB...
shan$ovel in task[1] is executing by ProductionLineB...
shan$vole in task[9] is executing by ProductionLineB...
shan$evol in task[7] is executing by ProductionLineB...
shan$vole in task[6] is executing by ProductionLineB...
shan$evol in task[9] is executing by ProductionLineB...
shan$leov in task[8] is executing by ProductionLineB...
task4 is done...
shan$evol in task[5] is executing by ProductionLineB...
shan$vole in task[1] is executing by ProductionLineB...
shan$ovel in task[1] is executing by ProductionLineB...
task3 is done...
shan$evol in task[7] is executing by ProductionLineB...
task6 is done...
shan$leov in task[8] is executing by ProductionLineB...
task9 is done...
task5 is done...
shan$vole in task[1] is executing by ProductionLineB...
shan$evol in task[7] is executing by ProductionLineB...
task8 is done...
task1 is done...
task7 is done...

完整源码:
multiple-consumers-problem

JVM标记贴

    JVM参数

  • JMX参数
  • -Dcom.sun.management.jmxremote.port=1090
    -Dcom.sun.management.jmxremote.ssl=false
    -Dcom.sun.management.jmxremote.authenticate=false

  • 扩展参数
  • -XX:+PrintGC
    -XX:+PrintGCDetails
    -XX:+PrintGCTimeStamps 和PrintGC以及PrintGCDetails一起使用
    -Xloggc:gc.log

    -XX:+DoEscapeAnalysis
    -XX:+HeapDumpOnOutOfMemoryError

自己动手编译OpenJDK

无聊的时候决定自己动手编译个JDK,曾经想在X86上编译一个Dalvik出来玩玩,但基于那玩意是高手才玩的起的,所以自己那个想法就不了了知了
看了一圈后发现OpenJDK还是比较容易编译的,所以就来炒份现饭
现代JDK这么容易自己编译还是归功于开源和社区

开场白就说这么多,下面是过程记录
下载源码,解压,阅读README和README-builds.html,然后就可以开工了

我是在Linux 2.6.35-28-generic #50-Ubuntu i686 GNU/Linux上编译的,我编译的是openjdk-7-ea-src-b141-05_may_2011这个版本

主要需要以下条件
Basic Linux Check List
1. Install the Bootstrap JDK, set ALT_BOOTDIR.
2. Optional Import JDK, set ALT_JDK_IMPORT_PATH.(可以不要,如果你是完全编译的话)
3. Install or upgrade the FreeType development package.(这个基本有了)
4. Install Ant 1.7.1 or newer, make sure it is in your PATH.

然后在环境变量下做些设置
ALT_BOOTDIR=$SUN_JDK1.6.0_25_HOME(我是用的SUN的JDK6来作为Bootstrap JDK的)
LANG=C(需要设置成这样,否则编译会报错,Linux一般是zh_CN.utf8改下就可以)
ALT_CUPS_HEADERS_PATH=$CUPS_HOME/include(何为CUPS见此)

另外环境变量中不要出现JAVA_HOME,CLASSPATH,有的话就把它们注释掉

记得使修改过的环境变量生效

然后就cd到$openjdk_src下开始执行make sanity检测
成功的话就执行make all ALLOW_DOWNLOADS=true WARNINGS_ARE_ERRORS=开始较为耗时的编译之旅

这两个参数的意思还是比较明白
ALLOW_DOWNLOADS=true就是编译的时候发现缺少某些预知的源码或依赖时,它会自动去下载,前提是必须联网
WARNINGS_ARE_ERRORS=就是禁止编译器把一些警告当错误,如果不加这个就可能会因为类似于这样的cc1plus: warnings being treated as errors提示而终止编译,这不是我们所希望的

但是不要高兴的太早,多多少少可能会遇到点问题,不过找找Google应该都能解决

下面贴出我在编译的时候遇到的问题
1、
/home/guohai/dev/src/java/openjdk-7-ea-src-b141-05_may_2011/hotspot/src/os/linux/vm/os_linux.cpp
cc1plus: warnings being treated as errors
/home/guohai/dev/src/java/openjdk-7-ea-src-b141-05_may_2011/hotspot/src/os/linux/vm/os_linux.cpp: In static member function ‘static bool os::Linux::hugetlbfs_sanity_check(bool, size_t)’:
/home/guohai/dev/src/java/openjdk-7-ea-src-b141-05_may_2011/hotspot/src/os/linux/vm/os_linux.cpp:2853: error: use of assignment suppression and length modifier together in gnu_scanf format
make[6]: *** [os_linux.o] Error 1
make[6]: Leaving directory `/home/guohai/dev/src/java/openjdk-7-ea-src-b141-05_may_2011/build/linux-i586/hotspot/outputdir/linux_i486_compiler2/product’

WARNINGS_ARE_ERRORS=

2、
../../../src/solaris/native/sun/awt/awt.h:38: fatal error: X11/Intrinsic.h: No such file or directory
compilation terminated.
make[5]: *** [/home/guohai/dev/src/java/openjdk-7-ea-src-b141-05_may_2011/build/linux-i586/tmp/sun/sun.awt/awt/obj/BufImgSurfaceData.o] Error 1
make[5]: *** Waiting for unfinished jobs….
make[5]: Leaving directory `/home/guohai/dev/src/java/openjdk-7-ea-src-b141-05_may_2011/jdk/make/sun/awt’
make[4]: *** [library_parallel_compile] Error 2
make[4]: Leaving directory `/home/guohai/dev/src/java/openjdk-7-ea-src-b141-05_may_2011/jdk/make/sun/awt’
make[3]: *** [all] Error 1
make[3]: Leaving directory `/home/guohai/dev/src/java/openjdk-7-ea-src-b141-05_may_2011/jdk/make/sun’
make[2]: *** [all] Error 1
make[2]: Leaving directory `/home/guohai/dev/src/java/openjdk-7-ea-src-b141-05_may_2011/jdk/make’
make[1]: *** [jdk-build] Error 2
make[1]: Leaving directory `/home/guohai/dev/src/java/openjdk-7-ea-src-b141-05_may_2011′
make: *** [build_product_image] Error 2

sudo apt-get install libxt-dev

3、
../../../src/solaris/native/sun/xawt/XToolkit.c:48: fatal error: X11/extensions/XTest.h: No such file or directory
compilation terminated.
make[5]: *** [/home/guohai/dev/src/java/openjdk-7-ea-src-b141-05_may_2011/build/linux-i586/tmp/sun/sun.awt.X11/xawt/obj/XToolkit.o] Error 1
make[5]: *** Waiting for unfinished jobs….
make[5]: Leaving directory `/home/guohai/dev/src/java/openjdk-7-ea-src-b141-05_may_2011/jdk/make/sun/xawt’
make[4]: *** [library_parallel_compile] Error 2

sudo apt-get install libxtst-dev

从2011-05-12 20:39开始编译,遇到问题,前前后后经历了近一个小时
另外如果编译出错了,并且你解决了错误,貌似你只需要继续执行make all ALLOW_DOWNLOADS=true WARNINGS_ARE_ERRORS=
就可以了,它会接着编译,而不需要从头开始编译
当你看到下面这种提示时
— Build times ———-
Target all_product_build
Start 2011-05-12 21:28:48
End 2011-05-12 21:37:48
00:00:04 corba
00:00:12 hotspot
00:00:03 jaxp
00:00:05 jaxws
00:08:32 jdk
00:00:04 langtools
00:09:00 TOTAL
————————-
应该就可以完工了,cd到$openjdk_src/build/platform/下,看看j2sdk-image和j2re-image中的内容是不是很熟悉?
cd$openjdk_src/build/platform/bin/下执行如下命令就应该可以看到结果,当然版本,硬件架构可能不一样
总之你就自己编译出了一个带自己名字的JDK了

$openjdk_src/build/linux-i586/bin$ ./java -version
openjdk version “1.7.0-internal”
OpenJDK Runtime Environment (build 1.7.0-internal-guohai_2011_05_12_20_39-b00)
OpenJDK Server VM (build 21.0-b11, mixed mode)

$openjdk_src/build/linux-i586/bin$ ./javac -version
javac 1.7.0-internal

有图
compile-my-openjdk

编译成功之后再把那些需要改回来的东西改回来


sudo apt-get install libfreetype6-dev
sudo apt-get install libasound2-dev
sudo apt-get install libcups2-dev