posts - 88, comments - 3, trackbacks - 0, articles - 0
  BlogJava :: 首页 :: 新随笔 :: 联系 :: 聚合  :: 管理

2012年12月6日

在Spring cloud config出来之前, 自己实现了基于ZK的配置中心, 杜绝了本地properties配置文件, 原理很简单, 只是重载了PropertyPlaceholderConfigurer的mergeProperties():

/**
* 重载合并属性实现
* 先加载file properties, 然后并入ZK配置中心读取的properties
*
* @return 合并后的属性集合
* @throws IOException 异常
*/
@Override
protected Properties mergeProperties() throws IOException {
Properties result = new Properties();
// 加载父类的配置
Properties mergeProperties = super.mergeProperties();
result.putAll(mergeProperties);
// 加载从zk中读取到的配置
Map<String, String> configs = loadZkConfigs();
result.putAll(configs);
return result;
}

这个实现在spring项目里用起来还是挺顺手的, 但是近期部分spring-boot项目里发现这种placeholder的实现跟spring boot的@ConfigurationProperties(prefix = "xxx") 不能很好的配合工作,
也就是属性没有被resolve处理, 用@Value的方式确可以读到, 但是@Value配置起来如果属性多的话还是挺繁琐的, 还是倾向用@ConfigurationProperties的prefix, 于是看了下spring boot的文档发现PropertySource order:
   * Devtools global settings properties on your home directory (~/.spring-boot-devtools.properties when devtools is active).
   * @TestPropertySource annotations on your tests.
   * @SpringBootTest#properties annotation attribute on your tests.
   * Command line arguments.
   * Properties from SPRING_APPLICATION_JSON (inline JSON embedded in an environment variable or system property)
   * ServletConfig init parameters.
   * ServletContext init parameters.
   * JNDI attributes from java:comp/env.
   * Java System properties (System.getProperties()).
   * OS environment variables.
   * A RandomValuePropertySource that only has properties in random.*.
   * Profile-specific application properties outside of your packaged jar (application-{profile}.properties and YAML variants)
   * Profile-specific application properties packaged inside your jar (application-{profile}.properties and YAML variants)
   * Application properties outside of your packaged jar (application.properties and YAML variants).
   * Application properties packaged inside your jar (application.properties and YAML variants).
   * @PropertySource annotations on your @Configuration classes.
   * Default properties (specified using SpringApplication.setDefaultProperties).
不难发现其会检查Java system propeties里的属性, 也就是说, 只要把mergerProperties读到的属性写入Java system props里即可, 看了下源码, 找到个切入点

/**
* 重载处理属性实现
* 根据选项, 决定是否将合并后的props写入系统属性, Spring boot需要
*
* @param beanFactoryToProcess
* @param props 合并后的属性
* @throws BeansException
*/
@Override
protected void processProperties(ConfigurableListableBeanFactory beanFactoryToProcess, Properties props) throws BeansException {
// 原有逻辑
super.processProperties(beanFactoryToProcess, props);
// 写入到系统属性
if (writePropsToSystem) {
// write all properties to system for spring boot
Enumeration<?> propertyNames = props.propertyNames();
while (propertyNames.hasMoreElements()) {
String propertyName = (String) propertyNames.nextElement();
String propertyValue = props.getProperty(propertyName);
System.setProperty(propertyName, propertyValue);
}
}
}
为避免影响过大, 设置了个开关, 是否写入系统属性, 如果是spring boot的项目, 就开启, 这样对线上非spring boot项目做到影响最小, 然后spring boot的@ConfigurationProperties完美读到属性;

具体代码见: org.springframework.boot.context.properties.ConfigurationPropertiesBindingPostProcessor

@Override
public Object postProcessBeforeInitialization(Object bean, String beanName)
throws BeansException {
ConfigurationProperties annotation = AnnotationUtils
.findAnnotation(bean.getClass(), ConfigurationProperties.class);
if (annotation != null) {
postProcessBeforeInitialization(bean, beanName, annotation);
}
annotation = this.beans.findFactoryAnnotation(beanName,
ConfigurationProperties.class);
if (annotation != null) {
postProcessBeforeInitialization(bean, beanName, annotation);
}
return bean;
}

posted @ 2017-12-08 14:13 Milo的海域 阅读(875) | 评论 (0)编辑 收藏

Spring默认不允许对类的变量, 也就是静态变量进行注入操作, 但是在某些场景比如单元测试的@AfterClass要访问注入对象, 而Junit的这个方法必须是静态的, 也就产生了悖论;

解决思路有两个:

  • 思路1: 想办法对静态变量注入, 也就是绕过Spring只能运行非静态变量才能注入依赖的壁垒
  • 思路2: 想办法@AfterClass改造为非静态
    • 实现Junit RunListener, 覆盖testRunFinished方法, 这里去实现类似@AfterClass的功能, 这个方法是非静态的
    • 不要用Junit, 改用TestNG, TestNG里的AfterClass是非静态的
    • 用Spring的TestExecutionListeners, 实现个Listener, 里面也有个类似非静态的AfterClass的实现, 覆盖实现就行

思路2的几个方法都可以实现, 但是单元测试Runner需要用

@RunWith(Theories.class)

而且改用TestNG工程浩大, 只能放弃掉这个思路

继续走思路1, 只能去绕过Spring的依赖注入的static壁垒了, 具体代码如下:

@Autowired
private Destination dfsOperationQueue;
private static Destination dfsOperationQueueStatic; // static version
@Autowired
private MessageQueueAPI messageQueueAPI;
private static MessageQueueAPI messageQueueAPIStatic; // static version


@PostConstruct
public void init() {
dfsOperationQueueStatic = this.dfsOperationQueue;
messageQueueAPIStatic = this.messageQueueAPI;
}

@AfterClass
public static void afterClass() {
MessageVO messageVO = messageQueueAPIStatic.removeDestination(dfsOperationQueueStatic);
System.out.println(messageVO);
}

其实就是用了@PostConstruct 来个偷梁换柱而已, 多声明个静态成员指向非静态对象, 两者其实是一个对象

posted @ 2017-04-15 10:32 Milo的海域 阅读(569) | 评论 (0)编辑 收藏

知道activemq现在已经支持了rest api, 但是官方对这部分的介绍一笔带过 (http://activemq.apache.org/rest.html),


通过google居然也没搜到一些有用的, 比如像删除一个destination, 都是问的多,然后没下文. 于是花了一些心思研究了一下:


首先通过rest api获取当前版本所有已支持的协议

    http://172.30.43.206:8161/api/jolokia/list


然后根据json输出关于removeTopic, removeQueue的mbean实现通过rest api删除destination的方法, 注意到用GET请求而不是POST,不然会报错 (官网的例子里用的wget给的灵感, 开始用了POST老报错)


import org.apache.activemq.command.ActiveMQQueue;
import org.apache.activemq.command.ActiveMQTopic;
import org.apache.http.auth.AuthScope;
import org.apache.http.auth.UsernamePasswordCredentials;
import org.apache.http.impl.client.BasicCredentialsProvider;
import org.apache.http.impl.client.DefaultHttpClient;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.http.client.ClientHttpRequestFactory;
import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
import org.springframework.web.client.RestTemplate;

import javax.jms.Destination;
import javax.jms.JMSException;
import java.util.Arrays;


public class MessageQueueAdmin {
    
private static final RestTemplate restTemplate = getRestTemplate("admin""admin");

    
private static String brokerHost = "172.30.43.206";
    
private static String adminConsolePort = "8161";
    
private static String protocol = "http";

    
public static void removeDestination(Destination destination) throws JMSException {
        String destName, destType;
        
if (destination instanceof ActiveMQQueue) {
            destName 
= ((ActiveMQQueue) destination).getQueueName();
            destType 
= "Queue";
        } 
else {
            destName 
= ((ActiveMQTopic) destination).getTopicName();
            destType 
= "Topic";
        }

        
// build urls
        String url = String.format("%s://%s:%s/api/jolokia/exec/org.apache.activemq:" +
                
"brokerName=localhost,type=Broker/remove%s/%s", protocol, brokerHost, adminConsolePort, destType, destName);
        System.out.println(url);
        
// do operation
        HttpHeaders headers = new HttpHeaders();
        headers.setAccept(Arrays.asList(MediaType.APPLICATION_JSON));
        HttpEntity
<String> entity = new HttpEntity<String>("parameters", headers);
        ResponseEntity response 
= restTemplate.exchange(url, HttpMethod.GET, entity, String.class);
        System.out.println(response.getBody());
    }

    
public static void main(String[] args) throws JMSException {
        ActiveMQTopic topic 
= new ActiveMQTopic("test-activemq-topic");
        removeDestination(topic);
    }


    
private static RestTemplate getRestTemplate(String user, String password) {
        DefaultHttpClient httpClient 
= new DefaultHttpClient();
        BasicCredentialsProvider credentialsProvider 
= new BasicCredentialsProvider();
        credentialsProvider.setCredentials(AuthScope.ANY, 
new UsernamePasswordCredentials(user, password));
        httpClient.setCredentialsProvider(credentialsProvider);
        ClientHttpRequestFactory rf 
= new HttpComponentsClientHttpRequestFactory(httpClient);

        
return new RestTemplate(rf);
    }
}

其他的请求,应该都是类似jolokia的exec get request的格式:


https://jolokia.org/reference/html/protocol.html#exec


<base url>/exec/<mbean name>/<operation name>/<arg1>/<arg2>/.

posted @ 2016-10-22 17:31 Milo的海域 阅读(1402) | 评论 (0)编辑 收藏

用Spring JMS 的JmsTemplate从消息队列消费消息时发现,使用了CLIENT_ACKNOWLEDGE模式,消息返回后总是自动被ack,也就是被broker "Dequeued"

    protected Message doReceive(Session session, MessageConsumer consumer) throws JMSException {
        
try {
            
// Use transaction timeout (if available).
            long timeout = getReceiveTimeout();
            JmsResourceHolder resourceHolder 
=
                    (JmsResourceHolder) TransactionSynchronizationManager.getResource(getConnectionFactory());
            
if (resourceHolder != null && resourceHolder.hasTimeout()) {
                timeout 
= Math.min(timeout, resourceHolder.getTimeToLiveInMillis());
            }
            Message message 
= doReceive(consumer, timeout);
            
if (session.getTransacted()) {
                
// Commit necessary - but avoid commit call within a JTA transaction.
                if (isSessionLocallyTransacted(session)) {
                    
// Transacted session created by this template -> commit.
                    JmsUtils.commitIfNecessary(session);
                }
            }
            
else if (isClientAcknowledge(session)) {
                
// Manually acknowledge message, if any.
                if (message != null) {
                    message.acknowledge();
                }
            }
            
return message;
        }
        
finally {
            JmsUtils.closeMessageConsumer(consumer);
        }
    }

但是使用异步listener 就不会出现这个情况,搜了下google,发现果然存在这个问题

     https://jira.spring.io/browse/SPR-12995
     https://jira.spring.io/browse/SPR-13255
     http://louisling.iteye.com/blog/241073

同步方式拉取消息,暂时没找到好的封装,只能暂时用这。或者尽量用listener, 这个问题暂时标记下,或者谁有更好的解决方案可以comment我

posted @ 2016-10-12 16:32 Milo的海域 阅读(1495) | 评论 (0)编辑 收藏

默认的配置有时候点不亮显示器,且分辨率很低,通过tvservice工具不断调试,发现下面的参数可以完美匹配了
修改 /boot/config.txt的下列参数

disable_overscan=1
hdmi_force_hotplug
=1
hdmi_group
=1
hdmi_mode
=16
hdmi_drive
=2
config_hdmi_boost
=4
dtparam
=audio=on

posted @ 2016-06-15 09:32 Milo的海域 阅读(209) | 评论 (0)编辑 收藏

http://stackoverflow.com/questions/3294423/spring-classpath-prefix-difference



  

SIMPLE DEFINITION

The classpath*:conf/appContext.xml simply means that all appContext.xml files under conf folders in all your jars on the classpath will be picked up and joined into one big application context.

In contrast
, classpath:conf/appContext.xml will load only one such file the first one found on your classpath.


<bean id="propertyConfigurer"
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="locations">
<list>
<value>classpath:*.properties</value>
<value>classpath*:*.properties</value>
</list>
</property>
</bean>

posted @ 2016-05-26 14:14 Milo的海域 阅读(751) | 评论 (0)编辑 收藏

  1. IDEA_JDK (or IDEA_JDK_64) environment variable
  2. jre/ (or jre64/) directory in IDEA home
  3. registry
  4. JDK_HOME environment variable
  5. JAVA_HOME environment variable

posted @ 2016-05-16 08:49 Milo的海域 阅读(149) | 评论 (0)编辑 收藏

java里如何修改console的历史输出信息呢?如果是当前行的修改可以简单想到"\r"的方案,但是如果要修改上一行呢? google了下原来还是有方法的,需要用到ansi的control sequences
ANSI code

用java写了个简单的例子,例子就是把曾经的output修改为其他字符串并恢复之后的打印,代码里加了sleep,主要方便理解各种控制序列的含义
        //print some test messages
        System.out.println("1");
        Thread.sleep(
1000);
        System.out.println(
"22");
        Thread.sleep(
1000);
        System.out.println(
"333");
        Thread.sleep(
1000);
        System.out.println(
"4444");
        Thread.sleep(
1000);

        
/**
         * modify "333" to "-"
         
*/
        
// Move up two lines
        int count = 2;
        System.out.print(String.format(
"\033[%dA", count));
        Thread.sleep(
1000);
        
// Erase current line content
        System.out.print("\033[2K");
        Thread.sleep(
1000);
        
// update with new content
        System.out.print("-");
        Thread.sleep(
1000);
        
// Move down two lines
        System.out.print(String.format("\033[%dB", count));
        Thread.sleep(
1000);
        
// Move cursor to left beginning
        System.out.print(String.format("\033[D", count));
        
// continue print others
        Thread.sleep(1000);
        System.out.println(
"55555");
        Thread.sleep(
1000);

posted @ 2016-04-21 17:06 Milo的海域 阅读(396) | 评论 (0)编辑 收藏

1. zookeeper basic/fast paxsos 的形象表述 https://www.douban.com/note/208430424/
2. 详细介绍 http://blog.csdn.net/xhh198781/article/details/10949697

posted @ 2016-03-31 14:06 Milo的海域 阅读(169) | 评论 (0)编辑 收藏

server.compression.enabled=true 
server.compression.mime-types=application/json,application/xml,text/html,text/xml,text/plain
server.compression.min-response-size=4096
第一个参数打开压缩开关,第二个参数添加json reponse(尤其是为rest api),第三个参数是根据reponse的大小设置启用压缩的最小值(默认是2K,自己根据实际情况调整)

参考
http://docs.spring.io/spring-boot/docs/current-SNAPSHOT/reference/htmlsingle/#how-to-enable-http-response-compression

posted @ 2016-03-29 11:50 Milo的海域 阅读(1864) | 评论 (0)编辑 收藏

介绍centos7如何安装3.0以上的新版本mongodb
https://docs.mongodb.org/manual/tutorial/install-mongodb-on-red-hat/

posted @ 2016-03-23 10:14 Milo的海域 阅读(172) | 评论 (0)编辑 收藏

1. 默认的3个classloader: BootstrapClassloader (Native实现), ExtClassloader, AppClassloader (Java实现)
2. 3个加载器并不是真正的父子继承关系,而是逻辑上的,JVM启动先创建ExtClassloader instance,然后构造AppClassloader的时候传入ExtClassloader实例作为parent
        Launcher.ExtClassLoader extcl;
        
try {
            extcl 
= Launcher.ExtClassLoader.getExtClassLoader();
        } 
catch (IOException var10) {
            
throw new InternalError("Could not create extension class loader", var10);
        }

        
try {
            
this.loader = Launcher.AppClassLoader.getAppClassLoader(extcl);
        } 
catch (IOException var9) {
            
throw new InternalError("Could not create application class loader", var9);
        }

关于双亲委派原理: 在加载类的时候,会看看parent有没有设定,如果设定了 就调用parent.loadClass方法,如果没设定(==null)也就是parent应该是BootstrapClassloader, 会调用native的findBootstrapClass来加载类,代码:
                try {
                    
if(this.parent != null) {
                        c 
= this.parent.loadClass(name, false);
                    } 
else {
                        c 
= this.findBootstrapClassOrNull(name);
                    }
                } 
catch (ClassNotFoundException var10) {
                    ;
                }

目的是按照一定优先级别装载系统的lib,系统ext目录的lib,以及classpath的lib,防止系统的默认行为或者类的实现被修改。

3. java 类的动态加载
Java内置的ClassLoader总会在加载一个Class之前检查这个Class是否已经被加载过,已经被加载过的Class不会加载第二次。因此要想重新加载Class,我们需要实现自己的ClassLoader。
另外一个问题是,每个被加载的Class都需要被链接(link),这是通过执行ClassLoader.resolve()来实现的,这个方法是 final的,因此无法重写。Resove()方法不允许一个ClassLoader实例link一个Class两次,因此,当你需要重新加载一个 Class的时候,你需要重新New一个你自己的ClassLoader实例。

posted @ 2016-03-16 15:40 Milo的海域 阅读(308) | 评论 (0)编辑 收藏


maven-shade-plugin 用来打可执行jar包, 可以把所有依赖的三方库都包括进来
exec-maven-plugin 可以执行外部命令, 在项目中对python代码进行编译, 配合maven-assembly-plugin来生成package
maven-assembly-plugin 用来构建项目发行包, 要配合xml配置文件来组织包的结构,基本思路是从build环境copy到outputDirectory
license-maven-plugin 用来生成项目用到的3方库的版权汇总 或者其他的一些用法
maven-dependency-plugin 用来生成项目库之间的依赖关系
appassembler-maven-plugin 可以为项目生成优雅的启动脚本 支持linux/win
rpm-maven-plugin 用来为项目构建rpm安装包
maven-compiler-plugin 指定项目的jdk的编译兼容版本以及encoding类别

posted @ 2016-01-26 11:41 Milo的海域 阅读(251) | 评论 (0)编辑 收藏

快捷键migrating
定位选中字符串下个匹配的位置
eclipse: ctrl + k
idea: ctrl + F3       

eclipse: ctrl + q
idea: ctrl + shift + backspace
回到上一次编辑的位置

持续更新

posted @ 2015-11-25 16:46 Milo的海域 阅读(115) | 评论 (0)编辑 收藏

发现一个不错的介绍shell中冒号的用法的文章
http://codingstandards.iteye.com/blog/1160298

posted @ 2015-11-09 15:11 Milo的海域 阅读(231) | 评论 (0)编辑 收藏

项目用mvn exec:exec指令来启动server, 工作中需要调式server初始化的过程, 很容易想到mvnDebug, 但是发现设置的断点都没有hit, 反复调式多次都是如此,折腾了1个多小时, 突然看到stackoverflow 上有人说exec:exec是独立进程模式, mvnDebug的一些debug选项都被append到了父进程了. idea设置断点就然并卵了.

知道了问题所在解决就容易了, 只要修改pom.xml, 然后直接mvn exec:exec就能正常调式了
            <build>
                <plugins>
                    <plugin>
                        <groupId>org.codehaus.mojo</groupId>
                        <artifactId>exec-maven-plugin</artifactId>
                        <version>${mvnexec.version}</version>
                        <executions>
                            <execution>
                                <goals>
                                    <goal>exec</goal>
                                </goals>
                            </execution>
                        </executions>
                        <configuration>
                            <includeProjectDependencies>true</includeProjectDependencies>
                            <executable>java</executable>
                            <workingDirectory>${basedir}/config/sim</workingDirectory>
                            <classpathScope>runtime</classpathScope>
                            <arguments>
                                <argument>-agentlib:jdwp
=transport=dt_socket,server=y,suspend=y,address=4000</argument>
                                <argument>-classpath</argument>
                                <classpath/>
                                <argument>com.ymiao.Main</argument>
                                <argument>server</argument>
                                <argument>${basedir}/config/sim/sim.yml</argument>
                            </arguments>
                        </configuration>
                    </plugin>
                </plugins>
            </build>

总结就是exec:exec是要独立一个新进程来执行程序的, exec:java就相反, 其实用mvnDebug + exec:java也是理论可行的

posted @ 2015-10-21 17:12 Milo的海域 阅读(818) | 评论 (0)编辑 收藏

After Centos 7.1 tobe installed on my t400, my wireless link "Intel 5100 AGN" cannot be managed by NetworkManager, which show in "PCI unknown" state.

Googled many pages, most of them introduced how to scan wifi links by command line tool "iw", i tried all steps supplied by the pages but was blocked at the last step to get dynamical ipaddress by dhclient command "sudo dhclient wlp3s0 -v". The dhclient always complain "NO DHCPOFFERS received." (I doubted there should be some tricky to play with dhclient but which i am not faimiar with.. sad.. )

But i think there would be some extending tool for NetworkManager to manager wifi, then i google "NetworkManager wifi", i got "NetwrokManager-wifi plugin" from link https://www.centos.org/forums/viewtopic.php?f=47&t=52810

After following steps , i finally make wifi work well on centos 7.1

  • yum install NetworkManager-wifi
  • reboot machine (i tried logout and login, not work) 

Problem is NetworkManager-wifi is not installed by default on centos 7.1, (would it be my mistake when install OS? strange..)

posted @ 2015-09-17 10:41 Milo的海域 阅读(372) | 评论 (1)编辑 收藏

http://onlywei.github.io/explain-git-with-d3

posted @ 2015-09-09 15:57 Milo的海域 阅读(237) | 评论 (0)编辑 收藏

项目中要用到MBean,于是快速体验下,体验过程中发现2个问题:

  1. 自定义的Mbean的普通method能在jconsole的Mbeans里显示出来,但是涉及到geters/seters就无法显示了
  2. 如果MBean注册到下面形式创建的MBeanServer在Jconsole上无法显示的
    MBeanServer server = MBeanServerFactory.createMBeanServer();
    但是如果注册到下面的形式创建的Server在Jconsole上是可以显示MBean的
    MBeanServer server = ManagementFactory.getPlatformMBeanServer();       

stackoverflow上也有人发现这个问题

    http://stackoverflow.com/questions/7424009/mbeans-registered-to-mbean-server-not-showing-up-in-jconsole

posted @ 2015-09-08 10:53 Milo的海域 阅读(494) | 评论 (0)编辑 收藏

http://www.ourd3js.com/wordpress/

posted @ 2015-08-26 11:22 Milo的海域 阅读(238) | 评论 (0)编辑 收藏

Two compile issues i got:

One issue is:
    uuid_gen_unix.c: In function 'axutil_uuid_gen_v1':uuid_gen_unix.c:62:20: error: variable 'tv' set but not used [-Werror=unused-but-set-variable]     struct timeval tv;                    ^cc1: all warnings being treated as errors    


Solution is remove "-Werror" in all configure scripts
find -type f -name configure -exec sed -i '/CFLAGS/s/-Werror//g' {} \;
Another issue is:
/usr/bin/ld: test.o: undefined reference to symbol 'axiom_xml_reader_free'
/usr/local/axis2c/lib/libaxis2_parser.so
.0: error adding symbols: DSO missing from command line
collect2: error: ld returned 
1 exit status
make
[4]: *** [test] Error 1
make
[4]: Leaving directory `/home/miaoyachun/softwares/test/axis2c-src-1.6.0/neethi/test'

As suggested in https://code.google.com/p/staff/issues/detail?id=198, the solution is disable neethi/test in following files:
  • neethi/configure, remove all "test/Makefile"
  • neethi/Makefile.am, update "SUBDIRS = src test" with "SUBDIRS = src"
  • neethi/Makefile.in, update "SUBDIRS = src test" with "SUBDIRS = src"

Finally, you could run "make; sudo make install"" successfully. Last thing should be paid attention to is you may need copy all head files of neethi/include into /usr/local/axis2c/include/axis2-1.6.0/ which needed when you compile customized web service.

Enjoining it!!

posted @ 2015-08-21 11:00 Milo的海域 阅读(508) | 评论 (0)编辑 收藏

http://axis.apache.org/axis2/c/core/docs/axis2c_manual.html#client_api 的hello.c client 编译命令在我的ubuntu 12.04s上总是报错
gcc -o hello -I$AXIS2C_HOME/include/axis2-1.6.0/ -L$AXIS2C_HOME/lib -laxutil -laxis2_axiom -laxis2_parser -laxis2_engine -lpthread -laxis2_http_sender -laxis2_http_receiver -ldl -Wl,--rpath -Wl,$AXIS2C_HOME/lib hello.c
/tmp/ccCYikFh.o: In function `main':
hello.c:(.text+0x57): undefined reference to `axutil_env_create_all'
hello.c:(.text+0x68): undefined reference to `axis2_options_create'
hello.c:(.text+0x93): undefined reference to `axutil_strcmp'
hello.c:(.text+0xeb): undefined reference to `axis2_endpoint_ref_create'
hello.c:(.text+0x102): undefined reference to `axis2_options_set_to'
hello.c:(.text+0x13d): undefined reference to `axis2_svc_client_create'
hello.c:(.text+0x168): undefined reference to `axutil_error_get_message'
hello.c:(.text+0x193): undefined reference to `axutil_log_impl_log_error'
hello.c:(.text+0x1b1): undefined reference to `axis2_svc_client_set_options'
hello.c:(.text+0x1d6): undefined reference to `axis2_svc_client_send_receive'
hello.c:(.text+0x21d): undefined reference to `axiom_node_free_tree'
hello.c:(.text+0x238): undefined reference to `axutil_error_get_message'
hello.c:(.text+0x266): undefined reference to `axutil_log_impl_log_error'
hello.c:(.text+0x28d): undefined reference to `axis2_svc_client_free'
hello.c:(.text+0x2a8): undefined reference to `axutil_env_free'
/tmp/ccCYikFh.o: In function `build_om_request':
hello.c:(.text+0x2ed): undefined reference to `axiom_element_create'
hello.c:(.text+0x307): undefined reference to `axiom_element_set_text'
/tmp/ccCYikFh.o: In function `process_om_response':
hello.c:(.text+0x337): undefined reference to `axiom_node_get_first_child'
hello.c:(.text+0x351): undefined reference to `axiom_node_get_node_type'
hello.c:(.text+0x367): undefined reference to `axiom_node_get_data_element'
hello.c:(.text+0x381): undefined reference to `axiom_text_get_value'
hello.c:(.text+0x396): undefined reference to `axiom_text_get_value'
collect2: error: ld returned 
1 exit status
仔细检查了gcc命令,头文件,库文件的路径都是对的,最后跟同事讨论才发现hello.c的位置的问题。。如果hello.c的位置放到了依赖库的右面 就会报类似错误。但是官方的例子应该是测试过的,怎么会有这个问题呢? 难道我的ubuntu 12.04的gcc比较严格?

修正后的gcc命令如下
gcc -o hello hello.c  -I$AXIS2C_HOME/include/axis2-1.6.0/ -L$AXIS2C_HOME/lib -laxutil -laxis2_axiom -laxis2_parser -laxis2_engine -lpthread -laxis2_http_sender -laxis2_http_receiver -ldl -Wl,--rpath -Wl,$AXIS2C_HOME/lib

posted @ 2015-08-18 17:59 Milo的海域 阅读(331) | 评论 (0)编辑 收藏

ubuntu 12.04s每次修改limit.conf文件后,要想让所有的后继ssession都能看到修改,一般要么重启系统,要么relogin系统。下面介绍一个不退出terminal就让修改立刻生效的方式
1. 修改/etc/pam.d/sudo,添加下面行到文件末尾
session    required   pam_limits.so
2. 修改 /etc/security/limits.conf, 比如
root soft nofile 65535
root hard nofile 
65535
3. 执行sudo -i -u root 模拟登录初始化

另外发现centos 6系统/etc/pam.d/sudo已经默认enable pam_limits.so了,直接2,3就可以了。

当然如果用ssh重新登录下可能来的更快。。因为/etc/pam.d/sshd默认enable了pam_limits.so, 多输入个密码而已

posted @ 2015-08-13 17:58 Milo的海域 阅读(4469) | 评论 (0)编辑 收藏

ss(shadowsocks) 是基于socks5的,但是android studio sdk manager只支持http代理,导致android studio无法更新sdk tools,解决方法就是polipo,可以将socks5转换为http代理
具体方法见
https://github.com/shadowsocks/shadowsocks/wiki/Convert-Shadowsocks-into-an-HTTP-proxy

posted @ 2015-06-28 21:50 Milo的海域 阅读(1325) | 评论 (0)编辑 收藏

ubuntu上ibus经常出现不能输入中文的情况,用下面命令可以临时解决问题
ibus-daemon -r &

posted @ 2015-06-17 13:45 Milo的海域 阅读(504) | 评论 (0)编辑 收藏

从jdk7最开始的release version (http://www.oracle.com/technetwork/java/javase/jdk7-relnotes-418459.html)的notes里看到

Area: HotSpot
Synopsis: In JDK 7, interned strings are no longer allocated in the permanent generation of the Java heap, but are instead allocated in the main part of the Java heap (known as the young and old generations), along with the other objects created by the application. This change will result in more data residing in the main Java heap, and less data in the permanent generation, and thus may require heap sizes to be adjusted. Most applications will see only relatively small differences in heap usage due to this change, but larger applications that load many classes or make heavy use of the String.intern() method will see more significant differences.
RFE: 6962931

posted @ 2015-05-06 17:35 Milo的海域 阅读(1840) | 评论 (0)编辑 收藏

今天有同事问为什么ubuntu上启动jenkins失败,我记得之前玩的时候并没有出现这种情况,于是跟踪了下,最终错误信息是:

daemon: fatal: refusing to execute unsafe program: /usr/bin/java (/opt is group and world writable)

根本原因是机器装了多个版本的jdk, jdk所在的/opt父目录的权限放的比较大,按照daemon要求的限制到755
chmod -R 755 /opt

问题就解决了。

其实这个场景还是蛮常见的,遇到的人应该挺多的

posted @ 2015-02-28 16:51 Milo的海域 阅读(527) | 评论 (0)编辑 收藏

latency = client send request time + network trans time (->)+ server receive request time+ reponse time + server send reponse time+ network trans time (<-)+ client receive reponse time

latency = first byte out, last byte in time

posted @ 2014-07-01 14:10 Milo的海域 阅读(550) | 评论 (0)编辑 收藏

以前用centos的chkconfig来管理系统服务,而ubuntu上是没有这个工具的,google上提到一个替代品sysv-rc-conf, apt-get install下就可以直接用了,有个text console可以使用

posted @ 2013-12-24 14:54 Milo的海域 阅读(5262) | 评论 (0)编辑 收藏

Java程序的memory leak分析也可以用valgrind, 尤其是JNI程序尤其有用:
valgrind --error-limit=no --trace-children=yes --smc-check=all --leak-check=full JAVA_CMD

特意写了个有leak的jni函数,用valgrind成功检查出来了
==31915== 100 bytes in 1 blocks are definitely lost in loss record 447 of 653
==31915==    at 0x402CE68: malloc (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so)
==31915==    by 0x60424F9: Java_MyJNI_hello (MyJNI.c:16)

在老版本valgrind(3.5.0) enable了--trace-children选项后可能出现错误:
 Error occurred during initialization of VM    
Unknown x64 processor: SSE2 not supported

升级到最新版可以解决这个问题,升级方法:下载src包 解压后执行 ./configure; make; make install

posted @ 2013-12-06 10:26 Milo的海域 阅读(975) | 评论 (0)编辑 收藏

maven项目中有很多本地三方依赖,但是一个一个加入dependency + system scope又很麻烦,又貌似没有搜索到通配符的成功案例,但是从stackoverflow上看到一个插件addjars-maven-plugin, 可以很好解决这类需求:
    <build>
        
<plugins>
            
<plugin>
                
<groupId>com.googlecode.addjars-maven-plugin</groupId>
                
<artifactId>addjars-maven-plugin</artifactId>
                
<version>1.0.2</version>
                
<executions>
                    
<execution>
                        
<goals>
                            
<goal>add-jars</goal>
                        
</goals>
                        
<configuration>
                            
<resources>
                                
<resource>
                                    
<directory>${basedir}/../lib</directory>
                                
</resource>
                            
</resources>
                        
</configuration>
                    
</execution>
                
</executions>
            
</plugin>
            
<plugin>
                
<groupId>org.apache.maven.plugins</groupId>
                
<artifactId>maven-assembly-plugin</artifactId>
                
<version>${maven.assembly.version}</version>
                
<configuration>
                    
<descriptorRefs>
                        
<descriptorRef>jar-with-dependencies</descriptorRef>
                    
</descriptorRefs>
                    
<appendAssemblyId>false</appendAssemblyId>
                
</configuration>
                
<executions>
                    
<execution>
                        
<phase>package</phase>
                        
<goals>
                            
<goal>single</goal>
                        
</goals>
                    
</execution>
                
</executions>
            
</plugin>
        
</plugins>
    
</build>

把项目中依赖的三方jars全放到lib目录里,就全部会打包到release jar里了

posted @ 2013-10-30 14:03 Milo的海域 阅读(1859) | 评论 (0)编辑 收藏

#include <stdio.h>
#include 
<stdlib.h>
#include 
<string.h>
#include 
<arpa/inet.h>
#include 
<inttypes.h>

uint64_t htonll(uint64_t val) {
    
return (((uint64_t) htonl(val)) << 32+ htonl(val >> 32);
}

uint64_t ntohll(uint64_t val) {
    
return (((uint64_t) ntohl(val)) << 32+ ntohl(val >> 32);
}
int main() {
    uint64_t hll 
= 0x1122334455667788;
    printf(
"uint64: %"PRIu64"\n", hll);
    printf(
"0x%"PRIX64"\n", hll);
    printf(
"htonll(hll) = 0x%"PRIX64"\n", htonll(hll));
    printf(
"ntohll(htonll(hll)) = 0x%"PRIX64"\n", ntohll(htonll(hll)));
    printf(
"ntohll(hll) = 0x%"PRIX64"\n", ntohll(hll)); // no change
    return 1;
}

big endian(network byte order), little endian (host byte order in intel arch)

posted @ 2013-07-23 16:42 Milo的海域 阅读(3281) | 评论 (0)编辑 收藏

用jd-eclipse 插件来反编译java class文件的输出还是挺nice的,虽然阅读方便了 但是对debug确造成一定的困扰,主要问题是line number的不match.
Google了下遇到类似问题的真不少。最终找到了解决方案:
http://sourceforge.net/projects/realignmentjd/files/
-----------------

1. Download JD-Eclipse and JD-GUI - http://java.decompiler.free.fr/ and install.
2. Put a file realignment.jd.ide.eclipse_1.0.2.jar in eclipse/plugins directory.
    To use Realignment feature it is necessary to open the menu Preferences/General/Editors/File Associations and to select "*.class" file type and to choose "Realignment for JD Class File Editor" for Associated editors.
    Another possibility is the batch realignment after processing JD-GUI. To work properly you must to switch on the property "Display line numbers" in Help/Preferences of JD-GUI.
    To use this feature it is necessary to open the menu Preferences/Java/Decompiler/Batch Realignment and click button "Open dialog". Existing limitation: the realignment is performed only for the methods.
    To work properly it is necessary that the property "Display line numbers" in menu "Preferences/Java/Decompiler" was active.


JD-Eclipse插件 + realignment 补丁让优雅的debug class 文件成为可能。

如果只是为了阅读class代码,建议不要用realignment 补丁,这样会降低代码的可读性(会多出大量的空行)
 

posted @ 2013-02-22 15:01 Milo的海域 阅读(2031) | 评论 (0)编辑 收藏


sudo dpkg -l \*erlang\*
Desired
=Unknown/Install/Remove/Purge/Hold
| Status
=Not/Inst/Conf-files/Unpacked/halF-conf/Half-inst/trig-aWait/Trig-pend
|/ Err?
=(none)/Reinst-required (Status,Err: uppercase=bad)
||/ Name                          Version                       Description
+++-
=============================-=============================-==========================================================================
ii  erlang                        
1:14.b.4-dfsg-1ubuntu1        Concurrent, real-time, distributed functional language
un  erlang-abi-
13.a               <none>                        (no description available)
ii  erlang-appmon                 
1:14.b.4-dfsg-1ubuntu1        Erlang/OTP application monitor
ii  erlang-asn1                   
1:14.b.4-dfsg-1ubuntu1        Erlang/OTP modules for ASN.1 support
rc  erlang-base                   
1:14.b.4-dfsg-1ubuntu1        Erlang/OTP virtual machine and base applications
ii  erlang-base-hipe              
1:14.b.4-dfsg-1ubuntu1        Erlang/OTP HiPE enabled virtual machine and base applications
ii  erlang-common-test            
1:14.b.4-dfsg-1ubuntu1        Erlang/OTP application for automated testing
ii  erlang-corba                  
1:14.b.4-dfsg-1ubuntu1        Erlang/OTP applications for CORBA support
ii  erlang-crypto                 
1:14.b.4-dfsg-1ubuntu1        Erlang/OTP cryptographic modules
ii  erlang-debugger               
1:14.b.4-dfsg-1ubuntu1        Erlang/OTP application for debugging and testing
ii  erlang-dev                    
1:14.b.4-dfsg-1ubuntu1        Erlang/OTP development libraries and headers
ii  erlang-dialyzer               
1:14.b.4-dfsg-1ubuntu1        Erlang/OTP discrepancy analyzer application
ii  erlang-diameter               
1:14.b.4-dfsg-1ubuntu1        Erlang/OTP implementation of RFC 3588 protocol
ii  erlang-doc                    
1:14.b.4-dfsg-1ubuntu1        Erlang/OTP HTML/PDF documentation
un  erlang-doc-html               <none>                        (no description available)
ii  erlang-docbuilder             
1:14.b.4-dfsg-1ubuntu1        Erlang/OTP application for building HTML documentation
ii  erlang-edoc                   
1:14.b.4-dfsg-1ubuntu1        Erlang/OTP module for generating documentation
ii  erlang-erl-docgen             
1:14.b.4-dfsg-1ubuntu1        Erlang/OTP documentation stylesheets
ii  erlang-et                     
1:14.b.4-dfsg-1ubuntu1        Erlang/OTP event tracer application
ii  erlang-eunit                  
1:14.b.4-dfsg-1ubuntu1        Erlang/OTP module for unit testing
ii  erlang-examples               
1:14.b.4-dfsg-1ubuntu1        Erlang/OTP application examples
ii  erlang-gs                     
1:14.b.4-dfsg-1ubuntu1        Erlang/OTP graphics system
ii  erlang-ic                     
1:14.b.4-dfsg-1ubuntu1        Erlang/OTP IDL compiler
ii  erlang-ic-java                
1:14.b.4-dfsg-1ubuntu1        Erlang/OTP IDL compiler (Java classes)
ii  erlang-inets                  
1:14.b.4-dfsg-1ubuntu1        Erlang/OTP Internet clients and servers
ii  erlang-inviso                 
1:14.b.4-dfsg-1ubuntu1        Erlang/OTP trace tool
ii  erlang-jinterface             
1:14.b.4-dfsg-1ubuntu1        Java communication tool to Erlang
ii  erlang-manpages               
1:14.b.4-dfsg-1ubuntu1        Erlang/OTP manual pages
ii  erlang-megaco                 
1:14.b.4-dfsg-1ubuntu1        Erlang/OTP implementation of Megaco/H.248 protocol
ii  erlang-mnesia                 
1:14.b.4-dfsg-1ubuntu1        Erlang/OTP distributed relational/object hybrid database
ii  erlang-mode                   
1:14.b.4-dfsg-1ubuntu1        Erlang major editing mode for Emacs
ii  erlang-nox                    
1:14.b.4-dfsg-1ubuntu1        Erlang/OTP applications that don't require X Window System
ii  erlang-observer               
1:14.b.4-dfsg-1ubuntu1        Erlang/OTP application for investigating distributed systems
ii  erlang-odbc                   
1:14.b.4-dfsg-1ubuntu1        Erlang/OTP interface to SQL databases
ii  erlang-os-mon                 
1:14.b.4-dfsg-1ubuntu1        Erlang/OTP operating system monitor
ii  erlang-parsetools             
1:14.b.4-dfsg-1ubuntu1        Erlang/OTP parsing tools
ii  erlang-percept                
1:14.b.4-dfsg-1ubuntu1        Erlang/OTP concurrency profiling tool
ii  erlang-pman                   
1:14.b.4-dfsg-1ubuntu1        Erlang/OTP process manager
ii  erlang-public-key             
1:14.b.4-dfsg-1ubuntu1        Erlang/OTP public key infrastructure
ii  erlang-reltool                
1:14.b.4-dfsg-1ubuntu1        Erlang/OTP release management tool
ii  erlang-runtime-tools          
1:14.b.4-dfsg-1ubuntu1        Erlang/OTP runtime tracing/debugging tools
ii  erlang-snmp                   
1:14.b.4-dfsg-1ubuntu1        Erlang/OTP SNMP applications
ii  erlang-src                    
1:14.b.4-dfsg-1ubuntu1        Erlang/OTP applications sources
ii  erlang-ssh                    
1:14.b.4-dfsg-1ubuntu1        Erlang/OTP implementation of SSH protocol
ii  erlang-ssl                    
1:14.b.4-dfsg-1ubuntu1        Erlang/OTP implementation of SSL
ii  erlang-syntax-tools           
1:14.b.4-dfsg-1ubuntu1        Erlang/OTP modules for handling abstract Erlang syntax trees
ii  erlang-test-server            
1:14.b.4-dfsg-1ubuntu1        Erlang/OTP server for automated application testing
ii  erlang-toolbar                
1:14.b.4-dfsg-1ubuntu1        Erlang/OTP graphical toolbar
ii  erlang-tools                  
1:14.b.4-dfsg-1ubuntu1        Erlang/OTP various tools
ii  erlang-tv                     
1:14.b.4-dfsg-1ubuntu1        Erlang/OTP table viewer
ii  erlang-typer                  
1:14.b.4-dfsg-1ubuntu1        Erlang/OTP code type annotator
ii  erlang-webtool                
1:14.b.4-dfsg-1ubuntu1        Erlang/OTP helper for web-based tools
ii  erlang-x11                    
1:14.b.4-dfsg-1ubuntu1        Erlang/OTP applications that require X Window System
ii  erlang-xmerl                  
1:14.b.4-dfsg-1ubuntu1        Erlang/OTP XML tools

erlang-dev包含头文件,erlang-src包含源代码,erlang-debugger包含调试工具,erlang-base包含虚拟机

还可以根据package 名字的suffix察看erlang man doc,比如
man 3erl erlang
man 3erl mnesia
man 3erl io

posted @ 2013-01-15 11:34 Milo的海域 阅读(639) | 评论 (0)编辑 收藏

命令行调试erlang程序报错:
2> c(hello, [debug_info]).
{ok
,hello}
3> im().
Call to i:im/
0 in application debugger failed.
ok

google之原来是erlang-debugger没装
sudo apt-get install erlang-debugger

然后Monitor窗口就出来了。不过用eclipse 的erlide插件调试也可以。

posted @ 2013-01-11 17:06 Milo的海域 阅读(440) | 评论 (0)编辑 收藏

mvn 执行外部命令
命令行模式
mvn exec:exec -Dexec.executable=sh -Dexec.workingdir=./bin -Dexec.args=hello.sh

配置文件形式
                        <plugin>
                                <groupId>org.codehaus.mojo</groupId>
                                <artifactId>exec-maven-plugin</artifactId>
                                <executions>
                                        <execution>
                                                <id>test-exec</id>
                                                <phase>initialize</phase>
                                                <configuration>
                                                        <executable>sh</executable>
                                                        <workingDirectory>./bin</workingDirectory>
                                                        <arguments>
                                                                <argument>hello.sh</argument>
                                                        </arguments>
                                                </configuration>
                                                <goals>
                                                        <goal>exec</goal>
                                                </goals>
                                        </execution>
                                </executions>
                        </plugin>

mvn 生成java项目
生成骨架
mvn archetype:generate -DgroupId=com.abc.product -DartifactId=product -DpackageName=com.abc.product -DarchetypeArtifactId=maven-archetype-quickstart

转成eclipse能识别的java 项目
mvn eclipse:eclipse
导入eclipse 然后coding

mvn进行单元测试
                        <plugin>
                                <groupId>org.apache.maven.plugins</groupId>
                                <artifactId>maven-surefire-plugin</artifactId>
                                <version>
2.12.4</version>
                                <configuration>
                                        <forkMode>pertest</forkMode>
                                        <excludes>
                                                <exclude>**/perftest/*.java</exclude>
                                        </excludes>
                                        <systemProperties>
                                                <property>
                                                        <name>log4j.configuration</name>
                                                        <value>target/test-classes/log4j.properties</value>
                                                </property>
                                        </systemProperties>
                                </configuration>
                        </plugin>

mvn进行code coverage统计
  <reporting>
    <plugins>
      <plugin>
        <groupId>org.codehaus.mojo</groupId>
        <artifactId>emma-maven-plugin</artifactId>
        <version>1.0-alpha-3</version>
        <inherited>true</inherited>
      </plugin>
      <plugin>
        <groupId>org.codehaus.mojo</groupId>
        <artifactId>surefire-report-maven-plugin</artifactId>
        <inherited>true</inherited>
      </plugin>
    </plugins>
  </reporting>

mvn生成javadoc
                        <plugin>
                                <groupId>org.apache.maven.plugins</groupId>
                                <artifactId>maven-javadoc-plugin</artifactId>
                                <version>
2.9</version>
                                <configuration>
                                        <show>private</show>
                                </configuration>
                                <executions>
                                        <execution>
                                                <id>attach-javadocs</id>
                                                <goals>
                                                        <goal>javadoc</goal>
                                                        <goal>test-javadoc</goal>
                                                </goals>
                                                <phase>site</phase>
                                        </execution>
                                </executions>
                        </plugin>

posted @ 2013-01-10 13:33 Milo的海域 阅读(1277) | 评论 (0)编辑 收藏

最近项目要用JNI, 涉及到用java.library.path这个参数,开始以为只要ldconfig能识别到的so文件java 一定能找到,可惜并不是这样。。
要想java程序找到共享库还是要在执行java程序的时候指定java.library.path,用eclipse的话可以设置如下:
Properties->Run/Debug settings->Arguments->VM arguments
-----------------------------------------
-Djava.library.path=/home/miaoyachun/workspace/JNIC/Release
这个是传统的方式,google了下有个tricky的方式让程序动态修改java.library.path
    private static void loadJNILibDynamically() {
        
try {
            System.setProperty(
"java.library.path", System.getProperty("java.library.path")
                    
+ ":/home/miaoyachun/workspace/JNIC/Release/");
            Field fieldSysPath 
= ClassLoader.class.getDeclaredField("sys_paths");
            fieldSysPath.setAccessible(
true);
            fieldSysPath.set(
nullnull);

            System.loadLibrary(
"JNIC");
        } 
catch (Exception e) {
            
// do nothing for exception
        }
    }

事实上linux下还有个环境变量LD_LIBRARY_PATH,如果lib能在这个path里找到,java.library.path就不用配置了,而且不需要关心lib之间依赖的问题。java.library.path在这方面就弱很多,比如lib依赖其他目录的lib等。

posted @ 2012-12-06 11:05 Milo的海域 阅读(6816) | 评论 (0)编辑 收藏