笔记

way

2012年5月8日

最近在网上看到的相关材料都比较陈旧,也太简略,参看了一下其他人的内容,针对Hive2.1.1做点分享:
1)下载apache-hive-2.1.1-bin.tar.gz

2)解压缩,下面的命令行如启动报错,请自行查略Hive启动配置

3)启动hiveserver2 (非必须,使用jdbc访问的时候才使用)
bin目录下
hive --service hiveserver2 -p10001来启动hiveserver2 服务(默认为10000端口)
nohup hive --service hiverserver2 -p10001可以在后台跑
4)hive脚本运行流程
bin目录下,使用命令方法为:
./hive <parameters> --service serviceName <service parameters>
举例:hive --debug :
   查看bin/hive文件
流程中会判断$1=‘--debug’则$DEBUG=‘--debug’
 
if [ "$DEBUG" ]; then
  if [ "$HELP" ]; then //如还有--help,就会执行debug_help方法。
    debug_help
    exit 0
  else
    get_debug_params "$DEBUG"
    export HADOOP_CLIENT_OPTS="$HADOOP_CLIENT_OPTS $HIVE_MAIN_CLIENT_DEBUG_OPTS"//设置HIVE_MAIN_CLIENT_DEBUG_OPTS的参数中加入debug相应参数
  fi
fi
if [ "$SERVICE" = "" ] ; then
  if [ "$HELP" = "_help" ] ; then
    SERVICE="help"
  else
    SERVICE="cli"     //默认赋值cli
  fi
fi
这个shell脚本很多变量应该是在其他sh文件中定义,其中$SERVICE_LIST就是其他很多sh文件的最开始形成的:export SERVICE_LIST="${SERVICE_LIST}${THISSERVICE} "
hive脚本最后的$TORUN "$@" ,默认情况下TORUN其实就是cli,即执行/ext/cli.sh脚本,该脚本中主要是调用/ext/util/execHiveCmd.sh 来执行最后的CliDriver。
 【shell脚本中的$*,$@和$#
举例说:
脚本名称叫test.sh 入参三个: 1 2 3
运行test.sh 1 2 3后
$*为"1 2 3"(一起被引号包住)
$@为"1" "2" "3"(分别被包住)
$#为3(参数数量)
即exec $HADOOP jar ${HIVE_LIB}/$JAR $CLASS $HIVE_OPTS "$@" //1
其中:
$HADOOP=$HADOOP_HOME/bin/hadoop 【hive脚本中定义HADOOP=$HADOOP_HOME/bin/hadoop】
$CLASS=org.apache.hadoop.hive.cli.CliDriver【传入的第一个参数,在cli.sh中有定义】
hadoop脚本(2.7.3为例)中最终会执行:
# Always respect HADOOP_OPTS and HADOOP_CLIENT_OPTS
    HADOOP_OPTS="$HADOOP_OPTS $HADOOP_CLIENT_OPTS"
    #make sure security appender is turned off
    HADOOP_OPTS="$HADOOP_OPTS -Dhadoop.security.logger=${HADOOP_SECURITY_LOGGER:-INFO,NullAppender}"
 
    export CLASSPATH=$CLASSPATH
    exec "$JAVA" $JAVA_HEAP_MAX $HADOOP_OPTS $CLASS "$@" //2
hive的debug参数就是在启动hive脚本时放到HADOOP_OPTS中的
1和2处结合可得到最终的运行命令,查看一下运行结果:ps -ef|grep CliDriver

  /usr/java/jdk1.8.0_101/bin/java -Xmx256m -Djava.net.preferIPv4Stack=true -Dhadoop.log.dir=.. -Dhadoop.log.file=hadoop.log -Dhadoop.home.dir=.. -Dhadoop.id.str=root -Dhadoop.root.logger=INFO,console -Djava.library.path=.. -Dhadoop.policy.file=hadoop-policy.xml -Djava.net.preferIPv4Stack=true -Xmx512m -Dproc_hivecli -XX:+UseParallelGC -agentlib:jdwp=transport=dt_socket,server=y,address=8000,suspend=-Dlog4j.configurationFile=hive-log4j2.properties -Djava.util.logging.config.file=..
  
-Dhadoop.security.logger=INFO,NullAppender org.apache.hadoop.util.RunJar /yuxh/app/apache-hive-2.*/lib/hive-cli-2.*.jar org.apache.hadoop.hive.cli.CliDriver
posted @ 2017-03-29 16:01 yuxh 阅读(1557) | 评论 (0)编辑 收藏
     摘要:   阅读全文
posted @ 2015-09-23 21:14 yuxh 阅读(4394) | 评论 (0)编辑 收藏
appfuse3.5使用Hibernate4.3.6, 而Hibernate日志框架使用了jboss-logging,想在后台打出sql的参数一直无法生效。
检查配置文件,框架里面的两个配置文件,src/test/resources/log4j2.xml(单元测试时配置),src/main/resources/log4j2.xml(运行时配置)
搞清log4j2的配置后,各种修改(主要是
  <Logger name="org.hibernate.SQL" level="trace"/>
  <Logger name="org.hibernate.type" level="trace"/>)
用junit测试任然无法打印出真实参数。根据这些实践,确定log4j2是使用无误生效的,只是org.hibernate这部分的logger一直未起效
参考国内外网站,一直无人回答hibernate4的这个问题,有人指出这部分Hibernate官方文档只是提了一句,一直未更新相关内容。最后有人提到应该是 jboss-logging 的LoggerProviders这个类的问题,看实现对log4j2已经做支持。最后发现 jboss-logging使用的是3.2.0.beta,对比相关类的源代码,更改为3.2.0.Final,生效!

P.S 把这个问题提交给Appfuse官网,issue APF-1478,作者标志为4.0版本修复。
posted @ 2015-07-22 14:11 yuxh 阅读(285) | 评论 (0)编辑 收藏
新电脑装上eclipse4.4.2,导入maven项目之后,依赖库总是有很多错误。最后搜索到可能是eclipse的bug(据说是JAVA_HOME没有正确传递),查看到eclipse默认的是安装的jre目录,修改到jdk目录下,依赖问题解决。
不过目前版本仍然没有解决pom文件的“Plugin execution not covered by lifecycle configuration”错误,暂时忽略不管吧。
posted @ 2015-06-02 10:27 yuxh 阅读(319) | 评论 (0)编辑 收藏
本打算继承一个API中的Parent类(Parent继承自GrandParent类),重写其中的service方法,copy了Parent的service方法。不过发现Parent的service中也有super.service方法。当时考虑直接调用GrandParent的service方法。。。未遂(包括反射也不行)。正好看到老外写的一篇文章,翻译:
在Son类里面写一个test方法:
public void test() {
 
super.test();
 
this.test();
}
反编译之后:
public void test()
    {
    
//    0    0:aload_0         
    
//    1    1:invokespecial   #2   <Method void Parent.test()>
    
//    2    4:aload_0         
    
//    3    5:invokevirtual   #3   <Method void test()>
    
//    4    8:return          
    }
使用ASM可以完成对GrandParent方法的调用
public class GrandParent {
    
public void test() {
            System.out.println(
"test of GrandParent");
    }
}

public class Parent extends GrandParent{
    
public void test() {
        System.out.println(
"test of Parent");
    }
}

public class Son extends Parent{
    
public void test() {
        System.out.println(
"test of Son");
    }
}
调用Son实例的test方法只会执行Son的test方法。而ASM可以修改class,先写一个Example类继承Son,重写test方法

 1 import java.io.FileOutputStream;
 2  
 3 import org.objectweb.asm.ClassWriter;
 4 import org.objectweb.asm.MethodVisitor;
 5 import org.objectweb.asm.Opcodes;
 6  
 7 public class ASMByteCodeManipulation extends ClassLoader implements Opcodes {
 8  
 9  public static void main(String args[]) throws Exception {
10   ClassWriter cw = new ClassWriter(0);
11   cw.visit(V1_1, ACC_PUBLIC, "Example"null"Son"null);
12  
13   // creates a MethodWriter for the (implicit) constructor
14   MethodVisitor mw = cw.visitMethod(ACC_PUBLIC, "<init>""()V"null,null);
15   mw.visitVarInsn(ALOAD, 0);
16   mw.visitMethodInsn(INVOKESPECIAL, "Son""<init>""()V");
17   mw.visitInsn(RETURN);
18   mw.visitMaxs(11);
19   mw.visitEnd();
20  
21   // creates a MethodWriter for the 'test' method
22   mw = cw.visitMethod(ACC_PUBLIC, "test""()V"nullnull);
23   mw.visitFieldInsn(GETSTATIC, "java/lang/System""out","Ljava/io/PrintStream;");
24   mw.visitLdcInsn("test of AI3");
25   mw.visitMethodInsn(INVOKEVIRTUAL, "java/io/PrintStream""println",
26     "(Ljava/lang/String;)V");
27   //Call test() of GrandParent
28   mw.visitVarInsn(ALOAD, 0);
29   mw.visitMethodInsn(INVOKESPECIAL, "GrandParent""test""()V");
30   //Call test() of GrandParent
31   mw.visitVarInsn(ALOAD, 0);
32   mw.visitMethodInsn(INVOKESPECIAL, "Parent""test""()V");
33   //Call test() of GrandParent
34   mw.visitVarInsn(ALOAD, 0);
35   mw.visitMethodInsn(INVOKESPECIAL, "Son""test""()V");
36   mw.visitInsn(RETURN);
37   mw.visitMaxs(21);
38   mw.visitEnd();
39  
40   byte[] code = cw.toByteArray();
41   FileOutputStream fos = new FileOutputStream("Example.class");
42   fos.write(code);
43   fos.close();
44  
45   ASMByteCodeManipulation loader = new ASMByteCodeManipulation();
46   Class<?> exampleClass = loader.defineClass("Example", code, 0,
47     code.length);
48   Object obj = exampleClass.newInstance();
49   exampleClass.getMethod("test"null).invoke(obj, null);
50  
51  }
52 }
输出:
test of AI3
test of GrandParent
test of Parent
test of Son
看看怎样实现的,11行定义一个新的类Example继承Son。22行,Example重写test方法,先打印“test of AI3”,再分别在29、32、35行调用GrandParent、Parent、Son的test方法。
 main方法中,45行创建Example的实例,再用反射调他的test方法。
使用invokespecial这种方式也有局限,只能从子类调用。否则报错:
Exception in thread "main" java.lang.VerifyError: (class: Example, method: test1 signature: (LAI2;)V) Illegal use of nonvirtual function call
posted @ 2012-05-31 11:23 yuxh 阅读(2044) | 评论 (0)编辑 收藏
使用Google calendar v3 API的时候,大量发现Builder使用。比如Credential类,查了查Builder模式的讲解,始终感觉代码的实现和标准定义不太相同。最后发现这种实现方式是《Effective java 2nd》中的一种实现(Item 2: Consider a builder when faced with many constructor parameters)。静态工厂和构造器都有一个通病:对于存在大量可选构造参数的对象,扩展性不好。经典的解决方案是提供多个构造函数,第一个构造函数只有必须的参数,第二个构造函数除了必须参数还有一个可选参数,第三个除了必须参数还有两个可选参数。。。这样下去知道最后一个可选参数出现(telescoping constructor)。这种方案的问题是,当构建对象的时候很容易把其中两个参数的位置放反。。。。(难发现的bug)
另一种解决方案是JavaBean 模式,先调用无参构造函数再调用各个set方法来组装对象。这种方案的问题是不能强制一致性。如果没有set某些必须的参数的话,对象可能处于不一致(
inconsistent)的状态(难发现的bug)。另外一个缺点是JavaBean模式不能让类immutable,需要程序员额外工作保证线程安全。
第三种方式就是Builder设计模式。这种方式混合了telescoping constructor模式的安全性和JavaBean模式的可读性。客户端调用有所有必填参数的构造器(或静态工厂),得到一个builder对象。然后调用builder对象的方法去set各个选填参数。最后调用无参的build方法产生一个immutable的对象实例。immutable对象有非常多优点而且可能很有用。builder的set方法都是返回builder本身,所以调用也是可以chained。如:
  GoogleCredential credentialNew = new GoogleCredential.Builder().setTransport(HTTP_TRANSPORT)
                    .setJsonFactory(JSON_FACTORY).setClientSecrets(clientSecrets)
                    .addRefreshListener(
new CredentialStoreRefreshListener(userID, new DBCredentialStore())).build()
                    .setAccessToken(accessToken).setRefreshToken(refreshToken)
客户端代码很好写,更重要的是易读。Builder模式模拟了在Ada和Python语言里的命名可选参数(named optional parameters)。
同时Builder类设置为static也是对Item 22:Favor static member classes over nonstatic的实践
posted @ 2012-05-30 17:44 yuxh 阅读(379) | 评论 (0)编辑 收藏
以典型的客户端-服务器端授权为例
一 基本流程
使用Google Calendar v3 ,如果以servlet作为代理,可以使用官方示例,自己写一个类A.java继承AbstractAuthorizationCodeServlet类,这个类主要用于跳转到google提供的授权页面,如果用户同意授权,则根据A类中的URL(这个必须和注册的google 回调路径相同,比如oauth_callback否则报错)重定向到B类,B.java 继承AbstractAuthorizationCodeCallbackServlet类,这个访问路径类似http://www.example.com/oauth_callback?code=ABC1234。这里我配置oauth_callback为servlet的访问路径,B类中的
onSuccess方法将根据获得的access Token(这是根据传过来的code获得的)做业务操作。

二 需要参数的情况
有些业务需要用户传参数,直接传参数给A,再试图在B中获取是不行的!B类中只能获取某些固定的参数,如code。要想传用户参数,我们可以在A中先获取,把几个参数组装为json格式字符串(还可以继续base64编码),把这个字符串作为state的值,再重定向到授权页面,同意后state参数可以传到B类,取值解析json字符串(或先base64解码),得到参数。
由于API中AuthorizationCodeRequestUrl有处理state的方法,而AbstractAuthorizationCodeServlet已经直接封装,为了使用setState,直接在A类中继承HttpServlet重写service方法,复制大部分AbstractAuthorizationCodeServlet的内容,稍作修改:
resp.sendRedirect(flow.newAuthorizationUrl().setState(json).setRedirectUri(redirectUri).build());

三 关于refresh token
默认情况下,用户授权之后token会有一个小时的有效期,之后你可以通过refresh token再重新获取token。所以,如果不需要用户再次授权,可以在第一次,保存好token、refresh token、ExpirationTime。实例中用了JDO来实现,自己如果使用数据库保存,可类似写一个类实现CredentialStore类。使用的时候,现在数据库中取出,再创建credential,如:
            GoogleCredential credentialNew = new GoogleCredential.Builder().setTransport(HTTP_TRANSPORT)
                    .setJsonFactory(JSON_FACTORY).setClientSecrets(clientSecrets)
                    .addRefreshListener(new CredentialStoreRefreshListener(userID, new DBCredentialStore())).build()
                    .setAccessToken(accessToken).setRefreshToken(refreshToken)
                    .setExpirationTimeMilliseconds(expirationTimeMilliseconds);
在无效的情况下,Listener会自动去用refresh token请求。
posted @ 2012-05-08 11:40 yuxh 阅读(942) | 评论 (0)编辑 收藏
json格式经常需要用到,google提供了一个处理json的项目:GSON,能很方便的处理转换java对象和JSON表达。他不需要使用annotation,也不需要对象的源代码就能使用。
以字符串为例介绍:
1 。构造json 字符串
  例如要传送json格式的字符串
        String appID = req.getParameter("appID");
        String userID  = req.getParameter("userID");
        Map map = new HashMap();
        map.put("appID", appID);
        map.put("userID", userID);
        Gson gson = new Gson();
        String state = gson.toJson(map);
2.解析json字符串
          JsonParser jsonparer = new JsonParser();//初始化解析json格式的对象
          String state = req.getParameter("state");
          String appID = jsonparer.parse(state).getAsJsonObject().get("appID").getAsString();
          String userID = jsonparer.parse(state).getAsJsonObject().get("userID").getAsString();
posted @ 2012-05-08 10:23 yuxh 阅读(2136) | 评论 (1)编辑 收藏

导航

<2012年5月>
293012345
6789101112
13141516171819
20212223242526
272829303112
3456789

统计

常用链接

留言簿

随笔分类

随笔档案

收藏夹

博客

搜索

最新评论

阅读排行榜

评论排行榜