PuTTY连接跳板机频繁被断开的问题

公司的服务器只能通过跳板机的方式来链接,因此在Windows中使用PuTTY连接跳板机,结果实际使用中发现,会频繁被跳板机断开,而如果在目标机器中执行一个ping 127.0.0.1则连接始终不会被断开。那么说明是由于跳板机设置了一段时间如果没有报文通信就断开连接的功能,而且这个时间设置的比较激进。

请教了一下别人,找到如下设置即可解决这个问题:

puttyconfigurationkeepalives

其实质是开启了TCPKeepAlive心跳报文。默认这个时间是"0",也就是TCP链路中不发送心跳报文。把这个时间设置成"1",也就是每秒都发送一次心跳。

Android Studio升级到2.2正式版本后,在Windows命令行中执行“gradlew build”时,报告错误“Unsupported major.minor version 52.0”

Android Studio升级到2.2正式版本后,在Android Studio中编译一切正常。但是在Windows命令行中执行“gradlew build”时,报告如下错误:

* What went wrong:
A problem occurred evaluating project ':XXX'.
> java.lang.UnsupportedClassVersionError: com/android/build/gradle/LibraryPlugin
 : Unsupported major.minor version 52.0

* Try:
Run with --stacktrace option to get the stack trace. Run with --info or --debug
option to get more log output.

这个原因,目前本人遇到的原因是,机器上同时安装了jdk1.7.0_80jdk1.8.0_73两个版本的JDK,而环境变量中的JAVA_HOME指向的是jdk1.7.0_80

解决方法就是修改JAVA_HOME指向jdk1.8.0_73即可。

注意,修改完成环境变量后,需要重启一下Android Studio,以及Windows命令行窗口。否则环境变量不生效。

Apache-2.4使用ServerAlias实现同一个网站绑定多个域名(Ubuntu 14.04)

最近自己申请了多个域名,打算绑定到同一台服务器上面,网上搜索了一下,很多的答案是开多个主机的方式来处理,方式可以,但是比较繁琐,不如使用ServerAlias来的方便。
ServerAlias:服务器别名,在Apache中可以用于设置虚拟主机接收到个域名,也可以用于接收泛解析的域名。具体的设置方法如下:

$ sudo vim /etc/apache2/sites-enabled/000-default.conf

可以看到如下的配置内容:

<VirtualHost *>
	ServerName www.mobibrw.com
	ServerAlias www.mobibrw.com mobibrw.com www.miniab.com miniab.com
	<Directory />
		Options Indexes FollowSymLinks
		AllowOverride all
	</Directory>
</VirtualHost>

注意其中的ServerAlias字段,就是指定多个域名同时指向的这个服务器的。中间用空格来区分。

注意上述的ServerAlias中,包含www字段的域名www.mobibrw.com,跟不包含www字段的域名mobibrw.com声明了两次,目的是某些浏览器在进行域名认证的时候(HTTPS证书校验),采用的是全字匹配,导致尽管这两个实际上是指向同一个地址,但是这些浏览器会报告域名证书不正确。

同样道理,对于使用了HTTPS的服务器来说,这个更重要

$ sudo vim /etc/apache2/sites-enabled/000-default-le-ssl.conf

执行跟上述相同设置即可。
如果跟本站一样使用Let‘s Encrypt颁发的SSL证书的网站来说,修改完成配置后,需要重新申请一下证书。

Android真机使用Mockito-1.10.19+Dexmaker-1.2在Mock仅包内可见类时报告错误“java.lang.UnsupportedOperationException: cannot proxy inaccessible class ***”

Android真机使用Mockito-1.10.19+Dexmaker-1.2Mock仅包内可见类时报告如下错误:

java.lang.UnsupportedOperationException: cannot proxy inaccessible class class com.yunos.tv.shake.biz.PackageAccessible
at com.android.dx.stock.ProxyBuilder.buildProxyClass(ProxyBuilder.java:269)
at com.android.dx.mockito.DexmakerMockMaker.createMock(DexmakerMockMaker.java:56)
at org.mockito.internal.util.MockUtil.createMock(MockUtil.java:33)
at org.mockito.internal.MockitoCore.mock(MockitoCore.java:59)
at org.mockito.Mockito.mock(Mockito.java:1285)
at org.mockito.Mockito.mock(Mockito.java:1163)
at com.yunos.tv.shake.biz.PackageAccessibleTest.setUp(PackageAccessibleTest.java:17)
at android.test.AndroidTestRunner.runTest(AndroidTestRunner.java:191)
at android.test.AndroidTestRunner.runTest(AndroidTestRunner.java:176)
at android.test.InstrumentationTestRunner.onStart(InstrumentationTestRunner.java:555)
at android.app.Instrumentation$InstrumentationThread.run(Instrumentation.java:1853)
Caused by: java.lang.IllegalAccessError: Class com.yunos.tv.shake.biz.PackageAccessible extended by class PackageAccessible_Proxy is inaccessible (declaration of 'PackageAccessible_Proxy' appears in /data/data/com.yunos.tv.shake.biz.test/cache/Generated_179875952.jar)
at dalvik.system.DexFile.defineClassNative(Native Method)
at dalvik.system.DexFile.defineClass(DexFile.java:226)
at dalvik.system.DexFile.loadClassBinaryName(DexFile.java:219)
at dalvik.system.DexPathList.findClass(DexPathList.java:321)
at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:54)
at java.lang.ClassLoader.loadClass(ClassLoader.java:511)
at java.lang.ClassLoader.loadClass(ClassLoader.java:469)
at com.android.dx.stock.ProxyBuilder.loadClass(ProxyBuilder.java:284)
at com.android.dx.stock.ProxyBuilder.buildProxyClass(ProxyBuilder.java:266)
... 15 more

被测试类代码如下:

package com.yunos.tv.shake.biz;

class PackageAccessible {
}

注意上述被测试类前面没有声明public,因此默认是default访问,也就是包内可见。我们下面的测试代码跟被测试类属于同一个包名package com.yunos.tv.shake.biz,因此,按理说,是可以正常访问的。
测试类的代码如下:

package com.yunos.tv.shake.biz;

import android.test.AndroidTestCase;

import org.mockito.Mockito;

public class PackageAccessibleTest extends AndroidTestCase {
    protected void setUp() throws Exception {
        super.setUp();
        /*解决BUG dexcache == null (and no default could be found; consider setting the 'dexmaker.dexcache' system pr*/
        System.setProperty(
                "dexmaker.dexcache",
                getContext().getCacheDir().getPath());
        PackageAccessible packageAccessible = Mockito.mock(PackageAccessible.class);
    }
}

这个问题只在ART虚拟机下面发生异常,相同的代码在Dalvik下面是完全正常的。
问题发生的原因暂时还不能确定,应该是ART虚拟机实现功能的时候的不兼容导致的。
解决方法为在测试代码中声明一个继承被测试类的子类,并且把子类声明成public
如下:

package com.yunos.tv.shake.biz;

public class PackageAccessibleShadow extends PackageAccessible {
}

修改后的测试代码如下:

package com.yunos.tv.shake.biz;

import android.test.AndroidTestCase;

import org.mockito.Mockito;

public class PackageAccessibleTest extends AndroidTestCase {
    protected void setUp() throws Exception {
        super.setUp();
        /*解决BUG dexcache == null (and no default could be found; consider setting the 'dexmaker.dexcache' system pr*/
        System.setProperty(
                "dexmaker.dexcache",
                getContext().getCacheDir().getPath());
        PackageAccessibleShadow packageAccessible = Mockito.mock(PackageAccessibleShadow.class);
    }
}

即可解决上述问题。

Android ContentProvider使用时出现的错误“java.lang.SecurityException: Permission Denial: opening provider ***”

AndroidAPK上自定义了一个ContentProvider,但是在调用者使用时出现的错误"java.lang.SecurityException: Permission Denial: opening provider ***"。

查询了半天才发现是由于在声明ContentProvider的时候没有声明android:exported="true"导致的。

从目前的测试情况来看,跟Android的版本有关系,目前看到在低版本的Android系统上面,这个如果不设置,默认是自动导出的,但是在高版本的Android上面,默认就是不导出了,这就导致一个问题,就是相同的APK在不同系统上面会出现不同的行为。因此要求必须显示指定这个字段

注意如下说明:

android:exported
Whether the content provider is available for other applications to use:
true: The provider is available to other applications. Any application can use the provider's content URI to access it, subject to the permissions specified for the provider.
false: The provider is not available to other applications. Set android:exported="false" to limit access to the provider to your applications. Only applications that have the same user ID (UID) as the provider will have access to it.
The default value is "true" for applications that set either android:minSdkVersion or android:targetSdkVersion to "16" or lower. For applications that set either of these attributes to "17" or higher, the default is "false".
 
You can set android:exported="false" and still limit access to your provider by setting permissions with the permission attribute.

参考链接


Android真机使用Mockito-1.10.19+Dexmaker-1.2在Mock继承抽象父类的子类时报告错误“java.lang.AbstractMethodError: abstract method not implemented”

Android真机使用Mockito-1.10.19+Dexmaker-1.2Mock继承抽象父类的子类时报告如下错误:

java.lang.AbstractMethodError: abstract method not implemented
at org.mockito.internal.invocation.AbstractAwareMethod.isAbstract(Native Method)
at org.mockito.internal.invocation.InvocationImpl.callRealMethod(InvocationImpl.java:109)
at org.mockito.internal.stubbing.answers.CallsRealMethods.answer(CallsRealMethods.java:41)
at org.mockito.internal.stubbing.StubbedInvocationMatcher.answer(StubbedInvocationMatcher.java:34)
at org.mockito.internal.handler.MockHandlerImpl.handle(MockHandlerImpl.java:91)
at org.mockito.internal.handler.NullResultGuardian.handle(NullResultGuardian.java:29)
at org.mockito.internal.handler.InvocationNotifierHandler.handle(InvocationNotifierHandler.java:38)
at com.google.dexmaker.mockito.InvocationHandlerAdapter.invoke(InvocationHandlerAdapter.java:49)
at ChildCls_Proxy.forParentMock(ChildCls_Proxy.generated)
at com.yunos.tv.shake.biz.DiTingMessageProviderTest.setUp(childClsTest.java:33)
at android.test.AndroidTestRunner.runTest(AndroidTestRunner.java:203)
at android.test.AndroidTestRunner.runTest(AndroidTestRunner.java:177)
at android.test.InstrumentationTestRunner.onStart(InstrumentationTestRunner.java:554)
at android.app.Instrumentation$InstrumentationThread.run(Instrumentation.java:1727)

父类代码如下:

abstract public class ParentCls {
    abstract public void forChildMock();
}

子类代码如下:

public class ChildCls extends ParentCls{

    @Override
    public void forChildMock() {

    }
}

测试代码如下:

public class childClsTest extends AndroidTestCase {

    @Override
    protected void setUp() throws Exception {
        super.setUp();
        /*解决BUG dexcache == null (and no default could be found; consider setting the 'dexmaker.dexcache' system pr*/
        System.setProperty(
                "dexmaker.dexcache",
                getContext().getCacheDir().getPath());
        ChildCls childCls = Mockito.mock(ChildCls.class);
        Mockito.doCallRealMethod().when(childCls).forParentMock();
        childCls.forParentMock();
    }
}

在项目的build.gradle中的声明如下:

//for mockito
androidTestCompile 'org.mockito:mockito-core:1.10.19'
androidTestCompile 'com.google.dexmaker:dexmaker:1.2'
androidTestCompile 'com.google.dexmaker:dexmaker-mockito:1.2'

这个问题只在Dalvik虚拟机下面发生异常,相同的代码在ART下面是完全正常的。
导致问题发生的原因是Google提供的dexmaker库存在BUG导致的,而这个库,从Maven Center上看,自从2012年开始就没有提供过任何的更新了。
解决方法是不使用Google提供的dexmaker,而是使用com.crittercism.dexmaker修正过这个BUG的版本。

//for mockito
androidTestCompile 'org.mockito:mockito-core:1.10.19'
androidTestCompile 'com.crittercism.dexmaker:dexmaker:1.4'
androidTestCompile "com.crittercism.dexmaker:dexmaker-dx:1.4"
androidTestCompile 'com.crittercism.dexmaker:dexmaker-mockito:1.4'

com.crittercism.dexmaker项目的GitHub地址是https://github.com/crittercism/dexmaker

Android上使用Mockito+Dexmaker报告错误“java.lang.IllegalArgumentException: dexcache == null (and no default could be found; consider setting the 'dexmaker.dexcache' system property) ”

Android上使用Mockito+Dexmaker,测试用例运行时,报告错误:

java.lang.IllegalArgumentException: 
    dexcache == null (and no default could be found; 
    consider setting the 'dexmaker.dexcache' system property)
at com.google.dexmaker.DexMaker.generateAndLoad(DexMaker.java:359)
at com.google.dexmaker.stock.ProxyBuilder.buildProxyClass(ProxyBuilder.java:252)
at com.google.dexmaker.mockito.DexmakerMockMaker.createMock(DexmakerMockMaker.java:54)
at org.mockito.internal.util.MockUtil.createMock(MockUtil.java:26)

解决方法就是在调用Mockito之前设置环境变量"dexmaker.dexcache",如下:

public class BasicTestCase extends AndroidTestCase {
    @Override
    protected void setUp() throws Exception {
        super.setUp();
        /*解决BUG dexcache == null (and no default could be found; consider setting the 'dexmaker.dexcache' system pr*/
        System.setProperty(
                "dexmaker.dexcache",
                getContext().getCacheDir().getPath());
    }
}

参考链接


Mockito + Dexmaker on Android

Tomcat 7使用AJP协议导致AJP端口被意外暴露给外网

使用Ubuntu 13.10 Apache 2.2 通过 AJP 整合 Tomcat 7中的方法配置了通过AJP协议来通过Apache进行访问的代理。

但是最近发现Tomcat有时候会崩溃掉。刚刚开始以为是正常的OOM,后来分析日志,并没有找到相关的记录,反倒是发现如下内容:

Jan 26, 2016 5:06:47 PM org.apache.coyote.ajp.AjpMessage processHeader
SEVERE: Invalid message received with signature 18245
Jan 26, 2016 5:06:48 PM org.apache.coyote.ajp.AjpMessage processHeader
SEVERE: Invalid message received with signature 5635
Jan 26, 2016 5:06:48 PM org.apache.coyote.ajp.AjpMessage processHeader
SEVERE: Invalid message received with signature 18245
Jan 26, 2016 5:06:48 PM org.apache.coyote.ajp.AjpMessage processHeader
SEVERE: Invalid message received with signature 3338
Jan 26, 2016 5:06:48 PM org.apache.coyote.ajp.AjpMessage processHeader
SEVERE: Invalid message received with signature 20304
Jan 26, 2016 5:06:48 PM org.apache.coyote.ajp.AjpMessage processHeader
SEVERE: Invalid message received with signature 20304
Jan 26, 2016 5:06:48 PM org.apache.coyote.ajp.AjpMessage processHeader
SEVERE: Invalid message received with signature 32768
Jan 26, 2016 5:06:48 PM org.apache.coyote.ajp.AjpMessage processHeader
SEVERE: Invalid message received with signature 30

于是感觉有些奇怪,因为AJP协议应该不会发生非常频繁的通信协议错误问题。结果尝试从外网连接TomcatAjp端口8009,发现竟然可以通过telnet连接成功!!说明端口意外暴露给了外网。

那么根据The AJP Connector中的介绍说明(注意address部分),如果没有指定IP地址的话,默认是绑定任意地址,这样就导致外网也可以访问这个端口。因此出于安全考虑,我们需要增加这个address的设置,并且绑定到127.0.0.1。最终结果如下:

<!-- Define an AJP 1.3 Connector on port 8009 -->
<Connector port="8009" protocol="AJP/1.3" address="127.0.0.1" redirectPort="8443" />

而我在配置的时候,恰恰少设置了address="127.0.0.1".这个这种错误有些低级啊。

在Windows 7系统上编译运行体验Apache OFBiz-13.07.03

作为Apache基金会的赞助项目,OFBiz(全称为"Open for Business")是一套功能齐全的企业自动化套件,其中包含企业资源规划(简称ERP)、客户关系管理(简称CRM)、电子商务、内容管理、计费与费 率管理、供应链管理、制造资源规划以及企业资产管理等方案。OFBiz拥有丰富的说明文档及指导视频,其基于Java语言因此能够运行在任意支持Java SDK的系统当中,包括WindowsOS XLinux以及Unix

1.去OFBiz的官网http://ofbiz.apache.org/下载目前最新版本的13.07.03。下载完成后,是个zip格式的压缩包。解压压缩包到任意目录。

2.安装最新的JDK(要求最低是1.7,目前的1.8版本是可以正常使用的)。

$ cd apache-ofbiz-13.07.03
$ ant build
$ ant load-demo
$ ant start

完成后,直接访问http://localhost:8080/ecommerce即可看到如下页面:
ofbiz_index
其他的参考代码根目录下面的README.

参考链接


Ubuntu 16.04运行iLO-jirc.jnlp(.jnlp格式文件)

HP Gen8的远程控制支持.Net,Java Web Start,Java Applet三种控制方式,如下图所示:

hp_ilo_html
Windows下面首选是.Net方式,简单,快速,比较坑的就是必须在IE浏览器下面点击链接,在FireFox,Chrome中点击这个链接都是无效的。那么如何在Ubuntu 16.04下面运行远程控制呢?答案就是使用Java Web Start。但是Java Web Start下载下来的是iLO-jirc.jnlp这个文件,那么如何运行这个文件呢?如下方式即可:

$ sudo apt install icedtea-netx
$ javaws iLO-jirc.jnlp