部署 servlet

OS : ubuntu 12.04

Tomcat : tomcat7

  • 进入Tomcat7默认安装目录为/var/lib/tomcat7

  • cd /var/lib/tomcat7
    
  • 进入webapps,并在该目录下新建一个自己的项目名称

  • cd webapps
    mkdir streamserver #这里自己取的项目名为streamserver
    
  • 进入streamserver,新建WEB-INF目录

  • cd streamserver
    mkdir WEB-INF
    
  • 在WEB-INF目录中需要建立一些固定的目录和web.xml文件

  • cd WEB-INF
    mkdir classes #所有要用到的java类都要放到这里
    touch web.xml
    
  • 拷贝项目的类文件到classes目录

  • classes中的目录结构需要跟项目的目录结构一致,这里假设类名为net.lnmcc.streamserver.StreamServer

  • cp  -av projectpath/bin/net/lnmcc/streamserver/*  /var/lib/tomcat7/webapps/streamserver/WEB-INF/classes/net/lnmcc/streamserver/ 
    
  • 编写web.xml文件

  • <?xml version="1.0" encoding="utf-8"?>
    <web-app xmlns="http://java.sun.com/xml/ns/javaee"
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
                          http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
      version="3.0"
      metadata-complete="true">
              
             <display-name>Welcome to StreamServer</display-name>
                <description>
                 Welcome to StreamServer
              </description>
    
            <servlet>
                      
                    <servlet-name>StreamServer</servlet-name>
                      
                    <servlet-class>net.lnmcc.streamserver.StreamServer</servlet-class>
                      
                    <load-on-startup>1</load-on-startup>
            </servlet>
            <servlet-mapping>
                 <servlet-name>StreamServer</servlet-name>
                   
                 <url-pattern>/streamserver</url-pattern>
            </servlet-mapping>
    </web-app>
    
  • 重启Tomcat

  • /etc/init.d/tomcat7 restart
    
  • 访问servlet

  • http://localhost:8080/streamserver/streamserver
    #第一个streamserver是项目路径
    #第二个streamserver对应web.xml中设置的url
    

Android Binder IPC

AndroidBinderIPC

定制 operator new 记录分配的内存大小

调用operator new的时候在所分配的内存的第一个字节中记录本次new分配的内存大小。

void* operator new(size_t size) throw(bad_alloc){
    
    if(size == 0)
        size = 1;

    void* address = NULL;
    size_t *p = NULL;
    
    while(true) {
        p = (size_t*)malloc(size + sizeof(size_t));
        if(p)
            break;
        new_handler oldHandler = set_new_handler(0);
        set_new_handler(oldHandler);
        
        if(oldHandler)
            (*oldHandler)();
        else
            throw bad_alloc();
    }
    p[0] = size;
    address = (void*)(&p[1]);
	
    return address;
}

对应的operator delete

void operator delete(void* address) {
    if (NULL == address)
	return;
    
    size_t* p = (size_t*)address;

    /* Get the size and do something else */
    /* size_t size = p[-1];               */

    void* p2 = (void*)(&p[-1]); 

    free(p2);
}

github: MemoryMonitor

C/CPP 调用 JNI 的区别

C++支持真正的对象而C不支持对象,所有C和C++调用JNI函数的时候会有一些细微的区别。

C++:

JavaVM* vm
JNIEnv* env = NULL;

vm->GetEnv((void**)&env, JNI_VERSION_1_6);
env->FindClass("main");

C:

JavaVM* vm
JNIEnv* env = NULL;

(*vm)->GetEnv(vm, (void**)&env, JNI_VERSION_1_6);
(*env)->FindClass(env, "main");

使用 Invocation API 调用 Java 类

InvocationApiTest.java

import java.io.*;

public class InvocationApiTest {
    public static void main(String[] args) {
        System.out.println(args[0]);
    }
}

invocationApi.c

#include <jni.h>

int main() {
    JNIEnv* env;
    JavaVM* vm;
    JavaVMInitArgs vm_args;
    JavaVMOption options[1];
    jint res;
    jclass cls;
    jmethodID mid;
    jstring jstr;
    jclass stringClass;
    jobjectArray args;

    //1.生成Java虚拟机选项
    options[0].optionString = "-Djava.class.path=.";
    vm_args.version = JNI_VERSION_1_6;
    vm_args.options = options;
    vm_args.nOptions = 1;
    vm_args.ignoreUnrecognized = JNI_TRUE;

    //2.生成Java虚拟机
    res = JNI_CreateJavaVM(&vm, (void**)&env, &vm_args);

    //3.查找并加载类
    cls = (*env)->FindClass(env, "invocationApiTest");

    //4.获取mian()方法的ID
    mid = (*env)->GetStaticMethodID(env, cls, "main", "([Ljava/lang/String;)V");

    //5.生成字符串对象,用作main()方法的参数
    jstr = (*env)->NewStringUTF(env, "Hello Invocation API");
    stringClass = (*env)->FindClass(env, "java/lang/String");
    args = (*env)->NewObjectArray(env, 1, stringClass, jstr);

    //6.调用main()方法的
    (*env)->CallStaticVoidMethod(env, cls, mid, args);

    //7.销毁Java虚拟机
    (*vm)->DestroyJavaVM(vm);

    return 0;
}

MAC上的编译参数:

gcc -Wall -g -o invocationApi invocationApi.c -I$JAVA_HOME/include  -I$JAVA_HOME/include/darwin  -L$JAVA_HOME/jre/lib/server -ljvm -rpath $JAVA_HOME/jre/lib/server

ref: jdk-7u45-apidocs/technotes/guides/jni/spec/invocation.html#wp9502 ref: 《Android框架揭秘》