https://wprp.zemanta.com/static/js/loader.js影响wordpress页面加载速度

最近发现我的wordpress博客访问速度又变慢了,在chrome下F12打开network一看,发现有这样一个请求无法连接:https://wprp.zemanta.com/static/js/loader.js?version=3.5.3。

于是用老方法,notepad++查找wordpress所有文件的代码(相关的方法请看:WordPress搭建的博客访问变慢的解决方案),发现public_html\wp-content\plugins\wordpress-23-related-posts-plugin\config.php文件中有两处出现了https://wprp.zemanta.com/static/(除了cache的文件以外)。

这样就清晰了,原来是WordPress Related Posts插件导致的,这个插件用于自动生成文章末尾的相关文章,这个插件是外国人开发的,所以引入了被墙的js。而现在国内支持各种相关链接的有很多:比如:无觅推荐、百度推荐、友荐等,我网站上已经使用百度推荐,于是可以直接删掉WordPress Related Posts插件,还顺带提升下性能。当然博客的内链少了一些,因为WordPress Related Posts插件是同步展示推荐的相关文章的,而百度推荐等其他的推荐都是js异步的。

现在博客速度恢复正常。

ipad4屏幕碎了,自己淘了个屏自己换

ipad4从桌上掉下了,正好一个角着地,屏幕碎了,而且受力的角变形了,有点翘起来。原打算找苹果的官方维修点修理的,结果打电话一问,说不能换屏幕,只能整机换,整机换需要1900元。请问这是维修么?到底会不会修屏幕我都怀疑了。

这是我见过的最烂的售后,这帮维修的为了赚钱,换屏幕这种费力不赚钱的活,他们不干,只做大单。

没想过找乱七八糟的维修点修理,因为那里修复估计也挺贵的。于是尝试了下在淘宝上看看有没有维修ipad屏幕的,一搜才发现修屏幕是淘宝上一个很正常的行业,而且价格出奇的便宜,只要100元左右。然后找了个销量最高的店,进去一看,发现还可以自己买回屏幕,自己DIY。一想要是自己把ipad拿去给别人修不太放心,要是别人给你更换了次品的零件,那就不好玩了。还是自己DIY比较靠谱,然后看了下更换屏幕的视频,似乎不难。于是自己买了个屏幕——127元,包含操作手册和一些必要的小工具。(尼玛,才过几天就降到110元了,如果也有想自己DIY的可以也来这家店买:https://new9.taobao.com/?spm=2013.1.1000126.3.0hDhCv)。

屏幕到了以后,卖家让我看网上的视频,按照视频里面的方式来操作,当然我顺便搜了一下其他的修理ipad4的视频,比如这个:国内最详细iPad4更换触摸屏教程,里面讲的很清晰。

在维修之前需要了解一点ipad里面的基本构造:

  1. ipad屏幕这个概念其实包含两个内容:触摸屏和显示屏。触摸屏就是我们摸到的屏幕,专门用来感受触摸的;显示屏是在触摸屏下面的,专门用来控制显示的。显示屏与触摸屏不是贴合的,而是分离的;两个屏分别有排线与主板相连。也就是说层次关系是最上面是触摸屏,其实是显示屏,再其次是主板
  2. 其实触摸屏也有两层,一层是硬度较高的玻璃,这才是我们真正每天在摸的屏,底下一层是用来感应触摸的屏,这一层是有排线的,需要和主板连接,用来专门控制触摸的,这两层屏是贴合在一起的整体。我从淘宝买来的就是整个触摸屏(另外还包含了home键和对应的排线),往往我们屏幕碎了都是外面的那层碎掉了,底下那层真正管理触摸的没有碎,因为我们屏幕碎了,仍然可以触摸使用;
  3. 尽管触摸屏在显示屏上面,但是触摸屏的排线却在显示屏的下面,所以在拆机时需要在掀开了触摸屏后,要先卸下显示屏,然后再卸下触摸屏

当然视频再详细,也需要注意一些细节的易错的点,我整理了一下:

  1. home键的右侧,的4cm距离的范围不要敲,那里有蓝牙天线,撬不好,就把蓝牙搞坏了,建议留到最后,热风吹一下就可以轻松的拿下来了。
  2. 拆机很关键,也最耗时,要想快一点,就得用吹风机多吹一下,核心是要从屏幕没坏的一边开始。
  3. 撬屏幕边缘的时候,不要把工具深得太靠里面了,基本不要超过白色的边框的宽度。因为超过后,里面就是显示屏了,要是划伤了显示屏,就不好玩了
  4. 把触摸屏的边缘都撬好以后,注意掀开屏幕的方位,让home键靠近自己,摄像头远离自己,然后把屏幕像翻书一样,从右往左掀开,注意动作要轻,如果遇到阻力一定要看看怎么回事,在home键的左边是触摸屏的排序位置,掀开到左边放下,然后用小启子把显示屏的4个螺丝拧下,然后按照和触摸屏一样的方式,把显示屏从右往左掀开,显示屏的排线也在左边,然后先把显示屏的排线取下,再把触摸屏的排线取下。安装的过程和拆的过程相反。
  5. 注意取下排线的时候,最好记住排线的那一面是朝上的,以免到时候安装的时候不记得了,一个简单的办法是在拆之前,给排线拍张照片,回头安装时可以作为参考
  6. 在安装屏幕之前一定要注意把摔碎ipad屏幕的着力点清理一下,让ipad的边缘平整,可以用刀慢慢的一层层的割掉不平整的地方,还可以借助钳子。这个过程中,需要注意最好不要把密封圈弄坏了,可以把密封圈揭开一段,但是不要弄断了,否则自己粘密封圈也挺麻烦的。
  7. 把机器倒过来摇一摇,让一些玻璃碎片调出来,然后用吹风机把整个机器内部吹一下,尽量保证里面干净。
  8. 把新的触摸屏和显示的排线接上后,不用要螺丝,不要撕掉保护膜,先测试一下,如果你开机发现屏幕不亮,那么可以尝试按住home键和开机键保持10秒,强制重启。如果还是不行,可能你的排线没有插入到位。需要对照拆机时拍下的照片对比下,是哪里没有插好。测试没有问题了,再把显示屏装上然后擦干净,再安装好触摸屏即可。

下面是一些我安装过程中的照片:

ipad屏幕更换——用吹风机加热屏幕边缘
ipad屏幕更换——用吹风机加热屏幕边缘

 

ipad4屏幕更换——撬开触摸屏边缘
ipad4屏幕更换——撬开触摸屏边缘
ipad4屏幕更换——从右往左掀开触摸屏
ipad4屏幕更换——从右往左掀开触摸屏
ipad4屏幕更换——把屏幕放好,注意排序
ipad4屏幕更换——把屏幕放好,注意排序
ipad4屏幕更换——掀开显示屏后排线的样子
ipad4屏幕更换——掀开显示屏后排线的样子
ipad4屏幕更换——触摸屏和显示屏的排线
ipad4屏幕更换——触摸屏和显示屏的排线
ipad4屏幕更换——home键的排线
ipad4屏幕更换——home键的排线,注意引脚是朝上的

整个过程可以看出一个非专业人士完全可以根据网上的视频、卖家的手册和售后服务搞定拆机和安装。

java.lang.NullPointerException at com.opensymphony.xwork2.util.LocalizedTextUtil.findText(LocalizedTextUtil.java:630)

为了防止CSRF攻击,在struts2的form表单中使用<s:token/>,在拦截器里添加了<interceptor-ref name=”token”/>,结果发现抛出下面的异常:

java.lang.NullPointerException
at com.opensymphony.xwork2.util.LocalizedTextUtil.findText(LocalizedTextUtil.java:630)
at com.opensymphony.xwork2.util.LocalizedTextUtil.findText(LocalizedTextUtil.java:606)
at com.opensymphony.xwork2.TextProviderSupport.getText(TextProviderSupport.java:210)
at com.opensymphony.xwork2.TextProviderSupport.getText(TextProviderSupport.java:139)
at org.apache.struts2.interceptor.TokenInterceptor.getErrorMessage(TokenInterceptor.java:182)
at org.apache.struts2.interceptor.TokenInterceptor.handleInvalidToken(TokenInterceptor.java:166)
at org.apache.struts2.interceptor.TokenInterceptor.handleToken(TokenInterceptor.java:151)
at org.apache.struts2.interceptor.TokenInterceptor.doIntercept(TokenInterceptor.java:142)
at com.alibaba.search.scc.web.interceptor.SccTokenInterceptor.intercept(SccTokenInterceptor.java:42)
at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:246)
at org.apache.struts2.impl.StrutsActionProxy.execute(StrutsActionProxy.java:54)
at org.apache.struts2.dispatcher.Dispatcher.serviceAction(Dispatcher.java:562)
at org.apache.struts2.dispatcher.ng.ExecuteOperations.executeAction(ExecuteOperations.java:77)
at org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter.doFilter(StrutsPrepareAndExecuteFilter.java:99)

我的用法照理讲应该是官方的用法,按照异常堆栈查看struts2源码,发现问题在这里:

出问题的是textProvider.getText方法,原因是textProvider中的bundle和class是空的,为什么是空的呢?可以看到setTextProvider方法上有一个@Inject注解,这个注解告诉了struts2需要注入一个类型为com.opensymphony.xwork2.TextProvider的实例,因为struts jar包里面的struts-default.xml中默认的配置是:

所以默认注入的就是TextProviderSupport实例对象,而这个bean中没有默认指定class和bundle,这就导致了textProvider.getText方法抛出空指针异常。

根据官方文档中的说法,可以自己实现TextProvider,形如:

<bean class=”org.demo.MyTextProvider” name=”myTextProvider” type=”com.opensymphony.xwork2.TextProvider” />

<constant name=”struts.xworkTextProvider” value=”myTextProvider” />

换个方式解决问题:

如果上面的getErrorMessage方法中执行了if语句里面的内容就不会走到textProvider.getText方法那里去,所以可以尝试让action的类型属于TextProvider,在TextProvider上ctrl+T可以看到其实现类上有ActionSupport类,所以这就知道了只需要让action类继承ActionSupport类即可避免抛出上面的空指针异常。

当然,既然进入到handleInvalidToken方法里面来了,那就需要为返回值INVALID_TOKEN_CODE(“invalid.token“)配置出错页面,形如:

 

java.lang.NoClassDefFoundError: com/sun/mail/util/SharedByteArrayInputStream

java classloader体系结构
java classloader体系结构

最近碰到jar包冲突,抛出的异常:java.lang.NoClassDefFoundError: com/sun/mail/util/SharedByteArrayInputStream,导致发邮件发布出去。在线下无法重现,而线上确大部分情况都能重现。

在http://www.findjar.com搜了一下发现含有这个类的有mail-1.3.3.jar,而我工程里面使用的mail-1.4.5.jar。这样一来似乎把mail包的版本降低到1.3.3就行了。

but倔强的我不想降版本,所以不得不找出到底是哪里使用到了com.sum.mail.util.SharedByteArrayInputStream类,在网上百度了一番,发现j2ee.jar有嫌疑,我用的是j2ee-1.4.jar和mail-1.4.5.jar,把这个jar包使用jd反编译后看到了原因,j2ee-1.4.jar和mail-1.4.5.jar中都使用了javax.mail.internet.MimeMessage类,而j2ee-1.4.jar中的MimeMessage中import了com.sun.mail.util.SharedByteArrayInputStream类,mail-1.4.5.jar中的MimeMessage中import了javax.mail.util.SharedByteArrayInputStream类。在线下很可能mail-1.4.5.jar包中的MimeMessage类被优先load到jvm中,所以使用了javax.mail.util.SharedByteArrayInputStream类;而线上则很可能j2ee-1.4.jar中的MimeMessage类被优先load到jvm中,而com.sun.mail.util.SharedByteArrayInputStream类在整个web工程中确实不存在,所以出现了如题的异常。

这样一来解决的办法就是得升级j2ee.jar包,经查j2ee-5.jar使用MimeMessage类与mail-1.4.5.jar中的完全一样,都import的是javax.mail.util.SharedByteArrayInputStream类。这样把升级j2ee包到版本5就行了。

总结一下:j2ee-1.4.jar与mail-1.3.3jar匹配,j2ee-5.jar与mail-1.4.5.jar匹配即可避免jar包冲突。

mysql timeout setting using the Connector / J connection property ‘autoReconnect = true’ to avoid this problem.

最近发现应用隔段时间就不可用了,发现有如下的错误日志:

Caused by: com.mysql.jdbc.exceptions.jdbc4.CommunicationsException: The last packet successfully received from the server was 45,012,127 milliseconds ago.  The last packet sent successfully to the server was 45,012,127 milliseconds ago. is longer than the server configured value of ‘wait_timeout’. You should consider either expiring and/or testing connection validity before use in your application, increasing the server configured values for client timeouts, or using the Connector/J connection property ‘autoReconnect=true’ to avoid this problem.

经查,是因为默认的mysql的超时时间设置导致的:如果连接空闲超过8小时(即没有任何数据库操作),mysql会自动的断开与应用的链接,但可通过重启tomcat(或者其他web容器)的方式来解决。

以下是解决方案:

方案一

如果你的jdbc链接的url上没有autoReconnect=true参数的话,就添加类似下面的参数:

jdbc.url = jdbc:mysql ://ipaddress: 3306/database?autoReconnect=true&autoReconnectForPools=true

方案二

如果你使用了hibernate的话,还可以用下面的方式来配置:

<property name=”connection.autoReconnect”>true</property>
<property name=”connection.autoReconnectForPools”>true</property>
<property name=”connection.is-connection-validation-required”>true</property>

如果你使用的是c3p0连接池,可以这样配置:

<property name=”hibernate.c3p0.acquire_increment”>1</property>

<property name=”hibernate.c3p0.idle_test_period”>0</property>
<property name=”hibernate.c3p0.timeout”>0</property>
<property name=” hibernate. c3p0.validate”> true </property>

 方案三

最坏的方案:修改mysql的配置问加你my.cnf,wait_timeout 31536000就是一年,够长了:

[Mysqld]

wait_timeout = 31536000

interactive_timeout = 31536000

修改后,重启即可

或者参考这篇文章http://www.2cto.com/database/201312/261593.html动态修改超时时间。

值得注意的是,这种设置方法会对有的mysql上的所有数据库和所有客户端都有效,而往往不同的应用对超时时间的要求可能不尽相同,所以这种方法需要慎重使用。

Reference

http://www.databaseskill.com/2615216/

http://www.2cto.com/database/201312/261593.html

error the @annotation pointcut expression is only supported at Java 5 compliance level or above

碰到了这个error the @annotation pointcut expression is only supported at Java 5 compliance level or above报错,一看就知道是jar包冲突,在网上百度了半天,大部分的说法都是把org.aspectj:aspectjweaver:jar包升级到1.6以上,但是我尝试了还是不行。这种spring的jar冲突,基本只能考百度谷歌了。

后来把dependency tree打印出来,搜索aspectj后,发现我的工程里面除了aspectjweaver外,还有个aspectjtools,这两个的版本都偏低,于是把这两个包都升级到了1.7.3,重新mvn clean install eclipse:eclipse后果然成功。

我只想说这些jar包冲突真的好坑爹啊

Reference

Error when using AspectJ AOP with Java 7

eclipse的hot swap功能失效导致代码修改后必须重启web应用:Absent Line Number Information

很长时间一直被ecipse的hotSwap功能失效问题困扰,hotSwap是jvm的一个重要功能,它可以让你在正在运行的程序中,修改方法体内容,修改后的代码能在应用不重启的条件下生效。而且经常提示这样的错误:

Absent Line Number Information

The virtual machine was unable to remove all stack frames running old code from the call stack. The virtual machine is not supplying the debugger with valid data for those frames. Stepping into these obsolete frames may be hazardous to the target virtual machine

hotSwap这个功能能大大降低开发调试成本。可是原本eclipse中能正常工作的hotSwap功能居然不能用了。在网上找了很多的方案,基本都是在说Preferences –> Java –> Compiler –> Classfile Generation的几项要勾上。但是eclipse默认这几项就是勾上的。

经查阅n多资料后,发现其本质原因是虚拟机和调试器不配套。说明很可能有两套javac.exe(用来编译的)和jdb.exe(用来调试的)同时被使用了,而这两套还不是来自同一个jdk的。顺着这个思路,我查看了下我的环境变量,在cmd中敲”echo %PATH%”:

C:\Program Files (x86)\Common Files\NetSarang;D:\amd\AMD APP SDK\2.9\bin\x86_64;D:\amd\AMD APP SDK\2.9\bin\x86;C:\Program Files (x86)\AMD APP SDK\2.9\bin\x86_64;C:\Program Files (x86)\AMD APP SDK\2.9\bin\x86;%SystemRoot%\system32;%SystemRoot%;%SystemRoot%\System32\Wbem;%SYSTEMROOT%\System32\WindowsPowerShell\v1.0\;D:\software\apache-maven-3.0.5\bin;%JAVA_HOME%\bin;%JAVA_HOME%\jre\bin;%GOBIN%;C:\Program Files (x86)\Git\cmd;%GROOVY_HOME%\bin;C:\Program Files\TortoiseSVN\bin

jdk只配置了一个,看起来没什么异样。我尝试用everything软件在整个硬盘上搜索javac.exe,结果发现有两个javac.exe,一个在jdk下,还有一个在%SystemRoot%\system32下,而且这个system32目录下还有个java.exe。看来问题应该是在这里了,至于为什么system32下会有javac.exe,就不得而知了,把java相关的exe文件都删除后,再试了试果然hotSwap功能恢复了。

困扰我许久的问题终于被解开了。

Reference

http://stackoverflow.com/questions/957822/eclipse-unable-to-install-breakpoint-due-to-missing-line-number-attributes

小米1升级最新miui后很卡的请看这里

nnd,我的小米1是第一批买的,去年发现小米1的一些服务停止了,很不爽,只能升级到最新的miuiv4,后来又升级到miuiv5,近来几个月速度明显在下降,甚至到了很难用的地步,不知原因。

我一度在小米论坛上找破解方案。有人说小米已经抛弃米1了,不支持小米1了,所以把系统升级到最新的miuiv5后就自动慢了,还是回复出厂设置使用原来的android 2.3的miui吧;也有人说要想变得快点,就需要三清(清楚缓存,清楚用户数据,清楚所有数据)后,刷卡重装,感觉挺费劲的。

最近实在是不能忍受米1的慢了,正好米4出来了,看起来还不错,想入手玩玩,结果发现如今的手机没有当年那么好抢了,抢了几次都没有抢到。没办法,还是回来整米1吧。

话说红米手机的配置和米1差不多,为啥红米跑miuiv5一点问题都没有,我的米1这么卡呢,应该不是硬件配置的问题。所以我猜测是我曾经的多次系统升级,而软件不一定赶上了系统的版本升级,导致软件与系统有一定的调优方面的不兼容,另外,手机用了快3年了,卡和rom里的太多了,没有清理过,估计碎片也很多。所以这次我狠下心,不管费不费劲都要彻底的清空重装。

按照miui官网的教程这样刷机http://www.miui.com/shuaji-301.html:

  1. 下载相应的miui最新的稳定版安装包:http://www.miui.com/download.html
  2. 重命名安装包为 update.zip 拷贝至格式化后的SD卡的根目录
  3. 三清(清楚缓存,清楚用户数据,清楚所有数据),在关机状态下,同时按+音量键和关机键 进入recovery模式(此模式下:关机键为确认键,音量键为上下移动的按键),然后选择“简体中文”–>”清楚数据”–>分别清楚缓存,清楚用户数据,清楚所有数据,然后关机
  4. 把SD卡插入后,再使用步骤3中的方法进入recovery模式,选择“简体中文”后,选择“将update.zip安装至系统一”并确认。选择确认等待完成,然后重启即可

现在感觉我的米1速度快了不少,和当初刚买来是差不多的速度了。

eclipse中文乱码问题解决方案汇总

eclipse中文乱码都是因为字符编码与默认的编码不符合导致的,有很多的方法可以解决,不需要安装任何插件就可以搞定。针对不同的情况,需要使用不同的方案,下面就针对一些案例讲解如何解决乱码问题。解决乱码问题的主要思路是设置正确合适的编码,如果不知道目标文件原本的编码,可以进行一定的尝试,通常尝试下GBK和UTF-8这两个编码即可。

1. 设置单个文件的字符编码,解决单个文件的乱码问题

有时候不小心copy来的单个文件编码与你workspace的默认编码不一致,就导致了单个乱码。解决办法:在Pakcage Explorer或者Project Explorer视图里面,右键点击该文件–>选择“Properties”–>”Text file encoding”–>给”Other”项设置相应的编码。(需要注意的是,如果copy来的文件在eclipse中显示的是正常,但是编码与其他文件不一致,若你想统一编码,就需要在设置编码前,记得先把文件内容copy一下,然后设置好编码,再把copy的内容粘贴到编码修改后的文件中,这样会不乱码;一修改编码文件内容就会乱码),如下图:

eclipse设置单个文件的字符编码
eclipse设置单个文件的字符编码

2. 设置第三方jar包的字符编码,解决整个jar的乱码问题

第三方jar包的编码问题可能是最常见的问题,其解决方案与单个文件的比较类似,在Pakcage Explorer或者Project Explorer视图里面,右键第三方jar包–>选择“Properties”–>给”Encoding”项设置相应的编码,如下图:

在eclipse中给jar包设置字符编码
在eclipse中给jar包设置字符编码

3. 分别设置不同类型文件的字符编码

有时候为了统一所有工程的编码,可能需要提前设置好各类型文件的字符编码,比如:把所有的jar类都设置为GBK编码,把所有的xml设置为UTF-8编码等。这时候就需要有针对性的给不同类型的文件设置不同的编码。步骤是这样的:Windows–>Perferences–>General–>Content Types–>选择文件类型–>设置“Default encoding”项。如图下:

在eclipse中给指定类型的文件设置字符编码
在eclipse中给指定类型的文件设置字符编码

4. 设置整个workspace的文本文件的默认字符编码

往往workspace都有一个默认的字符编码,如果你的工程大部分或者全部是另一个编码,那么你可以重新设置一个默认的字符编码,后续新建工程就不需要再去设置编码了。步骤是这样的:Windows–>Perferences–>General–>Workspace–>Test file encoding–>给“Other:”设置相应的编码,如下图:

在eclipse中设置workspace的字符编码
在eclipse中设置workspace的字符编码

个人经验

其实一般开源的代码都是UTF-8编码的,我们平时开发的时候最好也都统一使用UTF-8,在开发初期直接把workspace的文本文件的编码设置为UTF-8,这比较省事。在开发过程中,如果发现添加进来的三方jar包编码不是UTF-8,那么可以针对这个jar设置其编码;若copy某个源码文件到工程中发现是乱码的,那么可以仅设置这一个文件的编码成正确的编码。

解决mysql命令行的字符编码问题

mysql命令行的字符编码问题是很常见的,也是比较麻烦的问题,但其实解决的方法比较简单,只需要知道哪些地方需要设置编码,并把这些编码设置成统一的就行了,比如:在使用mysql的命令行工具时,就需要设置命令行工具的字符编码与数据库的编码保持一致。

查看和设置数据库的字符编码

首先需要知道数据库的编码是怎么样的,可以使用下的命令,效果如下图:

show variables like ’character_set_%’;

查看数据库的编码
查看数据库的编码

除了charaacter_set_filesystem以外,其他的最好保持一致。可以看到我的数据库的字符编码设置都是utf8的。

这里的设置正确以后,就需要保证客户端的编码和数据库的编码一致,这样客户端才能正常显示数据库中的中文数据,数据库才能正确的识别客户端发来的带有中文的查询语句。

如果你的编码设置不一致,请使用类似下面的语句来设置编码:

set character_set_client=gb2312; // 客户端编码方式
set character_set_connection= gb2312; // 建立连接使用的编码
set character_set_database= gb2312; // 数据库的编码
set character_set_results= gb2312; // 结果集的编码
set character_set_server= gb2312; // 数据库服务器的编码

下面图文解释如何设置命令行工具的字符编码:

secureCRT的字符编码设置

在一个连接上右键,选择“属性”,如下图设置编码:

 

设置secureCRT的字符编码
设置secureCRT的字符编码

xshell的字符编码设置

如果你使用的是xshell作为你的命令行工具,那么你可以这样设置,在一个会话上,右键点击“属性”,然后按照如下设置你数据库对应的字符编码即可,我的数据库是用utf8,所以我设置了utf8:

 

xshell的字符编码设置
xshell的字符编码设置

Reference