`
lobin
  • 浏览: 417577 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

Java: 高级编程

 
阅读更多

动态代理

 

Java动态代理的两个主要的类:InvocationHandler,Proxy。Proxy通过newProxyInstance创建代理对象,对应的有个动态代理类, 该方法声明如下:

public static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h);

动态代理创建的是个类似com.sun.proxy.$Proxy1,2,...,n的代理类。它有个构造函数,这个构造函数的参数传入一个InvocationHandler。在创建代理类时:

它首先查找或者生成一个委派的代理类:

/*
 * Look up or generate the designated proxy class.
 */
Class<?> cl = getProxyClass0(loader, intfs);

然后通过构造函数创建代理实例:

final Constructor<?> cons = cl.getConstructor(constructorParams);
final InvocationHandler ih = h;
if (!Modifier.isPublic(cl.getModifiers())) {
    AccessController.doPrivileged(new PrivilegedAction<Void>() {
        public Void run() {
            cons.setAccessible(true);
            return null;
        }
    });
}

该构造函数参数为一个InvocationHandler:

return cons.newInstance(new Object[]{h});

在这里大家有没有什么疑问?既然是代理,为什么没看到代理是哪个对象?newProxyInstance创建的代理对象到底代理的是哪个对象?这里可能会让人引起误解,newProxyInstance实际上创建一个实现了interfaces参数指定的接口的动态类实例,在调用interfaces参数指定的接口方法时会被h参数的InvocationHandler拦截,也就是interfaces参数指定的接口方法实现在动态类中是交给InvocationHandler处理的。

 

InvocationHandler:

 

public interface InvocationHandler {
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable;
}
invoke方法:
关于invoke方法的第一个参数proxy,它就是创建的代理对象, 也就是newProxyInstance方法返回创建的代理对象。

 

 

 

public interface GreetService {

    public String testString(String s);
}

 

public class GreetServiceImpl implements GreetService {

    public String testString(String s) {
        System.out.println(s);
        return s;
    }
}

 

class ProxyTargetInvocationHandler implements InvocationHandler {

    private Object target;

    public ProxyTargetInvocationHandler(Object target) {
        this.target = target;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        method.setAccessible(true); // it's not necessary
        return method.invoke(target, args);
    }
}

 

@org.junit.Test
public void testStringWithProxyTargetInvocationHandler() {
    ClassLoader cl = Thread.currentThread().getContextClassLoader();

    GreetService greetService = new GreetServiceImpl();
    InvocationHandler handler = new ProxyTargetInvocationHandler(greetService);
    GreetService proxy = (GreetService) Proxy.newProxyInstance(cl, new Class<?>[] {GreetService.class}, handler);
    System.out.println(proxy.testString("greeting."));
}

借用上面例子中的GreetService,如果InvocationHandler实现如下,下面测试代码运行结果是什么?

 

class ProxyInvocationHandler implements InvocationHandler {
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        return method.invoke(proxy, args);
    }
}

 

@org.junit.Test
public void testStringWithProxyInvocationHandler() {
    GreetService greetService = new GreetServiceImpl();
    ClassLoader cl = greetService.getClass().getClassLoader();

    InvocationHandler handler = new ProxyInvocationHandler();
    GreetService proxy = (GreetService) Proxy.newProxyInstance(cl, new Class<?>[] {GreetService.class}, handler);
    System.out.println(proxy.testString("greeting."));
}

 

java.lang.OutOfMemoryError: Java heap space

 

借用上面例子中的GreetService,如果InvocationHandler实现如下,下面测试代码运行结果是什么?

 

class ProxyInvocationHandler implements InvocationHandler {
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println(proxy);
        return null;
    }
}

 

 

@org.junit.Test
public void testStringWithProxyInvocationHandler() {
    GreetService greetService = new GreetServiceImpl();
    ClassLoader cl = greetService.getClass().getClassLoader();

    InvocationHandler handler = new ProxyInvocationHandler();
    GreetService proxy = (GreetService) Proxy.newProxyInstance(cl, new Class<?>[] {GreetService.class}, handler);
    System.out.println(proxy.testString("greeting."));
}

 

java.lang.StackOverflowError

 这两个运行结果是不是挺奇怪?第一个报OOM,第二个报栈溢出。

第一个测试代码,运行前如果加上-Xmx1024m,报如下错误:

java.lang.StackOverflowError

 这个错误结果是正常的。其实对于第一个测试代码,两个错误结果都是可以理解的,而报这两个不同结果都是因栈溢出导致的,我们在运行前加上-Xmx1024m后,直接报栈溢出错误,这个是期望的错误,也是真正报错的原因。至于报OOM的情况,其实也是由于栈溢出导致,只是由于调用栈太长,报错后打印栈信息时OOM了。

至于第二个测试代码,报栈溢出错误,但从代码上不太容易看出来,并没有直接体现,这里就是简单打印了下proxy:System.out.println(proxy);怎么最后运行报栈溢出呢?这里在打印proxy的时候,实际上调用了proxy的toString()方法,看到这里就跟第一个测试代码差不多了,最后报栈溢出错误了。

RMI

关于Java RMI(RPC)的绑定(bind)、导出(export)以及发现(lookup) 

关于Java RMI(RPC)的绑定(bind)和导出(export)

 

绑定(bind)是将远程对象存根和对应的绑定名称在Registry上进行关联,以便在查找(lookup)是能够根据绑定名称查找绑定的远程对象(实际上市对应的远程对象存根,静态存根或动态存根)。

 

导出(export)

 

将对象暴露到网络上,以便中间通过网络可以访问到这个对象,调用它的方法。会启动一个TCPEndpoint,TCPEndpoint对应一个TCPTransport。TCPTransport在指定端口上监听tcp请求,以便接受远程方法调用请求。

 

TCPTransport会启动一个线程来处理远程方法调用请求的连接。

 

TCPTransport会创建一个线程池来处理远程方法调用请求:

 

connectionThreadPool = new ThreadPoolExecutor(0, maxConnectionThreads, threadKeepAliveTime, TimeUnit.MILLISECONDS, new SynchronousQueue(), new ThreadFactory() {
    public Thread newThread(Runnable var1) {
        return (Thread)AccessController.doPrivileged(new NewThreadAction(var1, "TCP Connection(idle)", true, true));
    }
});

TCPTransport通过TCPTransport#handleMessages方法处理远程方法调用请求。

 

是将远程对象导出到一个对象表。

 

Java RMI每个远程服务对象都对应一个TCPEndpoint,在Transport层上对应一个TCPTransport。所以基于Java RMI开发时,有多少个远程服务就有多少个对应的TCPEndpoint,都有对应的TCPTransport,他们并不共享Transport。

 

一个对象能够被其他程序调用,要解决两个问题:

1、首先是这两个程序之间的通信问题

2、方法调用的序列化问题,包括调用的方法以及传参。

 

可能这两个程序是系统内的两个程序进程,系统内,不跨网络;可能是不同系统之间的两个程序进程,跨网络。

 

系统内进程间的对象调用情况:

 

跨网络不同系统之间的对象调用情况:

 

 

 

 

参考文章:https://lobin.iteye.com/blog/2345976

 

Java RMI 远程方法调用: Java RPC实现

Java RMI规范

Java序列化机制实现:参考https://lobin.iteye.com/blog/629414 远程方法调用(RMI)章节。 

Java 序列化

Java序列化机制实现:参考https://lobin.iteye.com/blog/629414 序列化章节。 

 

Java RMI 实例

新版本java开发rmi服务很方便,不需要通过rmic生成Stub(存根)和Skel(Skeleton),老版本java开发rmi服务还需要生成Stub(存根)和Skel(Skeleton)

import java.rmi.Remote;
import java.rmi.RemoteException;

public interface FPingTaskService extends Remote {

    public int fping(int target) throws RemoteException;
}

 

import java.rmi.RemoteException;
import java.rmi.server.RMIClientSocketFactory;
import java.rmi.server.RMIServerSocketFactory;
import java.rmi.server.UnicastRemoteObject;

public class FPingTaskServiceImpl extends UnicastRemoteObject implements FPingTaskService {
    protected FPingTaskServiceImpl() throws RemoteException {

    }

    protected FPingTaskServiceImpl(int port) throws RemoteException {
        super(port);
    }

    protected FPingTaskServiceImpl(int port, RMIClientSocketFactory csf, RMIServerSocketFactory ssf) throws RemoteException {
        super(port, csf, ssf);
    }

    @Override
    public int fping(int target) throws RemoteException {
        System.out.println("ping " + target);
        return 1;
    }
}

 

import java.rmi.Remote;
import java.rmi.RemoteException;

public interface RemotePingTaskService extends Remote {

    public int rping(int target) throws RemoteException;
}

 

import java.rmi.RemoteException;
import java.rmi.server.RMIClientSocketFactory;
import java.rmi.server.RMIServerSocketFactory;
import java.rmi.server.UnicastRemoteObject;

public class RemotePingTaskServiceImpl extends UnicastRemoteObject implements RemotePingTaskService {
    protected RemotePingTaskServiceImpl() throws RemoteException {

    }

    protected RemotePingTaskServiceImpl(int port) throws RemoteException {
        super(port);
    }

    protected RemotePingTaskServiceImpl(int port, RMIClientSocketFactory csf, RMIServerSocketFactory ssf) throws RemoteException {
        super(port, csf, ssf);
    }

    @Override
    public int rping(int target) throws RemoteException {
        System.out.println("remote ping " + target);
        return 1;
    }
}

 

import java.net.MalformedURLException;
import java.rmi.AlreadyBoundException;
import java.rmi.Naming;
import java.rmi.Remote;
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
import java.rmi.server.ExportException;
import java.rmi.server.UnicastRemoteObject;
import java.util.ArrayList;
import java.util.Map;

public class ServiceExportor {
    public static java.util.List<java.util.Map<String, Object>> services;

    public static int DEFAULT_RMI_PORT = 10999;

    static {
        services = new ArrayList<Map<String, Object>>();
        java.util.Map<String, Object> map = new java.util.HashMap<String, Object>();
        map.put("NAME", "RemotePingTaskService");
        map.put("CLASS_NAME", "RemotePingTaskServiceImpl");
//        map.put("PORT", 11000);
        services.add(map);

        map = new java.util.HashMap<String, Object>();
        map.put("NAME", "FPingTaskService");
        map.put("CLASS_NAME", "FPingTaskServiceImpl");
        map.put("PORT", 10990);
        services.add(map);
    }

    private static void createRegistry(int port) throws RemoteException {
        if (port != -1) {
            //java.rmi.registry.Registry registry = java.rmi.registry.LocateRegistry.getRegistry("localhost", port);
            //System.out.println("--->" + registry);
            //if (registry == null) {
            System.out.println("Create registry for localhost on " + port);
            try {
                Registry registry = LocateRegistry.createRegistry(port);
            } catch (ExportException e) {
                System.out.println("Registry for localhost on " + port + " already exists");
            }
            //}
        }
    }

    private static void export(Remote stub, int port) throws RemoteException {
        if (! (stub instanceof UnicastRemoteObject)) {
            if (port == -1) {
                System.out.println("export " + stub.getClass().getName() + " on an anonymous port");
                UnicastRemoteObject.exportObject(stub);
            } else {
                System.out.println("export " + stub.getClass().getName() + " on port " + port);
                UnicastRemoteObject.exportObject(stub, port);
            }
        }
    }

    public static void main(String[] args) throws Exception {
        createRegistry(DEFAULT_RMI_PORT);

        try {
            for (int i = 0, size = services.size(); i < size; i++) {
                Map<String, Object> service = services.get(i);
                String serviceName = (String) service.get("NAME");
                String className = (String) service.get("CLASS_NAME");

                Object o = service.get("PORT");
                int port = -1;
                if (o != null) {
                    port = ((Integer) o).intValue();
                }

                Class clazz = Class.forName(className);
                Object object = clazz.newInstance();
                if (object instanceof Remote) {
                    Remote stub = (Remote) object;
                    export(stub, port);
                    Naming.bind("rmi://localhost:" + DEFAULT_RMI_PORT + "/" + serviceName, stub);
                    System.out.println("RMI service '" + serviceName + "' on localhost:" + DEFAULT_RMI_PORT + " is binding...");
                } else {
                    System.out.println("\"" + className + "\" is not a available RMI service");
                }


                System.out.println("------------------------------------------------------------------------------------------------");
            }
        } catch (ClassNotFoundException e) {
            throw new ServiceException(e);
        } catch (RemoteException e) {
            throw new ServiceException(e);
        } catch (AlreadyBoundException e) {
            throw new ServiceException(e);
        } catch (MalformedURLException e) {
            throw new ServiceException(e);
        }
    }
}

其中createRegistry(DEFAULT_RMI_PORT);会启动一个Registry。Registry也可以单独启动,服务启动的时候,服务注册绑定时(将服务绑定bind到某个地址上),将服务注册到单独启动的Registry上。

 

单独启动Registry:

public class ServiceRegistry {

    public static int DEFAULT_PORT = 20999;

    private void start() {
        Registry registry = null;
        try {
            registry = LocateRegistry.createRegistry(DEFAULT_PORT);
        } catch (RemoteException e) {
            e.printStackTrace();
        }
        synchronized (this) {
            try {
                wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    public static void main(String[] args) {
        new ServiceRegistry().start();
    }
}

RMI Registry默认端口为1099。

RMI服务注册绑定地址rmi://host:port/servicename,如果是本地地址localhost可省略。

如rmi://:10999/FPingTaskService,rmi://:10999/RemotePingTaskService

 

Registry Admin:

 

public class ServiceRegistryAdmin {

    public static int DEFAULT_PORT = 20999;

    private void start() {
        Registry registry = null;
        try {
            registry = LocateRegistry.getRegistry(DEFAULT_PORT);
        } catch (RemoteException e) {
            e.printStackTrace();
        }
        try {
            String[] list = registry.list();
            for (String serviceName : list) {
                System.out.println("service: " + serviceName);
            }
        } catch(RemoteException e) {
            e.printStackTrace();
        }
        synchronized (this) {
            try {
                wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    public static void main(String[] args) {
        new ServiceRegistryAdmin().start();
    }
}

 

 

public class ServiceException extends Exception {
    public ServiceException() {
        super();
    }

    public ServiceException(String message) {
        super(message);
    }

    public ServiceException(Throwable cause) {
        super(cause);
    }
}

 

启动RMI服务,运行结果如下:

Create registry for localhost on 10999
RMI service 'RemotePingTaskService' on localhost:10999 is binding...
------------------------------------------------------------------------------------------------
RMI service 'FPingTaskService' on localhost:10999 is binding...
------------------------------------------------------------------------------------------------

  

 

import java.rmi.Naming;

public class ServiceTest {

    public static void main(String[] args) throws Exception {
        FPingTaskService fPingTaskService = (FPingTaskService) Naming.lookup("rmi://:10999/FPingTaskService");
        System.out.println(fPingTaskService.fping(1234));

        RemotePingTaskService remotePingTaskService = (RemotePingTaskService) Naming.lookup("rmi://:10999/RemotePingTaskService");
        System.out.println(remotePingTaskService.rping(1234));
    }
}

 启动客户端,调用rmi服务。服务端输出:

ping 1234
remote ping 1234

 在上面例子中,FPingTaskService,RemotePingTaskService 服务接口实现RemotePingTaskServiceImpl,FPingTaskServiceImpl继承了UnicastRemoteObject类,在创建服务实例时,会自动export服务对象(默认将服务对象export到端口0上)。

protected UnicastRemoteObject() throws RemoteException
{
	this(0);
}

 

protected UnicastRemoteObject(int port) throws RemoteException
{
	this.port = port;
	exportObject((Remote) this, port);
}

 

protected UnicastRemoteObject(int port,
							  RMIClientSocketFactory csf,
							  RMIServerSocketFactory ssf)
	throws RemoteException
{
	this.port = port;
	this.csf = csf;
	this.ssf = ssf;
	exportObject((Remote) this, port, csf, ssf);
}

 关键代码:

exportObject((Remote) this, port);

在这个例子中,

 

FPingTaskService fPingTaskService = (FPingTaskService) Naming.lookup("rmi://:10999/FPingTaskService");
RemotePingTaskService remotePingTaskService = (RemotePingTaskService) Naming.lookup("rmi://:10999/RemotePingTaskService");
lookup返回的远程对象是java动态代理对象,而不是类似FPingTaskServiceImpl_Stub,RemotePingTaskServiceImpl_Stub的Stub(存根)对象。
如果FPingTaskService,RemotePingTaskService 服务接口实现RemotePingTaskServiceImpl,FPingTaskServiceImpl没有继承UnicastRemoteObject类,在创建服务实例后,需要export服务对象到端口上。
public static RemoteStub exportObject(Remote obj) throws RemoteException
public static Remote exportObject(Remote obj, int port) throws RemoteException
public static Remote exportObject(Remote obj, int port, RMIClientSocketFactory csf, RMIServerSocketFactory ssf) throws RemoteException
其中public static RemoteStub exportObject(Remote obj) throws RemoteException方法已废弃。
如果使用public static RemoteStub exportObject(Remote obj) throws RemoteException方法将服务对象export到端口(匿名端口)上,需要通过rmic为服务生成对应的Stub,命令如下:
>rmic RemotePingTaskServiceImpl
>rmic FPingTaskServiceImpl
而如果使用
public static Remote exportObject(Remote obj, int port) throws RemoteException
public static Remote exportObject(Remote obj, int port, RMIClientSocketFactory csf, RMIServerSocketFactory ssf) throws RemoteException
 
方法将服务对象export到指定端口上,则不需要为服务生成对应的Stub。在这种情况下,
FPingTaskService fPingTaskService = (FPingTaskService) Naming.lookup("rmi://:10999/FPingTaskService");
RemotePingTaskService remotePingTaskService = (RemotePingTaskService) Naming.lookup("rmi://:10999/RemotePingTaskService");

lookup返回的远程对象是类似FPingTaskServiceImpl_Stub,RemotePingTaskServiceImpl_Stub的Stub(存根)对象。

通过rmic生成的Stub代码如下:(反编译后的代码)
public final class RemotePingTaskServiceImpl_Stub extends RemoteStub implements RemotePingTaskService {
    private static final long serialVersionUID = 2L;
    private static Method $method_rping_0;

    static {
        try {
            $method_rping_0 = (class$RemotePingTaskService != null?class$RemotePingTaskService:(class$RemotePingTaskService = class$("RemotePingTaskService"))).getMethod("rping", new Class[]{Integer.TYPE});
        } catch (NoSuchMethodException var0) {
            throw new NoSuchMethodError("stub class initialization failed");
        }
    }

    public RemotePingTaskServiceImpl_Stub(RemoteRef var1) {
        super(var1);
    }

    public int rping(int var1) throws RemoteException {
        try {
            Object var2 = super.ref.invoke(this, $method_rping_0, new Object[]{new Integer(var1)}, -3207680512012333040L);
            return ((Integer)var2).intValue();
        } catch (RuntimeException var3) {
            throw var3;
        } catch (RemoteException var4) {
            throw var4;
        } catch (Exception var5) {
            throw new UnexpectedException("undeclared checked exception", var5);
        }
    }
}
 
public final class FPingTaskServiceImpl_Stub extends RemoteStub implements FPingTaskService {
    private static final long serialVersionUID = 2L;
    private static Method $method_fping_0;

    static {
        try {
            $method_fping_0 = (class$FPingTaskService != null?class$FPingTaskService:(class$FPingTaskService = class$("FPingTaskService"))).getMethod("fping", new Class[]{Integer.TYPE});
        } catch (NoSuchMethodException var0) {
            throw new NoSuchMethodError("stub class initialization failed");
        }
    }

    public FPingTaskServiceImpl_Stub(RemoteRef var1) {
        super(var1);
    }

    public int fping(int var1) throws RemoteException {
        try {
            Object var2 = super.ref.invoke(this, $method_fping_0, new Object[]{new Integer(var1)}, -5354781327026957849L);
            return ((Integer)var2).intValue();
        } catch (RuntimeException var3) {
            throw var3;
        } catch (RemoteException var4) {
            throw var4;
        } catch (Exception var5) {
            throw new UnexpectedException("undeclared checked exception", var5);
        }
    }
}

在这种情况下,

 

FPingTaskService fPingTaskService = (FPingTaskService) Naming.lookup("rmi://:10999/FPingTaskService");
RemotePingTaskService remotePingTaskService = (RemotePingTaskService) Naming.lookup("rmi://:10999/RemotePingTaskService");
lookup返回的远程对象是类似FPingTaskServiceImpl_Stub,RemotePingTaskServiceImpl_Stub的Stub(存根)对象。
下面是java 1.1下开发rmi的例子:
接口不变
import java.rmi.RemoteException;

public class FPingTaskServiceImpl_Java1_1_8 implements FPingTaskService {
    public int fping(int target) throws RemoteException {
        System.out.println("ping " + target);
        return 1;
    }
}
 
import java.rmi.RemoteException;

public class RemotePingTaskServiceImpl_Java1_1_8 implements RemotePingTaskService {
    public int rping(int target) throws RemoteException {
        System.out.println("remote ping " + target);
        return 1;
    }
}
 
import java.net.MalformedURLException;
import java.rmi.AlreadyBoundException;
import java.rmi.Naming;
import java.rmi.Remote;
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
import java.rmi.server.ExportException;
import java.rmi.server.UnicastRemoteObject;
import java.util.*;

public class ServiceExportor_Java1_1_8 {
    public static Vector services;

    public static int DEFAULT_RMI_PORT = 10999;

    static {
        services = new Vector();
        Hashtable map = new Hashtable();
        map.put("NAME", "RemotePingTaskService");
        map.put("CLASS_NAME", "RemotePingTaskServiceImpl_Java1_1_8");
        map.put("PORT", new Integer(11000));
        services.addElement(map);

        map = new Hashtable();
        map.put("NAME", "FPingTaskService");
        map.put("CLASS_NAME", "FPingTaskServiceImpl_Java1_1_8");
        map.put("PORT", new Integer(10990));
        services.addElement(map);
    }

    private static void createRegistry(int port) throws RemoteException {
        if (port != -1) {
            //java.rmi.registry.Registry registry = java.rmi.registry.LocateRegistry.getRegistry("localhost", port);
            //System.out.println("--->" + registry);
            //if (registry == null) {
            System.out.println("Create registry for localhost on " + port);
            try {
                Registry registry = LocateRegistry.createRegistry(port);
            } catch (ExportException e) {
                e.printStackTrace();
                System.out.println("Registry for localhost on " + port + " already exists");
            }
            //}
        }
    }

    private static void export(Remote stub, int port) throws RemoteException {
        if (! (stub instanceof UnicastRemoteObject)) {
            System.out.println("export " + stub.getClass().getName() + " on an anonymous port");
            UnicastRemoteObject.exportObject(stub);
        }
    }

    public static void main(String[] args) throws Exception {
        createRegistry(DEFAULT_RMI_PORT);

        try {
            for (int i = 0, size = services.size(); i < size; i++) {
                Hashtable service = (Hashtable) services.elementAt(i);
                String serviceName = (String) service.get("NAME");
                String className = (String) service.get("CLASS_NAME");

                Object o = service.get("PORT");
                int port = -1;
                if (o != null) {
                    port = ((Integer) o).intValue();
                }

                Class clazz = Class.forName(className);
                Object object = clazz.newInstance();
                if (object instanceof Remote) {
                    Remote stub = (Remote) object;
                    export(stub, port);
                    Naming.bind("rmi://localhost:" + DEFAULT_RMI_PORT + "/" + serviceName, stub);
                    System.out.println("RMI service '" + serviceName + "' on localhost:" + DEFAULT_RMI_PORT + " is binding...");
                } else {
                    System.out.println("\"" + className + "\" is not a available RMI service");
                }


                System.out.println("------------------------------------------------------------------------------------------------");
            }
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
            throw new ServiceException_Java1_1_8(e.getMessage());
        } catch (RemoteException e) {
            e.printStackTrace();
            throw new ServiceException_Java1_1_8(e.getMessage());
        } catch (AlreadyBoundException e) {
            e.printStackTrace();
            throw new ServiceException_Java1_1_8(e.getMessage());
        } catch (MalformedURLException e) {
            e.printStackTrace();
            throw new ServiceException_Java1_1_8(e.getMessage());
        }
    }
}
 
public class ServiceException_Java1_1_8 extends Exception {
    public ServiceException_Java1_1_8() {
        super();
    }

    public ServiceException_Java1_1_8(String message) {
        super(message);
    }

}
编译后,为rmi服务生成Stub(存根)和Skel(Skeleton):
>rmic RemotePingTaskServiceImpl_Java1_1_8

>rmic FPingTaskServiceImpl_Java1_1_8
生成的Stub(存根)和Skel(Skeleton)
public final class FPingTaskServiceImpl_Java1_1_8_Stub extends RemoteStub implements FPingTaskService {
    private static final Operation[] operations = new Operation[]{new Operation("int fping(int)")};
    private static final long interfaceHash = 2769259642710215340L;

    public FPingTaskServiceImpl_Java1_1_8_Stub() {
    }

    public FPingTaskServiceImpl_Java1_1_8_Stub(RemoteRef var1) {
        super(var1);
    }

    public int fping(int var1) throws RemoteException {
        try {
            RemoteCall var2 = super.ref.newCall(this, operations, 0, 2769259642710215340L);

            try {
                ObjectOutput var3 = var2.getOutputStream();
                var3.writeInt(var1);
            } catch (IOException var15) {
                throw new MarshalException("error marshalling arguments", var15);
            }

            super.ref.invoke(var2);

            int var19;
            try {
                ObjectInput var6 = var2.getInputStream();
                var19 = var6.readInt();
            } catch (IOException var13) {
                throw new UnmarshalException("error unmarshalling return", var13);
            } finally {
                super.ref.done(var2);
            }

            return var19;
        } catch (RuntimeException var16) {
            throw var16;
        } catch (RemoteException var17) {
            throw var17;
        } catch (Exception var18) {
            throw new UnexpectedException("undeclared checked exception", var18);
        }
    }
}
 
public final class FPingTaskServiceImpl_Java1_1_8_Skel implements Skeleton {
    private static final Operation[] operations = new Operation[]{new Operation("int fping(int)")};
    private static final long interfaceHash = 2769259642710215340L;

    public Operation[] getOperations() {
        return (Operation[])operations.clone();
    }

    public void dispatch(Remote var1, RemoteCall var2, int var3, long var4) throws Exception {
        if(var4 != 2769259642710215340L) {
            throw new SkeletonMismatchException("interface hash mismatch");
        } else {
            FPingTaskServiceImpl_Java1_1_8 var6 = (FPingTaskServiceImpl_Java1_1_8)var1;
            switch(var3) {
            case 0:
                int var7;
                try {
                    ObjectInput var10 = var2.getInputStream();
                    var7 = var10.readInt();
                } catch (IOException var15) {
                    throw new UnmarshalException("error unmarshalling arguments", var15);
                } finally {
                    var2.releaseInputStream();
                }

                int var8 = var6.fping(var7);

                try {
                    ObjectOutput var9 = var2.getResultStream(true);
                    var9.writeInt(var8);
                    return;
                } catch (IOException var14) {
                    throw new MarshalException("error marshalling return", var14);
                }
            default:
                throw new UnmarshalException("invalid method number");
            }
        }
    }

    public FPingTaskServiceImpl_Java1_1_8_Skel() {
    }
}
 
public final class RemotePingTaskServiceImpl_Java1_1_8_Stub extends RemoteStub implements RemotePingTaskService {
    private static final Operation[] operations = new Operation[]{new Operation("int rping(int)")};
    private static final long interfaceHash = -3061403402385181673L;

    public RemotePingTaskServiceImpl_Java1_1_8_Stub() {
    }

    public RemotePingTaskServiceImpl_Java1_1_8_Stub(RemoteRef var1) {
        super(var1);
    }

    public int rping(int var1) throws RemoteException {
        try {
            RemoteCall var2 = super.ref.newCall(this, operations, 0, -3061403402385181673L);

            try {
                ObjectOutput var3 = var2.getOutputStream();
                var3.writeInt(var1);
            } catch (IOException var15) {
                throw new MarshalException("error marshalling arguments", var15);
            }

            super.ref.invoke(var2);

            int var19;
            try {
                ObjectInput var6 = var2.getInputStream();
                var19 = var6.readInt();
            } catch (IOException var13) {
                throw new UnmarshalException("error unmarshalling return", var13);
            } finally {
                super.ref.done(var2);
            }

            return var19;
        } catch (RuntimeException var16) {
            throw var16;
        } catch (RemoteException var17) {
            throw var17;
        } catch (Exception var18) {
            throw new UnexpectedException("undeclared checked exception", var18);
        }
    }
}
 
public final class RemotePingTaskServiceImpl_Java1_1_8_Skel implements Skeleton {
    private static final Operation[] operations = new Operation[]{new Operation("int rping(int)")};
    private static final long interfaceHash = -3061403402385181673L;

    public Operation[] getOperations() {
        return (Operation[])operations.clone();
    }

    public void dispatch(Remote var1, RemoteCall var2, int var3, long var4) throws Exception {
        if(var4 != -3061403402385181673L) {
            throw new SkeletonMismatchException("interface hash mismatch");
        } else {
            RemotePingTaskServiceImpl_Java1_1_8 var6 = (RemotePingTaskServiceImpl_Java1_1_8)var1;
            switch(var3) {
            case 0:
                int var7;
                try {
                    ObjectInput var10 = var2.getInputStream();
                    var7 = var10.readInt();
                } catch (IOException var15) {
                    throw new UnmarshalException("error unmarshalling arguments", var15);
                } finally {
                    var2.releaseInputStream();
                }

                int var8 = var6.rping(var7);

                try {
                    ObjectOutput var9 = var2.getResultStream(true);
                    var9.writeInt(var8);
                    return;
                } catch (IOException var14) {
                    throw new MarshalException("error marshalling return", var14);
                }
            default:
                throw new UnmarshalException("invalid method number");
            }
        }
    }

    public RemotePingTaskServiceImpl_Java1_1_8_Skel() {
    }
}
 
启动rmi服务:
>java ServiceExportor_Java1_1_8
Create registry for localhost on 10999
export RemotePingTaskServiceImpl_Java1_1_8 on an anonymous port
RMI service 'RemotePingTaskService' on localhost:10999 is binding...
--------------------------------------------------------------------------------
----------------
export FPingTaskServiceImpl_Java1_1_8 on an anonymous port
RMI service 'FPingTaskService' on localhost:10999 is binding...
--------------------------------------------------------------------------------
----------------
 
import java.rmi.Naming;

public class ServiceTest_Java1_1_8 {

    public static void main(String[] args) throws Exception {
        FPingTaskService fPingTaskService = (FPingTaskService) Naming.lookup("rmi://:10999/FPingTaskService");
        int result = fPingTaskService.fping(1234);
        System.out.println(result);

        RemotePingTaskService remotePingTaskService = (RemotePingTaskService) Naming.lookup("rmi://:10999/RemotePingTaskService");
        System.out.println(remotePingTaskService.rping(1234));
    }
}
  启动客户端,调用rmi服务。服务端输出:
ping 1234
remote ping 1234

JNI

GetMethodID函数声明如下:

jmethodID (JNICALL *GetMethodID) (JNIEnv *env, jclass clazz, const char *name, const char *sig);

获取Java对象方法的jmethodID。包括构造方法,构造方法是一种特殊的方法,但在JVM层面和其他的方式是一样的。

 

参数说明:

env: 上面已经说明

clazz:表示对象类,如Object.class。

name:方法名,如果是得到构造方法的jmethodID,该参数固定为<init>。

sig:方法签名,形式如下:

(参数类型签名列表)返回类型签名。

 

如无参构造方法:public JniNewTestObjectX()

或者public void testMethod()方法定义,它的签名为:

()V

 

如无参构造方法:public JniNewTestObjectX(int i, String s)

或者public void testMethod(int i, String s)方法定义,它的签名为:

(ILjava/lang/String;)V

 

Java JNI: Java 本机接口可以采用C开发,也支持C++。

 

例子:

C开发的例子。

 

public class JniCallMethodReturnVoidTest {
	static {  
        System.loadLibrary("libjnitest");  
    }

	public static void main(String[] args) {
	  JniNewTest obj = new JniNewTest();
	  obj.testMethod();
	}
}

class JniNewTest {
	public native void testMethod();
}

 

>javac JniCallMethodReturnVoidTest.java

 

>javah -jni -d . JniNewTest

 

/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class JniNewTest */

#ifndef _Included_JniNewTest
#define _Included_JniNewTest
#ifdef __cplusplus
extern "C" {
#endif
/*
 * Class:     JniNewTest
 * Method:    testMethod
 * Signature: ()V
 */
JNIEXPORT void JNICALL Java_JniNewTest_testMethod
  (JNIEnv *, jobject);

#ifdef __cplusplus
}
#endif
#endif

 

实现:

#include "JniNewTest.h"
JNIEXPORT void JNICALL Java_JniNewTest_testMethod
  (JNIEnv *env, jobject jobj)
{
    printf("debug: Java_JniNewTest_testMethod.\n");
}

 

 

>cl /GR /GX /W3 /ID:\usr\bin\jdk1.6.0_12\include /ID:\usr\bin\jdk1.6.0_12\include\win32 /c /Fo.\ JniNewTest.c

 

>link /DLL /OUT:.\libjnitest.dll .\JniNewTest.obj

 

>java JniCallMethodReturnVoidTest
debug: Java_JniNewTest_testMethod.

 

 

Java native开发

 

目录结构:

>tree /F .

Folder PATH listing for volume D

Volume serial number is F075-351A

└───com

    └───jx

            com_jx_Object.c

            com_jx_Object.dll

            com_jx_Object.exp

            com_jx_Object.h

            com_jx_Object.lib

            com_jx_Object.obj

            libobj.dll

            libobj.exp

            libobj.lib

            Object.class

            Object.java

            ObjectTest.java

 

Object:

 

package com.jx;

public class Object {

	public native int addr();
	
	static {
		System.loadLibrary("libobj");
	}
}

 

 

>javac com\jx\Object.java
 
>javah -jni -d com\jx com.jx.Object
 

 

com_jx_Object.h:

 

/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class com_jx_Object */

#ifndef _Included_com_jx_Object
#define _Included_com_jx_Object
#ifdef __cplusplus
extern "C" {
#endif
/*
 * Class:     com_jx_Object
 * Method:    addr
 * Signature: ()I
 */
JNIEXPORT jint JNICALL Java_com_jx_Object_addr
  (JNIEnv *, jobject);

#ifdef __cplusplus
}
#endif
#endif
 

 

com_jx_Object.c:

 

#include <stdio.h>

#include "com_jx_Object.h"

JNIEXPORT jint JNICALL Java_com_jx_Object_addr
  (JNIEnv *env, jobject jobj)
{
  printf("Java_com_jx_Object_addr.\n");
  return 0;
}
 

 

编译:

 

>cl /GX /W3 /ID:\usr\bin\jdk1.8.0_101\include /ID:\usr\bin\jdk1.8.0_101\include\win32 /c /Fo.\ *.c 
连接生成库文件:

 

 

>link /DLL /OUT:.\libobj.dll .\*.obj

 

也可以使用以下命令一次就生成库文件

 

# 也可以使用以下命令一次就生成库文件:
>cl /ID:\usr\bin\jdk1.8.0_101\include /ID:\usr\bin\jdk1.8.0_101\include\win32 /LD com_jx_Object.c
 

 

将生成的库文件libobj.dll放在path目录下:

 

public static void main(String[] args) {
	String libPath = System.getProperty("java.library.path");
	System.out.println(libPath);
	Object obj = new Object();
	obj.addr();
}
 
运行结果
<java.library.path>
Java_com_jx_Object_addr.
Java JNI开发实例:实例化Java对象
在这个例子中,在Java Runtime(Java运行时环境)层面通过NewObject函数创建Java对象(对象实例化),这种方式和在Java层面实例化对象(如new ... ...)效果是一样的。
NewObject函数定义如下:
jobject (JNICALL *NewObject) (JNIEnv *env, jclass clazz, jmethodID methodID, ...);
Java通过构造方法实例化对象,构造方法是一种特殊的方法,但在JVM层面和其他的方式是一样的,所以在Java Runtime(Java运行时环境)层面通过NewObject函数创建Java对象(对象实例化)需要指定构造方法。
参数说明:
env:上面已经说明
clazz:表示构造对象的类
methodID:表示函数标识,这里是构造函数,通过GetMethodID得到函数标识(包括构造函数)。
最后一个不定长参数列表表示传给构造函数的参数列表。
变体:
jobject (JNICALL *NewObjectV) (JNIEnv *env, jclass clazz, jmethodID methodID, va_list args);
NewObjectV和NewObject不同的是在调用构造函数的传参上,也就是最后一个参数,NewObjectV在构造函数的参数传参上采用的是不定长参数列表:va_list。
jobject (JNICALL *NewObjectA) (JNIEnv *env, jclass clazz, jmethodID methodID, const jvalue *args);
NewObjectV和NewObject不同的是在调用构造函数的传参上,也就是最后一个参数,NewObjectV在构造函数的参数传参上采用的是jvalue指针。
class JniNewTestObject {
	public String toString() {
	    return super.toString() + ": jni new object.";
	}
}
 
class JniNewTestObjectX {

    private int i;

	private String s;

	public JniNewTestObjectX() {
	
	}

	public JniNewTestObjectX(int i, String s) {
	  this.i = i;
	  this.s = s;
	}

	public int i() {
	  return i;
	}

	public String s() {
	  return s;
	}

	public String toString() {
	    return super.toString() + ": jni new object.";
	}
}
 
abstract class JniNewTestAbstractObject 
{
	public String toString() {
	    return super.toString() + ": jni new object.";
	}
}
 
class JniNewTestObjectConstructor {
	public native JniNewTestObject constructJniNewTestObject(Class<?> clazz);

	public native JniNewTestObjectX constructJniNewTestObjectX(Class<?> clazz);

	public native JniNewTestObjectX constructJniNewTestObjectX(Class<?> clazz, int i, String s);

	public native JniNewTestAbstractObject constructJniNewTestAbstractObject(Class<?> clazz);
}
 
public class JniNewObjectTest {
	static {  
        System.loadLibrary("libjnitest");  
    }

	public static void main(String[] args) {
	  JniNewTestObjectConstructor constructor = new JniNewTestObjectConstructor();
	  JniNewTestObject obj = constructor.constructJniNewTestObject(JniNewTestObject.class);
	  if (obj == null) {
		System.out.println("construct fail.");
	  } else {
		System.out.println(obj.toString());
	  }

	  JniNewTestObjectX objx1 = constructor.constructJniNewTestObjectX(JniNewTestObjectX.class);
	  if (objx1 == null) {
		System.out.println("construct fail.");
	  } else {
		System.out.println(objx1.toString());
		System.out.println(objx1.i());
		System.out.println(objx1.s());
	  }

	  JniNewTestObjectX objx2 = constructor.constructJniNewTestObjectX(JniNewTestObjectX.class, 1234, "this is 1234.");
	  if (objx2 == null) {
		System.out.println("construct fail.");
	  } else {
		System.out.println(objx2.toString());
		System.out.println(objx2.i());
		System.out.println(objx2.s());
	  }

	  JniNewTestAbstractObject aobj = constructor.constructJniNewTestAbstractObject(JniNewTestAbstractObject.class);
	  if (aobj == null) {
		System.out.println("construct fail.");
	  } else {
		System.out.println(aobj.toString());
	  }
	}
}
 
>javac JniNewObjectTest.java
 为JniNewTestObjectConstructor生成本机接口:JniNewTestObjectConstructor.h
>javah -jni -d . JniNewTestObjectConstructor
 
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class JniNewTestObjectConstructor */

#ifndef _Included_JniNewTestObjectConstructor
#define _Included_JniNewTestObjectConstructor
#ifdef __cplusplus
extern "C" {
#endif
/*
 * Class:     JniNewTestObjectConstructor
 * Method:    constructJniNewTestObject
 * Signature: (Ljava/lang/Class;)LJniNewTestObject;
 */
JNIEXPORT jobject JNICALL Java_JniNewTestObjectConstructor_constructJniNewTestObject
  (JNIEnv *, jobject, jclass);

/*
 * Class:     JniNewTestObjectConstructor
 * Method:    constructJniNewTestObjectX
 * Signature: (Ljava/lang/Class;)LJniNewTestObjectX;
 */
JNIEXPORT jobject JNICALL Java_JniNewTestObjectConstructor_constructJniNewTestObjectX__Ljava_lang_Class_2
  (JNIEnv *, jobject, jclass);

/*
 * Class:     JniNewTestObjectConstructor
 * Method:    constructJniNewTestObjectX
 * Signature: (Ljava/lang/Class;ILjava/lang/String;)LJniNewTestObjectX;
 */
JNIEXPORT jobject JNICALL Java_JniNewTestObjectConstructor_constructJniNewTestObjectX__Ljava_lang_Class_2ILjava_lang_String_2
  (JNIEnv *, jobject, jclass, jint, jstring);

/*
 * Class:     JniNewTestObjectConstructor
 * Method:    constructJniNewTestAbstractObject
 * Signature: (Ljava/lang/Class;)LJniNewTestAbstractObject;
 */
JNIEXPORT jobject JNICALL Java_JniNewTestObjectConstructor_constructJniNewTestAbstractObject
  (JNIEnv *, jobject, jclass);

#ifdef __cplusplus
}
#endif
#endif
 
实现本机接口(JniNewTestObjectConstructor.h):JniNewTestObjectConstructor.c
#include "JniNewTestObjectConstructor.h"

JNIEXPORT jobject JNICALL Java_JniNewTestObjectConstructor_constructJniNewTestObject(JNIEnv *env, jobject jobj, jclass jclazz)
{
  jmethodID m_id = NULL;
  jobject obj = NULL;

  m_id = (*env)->GetMethodID(env, jclazz, "<init>", "()V");
  if (m_id == NULL)
  {
	printf("err: GetMethodID, no constructor with no args.");
	return NULL;
  }
  obj = (*env)->NewObject(env, jclazz, m_id); // public JniNewTestObject()
  if (obj == NULL)
  {
	  printf("err: NewObject, return null.");
	  return NULL;
  }
  return obj;
}

JNIEXPORT jobject JNICALL Java_JniNewTestObjectConstructor_constructJniNewTestObjectX__Ljava_lang_Class_2(JNIEnv *env, jobject jobj, jclass jclazz)
{
  jmethodID m_id = NULL;
  jobject obj = NULL;

  m_id = (*env)->GetMethodID(env, jclazz, "<init>", "()V");
  if (m_id == NULL)
  {
	printf("err: GetMethodID, no constructor with no args.");
	return NULL;
  }
  obj = (*env)->NewObject(env, jclazz, m_id); // public JniNewTestObjectX()
  if (obj == NULL)
  {
	  printf("err: NewObject, return null.");
	  return NULL;
  }
  return obj;
}

JNIEXPORT jobject JNICALL Java_JniNewTestObjectConstructor_constructJniNewTestObjectX__Ljava_lang_Class_2ILjava_lang_String_2(JNIEnv *env, 
    jobject jobj, 
	jclass jclazz, 
	jint i, jstring s)
{
  jmethodID m_id = NULL;
  jobject obj = NULL;

  m_id = (*env)->GetMethodID(env, jclazz, "<init>", "(ILjava/lang/String;)V");
  if (m_id == NULL)
  {
	printf("err: GetMethodID, no constructor with no args.");
	return NULL;
  }
  obj = (*env)->NewObject(env, jclazz, m_id, i, s); // public JniNewTestObjectX(int i, String s)
  if (obj == NULL)
  {
	  printf("err: NewObject, return null.");
	  return NULL;
  }
  return obj;
}

JNIEXPORT jobject JNICALL Java_JniNewTestObjectConstructor_constructJniNewTestAbstractObject(JNIEnv *env, jobject jobj, jclass jclazz) 
{
  jmethodID m_id = NULL;
  jobject obj = NULL;

  m_id = (*env)->GetMethodID(env, jclazz, "<init>", "()V");
  if (m_id == NULL)
  {
	printf("err: GetMethodID, no constructor with no args.");
	return NULL;
  }
  obj = (*env)->NewObject(env, jclazz, m_id); // public JniNewTestAbstractObject(), class JniNewTestAbstractObject declares abstract.
  if (obj == NULL)
  {
	  printf("err: NewObject, return null.");
	  return NULL;
  }
  return obj;
}
 
 
>cl /GR /GX /W3 /ID:\usr\bin\jdk1.6.0_12\include /ID:\usr\bin\jdk1.6.0_12\include\win32 /c /Fo.\ *.c
 
>link /DLL /OUT:.\libjnitest.dll .\*.obj
 运行结果:
>java JniNewObjectTest
JniNewTestObject@1fb8ee3: jni new object.
JniNewTestObjectX@14318bb: jni new object.
0
null
JniNewTestObjectX@ca0b6: jni new object.
1234
this is 1234.
err: NewObject, return null.Exception in thread "main" java.lang.InstantiationEx
ception: JniNewTestAbstractObject
        at JniNewTestObjectConstructor.constructJniNewTestAbstractObject(Native
Method)
        at JniNewObjectTest.main(JniNewObjectTest.java:33)
 

 

Security

 

Java Security API Provider:

java.security.Provider

 

一些实现:

sun.security.provider.Sun

sun.security.ec.SunEC

com.sun.crypto.provider.SunJCE

sun.security.ssl.SunJSSE

sun.security.pkcs11.SunPKCS11

sun.security.jgss.SunProvider

sun.security.smartcardio.SunPCSC

com.sun.deploy.security.MozillaJSSProvider

com.sun.deploy.security.MSCryptoProvider

sun.security.mscapi.SunMSCAPI

org.spongycastle.jce.provider.BouncyCastleProvider

 

java.lang.SecurityException: JCE cannot authenticate the provider SC

 

at javax.crypto.Cipher.getInstance(Cipher.java:657)

at spongycastle.RSATest.test1(RSATest.java:66)

at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)

at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)

at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)

at java.lang.reflect.Method.invoke(Method.java:498)

at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:45)

at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)

at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:42)

at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20)

at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:263)

at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:68)

at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:47)

at org.junit.runners.ParentRunner$3.run(ParentRunner.java:231)

at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:60)

at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:229)

at org.junit.runners.ParentRunner.access$000(ParentRunner.java:50)

at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:222)

at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:28)

at org.junit.runners.ParentRunner.run(ParentRunner.java:300)

at org.junit.runner.JUnitCore.run(JUnitCore.java:157)

at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:68)

at com.intellij.rt.execution.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:51)

at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:237)

at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:70)

Caused by: java.util.jar.JarException: file:/E:/.m2/com/madgag/spongycastle/prov/1.58.0.0/prov-1.58.0.0.jar has unsigned entries - org/spongycastle/jce/MultiCertStoreParameters.class

at javax.crypto.JarVerifier.verifySingleJar(JarVerifier.java:464)

at javax.crypto.JarVerifier.verifyJars(JarVerifier.java:322)

at javax.crypto.JarVerifier.verify(JarVerifier.java:250)

at javax.crypto.JceSecurity.verifyProviderJar(JceSecurity.java:160)

at javax.crypto.JceSecurity.getVerificationResult(JceSecurity.java:186)

at javax.crypto.Cipher.getInstance(Cipher.java:653)

... 24 more

 

 

DI/IOC

 

public class Test {

    @org.junit.Test
    public void test1() {
        HK2 hk2 = HK2.get();
        Services services = hk2.create(null, new Module[0]);
        DynamicBinderFactory dynamicBinderFactory = services.bindDynamically();

        Binder binder = dynamicBinderFactory.bind(ServiceImpl.class, ServiceImpl.class, Service.class);
        ResolvedBinder resolvedBinder = binder.to(ServiceImpl.class);
        resolvedBinder.in(Singleton.class);

        binder = dynamicBinderFactory.bind(ServiceImpl1.class);
        resolvedBinder = binder.to(ServiceImpl1.class);
        resolvedBinder.in(Singleton.class);

        binder = dynamicBinderFactory.bind(ServiceImpl2.class);
        resolvedBinder = binder.to(ServiceImpl2.class);
        resolvedBinder.in(Singleton.class);

        dynamicBinderFactory.commit();

        ServiceLocator serviceLocator = services.byType(ServiceImpl.class);
        ServiceImpl serviceImpl = (ServiceImpl) serviceLocator.get();
        serviceImpl.name();

        serviceLocator = services.byType(ServiceImpl1.class);
        ServiceImpl1 serviceImpl1 = (ServiceImpl1) serviceLocator.get();
        serviceImpl1.name();

        serviceLocator = services.byType(ServiceImpl2.class);
        ServiceImpl2 serviceImpl2 = (ServiceImpl2) serviceLocator.get();
        serviceImpl2.name();

        System.out.println();
    }

    @org.junit.Test
    public void test2() {
        HK2 hk2 = HK2.get();
        Services services = hk2.create(null, new Module[0]);
        DynamicBinderFactory dynamicBinderFactory = services.bindDynamically();

        Binder binder = dynamicBinderFactory.bind(Service.class);
        ResolvedBinder resolvedBinder = binder.to(ServiceImpl.class);
        resolvedBinder.in(Singleton.class);

        binder = dynamicBinderFactory.bind(ServiceImpl.class);
        resolvedBinder = binder.to(ServiceImpl.class);
        resolvedBinder.in(Singleton.class);

        binder = dynamicBinderFactory.bind(ServiceImpl1.class);
        resolvedBinder = binder.to(ServiceImpl1.class);
        resolvedBinder.in(Singleton.class);

        binder = dynamicBinderFactory.bind(ServiceImpl2.class);
        resolvedBinder = binder.to(ServiceImpl2.class);
        resolvedBinder.in(Singleton.class);

        dynamicBinderFactory.commit();

        ServiceLocator serviceLocator = services.byType(ServiceImpl.class);
        ServiceImpl serviceImpl = (ServiceImpl) serviceLocator.get();
        serviceImpl.name();

        serviceLocator = services.byType(ServiceImpl1.class);
        ServiceImpl1 serviceImpl1 = (ServiceImpl1) serviceLocator.get();
        serviceImpl1.name();

        serviceLocator = services.byType(ServiceImpl2.class);
        ServiceImpl2 serviceImpl2 = (ServiceImpl2) serviceLocator.get();
        serviceImpl2.name();

        System.out.println();
    }
}

 

 

 

 

 

 

 

 

 

 

 

public class Test {

    public static void main(String[] args) {
        ServiceLocator locator = ServiceLocatorFactory.getInstance().create("default");
        DynamicConfigurationService dynamicConfigurationService = locator.getService(DynamicConfigurationService.class);
        DynamicConfiguration config = dynamicConfigurationService.createDynamicConfiguration();

        config.bind(BuilderHelper.link(ServiceImpl.class).to(ServiceImpl.class).to(Service.class).in(Singleton.class).build());
        config.bind(BuilderHelper.link(ServiceImpl1.class).to(ServiceImpl1.class).in(Singleton.class).build());
        config.bind(BuilderHelper.link(ServiceImpl2.class).to(ServiceImpl2.class).in(Singleton.class).build());

        config.commit();

        ServiceLocator newLocator = ServiceLocatorFactory.getInstance().find("default");

        ServiceImpl service = locator.getService(ServiceImpl.class);
        System.out.println(service);
        service.name();

        ServiceImpl1 service1 = locator.getService(ServiceImpl1.class);
        System.out.println(service1);
        service1.name();

        ServiceImpl2 service2 = locator.getService(ServiceImpl2.class);
        System.out.println(service2);
        service2.name();
    }
}

 

 

0
0
分享到:
评论

相关推荐

    Java网络高级编程Java网络高级编程

    Java网络高级编程Java网络高级编程Java网络高级编程Java网络高级编程Java网络高级编程Java网络高级编程Java网络高级编程Java网络高级编程Java网络高级编程Java网络高级编程Java网络高级编程Java网络高级编程

    Java Web高级编程pdf含下载地址和源码

    Java Web高级编程pdf含下载地址和源码,《Java Web高级编程:涵盖WebSockets、Spring Framework、JPA 》面向的读者是已经了解Java SE、SQL和基本的HTML,准备将他们的Java编码技能提升到更高水平的程序员。...

    java:并发编程的两本书《Java并发编程实战》 《Java并发编程的艺术》 PDF

    《Java并发编程的艺术》是一本全面探讨Java并发编程技术的专业书籍,它深入剖析了Java并发机制的底层实现,如volatile、synchronized等关键技术的工作原理,并详细讲解了线程池、并发容器等高级并发工具的使用。...

    java网络高级编程

    Java网络高级编程是Java开发中的一个重要领域,它涵盖了网络通信的各种技术和实现,包括TCP/IP协议栈、套接字编程、HTTP、HTTPS、WebSocket等。在深入这个主题之前,我们需要了解一些基本概念。 首先,Java提供了...

    Java服务器高级编程

    Java服务器高级编程是Java开发领域中的重要主题,涵盖了在服务器端使用Java技术构建高效、可扩展和稳定的网络应用。这份资料可能包含了一系列深入的教程、最佳实践和实战案例,旨在帮助开发者提升在Java服务器端开发...

    Java网络高级编程源码人邮金勇华曲俊生

    《Java网络高级编程源码》是由人民邮电出版社出版,由金勇华和曲俊生两位专家编著的一本深入探讨Java网络编程的专著。这本书涵盖了Java在互联网开发中的高级应用,旨在帮助读者理解并掌握Java网络编程的核心技术。 ...

    Java数据库高级编程宝典

    Java数据库高级编程宝典

    《Java游戏高级编程》

    根据提供的信息,《Java游戏高级编程》是一本关于Java游戏开发的专业书籍。虽然给出的部分内容主要集中在如何加入学习交流群以及获取历史教学视频的方式,并没有直接提及书中的具体内容,但我们可以根据书名、描述及...

    java高手真经 高级编程卷:java.web高级开发技术.刘中兵java研究室

    java高手真经 高级编程卷:java.web高级开发技术.刘中兵java研究室

    Java网络高级编程1.pdf

    根据给定的文件标题“Java网络高级编程1.pdf”以及其描述和标签,我们可以推断出这份文档主要聚焦于Java语言在网络编程领域的高级应用。Java作为一种广泛应用的编程语言,在网络编程方面提供了丰富的API和框架,使得...

    java 网络高级编程(PDF)201242

    《Java网络高级编程》这本书是Java开发者深入理解网络编程的重要参考资料。它涵盖了多个关键主题,旨在帮助程序员构建高效、安全的网络应用。以下是对这些知识点的详细解释: 1. **网络进程通信**:网络进程通信是...

    Java服务器高级编程.pdf

    Java服务器高级编程.pdf

    Java数据库高级编程宝典.iso

    Java数据库高级编程宝典.isoJava数据库高级编程宝典.iso

    Java网络高级编程

    《Java网络高级编程》是一本专注于Java网络编程的教材,涵盖了从基础到高级的各种网络编程技术和概念。根据描述,本书共分为11章,每一章都详细介绍了网络编程中的不同知识点。以下是对本书内容的详细介绍: 在第1...

    java高级编程PPT

    Java高级编程涵盖了许多关键主题,这些主题在Java开发中至关重要,尤其对于提升程序员的技能水平和项目效率。以下是对每个章节的详细解释: 1. **Ch01 泛型和泛型接口** - **泛型**:泛型是Java 5引入的一个重要...

    java并发编程和网络高级编程pdf

    以下将详细讨论《JAVA并发编程实践》和《Java网络高级编程》两本书中涵盖的关键知识点。 首先,让我们关注并发编程。并发编程是现代多核处理器系统中不可或缺的一部分,它允许程序同时执行多个任务,从而提高系统...

    Java数据库高级编程宝典.part03

    Java数据库高级编程宝典.part03

Global site tag (gtag.js) - Google Analytics