以下内容来自:http://blog.csdn.net/cwmbecoming/archive/2006/08/26/1123400.aspx
Microsoft Windows XP Professional Version 2002 Service Pack 3
Microsoft Visual C++ 6.0
Cygwin
java version "1.4.1_02"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.4.1_02-b06)
Java HotSpot(TM) Client VM (build 1.4.1_02-b06, mixed mode)
下载CLDC1.1源码:j2me_cldc-1_1-fcs-src-winunix.zip
https://cds.sun.com/is-bin/INTERSHOP.enfinity/WFS/CDS-CDS_Developer-Site/en_US/-/USD/ViewProductDetail-Start?ProductRef=J2MECLDC-1.1-WINUNIX-G-F@CDS-CDS_Developer
下载MIDP2.0源码:midp2.0fcs.rar [sun网站现在似乎不提供midp2.0源码了,所以需要自行搜索]
下载CLDC1.04源码:以下所要描述的是midp2.0的编译,但是该midp2.0源码需要cldc1.04的源码,而在互联网上搜索很久都没有获得cldc1.04的源码,所以用cldc1.1代替。另外,虽然有cldc1.1的源码,在编译过程中还是需要cldc1.04的一个java文件[GeneralBase.java]。
编译源码:进入midp的目录build/win32/kvm,运行make ALT_BOOTDIR=JDK_HOME KVM_DIR=CLDC_DIR,JDK_HOME是jdk的目录,CLDC_DIR是cldc1.1源码的目录。例:make ALT_BOOTDIR=D:/j2sdk1.4.1_02/ KVM_DIR=../../../../j2me_cldc/
编译完成之后会生成模拟器midp2.0fcs/build/win32/kvm/bin/midp.exe
然而在编译过程中会有很多错误,以下是需要修改的地方,每改一步最好重新make一下。如果更改完成之后还有错误,那就将代码删除重新开始,并将所有错误一次改完再编译。
假设CLDC1.1的源码放在j2me_cldc目录下,MIDP2.0的源码放在midp2.0fcs目录下。
1. GeneralBase.ioWait()到Waiter.waitForIO()的映射
com.sun.cldc.io.GeneralBase.ioWait()是CLDC1.04里面的,在CLDC1.1里面对应的是com.sun.cldc.io.Waiter.waitForIO(),按照错误提示一个一个改为后者。
2. 将CLDC1.04的com/sun/cldc/io/GeneralBase.java文件复制到CLDC1.1相应的目录里[api/src/com/sun/cldc/io/],再从CLDC1.1的api/src/java/io/DateInputStream.java和api/src/java/io/DateOutputStream.java两个文件里面将writeFloat、writeDouble、readFloat、readDouble四个方法复制到j2me_cldc/api/src/com/sun/cldc/io/GeneralBase.java里面,并将GeneralBase.java的 ioWait()这个native方法删除
3. 在文件midp2.0fcs/src/win32/native/machine_md.h里添加 #include <setjmp.h> ,解决不识别global.h里的“jmp_buf”标识符的问题
4. 将文件midp2.0fcs/src/share/native/kvm/midpServices.c的宏 ERROR_THROW 改成 THROW
5. 修改midp2.0fcs/src/share/native/kvm/midpEvents.c:
void Java_com_sun_midp_lcdui_Events_open(void) {
Java_com_sun_cldc_io_j2me_events_PrivateInputStream_open();
}
void Java_com_sun_midp_lcdui_Events_readInt(void) {
Java_com_sun_cldc_io_j2me_events_PrivateInputStream_readInt();
}
void Java_com_sun_midp_lcdui_Events_readUTF(void) {
Java_com_sun_cldc_io_j2me_events_PrivateInputStream_readUTF();
}
改成:
void Java_com_sun_midp_lcdui_Events_open(void) {
}
void Java_com_sun_midp_lcdui_Events_readInt(void) {
JVM_EventsReadInt();
}
void Java_com_sun_midp_lcdui_Events_readUTF(void) {
JVM_EventsReadUTF();
}
6. 在文件j2me_cldc/kvm/VmCommon/src/ events.c中添加宏
#define SLEEP_FOR(wakeupTime) /
{ long delta = (long)(wakeupTime - CurrentTime_md()); /
Sleep(delta); /
}
7. 修改midp2.0fcs/build/share/makefiles/kvm/ VM.gmk
在
vpath %.c $(KVM_DIR)/kvm/VmCommon/src
vpath %.c $(KVM_DIR)/kvm/VmExtra/src
后面添加
vpath %.c $(KVM_DIR)/kvm/VmExtra/src/fp
8. 修改midp2.0fcs/build/share/makefiles/kvm/ Defs.gmk
KVM_DEF_SRC += cache.c class.c fields.c frame.c garbage.c global.c /
interpret.c loader.c native.c pool.c thread.c /
nativeCore.c loaderFile.c runtime_md.c events.c /
hashtable.c profiling.c StartJVM.c /
verifier.c verifierUtil.c log.c stackmap.c execute.c /
inflate.c jar.c kni.c
改为:(实际上是添加了一些,要注意每行前面的空白不是空格是/t)
KVM_DEF_SRC += cache.c class.c fields.c frame.c garbage.c global.c /
interpret.c loader.c native.c pool.c thread.c /
nativeCore.c loaderFile.c runtime_md.c events.c /
hashtable.c profiling.c StartJVM.c /
verifier.c verifierUtil.c log.c stackmap.c execute.c /
inflate.c jar.c kni.c /
e_rem_pio2.c e_sqrt.c fp_bytecodes.c k_cos.c k_rem_pio2.c k_sin.c k_tan.c /
s_ceil.c s_copysign.c s_cos.c s_fabs.c s_floor.c s_scalbn.c s_sin.c s_tan.c /
w_sqrt.c resource.c fp_math.c
cldc1.0 GeneralBase.java 源码:
package com.sun.cldc.io;
import java.io.*;
public abstract class GeneralBase
implements DataInput, DataOutput
{
public GeneralBase()
{
}
public void write(int i)
throws IOException
{
throw new RuntimeException("No write()");
}
public void write(byte abyte0[], int i, int j)
throws IOException
{
if(abyte0 == null)
{
throw new NullPointerException();
}
if(i < 0 || i > abyte0.length || j < 0 || i + j > abyte0.length || i + j < 0)
{
throw new IndexOutOfBoundsException();
}
if(j == 0)
{
return;
}
for(int k = 0; k < j; k++)
{
write(abyte0[i + k]);
}
}
public final void write(byte abyte0[])
throws IOException
{
write(abyte0, 0, abyte0.length);
}
public void writeBoolean(boolean flag)
throws IOException
{
write(flag ? 1 : 0);
}
public void writeByte(int i)
throws IOException
{
write(i);
}
public void writeShort(int i)
throws IOException
{
write(i >>> 8 & 0xff);
write(i >>> 0 & 0xff);
}
public void writeChar(int i)
throws IOException
{
write(i >>> 8 & 0xff);
write(i >>> 0 & 0xff);
}
public void writeInt(int i)
throws IOException
{
write(i >>> 24 & 0xff);
write(i >>> 16 & 0xff);
write(i >>> 8 & 0xff);
write(i >>> 0 & 0xff);
}
public void writeLong(long l)
throws IOException
{
write((int)(l >>> 56) & 0xff);
write((int)(l >>> 48) & 0xff);
write((int)(l >>> 40) & 0xff);
write((int)(l >>> 32) & 0xff);
write((int)(l >>> 24) & 0xff);
write((int)(l >>> 16) & 0xff);
write((int)(l >>> 8) & 0xff);
write((int)(l >>> 0) & 0xff);
}
public void writeBytes(String s)
throws IOException
{
throw new RuntimeException("Function not supported");
}
public void writeChars(String s)
throws IOException
{
int i = s.length();
for(int j = 0; j < i; j++)
{
char c = s.charAt(j);
write(c >>> 8 & 0xff);
write(c >>> 0 & 0xff);
}
}
public void writeUTF(String s)
throws IOException
{
writeUTF(s, ((DataOutput) (this)));
}
public static int writeUTF(String s, DataOutput dataoutput)
throws IOException
{
int i = s.length();
int j = 0;
char ac[] = new char[i];
int k = 0;
s.getChars(0, i, ac, 0);
for(int l = 0; l < i; l++)
{
char c = ac[l];
if(c >= '/001' && c <= '/177')
{
j++;
} else
if(c > '/u07FF')
{
j += 3;
} else
{
j += 2;
}
}
if(j > 65535)
{
throw new UTFDataFormatException();
}
byte abyte0[] = new byte[j + 2];
abyte0[k++] = (byte)(j >>> 8 & 0xff);
abyte0[k++] = (byte)(j >>> 0 & 0xff);
for(int i1 = 0; i1 < i; i1++)
{
char c1 = ac[i1];
if(c1 >= '/001' && c1 <= '/177')
{
abyte0[k++] = (byte)c1;
} else
if(c1 > '/u07FF')
{
abyte0[k++] = (byte)(0xe0 | c1 >> 12 & 0xf);
abyte0[k++] = (byte)(0x80 | c1 >> 6 & 0x3f);
abyte0[k++] = (byte)(0x80 | c1 >> 0 & 0x3f);
} else
{
abyte0[k++] = (byte)(0xc0 | c1 >> 6 & 0x1f);
abyte0[k++] = (byte)(0x80 | c1 >> 0 & 0x3f);
}
}
dataoutput.write(abyte0);
return j + 2;
}
public void flush()
throws IOException
{
}
public void close()
throws IOException
{
}
public int read()
throws IOException
{
throw new RuntimeException("No read()");
}
public long skip(long l)
throws IOException
{
long l1;
for(l1 = l; l1 > 0L; l1--)
{
if(read() < 0)
{
break;
}
}
return l - l1;
}
public void readFully(byte abyte0[])
throws IOException
{
readFully(abyte0, 0, abyte0.length);
}
public void readFully(byte abyte0[], int i, int j)
throws IOException
{
if(j < 0)
{
throw new IndexOutOfBoundsException();
}
for(int k = 0; k < j;)
{
int l = read();
if(l < 0)
{
throw new EOFException();
}
abyte0[i + k++] = (byte)l;
}
}
public int skipBytes(int i)
throws IOException
{
int j = 0;
for(int k = 0; j < i && (k = (int)skip(i - j)) > 0; j += k) { }
return j;
}
public boolean readBoolean()
throws IOException
{
int i = read();
if(i < 0)
{
throw new EOFException();
} else
{
return i != 0;
}
}
public byte readByte()
throws IOException
{
int i = read();
if(i < 0)
{
throw new EOFException();
} else
{
return (byte)i;
}
}
public int readUnsignedByte()
throws IOException
{
int i = read();
if(i < 0)
{
throw new EOFException();
} else
{
return i;
}
}
public short readShort()
throws IOException
{
int i = read();
int j = read();
if((i | j) < 0)
{
throw new EOFException();
} else
{
return (short)((i << 8) + (j << 0));
}
}
public int readUnsignedShort()
throws IOException
{
int i = read();
int j = read();
if((i | j) < 0)
{
throw new EOFException();
} else
{
return (i << 8) + (j << 0);
}
}
public char readChar()
throws IOException
{
int i = read();
int j = read();
if((i | j) < 0)
{
throw new EOFException();
} else
{
return (char)((i << 8) + (j << 0));
}
}
public int readInt()
throws IOException
{
int i = read();
int j = read();
int k = read();
int l = read();
if((i | j | k | l) < 0)
{
throw new EOFException();
} else
{
return (i << 24) + (j << 16) + (k << 8) + (l << 0);
}
}
public long readLong()
throws IOException
{
return ((long)readInt() << 32) + ((long)readInt() & 0xffffffffL);
}
public String readUTF()
throws IOException
{
return DataInputStream.readUTF(this);
}
public String readLine()
throws IOException
{
throw new RuntimeException("Function not supported");
}
public static native void iowait();
}