All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.taobao.hsf.standalone.HSFStarter Maven / Gradle / Ivy

The newest version!
package com.taobao.hsf.standalone;

import com.taobao.hsf.standalone.sar.HSFSarUtil;
import com.taobao.hsf.standalone.util.Constant;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.Map;

/**
 * 启动hsf容器,并通过HSFSpringConsumer/HSFSpringProvider和外界搭上联系,让hsf为应用服务 
* HSFContainer中的ThirdContainerClassLoader就是该类的classloader * * @author [email protected] */ @SuppressWarnings({"unchecked", "rawtypes"}) public class HSFStarter { private static Map> exportedClassMap; public static void startFromPropertyValue(String propertyName) { String sarPath = System.getProperty(propertyName); if (sarPath == null) { sarPath = System.getenv(propertyName); } if (sarPath == null) { throw new RuntimeException("没有设定变量[" + propertyName + "]的值"); } try { start(sarPath); } catch (Exception e) { throw new RuntimeException("start hsf fail.", e); } } /** * 从user.home/.hsf/release/taobao-hsf.sar启动hsf */ public static void startFromHsfHome() { String sarPath = System.getProperty("user.home") + "/.hsf/release/"; try { start(sarPath); } catch (Exception e) { throw new RuntimeException("start hsf fail.", e); } } public static void start(String sarPath) throws Exception { start(sarPath, HSFStarter.class.getClassLoader()); } /** * 太多反射,如果要转包异常抛出去的话,很难看 * * @param sarPath taobao-hsf.sar的路径,e.g. /Users/xiaozi/lightapi/release/taobao-hsf.sar * @throws Exception */ public static void start(String sarPath, ClassLoader bizClassLoader) throws Exception { URL[] sarJars = HSFSarUtil.listSarJar(sarPath); if(sarJars == null || sarJars .length == 0) { throw new RuntimeException("Build jars from sar failed.Please delete the directory of taobao-hsf.sar and re-start."); } // 判断HSF是1.x or 2.x decideVersion(sarJars); URLClassLoader hsfParentLoader = new URLClassLoader(sarJars, HSFStarter.class.getClassLoader()) { /*HSFContainer依赖log4j,导致不能完全和AppClassLoader隔离开*/ /** * Pandora已经不依赖log4j了 * @param name * @param resolve * @return * @throws ClassNotFoundException */ public synchronized Class loadClass(String name, boolean resolve) throws ClassNotFoundException { Class clazz = null; clazz = findLoadedClass(name); if (clazz != null) { if (resolve) resolveClass(clazz); return (clazz); } // osgi 的类要优先使用自己的,不要能用应用的 if (name.startsWith("org.eclipse") || name.startsWith("org.osgi")) { try { clazz = findClass(name); if (clazz != null) { if (resolve) resolveClass(clazz); return (clazz); } } catch (ClassNotFoundException e) { // Ignore } } return super.loadClass(name, resolve); } }; Class containerClass = Class.forName("com.taobao.hsf.container.HSFContainer", true, hsfParentLoader); Method startMethod = containerClass.getMethod("start", String[].class); startMethod.invoke(null, new Object[]{new String[]{sarPath}}); // hsf2.x必须要先启动,然后再设置应用类加载器 Method setThirdContainerClassLoaderMethod = containerClass.getMethod("setThirdContainerClassLoader", ClassLoader.class); setThirdContainerClassLoaderMethod.invoke(null, bizClassLoader); // 等待下启动吧。。。 Thread.sleep(5000); Method getExportedClassesMethod = containerClass.getMethod("getExportedClasses", (Class[]) null); exportedClassMap = (Map>) getExportedClassesMethod.invoke(null, (Object[]) null); if (exportedClassMap.size() < 5) { System.out.println("hsfstarter.log:exportedClassMap.size() < 5 !"); } ClassLoader osgiLoader = exportedClassMap.get("com.taobao.hsf.app.spring.util.HSFSpringConsumerBean") .getClassLoader(); if (Constant.main_version == 1) { // 等待processService被DS注入 Class serviceHolderClazz = Class.forName("com.taobao.hsf.app.spring.util.HSFServiceHolderComponent", true, osgiLoader); long startTime = System.currentTimeMillis(); Object processService = invokeStaticMethodWithoutParam(serviceHolderClazz, "getProcessService"); while (processService == null) { Thread.sleep(200); if (System.currentTimeMillis() - startTime > 3000) { break; } processService = invokeStaticMethodWithoutParam(serviceHolderClazz, "getProcessService"); } if (processService == null) { throw new IllegalStateException("HSFServiceHolderComponent.getProcessService() return null"); } startTime = System.currentTimeMillis(); Object configService = invokeReadField(processService, "configService"); while (configService == null) { Thread.sleep(200); if (System.currentTimeMillis() - startTime > 3000) { break; } configService = invokeReadField(processService, "configService"); } if(configService != null) setConfigServiceRunModeToTest(configService); } else { // 2.x是不需要等待注入的,但是保留这行代码算是验证包是否正确 Class.forName("com.taobao.hsf.util.HSFServiceContainer", true, osgiLoader); } } /** * export出去的类及其产生的instance可能被外部hold住 * * @return */ public static Class getHSFSpringConsumerBean() { return exportedClassMap.get("com.taobao.hsf.app.spring.util.HSFSpringConsumerBean"); } public static Class getHSFSpringProviderBean() { return exportedClassMap.get("com.taobao.hsf.app.spring.util.HSFSpringProviderBean"); } /** * 应用不需引入spring获取远程服务. hsf内部引用会用内部的spring.jar * * @param interfaceName * @param version * @return */ @Deprecated public static Object getRemotingServiceWithoutSpring(String interfaceName, String version, String group) { Class realConsumerClass = getHSFSpringConsumerBean(); try { Object realConsumer = realConsumerClass.newInstance(); Method stringSetter = realConsumerClass.getMethod("setInterfaceName", String.class); stringSetter.invoke(realConsumer, new Object[]{interfaceName}); stringSetter = realConsumerClass.getMethod("setVersion", String.class); stringSetter.invoke(realConsumer, new Object[]{version}); if (group != null) { stringSetter = realConsumerClass.getMethod("setGroup", String.class); stringSetter.invoke(realConsumer, new Object[]{group}); } Method noParamMethod = realConsumerClass.getMethod("init"); noParamMethod.invoke(realConsumer, new Object[]{}); noParamMethod = realConsumerClass.getMethod("getObject"); return noParamMethod.invoke(realConsumer, new Object[]{}); } catch (Exception e) { throw new RuntimeException("get service[" + interfaceName + "-" + version + "] fail", e); } } @Deprecated public static Object createProviderWithoutSpring(String interfaceName, String serviceVersion, Object serviceInstance, Map stringSetterParam) { Class providerBean = getHSFSpringProviderBean(); try { Object realProvider = providerBean.newInstance(); Method stringSetter = providerBean.getMethod("setServiceInterface", String.class); stringSetter.invoke(realProvider, new Object[]{interfaceName}); stringSetter = providerBean.getMethod("setServiceVersion", String.class); stringSetter.invoke(realProvider, new Object[]{serviceVersion}); if (stringSetterParam != null) { for (String methodName : stringSetterParam.keySet()) { stringSetter = providerBean.getMethod(methodName, String.class); stringSetter.invoke(realProvider, new Object[]{stringSetterParam.get(methodName)}); } } Method objSetter = providerBean.getMethod("setTarget", Object.class); objSetter.invoke(realProvider, new Object[]{serviceInstance}); Method noParamMethod = providerBean.getMethod("init"); noParamMethod.invoke(realProvider, new Object[]{}); return realProvider; } catch (Exception e) { throw new RuntimeException("create service[" + interfaceName + "] fail", e); } } private static Object invokeStaticMethodWithoutParam(Class clazz, String methodName) throws Exception { Method method = clazz.getDeclaredMethod(methodName); method.setAccessible(true); return method.invoke(null, null); } private static Object invokeReadField(Object instance, String fieldName) throws Exception { Class clazz = instance.getClass(); Field field = clazz.getDeclaredField(fieldName); field.setAccessible(true); return field.get(instance); } /** * 设置运行模式为测试模式 * * @param configService * @throws Exception */ private static void setConfigServiceRunModeToTest(Object configService) throws Exception { Method method = configService.getClass().getDeclaredMethod("setRunmode", int.class); method.setAccessible(true); method.invoke(configService, 0); } /** * 通过sar/lib/下的包的名字是否包含pandora来判断hsf版本是1.x还是2.x * * @param sarJars */ private static void decideVersion(URL[] sarJars) { for (URL url : sarJars) { if (url.toString().contains("pandora")) { // 2.x Constant.main_version = 2; return; } } // 默认 1.x } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy