??xml version="1.0" encoding="utf-8" standalone="yes"?>亚洲AV日韩AV天堂一区二区三区,亚洲制服丝袜在线播放,亚洲精品无码久久一线http://www.tkk7.com/cangshi004/category/50719.html日记?/description>zh-cnWed, 11 Sep 2013 16:21:08 GMTWed, 11 Sep 2013 16:21:08 GMT60JAVA~程之安全配|Struts 2应用E序详解http://www.tkk7.com/cangshi004/archive/2012/03/22/372435.htmlcangshicangshiThu, 22 Mar 2012 03:21:00 GMThttp://www.tkk7.com/cangshi004/archive/2012/03/22/372435.htmlhttp://www.tkk7.com/cangshi004/comments/372435.htmlhttp://www.tkk7.com/cangshi004/archive/2012/03/22/372435.html#Feedback0http://www.tkk7.com/cangshi004/comments/commentRss/372435.htmlhttp://www.tkk7.com/cangshi004/services/trackbacks/372435.html      当你在配|Struts 2q个应用E序Ӟ安全功能是一个最关键的问题,本文章详l介l一下这斚w的内容,希望对大家有所帮助吧。呵呵,当然Q如果有不当之处Q也h友们指正啊!配置Struts 2应用E序是基于servlet技术的Q所以Struts 2的安全策略也可以使用配置文gq行灉|的配|?

配置安全{略Ӟ有两个概念需要清楚的区分 Q用户和角色Q简单的说用户ؓ使用计算机的人,可以是个人或l织。角色是一个抽象的概念Q泛指职务或者权限。例如,张三Q李四,王五三个人,有职员、主和l理三个职务Q权限)Q张三是用户Q张三可以是ȝ职务Q代表张三这个用户含有主的权利?/p>

不同的servlet容器所提供的用户和角色理机制是不相同的。我使用的是Tomcat服务器,它提供的用户和角色管理机制文件是在其安装目录下的conf目录中的tomcat-users.xml文gQ可以在q个文g里完成对用户和角色的~辑。例如:

  1. <tomcat-users> 
  2.     <role rolename="tomcat"/> 
  3.     <role rolename="role1"/> 
  4.     <user username="tomcat" password="tomcat" roles="tomcat"/> 
  5.     <user username="both" password="tomcat" roles="tomcat,role1"/> 
  6.     <user username="role1" password="tomcat" roles="role1"/> 
  7. </tomcat-users> 

q个文g定义?个角?tomcat和role1)?名用?tomcat、both和role1)。你可以在tomcat-users.xml文g里定义Q意多个用户和角色?/p>

使用Struts 2保护应用E序的资?/p>

Struts 2应用E序的安全策略是通过部vweb.xml文g中的security-constraint元素实现的,该元素的语法定义Q?/p>

  1. <!ELEMENT security-constraint (display-name?, web-resource-collection+, auth-constraint?, user-data-constraint?)>  
  2. <!ELEMENT display-name (#PCDATA)>  
  3. <!ELEMENT web-resource-collection (web-resource-name, description?, url-pattern*, http-method*)>  
  4. <!ELEMENT auth-constraint (description?, role-name*)>  
  5. <!ELEMENT user-data-constraint (description?, transport-guarantee)> 

该语法说明了Qsecurity-constraint元素可以有一个可选的display-name子元素,臛_一个web-resource-collection子元素,一个可选的auth-constraint子元素和一个可选的user-data-constraint子元素?/p>

web-resource-collection子元素是用来列出打算保护的Web资源Q具体的做法是ؓq些资源讄URL限制Q它是通过讄web-resource-collection元素包含的子元素实现的:

◆  web-resource-nameQ是与受保护资源相关联的名称。该子元素ؓ必须元素?/p>

◆  descriptionQ对l定资源的描q。这个子元素为可选元素?/p>

◆  url-patternQ用来设|URL表达式,与这个URL表达式相匚w的URL地址指向的资源将受到保护。该子元素ؓ臛_有一个,为必d素?/p>

◆  http-methodQ用来表明哪些HTTPҎ受到限Ӟ例如讄为GET那么所有的GETh将受到限制。该元素为可选元素?/p>

auth-constraint元素用于指定可以讉K该资源用戯色集合。如果没有指定auth-constraint元素Q就安全约束应用于所有角艌Ӏ它包含下面几个子元素:

◆  descriptionQ描q。该元素是可选元素?/p>

◆  role-nameQ可以访问保护资源的用户角色。该元素可以有多个?/p>

◆  user-data-constraint元素用来讄怎样保护在客L和Web容器之间传递的数据?/p>

◆  descriptionQ?描述。可选元素?/p>

◆  transport-guarantee Q该元素有以下几个?/p>

1. NONEQ这意味着应用不需要传输保证?/p>

2. INTEGRALQ意味着服务器和客户端之间的数据必须以某U方式发送,而且在传送中数据不能被篡攏V?/p>

3. CONFIDENTIALQ这意味着传输的数据必d密?/p>

配置完毕security-constraint元素的基本信息,大致Z面的格式Q?/p>

  1. <security-constraint> 
  2.     <web-resource-collection> 
  3.         <web-resource-name>Admin Arew</web-resource-name> 
  4.         <url-pattern>*.action</url-pattern> 
  5.     </web-resource-collection> 
  6.     <auth-constraint> 
  7.         <role-name>myeclipseWeb</role-name> 
  8.     </auth-constraint> 
  9. </security-constraint> 

q个security-constraint元素的效果ؓQ只要与表达?*.action"匚w的请求不是来自拥?myeclipseWeb"权限的用PWeb容器׃L它。在q里q可以用http-method元素Q阻断特定方法的hQ因为没有用会L所有方法提交的h?/p>

讄完安全策略后Q还需要设|让用户有机会提供证明,证明自己有权限访问这个受限资源的登陆Ҏ。允怋用的登陆Ҏ使用login-config元素讄Q下面ؓlogin-config元素的语法定义:

  1. <!ELEMENT login-config (auth-method?, realm-name?, form-login-config?)>  
  2. <!ELEMENT auth-method (#PCDATA)>  
  3. <!ELEMENT realm-name (#PCDATA)>  
  4. <!ELEMENT form-login-config (form-login-page, form-error-page)> 

login-config子元素的描述如下Q?
◆  auth-method指定用来验证用户w䆾的方法。它的gؓ下面的一个:BASIC、DIGEST、FORM?CLIENT-CERT
◆  realm-name指定HTTP Basic验证中在标准登陆框中昄的一条提C?
◆  form-login-config元素是在<auth-method>元素gؓ"FORM"时用的。它是指定基于表单的d中应该用的d面和出错页面。如果没有用基于表单的验证Q则忽略q些元素。这个元素的定义如下Q其中form-login-page用于指定昄d面的资源\径, form-error-page则用于指定用L录失败时昄出错面的资源\径?/p>

  1. <!ELEMENT form-login-config (form-login-page, form-error-page)>  
  2. <!ELEMENT form-login-page (#PCDATA)>  
  3. <!ELEMENT form-error-page (#PCDATA)> 

讄完登陆方法后Q还应该使用security-role元素Q注册允许用来访问受保护资源所有角艌Ӏ在该元素内部用一个role-name子元素来注册一个角艌Ӏ例如:

  1. <security-role> 
  2.     <role-name>myeclipseWeb</role-name> 
  3. </security-role> 

注册了一?myeclipseWeb"的角艌Ӏ?/p>

演示CZQ用BASIC登陆Ҏ验证用户w䆾

1.我用的Servlet容器是TomcatQ找到它的目录下conf目录中的tomcat-users.xml文g打开内容如下Q?/p>

  1. <?xml version='1.0' encoding='utf-8'?> 
  2. <tomcat-users> 
  3.     <role rolename="myeclipseWeb"/> 
  4.     <role rolename="myeclipseWebservices"/> 
  5.     <user username="webservices" password="webservices-pwd" roles="myeclipseWebservices"/> 
  6.     <user username="admin" password="admin-pwd" roles="myeclipseWeb,myeclipseWebservices"/> 
  7.     <user username="web" password="web-pwd" roles="myeclipseWeb"/> 
  8. </tomcat-users> 

我用的IDE是myEclipse9.0Q它配置好Tomcat下的tomcat-users.xml文g内容如上Q我直接使用它了Q你也可以添加自q角色和用戗该文g定义?个角色和3个用P每一个用户都pq角色(或者说权限Q可以有多重权限)?/p>

2.创徏Web目Q找到web.xmlQ配|它Q它支持Struts 2q且启动Struts 2的安全策?/p>

  1. <?xml version="1.0" encoding="UTF-8"?> 
  2. <web-app id="WebApp_9" version="2.4"  
  3.          xmlns="http://java.sun.com/xml/ns/j2ee"  
  4.          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
  5.          xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"> 
  6.     <display-name>Struts Blank</display-name> 
  7.     <filter> 
  8.         <filter-name>struts2</filter-name> 
  9.         <filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class> 
  10.     </filter> 
  11.     <filter-mapping> 
  12.         <filter-name>struts2</filter-name> 
  13.         <url-pattern>/*</url-pattern> 
  14.     </filter-mapping> 
  15.     <welcome-file-list> 
  16.         <welcome-file>index.html</welcome-file> 
  17.     </welcome-file-list> 
  18.     <!--  配置应用E序需要保护的资源与什么角色才可以讉K?nbsp;  --> 
  19.     <security-constraint> 
  20.         <web-resource-collection> 
  21.             <web-resource-name>Admin Arew</web-resource-name> 
  22.             <url-pattern>*.action</url-pattern> 
  23.         </web-resource-collection> 
  24.         <auth-constraint> 
  25.             <role-name>myeclipseWeb</role-name> 
  26.         </auth-constraint> 
  27.     </security-constraint> 
  28.     <!-- 注册可以讉K保护资源的角?nbsp; --> 
  29.     <security-role> 
  30.         <role-name>myeclipseWeb</role-name> 
  31.     </security-role> 
  32.     <security-role> 
  33.         <role-name>myeclipseWebservices</role-name> 
  34.     </security-role> 
  35.     <!--  讄dҎ  --> 
  36.     <login-config> 
  37.         <auth-method>BASIC</auth-method> 
  38.         <realm-name>User Basic Authentication</realm-name> 
  39.     </login-config> 
  40. </web-app> 

3. 创徏接收一个字D信息的动作c:

  1. public class SecureAction extends ActionSupport { 
  2.     private static final long serialVersionUID = 1961430702313132722L; 
  3.     private String username; 
  4.     public String getUsername() { 
  5.         return username; 
  6.     } 
  7.     public void setUsername(String username) { 
  8.         this.username = username; 
  9.     } 
  10.     @Override 
  11.     public String execute() 
  12.     { 
  13.         return SUCCESS; 
  14.     } 

4. 创徏struts.xml配置文gQ声明动?/p>

  1. <?xml version="1.0" encoding="UTF-8" ?> 
  2. <!DOCTYPE struts PUBLIC 
  3.     "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN" 
  4.     "http://struts.apache.org/dtds/struts-2.0.dtd"> 
  5. <struts> 
  6.     <package name="securePackage" extends="struts-default"> 
  7.         <action name="secure" class="struts2.action.SecureAction"> 
  8.             <result name="success">/index.jsp</result> 
  9.         </action> 
  10.     </package> 
  11. </struts> 

5. 创徏输入面input.jsp和结果页面index.jsp

input.jsp:

  1. <body> 
  2.     <s:form action="secure"> 
  3.         <s:textfield name="username" label="Enter your name"></s:textfield> 
  4.         <s:submit value="submit"></s:submit> 
  5.     </s:form> 
  6. </body> 

index.jsp

  1. <body> 
  2.     <s:property value="username"/>,Welcome 
  3. </body> 

6.试效果Q在览器输入:http://localhost:8081/SecureTest/input.jspQ得到如?a style="text-decoration: none" >自力式温度调节阀界面Q输?Tom"Q点?submit"按钮Q查看效果:


看到了登陆框了吧Q此时我们要讉K的资源是一个受限资源所以要求权限验?a style="text-decoration: none" >装式球阀Q还记得我们的用戯吧,查看用户表输入用户信息查看结果:

 

输入"webservices"?webservices-pwd"的用户信息:

 

提示了一?403"错误Q这是因然用户信息正,但是"webservices"用户的没?myeclipseWeb"权限?/p>

q次输入一个不存在的用户信息:

q次获得了一?401"错误Q这是登陆失败的提示l果Q这里会因浏览器的不同而需要不同次数的p|登陆才会得到q个l果?/p>

接下来输入一个正的用户Qƈ且拥?webservices"权限的用户信息:

点击"定"Q获得如下结果:

可以看到Q我们成功的讉K了受保护的资源。若要传中文字,解决Ҏ我已l在前面"配置Struts2"时介l过了,需要修改Struts 2默认的编码方式还需要修攚w面的~码方式Q都改ؓ"GBK"?/p>

 



cangshi 2012-03-22 11:21 发表评论
]]>
Java虚拟机技术参数应用详?/title><link>http://www.tkk7.com/cangshi004/archive/2012/03/06/371316.html</link><dc:creator>cangshi</dc:creator><author>cangshi</author><pubDate>Tue, 06 Mar 2012 02:50:00 GMT</pubDate><guid>http://www.tkk7.com/cangshi004/archive/2012/03/06/371316.html</guid><wfw:comment>http://www.tkk7.com/cangshi004/comments/371316.html</wfw:comment><comments>http://www.tkk7.com/cangshi004/archive/2012/03/06/371316.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.tkk7.com/cangshi004/comments/commentRss/371316.html</wfw:commentRss><trackback:ping>http://www.tkk7.com/cangshi004/services/trackbacks/371316.html</trackback:ping><description><![CDATA[Java虚拟机技术参数应用详?br />      JAVA虚拟机参C要分为基本和扩展两类Q在命o行中输入JAVA_HOME\bin\java 可得到基本参数列表Q在命o行输入JAVA_HOME\bin\java –X 可得到扩展参数列表? <p>  基本参数说明Q?/p> <p>  -clientQ?server</p> <p>  q两个参数用于设|虚拟机使用何种q行模式Qclient模式启动比较快,但运行时性能和内存管理效率不如server模式Q通常用于客户端应用程序。相反,server模式启动比client慢,但可获得更高的运行性能?/p> <p>  ?windows上,~省的虚拟机cd为client模式Q如果要使用server模式Q就需要在启动虚拟机时?server参数Q以获得更高性能Q对服务器端应用Q推荐采用server模式Q尤其是多个CPU的系l。在LinuxQSolaris上缺省采用server模式?/p> <p>  -hotspot</p> <p>  含义与client相同Qjdk1.4以前使用的参敎ͼjdk1.4开始不再用,代之以client.</p> <p>  -classpathQ?cp</p> <p>  虚拟机在q行一个类Ӟ需要将其装入内存,虚拟机搜索类的方式和序如下Q?/p> <p>  Bootstrap classesQExtension classesQUser classes.</p> <p>  Bootstrap 中的路径是虚拟机自带的jar或zip文gQ虚拟机首先搜烦q些包文Ӟ用System.getPropertyQ?sun.boot.class.path"Q可得到虚拟机搜索的包名?/p> <p>  Extension是位于jre\lib\ext目录下的jar文gQ虚拟机在搜索完Bootstrap后就搜烦该目录下的jar文g。用System. getPropertyQ?java.ext.dirs“Q可得到虚拟Z用Extension搜烦路径?/p> <p>  User classes搜烦序为当前目录、环境变?CLASSPATH?classpath.</p> <p>  -classpath告知虚拟机搜索目录名、jar文名、zip文名,之间用分P分隔?/p> <p>  例如当你自己开发了公共cdƈ包装成一个common.jar包,在用common.jar中的cLQ就需要用-classpath common.jar 告诉虚拟Zcommon.jar中查找该c,否则虚拟机就会抛出java.lang.NoClassDefFoundError异常Q表明未扑ֈcd义?/p> <p>  在运行时可用System.getPropertyQ?#8220;java.class.path”Q得到虚拟机查找cȝ路径?/p> <p>  使用-classpath后虚拟机不再用CLASSPATH中的cL索\径,如果-classpath和CLASSPATH都没有设|,则虚拟机使用当前路径Q。)作ؓcL索\径?/p> <p>  推荐使用-classpath来定义虚拟机要搜索的c\径,而不要用环境变?CLASSPATH的搜索\径,以减多个项目同时用CLASSPATH时存在的潜在冲突。例如应?要用a1.0.jar中的cGQ应?要?a2.0.jar中的cGQa2.0.jar是a1.0.jar的升U包Q当a1.0.jarQa2.0.jar都在CLASSPATH中,虚拟机搜索到W一个包中的cG时就停止搜烦Q如果应?应用2的虚拟机都从CLASSPATH中搜索,׃有一个应用得不到正确版本的类G.</p> <p>  -D<propertyName>=value</p> <p>  在虚拟机的系l属性中讄属性名/值对Q运行在此虚拟机之上的应用程序可用System.getPropertyQ?#8220;propertyName”Q得到value的倹{?/p> <p>  如果value中有I格Q则需要用双引号将该值括hQ如-Dname=“space string”?/p> <p>  该参数通常用于讄pȝU全局变量|如配|文件\径,应ؓ该属性在E序中Q何地斚w可访问?/p> <p>  -verbose[Qclass|gc|jni]</p> <p>  在输备上昄虚拟行信息?/p> <p>  verbose和verboseQclass含义相同Q输拟机装入的类的信息,昄的信息格式如下:</p> <p>  [Loaded java.io.FilePermission$1 from shared objects file]</p> <p>  当虚拟机报告cL不到或类冲突时可用此参数来诊断来查看虚拟Z装入cȝ情况?/p> <p>  -verboseQgc在虚拟机发生内存回收时在输出讑֤昄信息Q格式如下:</p> <p>  [Full GC 268K->168KQ?984KQ, 0.0187390 secs]</p> <p>  该参数用来监视虚拟机内存回收的情c?/p> <p>  -verboseQjni在虚拟机调用nativeҎ时输备显CZ息,格式如下Q?/p> <p>  [Dynamic-linking native method HelloNative.sum …… JNI]</p> <p>  该参数用来监视虚拟机调用本地Ҏ的情况,在发生jni错误时可断提供便利?/p> <p>  -version</p> <p>  昄可运行的虚拟机版本信息然后退出。一台机器上装有不同版本的JDK?/p> <p>  -showversion</p> <p>  昄版本信息以及帮助信息?/p> <p>  -ea[Q?lt;packagename>……|Q?lt;classname>]</p> <p>  -enableassertions[Q?lt;packagename>……|Q?lt;classname>]</p> <p>  从JDK1.4开始,java可支持断a机制Q用于诊断运行时问题。通常在测试阶D断言有效Q在正式q行时不需要运行断a。断a后的表达式的值是一个逻辑|为true时断a不运行,为false时断aq行Q抛出java.lang.AssertionError错误?/p> <p>  上述参数q来设|虚拟机是否启动断言机制Q缺省时虚拟机关闭断a机制Q用-ea可打开断言机制Q不?lt;packagename>?classname时运行所有包和类中的断言Q如果希望只q行某些包或cM的断aQ可包名或cd加到-ea之后。例如要启动包com.foo.util 中的断言Q可用命?–eaQcom.foo.util .</p> <p>  -da[Q?lt;packagename>……|Q?lt;classname>]</p> <p>  -disableassertions[Q?lt;packagename>……|Q?lt;classname>]</p> <p>  用来讄虚拟机关闭断a处理Qpackagename和classname的用方法和-ea相同?/p> <p>  -esa | -enablesystemassertions</p> <p>  讄虚拟机显C系l类的断a?/p> <p>  -dsa | -disablesystemassertions</p> <p>  讄虚拟机关闭系l类的断a?/p> <p>  -agentlibQ?lt;libname>[=<options>]</p> <p>  该参数是JDK5新引入的Q用于虚拟机装蝲本地代理库?/p> <p>  Libname为本C理库文g名,虚拟机的搜烦路径为环境变量PATH中的路径QoptionsZl本地库启动时的参数Q多个参C间用逗号分隔。在Windowsq_上虚拟机搜烦本地库名为libname.dll的文Ӟ?Unix上虚拟机搜烦本地库名为libname.so的文Ӟ搜烦路径环境变量在不同系l上有所不同QLinux、SunOS、IRIX上ؓ LD_LIBRARY_PATHQAIX上ؓLIBPATHQHP-UX上ؓSHLIB_PATH.</p> <p>  例如可?agentlibQhprof来获取虚拟机的运行情况,包括CPU、内存、线E等的运行数据,q可输出到指定文件中Q可?agentlibQhprof=help来得C用帮助列表。在jre\bin目录下可发现hprof.dll文g?/p> <p>  -agentpathQ?lt;pathname>[=<options>]</p> <p>  讄虚拟机按全\径装载本地库Q不再搜索PATH中的路径。其他功能和agentlib相同?/p> <p>  -javaagentQ?lt;jarpath>[=<options>]</p> <p>  虚拟机启动时装入java语言讑֤代理。Jarpath文g中的mainfest文g必须有Agent-Class属性。代理类要实现public static void premainQString agentArgsQ?Instrumentation instQ方法。当虚拟机初始化Ӟ按代理cȝ说明序调用premainҎ?/p> <p>  参见Qjava.lang.instrument</p> <p>  扩展参数说明</p> <p>  -Xmixed</p> <p>  讄-client模式虚拟机对使用频率高的方式q行Just-In-Time~译和执行,对其他方法用解释方式执行。该方式是虚拟机~省模式?/p> <p>  -Xint</p> <p>  讄-client模式下运行的虚拟Z解释方式执行cȝ字节码,不将字节码编译ؓ本机码?/p> <p>  -XbootclasspathQpath</p> <p>  -Xbootclasspath/aQpath</p> <p>  -Xbootclasspath/pQpath</p> <p>  改变虚拟载缺省系l运行包rt.jar而从-Xbootclasspath中设定的搜烦路径中装载系l运行类。除非你自己能写一个运行时Q否则不会用到该参数?/p> <p>  /aQ将在缺省搜索\径后加上path 中的搜烦路径?/p> <p>  /pQ在~省搜烦路径前先搜烦path中的搜烦路径?/p> <p>  -Xnoclassgc</p> <p>  关闭虚拟机对class的垃圑֛收功能?/p> <p>  -Xincgc</p> <p>  启动增量垃圾攉器,~省是关闭的。增量垃圾收集器能减偶然发生的长时间的垃圾回收造成的暂停时间。但<a style="text-decoration: none" ><font color="black">浆?/font></a>增量垃圾攉器和应用E序q发执行Q因此会占用部分CPU在应用程序上的功能?/p> <p>  -XloggcQ?lt;file></p> <p>  虚拟机每次垃圾回收的信息写到日志文件中Q文件名由file指定Q文件格式是qxӞ内容?verboseQgc输出内容相同?/p> <p>  -Xbatch</p> <p>  虚拟机的~省q行方式是在后台~译cM码,然后在前台执行代码,使用-Xbatch参数关闭虚拟机后台~译Q在前台~译完成后再执行?/p> <p>  -Xms<size></p> <p>  讄虚拟机可用内存堆的初始大,~省单位为字节,该大ؓ1024的整数倍ƈ且要大于1MBQ可用kQKQ或mQMQؓ单位来设|较大的内存数。初始堆大小?MB.</p> <p>  例如Q?Xms6400KQ?Xms256M</p> <p>  -Xmx<size></p> <p>  讄虚拟机内存堆的最大可用大,~省单位为字节。该值必Mؓ1024整数倍,q且要大?MB.可用kQKQ或mQMQؓ单位来设|较大的内存数。缺省堆最大gؓ64MB.</p> <p>  例如Q?Xmx81920KQ?Xmx80M</p> <p>  当应用程序申请了大内存运行时虚拟机抛出java.lang.OutOfMemoryErrorQ?Java heap space错误Q就需要?Xmx讄较大的可用内存堆c?/p> <p>  -Xss<size></p> <p>  讄U程栈的大小Q缺省单位ؓ字节。与-XmxcMQ也可用K或M来设|较大的倹{通常操作pȝ分配l线E栈的缺省大ؓ1MB.</p> <p>  另外也可在java中创建线E对象时讄栈的大小Q构造函数原型ؓThreadQThreadGroup groupQ?Runnable targetQ?String nameQ?long stackSizeQ?/p> <p>  -Xprof</p> <p>  输出CPUq行时的诊断信息?/p> <p>  -Xfuture</p> <p>  对类文gq行严格格式查,以保证类代码W合cM码规范。ؓ保持向后兼容Q虚拟机~省不进行严格的格式查?/p> <p>  -Xrs</p> <p>  减少虚拟Z操作pȝ的信PsingalsQ的使用。该参数通常用在虚拟Z后台服务方式q行时用(如ServletQ?/p> <p>  -XcheckQjni</p> <p>  调用JNI函数时进行附加的查,特别地虚拟机校验传递给JNI函数参数的合法性,在本C码中遇到非法数据Ӟ虚拟机将报一个致命错误而终止。用该阀参数后将造成性能下降?/p> <p> <div><a >单螺杆܇</a>183 <a >不锈钢螺杆܇</a>30 <a >容积?/a>27 <a >防爆Ҏ܇</a></div></p><img src ="http://www.tkk7.com/cangshi004/aggbug/371316.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.tkk7.com/cangshi004/" target="_blank">cangshi</a> 2012-03-06 10:50 <a href="http://www.tkk7.com/cangshi004/archive/2012/03/06/371316.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>JAVA之JDK?4位系l默认开启压~指针分?/title><link>http://www.tkk7.com/cangshi004/archive/2012/03/02/371120.html</link><dc:creator>cangshi</dc:creator><author>cangshi</author><pubDate>Fri, 02 Mar 2012 03:07:00 GMT</pubDate><guid>http://www.tkk7.com/cangshi004/archive/2012/03/02/371120.html</guid><wfw:comment>http://www.tkk7.com/cangshi004/comments/371120.html</wfw:comment><comments>http://www.tkk7.com/cangshi004/archive/2012/03/02/371120.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.tkk7.com/cangshi004/comments/commentRss/371120.html</wfw:commentRss><trackback:ping>http://www.tkk7.com/cangshi004/services/trackbacks/371120.html</trackback:ping><description><![CDATA[   JAVA之JDK?4位系l默认开启压~指针分析(请多多指正!Q?br />      Sun的HotSpot VM从JDK5开始会Ҏq行环境来自动设定VM的一些参敎ͼergonomicsQ。其中大家最熟悉的可能是它会自动选择client与server模式、堆的初始和最大大等。事实上ergonomics会设|非常多的内部参敎ͼ包括自动选择GC法、ƈ行GC的线E数、GC的工作区分块大小、对象晋升阈值等{? <p>  Ergonomics相关的逻辑大都在hotspot/src/share/vm/runtime/arguments.cpp中,值得留意的是使用了FLAG_SET_ERGOQ)的地斏V?/p> <p>  于是我们可以留意一下几个版本的HotSpot对UseCompressedOops参数的处理的差异Q?/p> <p>  HotSpot 16Q?/p> <p>  C++代码</p> <div align="center"> <div class="quosuuc" id="dmk" align="center"> <div align="left"><code class="txcode"><code class="txcode"><font face="NSimsun"><code class="txcode"><code class="txcode"><span id="iaeqage" class="keyword"><font color="#006699"><span id="eikmgus" class="tag"><li id="mysmoec" class="alt"><span id="yikoqoo" class="preprocessor"><font color="#808080">#ifdef _LP64    </font></span><span> </span></li><li><span>  </span><span id="woacwwu" class="comment"><font color="#008200">// Check that UseCompressedOops can be set with <br />the max heap size allocated    </font></span><span> </span></li><li id="mikoygm" class="alt"><span>  </span><span id="gyumioo" class="comment"><font color="#008200">// by ergonomics.    </font></span><span> </span></li><li><span>  </span><span id="oykmgws" class="keyword"><strong>if</strong></span><span> (MaxHeapSize <= max_heap_for_compressed_oops()) {     </span></li><li id="kwgiusk" class="alt"><span>    </span><span id="moqkgsi" class="keyword"><strong>if</strong></span><span> (FLAG_IS_DEFAULT(UseCompressedOops)) {     </span></li><li><span>      </span><span id="iaoqkig" class="comment"><font color="#008200">// Turn off until bug is fixed.    </font></span><span> </span></li><li id="wqcoywe" class="alt"><span>      </span><span id="mwakgem" class="comment"><font color="#008200">// the following line to return it to default status.    </font></span><span> </span></li><li><span>      </span><span id="myqmwuk" class="comment"><font color="#008200">// FLAG_SET_ERGO(bool, UseCompressedOops, true);    </font></span><span> </span></li><li id="cwyseca" class="alt"><span>    }     </span></li><li><span>    </span><span id="aimmiye" class="comment"><font color="#008200">// ...    </font></span><span> </span></li><li id="yqieqem" class="alt"><span>  }     </span></li><li><span id="oacwaqo" class="preprocessor"><font color="#808080">#endif // _LP64</font></span></li></span></font></span></code></code></font></code></code></div></div></div><!--<span id="iimqqig" class="right ft12"><a href="#" target="_blank">转发此文到空?/a></span>--> <p>  HotSpot 17:</p> <p>  C++代码</p> <div align="center"> <div class="qkegkiy" id="dmk" align="center"> <div align="left"><code class="txcode"><code class="txcode"><font face="NSimsun"><code class="txcode"><code class="txcode"><span id="ueqmwoe" class="keyword"><font color="#006699"><span id="muokusa" class="tag"><li id="eegkkui" class="alt"><span id="cogceui" class="preprocessor"><font color="#808080">#ifndef ZERO    </font></span><span> </span></li><li><span id="gwsmesk" class="preprocessor"><font color="#808080">#ifdef _LP64    </font></span><span> </span></li><li id="egskgaa" class="alt"><span>  </span><span id="isoyawo" class="comment"><font color="#008200">// Check that UseCompressedOops can be set with <br />the max heap size allocated    </font></span><span> </span></li><li><span>  </span><span id="skgsusq" class="comment"><font color="#008200">// by ergonomics.    </font></span><span> </span></li><li id="meqauks" class="alt"><span>  </span><span id="yqkeqom" class="keyword"><strong>if</strong></span><span> (MaxHeapSize <= max_heap_for_compressed_oops()) {     </span></li><li><span id="qsmwaqe" class="preprocessor"><font color="#808080">#ifndef COMPILER1    </font></span><span> </span></li><li id="egsmgoe" class="alt"><span>    </span><span id="suoscki" class="keyword"><strong>if</strong></span><span> (FLAG_IS_DEFAULT(UseCompressedOops) && !UseG1GC) {     </span></li><li><span>      </span><span id="wysuomm" class="comment"><font color="#008200">// Disable Compressed Oops by default. Uncomment <br />next line to enable it.    </font></span><span> </span></li><li id="kkgykaq" class="alt"><span>      </span><span id="eokmemc" class="comment"><font color="#008200">// FLAG_SET_ERGO(bool, UseCompressedOops, true);    </font></span><span> </span></li><li><span>    }     </span></li><li id="quoiska" class="alt"><span>  }     </span></li><li><span id="uuqaccs" class="preprocessor"><font color="#808080">#endif    </font></span><span> </span></li><li id="kcykksy" class="alt"><span>  </span><span id="yqseaoo" class="comment"><font color="#008200">// ...    </font></span><span> </span></li><li><span id="aaeqsiq" class="preprocessor"><font color="#808080">#endif // _LP64    </font></span><span> </span></li><li id="qscoiom" class="alt"><span id="mgqmoow" class="preprocessor"><font color="#808080">#endif // !ZERO   </font></span><span> </span></li></span></font></span></code></code></font></code></code></div></div></div><!--<span id="cuwikow" class="right ft12"><a href="#" target="_blank">转发此文到空?/a></span>--> <p>  HotSpot 19 / HotSpot 20:</p> <p>  C++代码</p> <div align="center"> <div class="iuoqmca" id="dmk" align="center"> <div align="left"><code class="txcode"><code class="txcode"><font face="NSimsun"><code class="txcode"><code class="txcode"><span id="myauoec" class="keyword"><font color="#006699"><span id="cegausa" class="tag"><li id="iauqsiq" class="alt"><span id="kuwgaqo" class="preprocessor"><font color="#808080">#ifndef ZERO    </font></span><span> </span></li><li><span id="kuwoayg" class="preprocessor"><font color="#808080">#ifdef _LP64    </font></span><span> </span></li><li id="scmyqyg" class="alt"><span>  </span><span id="kmakwcs" class="comment"><font color="#008200">// Check that UseCompressedOops can be set with <br />the max heap size allocated    </font></span><span> </span></li><li><span>  </span><span id="eykcwcu" class="comment"><font color="#008200">// by ergonomics.    </font></span><span> </span></li><li id="gacgige" class="alt"><span>  </span><span id="eoamqgm" class="keyword"><strong>if</strong></span><span> (MaxHeapSize <= max_heap_for_compressed_oops()) {     </span></li><li><span id="wwikwmk" class="preprocessor"><font color="#808080">#ifndef COMPILER1    </font></span><span> </span></li><li id="wokcouk" class="alt"><span>    </span><span id="ceoimsk" class="keyword"><strong>if</strong></span><span> (FLAG_IS_DEFAULT(UseCompressedOops) && !UseG1GC) {     </span></li><li><span>      FLAG_SET_ERGO(</span><span id="eskwggu" class="datatypes"><strong><font color="#2e8b57">bool</font></strong></span><span>, UseCompressedOops, </span><span id="keykmkk" class="keyword"><strong>true</strong></span><span>);     </span></li><li id="ycwqkay" class="alt"><span>    }     </span></li><li><span id="oquwyye" class="preprocessor"><font color="#808080">#endif    </font></span><span> </span></li><li id="iisgyqm" class="alt"><span>  }     </span></li><li><span>  </span><span id="scwqesq" class="comment"><font color="#008200">// ...    </font></span><span> </span></li><li id="yqseogg" class="alt"><span id="gykoayo" class="preprocessor"><font color="#808080">#endif // _LP64    </font></span><span> </span></li><li><span id="skwiigg" class="preprocessor"><font color="#808080">#endif // !ZERO</font></span></li></span></font></span></code></code></font></code></code></div></div></div><!--<span id="seysmms" class="right ft12"><a href="#" target="_blank">转发此文到空?/a></span>--> <p>  Q注QHotSpot VM的版本号与JDK的版本号之间的关p,请参考另一笔讎ͼSun/Oracle JDK、OpenJDK、HotSpot VM版本之间的对应关p)</p> <p>  可以看到QUseCompressedOops参数从HotSpot 19开始终于开始受ergonomics控制Q会在下q条件满的时候默认开?a style="text-decoration: none" ><font color="black">道力?/font></a>Q?/p> <p>  1、是64位系l(#ifdef _LP64Qƈ且不是client VMQ?ifndef COMPILER1Q;</p> <p>  2、Java堆的最大大不大于一个阈|MaxHeapSize <= max_heap_for_compressed_oopsQ)Q;</p> <p>  3、没有通过。hotspotrc或命令行参数手动讑֮qUseCompressedOops参数的|</p> <p>  4、没有用Garbage-First QG1Q?GC.</p><br />W???炚w很直观,于是W?点就是个关键点了Q阈值是多大Q? <p>  q是看回代码QHotSpot 20Q?/p> <p>  C++代码</p> <div align="center"> <div class="eyceyww" id="dmk" align="center"> <div align="left"><code class="txcode"><code class="txcode"><font face="NSimsun"><code class="txcode"><code class="txcode"><span id="scgiusa" class="keyword"><font color="#006699"><span id="cwquewm" class="tag"><li id="aaeqsyg" class="alt"><span id="akwokiq" class="keyword"><strong>void</strong></span><span> set_object_alignment() {     </span></li><li><span>  </span><span id="qkmwkio" class="comment"><font color="#008200">// Object alignment.    </font></span><span> </span></li><li id="mgacems" class="alt"><span>  assert(is_power_of_2(ObjectAlignmentInBytes), </span><span id="asuosyg" class="string"><font color="#0000ff">"ObjectAlignmentInBytes must be power of 2"</font></span><span>);     </span></li><li><span>  MinObjAlignmentInBytes     = ObjectAlignmentInBytes;     </span></li><li id="mycmqog" class="alt"><span>  assert(MinObjAlignmentInBytes >= HeapWordsPerLong * HeapWordSize, <br /></span><span id="oysugou" class="string"><font color="#0000ff">"ObjectAlignmentInBytes value is too small"</font></span><span>);     </span></li><li><span>  MinObjAlignment         = MinObjAlignmentInBytes / HeapWordSize;     </span></li><li id="ikmackq" class="alt"><span>  assert(MinObjAlignmentInBytes == MinObjAlignment * HeapWordSize, <br /></span><span id="ggkmouk" class="string"><font color="#0000ff">"ObjectAlignmentInBytes value is incorrect"</font></span><span>);     </span></li><li><span>  MinObjAlignmentInBytesMask = MinObjAlignmentInBytes - 1;     </span></li><li id="uewqmka" class="alt"><span>    </span></li><li><span>  LogMinObjAlignmentInBytes  = exact_log2(ObjectAlignmentInBytes);     </span></li><li id="usuwioo" class="alt"><span>  LogMinObjAlignment         = LogMinObjAlignmentInBytes - LogHeapWordSize;     </span></li><li><span>    </span></li><li id="amwauui" class="alt"><span>  </span><span id="gqcwqgo" class="comment"><font color="#008200">// Oop encoding heap max    </font></span><span> </span></li><li><span>  OopEncodingHeapMax = (uint64_t(max_juint) + 1) << LogMinObjAlignmentInBytes;     </span></li><li id="kuoysay" class="alt"><span>}     </span></li><li><span>    </span></li><li id="mgicwck" class="alt"><span id="wykmgwm" class="keyword"><strong>inline</strong></span><span> uintx max_heap_for_compressed_oops() {     </span></li><li><span>  </span><span id="cmyiukk" class="comment"><font color="#008200">// Avoid sign flip.    </font></span><span> </span></li><li id="swgseem" class="alt"><span>  </span><span id="ygcegou" class="keyword"><strong>if</strong></span><span> (OopEncodingHeapMax < MaxPermSize + os::vm_page_size()) {     </span></li><li><span>    </span><span id="egaceaq" class="keyword"><strong>return</strong></span><span> 0;     </span></li><li id="suwakui" class="alt"><span>  }     </span></li><li><span>  LP64_ONLY(</span><span id="mmqicaa" class="keyword"><strong>return</strong></span><span> OopEncodingHeapMax - MaxPermSize - os::vm_page_size());     </span></li><li id="ycgakay" class="alt"><span>  NOT_LP64(ShouldNotReachHere(); </span><span id="iuyaeua" class="keyword"><strong>return</strong></span><span> 0);     </span></li><li><span>}</span></li></span></font></span></code></code></font></code></code></div></div></div><!--<span id="ogkcoow" class="right ft12"><a href="#" target="_blank">转发此文到空?/a></span>--> <p>  Q注Q其?Quint64_tQmax_juintQ?+ 1Q?的g被称为NarrowOopHeapMaxQ也是2?2ơ方Q?x100000000Q?/p> <p>  ObjectAlignmentInBytes?4位HotSpot上默认ؓ8Q?/p> <p>  HeapWord在globalDefinitions.hpp里定义,大小跟一个char*一P</p> <p>  HeapWordSize在同一个文仉定义Q等于sizeofQHeapWordQ,?4位系l上gؓ8Q?/p> <p>  LogHeapWordSize也在同一文g里,?4位系l上定义?Q?/p> <p>  跟踪一下里面几个参数的计算Q在64位HotSpot上有Q?/p> <p>  C++代码</p> <div align="center"> <div class="ggikoou" id="dmk" align="center"> <div align="left"><code class="txcode"><code class="txcode"><font face="NSimsun"><code class="txcode"><code class="txcode"><span id="okeyacs" class="keyword"><font color="#006699"><span id="wyicgem" class="tag"> </span></font></span></code></code></font></code><ol class="dp-cpp"><code class="txcode"><font face="NSimsun"><code class="txcode"><code class="txcode"><font color="#006699"><li id="scegsyy" class="alt"><span>ObjectAlignmentInBytes = 8     </span></li><li><span>MinObjAlignmentInBytes = 8     </span></li><li id="mokewum" class="alt"><span>HeapWordSize = 8     </span></li><li><span>MinObjAlignment = 1     </span></li><li id="cysmssi" class="alt"><span>MinObjAlignmentInBytesMask = 0x0111     </span></li><li><span>LogMinObjAlignmentInBytes = 3     </span></li><li id="eqqkwum" class="alt"><span>LogHeapWordSize = 3 </span><span id="mqaugmu" class="comment"><font color="#008200">// _LP64    </font></span><span> </span></li><li><span>LogMinObjAlignment = 0     </span></li></font></code></code></font></code><li id="kmosusk" class="alt"><code class="txcode"><font face="NSimsun"><code class="txcode"><code class="txcode"><font color="#006699"><span>OopEncodingHeapMax = 0x800000000 </span><span id="gicyiqy" class="comment"><font color="#008200">// 32GB   </font></span><span> </span></font></code></code></font></code></li></ol></code></div></div></div><!--<span id="awismwc" class="right ft12"><a href="#" target="_blank">转发此文到空?/a></span>--> <p>  于是Q前面提到的W?个条件在64位HotSpot VM上默认是Q?/p> <p>  C++代码</p> <div align="center"> <div class="yqkoqgu" id="dmk" align="center"> <div align="left"><code class="txcode"><code class="txcode"><font face="NSimsun"><code class="txcode"><code class="txcode"><span id="wqamymu" class="keyword"><font color="#006699"><li id="mwiceus" class="alt"><span id="smysmca" class="tag"><span>MaxHeapSize + MaxPermSize + os::vm_page_size() <= 32GB</span></span></li></font></span></code></code></font></code></code></div></div></div><!--<span id="akoiksa" class="right ft12"><a href="#" target="_blank">转发此文到空?/a></span>--> <p>  osQ:vm_page_sizeQ)是操作系l的虚拟内存的分大,在Linux上等于sysconfQ_SC_PAGESIZEQ的|在x86_64上的Linux默认分页大小?KB.</p> <p>  MaxHeapSize的值基本上{于-Xmx参数讄的|会根据分大、对齐等因素做调_?/p> <p>  MaxPermSize是perm gen讄的最大大?/p> <p>  q下可以认Q在我现在用的环境里Q当包括perm gen在内的GC堆大在32GB - 4KB以下的时候,使用64位的JDK 6 update 23或更高版本就会自动开启UseCompressedOops功能<div><a >硫酸液下܇</a>17 <a >长u液下?/a>17 <a >氟塑料液下܇</a>?a >潜水甉|܇</a>54 <a >׃潜水?/a>23 <a >耐腐蚀液下?/a></div></p><p><br /></p><img src ="http://www.tkk7.com/cangshi004/aggbug/371120.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.tkk7.com/cangshi004/" target="_blank">cangshi</a> 2012-03-02 11:07 <a href="http://www.tkk7.com/cangshi004/archive/2012/03/02/371120.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>深入解析Java核心内容QJVM中的栈和局部变?/title><link>http://www.tkk7.com/cangshi004/archive/2012/02/29/370972.html</link><dc:creator>cangshi</dc:creator><author>cangshi</author><pubDate>Wed, 29 Feb 2012 02:52:00 GMT</pubDate><guid>http://www.tkk7.com/cangshi004/archive/2012/02/29/370972.html</guid><wfw:comment>http://www.tkk7.com/cangshi004/comments/370972.html</wfw:comment><comments>http://www.tkk7.com/cangshi004/archive/2012/02/29/370972.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.tkk7.com/cangshi004/comments/commentRss/370972.html</wfw:commentRss><trackback:ping>http://www.tkk7.com/cangshi004/services/trackbacks/370972.html</trackback:ping><description><![CDATA[<p><span style="font-family: 黑体">深入解析Java核心内容QJVM中的栈和局部变?br />        ȝ来说Q深入Java核心其实最主要包含个方面的内容QJVM中的栈和局部变?Java内存分配原理  Java垃圾回收机制  Java中多态的实现机制 </span></p> <p><strong>Java中的?/strong></p> <p>每当启用一个线E时QJVM׃ؓ他分配一个Java栈,栈是以为单位保存当前线E的q行状态。某个线E正在执行的ҎUCؓ当前ҎQ当前方法用的栈UCؓ当前帧,当前Ҏ所属的cȝ为当前类Q当前类的常量池UCؓ当前帔R池。当U程执行一个方法时Q它会跟t当前常量池?/p> <p>每当U程调用一个JavaҎӞJVM׃在该U程对应的栈中压入一个Q这个自然成了当前。当执行q个ҎӞ它用这个来存储参数、局部变量、中间运结果等{?/p> <p>Java栈上的所有数据都是私有的。Q何线E都不能讉K另一个线E的栈数据。所以我们不用考虑多线E情况下栈数据访问同步的情况?/p> <p>像方法区和堆一PJava栈和帧在内存中也不必是连l的,帧可以分布在q箋的栈里,也可以分布在堆里</p> <p><strong>Java栈的l成元素——栈</strong></p> <p>栈׃部分l成Q局部变量区、操作数栈、数据区。局部变量区和操作数栈的大小要视对应的方法而定Q他们是按字长计的。但调用一个方法时Q它从类型信息中得到此方法局部变量区和操作数栈大,q据此分配栈内存Q然后压入Java栈?/p> <p>局部变量区 局部变量区被组lؓ以一个字长ؓ单位、从0开始计数的数组Q类型ؓshort、byte和char的值在存入数组前要被{换成int|而long?double在数l中占据q箋的两,在访问局部变量中的long或doubleӞ只需取出q箋两项的第一的索引值即?如某个long值在局部变量区中占据的索引??,取值时Q指令只需取烦引ؓ3的long值即可?/p> <p>下面q个例子,好让大家对局部变量区有更深刻的认识。这个图来自《深入JVM》:</p><pre><ol class="dp-j"><li id="woiugom" class="alt"><span id="mwyswcs" class="keyword">public</span><span> </span><span id="eyimomc" class="keyword">static</span><span> </span><span id="oqcwyww" class="keyword">int</span><span> runClassMethod(</span><span id="mgsmgeu" class="keyword">int</span><span> i,</span><span id="gsugaoo" class="keyword">long</span><span> l,</span><span id="acmgsig" class="keyword">float</span><span> f,</span><span id="iiugyoe" class="keyword">double</span><span> d,Object o,</span><span id="awsmgem" class="keyword">byte</span><span> b) {     </span></li><li><span>        </span><span id="kmgqmak" class="keyword">return</span><span> </span><span id="akwgcag" class="number">0</span><span>;     </span></li><li id="isgamsi" class="alt"><span>    }     </span></li><li><span>         </span></li><li id="wgsmweu" class="alt"><span>    </span><span id="oquoqge" class="keyword">public</span><span> </span><span id="oqaeywo" class="keyword">int</span><span> runInstanceMethod(</span><span id="qsmyqiy" class="keyword">char</span><span> c,</span><span id="wgsueuk" class="keyword">double</span><span> d,</span><span id="oqskeku" class="keyword">short</span><span> s,</span><span id="uwycmsa" class="keyword">boolean</span><span> b) {     </span></li><li><span>        </span><span id="wykwywo" class="keyword">return</span><span> </span><span id="keyauki" class="number">0</span><span>;     </span></li><li id="woscgek" class="alt"><span>    }    </span></li></ol></pre> <p>上面代码片的Ҏ参数和局部变量在局部变量区中的存储l构如下图:</p> <p style="text-align: center"><a target="_blank"><img class="fit-image" alt="局部变量区的存储结? src="http://java.itwaka.com/UploadFiles_4554/201107/20110727145124188.jpg" border="0" height="263" width="498" /></a></p> <p>上面q个图没什么好说的Q大家看看就会懂。但是,在这个图里,有一炚w要注意:</p> <p>runInstanceMethod的局部变量区W一Ҏ个referenceQ引用)Q它指定的就是对象本w的引用Q也是我们常用的this,但是在runClassMethodҎ中,没这个引用,那是因ؓrunClassMethod是个静态方法?</p><br /> <p>操作数栈和局部变量区一P操作数栈也被l织成一个以字长为单位的数组。但和前者不同的是,它不是通过索引来访问的Q而是通过入栈和出栈来讉K的。可把操作数栈理解ؓ存储计算Ӟ临时数据的存储区域。下面我们通过一D늮短的E序片段外加一q图片来了解下操作数栈的作用?/p> <p>int a = 100;</p> <p>int b = 98;</p> <p>int c = a+b;</p> <p style="text-align: center"><a target="_blank"><img class="fit-image" alt="操作数栈的结? src="http://java.itwaka.com/UploadFiles_4554/201107/20110727145127435.jpg" border="0" height="207" width="477" /></a></p> <p>从图中可以得出:操作数栈其实是个时数据存储区域,它是通过入栈和出栈来q行操作的?/p> <p>帧数据区除了局部变量区和操作数栈外QJava栈q需要一些数据来支持帔R池解析、正常方法返回以及异常派发机制。这些数据都保存在Java栈的数据Z?br />当JVM执行到需要常量池数据的指令时Q它都会通过帧数据区中指向常量池的指针来讉K它?/p> <p>除了处理帔R池解析外Q里的数据q要处理JavaҎ的正常结束和异常l止。如果是通过return正常l束Q则当前栈从Java栈中弹出Q恢?a style="text-decoration: none" ><font color="black">ȝ钢液下܇</font></a>发v调用的方法的栈。如果方法又q回|JVM会把q回值压入到发v调用Ҏ的操作数栈?/p> <p>Z处理JavaҎ中的异常情况Q数据必须保存一个对此方法异常引用表的引用。当异常抛出ӞJVMlcatch块中的代码。如果没发现Q方法立即终止,然后JVM用区数据的信息恢复发v调用的方法的帧。然后再发v调用Ҏ的上下文重新抛出同样的异常?/p> <p><strong>栈的整个l构</strong></p> <p>在前面就描述q:栈是由栈帧组成,每当U程调用一个JavaҎӞJVM׃在该U程对应的栈中压入一个Q而是由局部变量区、操作数栈和帧数据区l成。那在一个代码块中,栈到底是什么Ş式呢Q下面是我从《深入JVM》中摘抄的一个例子,大家可以看看Q?/p> <p>代码片段Q?/p> <p style="text-align: left"><a target="_blank"><img class="fit-image" alt="栈的整个l构代码CZ" src="http://java.itwaka.com/UploadFiles_4554/201107/20110727145127354.jpg" border="0" height="213" width="451" /></a></p> <p> </p> <p>执行q程中的三个快照Q?/p> <p style="text-align: center"><a target="_blank"><img class="fit-image" alt="" src="http://java.itwaka.com/UploadFiles_4554/201107/20110727145127315.jpg" border="0" height="262" width="498" /></a></p> <p> </p> <p>上面所l的图,只想说明两g事情Q我们也可用此来理解Java中的栈:</p> <p>1、只有在调用一个方法时Q才为当前栈分配一个Q然后将该压入栈?/p> <p>2、中存储了对应Ҏ的局部数据,Ҏ执行完,对应的则从栈中弹出Qƈ把返回结果存储在调用Ҏ的的操作数栈中?/p><p><div><a >立式多?/a>34 <a >卧式多?/a>24 <a >多񔼛d?/a>41 <a >不锈钢多U܇</a>31 <a >水环真空?/a>32 <a >旋片真空?/a></div><br /></p><img src ="http://www.tkk7.com/cangshi004/aggbug/370972.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.tkk7.com/cangshi004/" target="_blank">cangshi</a> 2012-02-29 10:52 <a href="http://www.tkk7.com/cangshi004/archive/2012/02/29/370972.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>利用DES加密Java源码的原因应用分?/title><link>http://www.tkk7.com/cangshi004/archive/2012/02/09/369665.html</link><dc:creator>cangshi</dc:creator><author>cangshi</author><pubDate>Thu, 09 Feb 2012 05:34:00 GMT</pubDate><guid>http://www.tkk7.com/cangshi004/archive/2012/02/09/369665.html</guid><wfw:comment>http://www.tkk7.com/cangshi004/comments/369665.html</wfw:comment><comments>http://www.tkk7.com/cangshi004/archive/2012/02/09/369665.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.tkk7.com/cangshi004/comments/commentRss/369665.html</wfw:commentRss><trackback:ping>http://www.tkk7.com/cangshi004/services/trackbacks/369665.html</trackback:ping><description><![CDATA[<p>    加密利用QDES加密Java源码的原因应用分?br />  Java源代码经q编译以后在JVM中执行。由于JVM界面是完全透明的,JavacL件能够很Ҏ通过反编译器重新转换成源代码。因此,所有的法、类文g{都可以以源代码的Ş式被公开Q得Y件不能受C护,Z保护产权Q一般可以有以下几种ҎQ?/p> <p>  Q?Q?模糊"cLӞ加大反编译器反编译源代码文g的难度。然而,可以修改反编译器Q之能够处理这些模p类文g。所以仅仅依?模糊cL?来保证代码的安全是不够的?/p> <p>  Q?Q流行的加密工具Ҏ文gq行加密Q比如PGPQPretty Good PrivacyQ或GPGQGNU Privacy GuardQ。这Ӟ最l用户在q行应用之前必须先进行解密。但解密之后Q最l用户就有了一份不加密的类文gQ这和事先不q行加密没有什么差别?/p> <p>  Q?Q加密类文gQ在q行中JVM用定制的c装载器QClass LoaderQ解密类文g。Javaq行时装入字节码的机刉含地意味着可以对字节码q行修改。JVM每次装入cL件时都需要一个称为ClassLoader的对象,q个对象负责把新的类装入正在q行的JVM。JVMlClassLoader一个包含了待装入类Q例如java.lang.ObjectQ名字的字符Ԍ然后由ClassLoader负责扑ֈcLӞ装入原始数据Qƈ把它转换成一个Class对象?/p> <p>  用户下蝲的是加密q的cLӞ在加密类文g装入之时q行解密Q因此可以看成是一U即时解密器。由于解密后的字节码文g永远不会保存到文件系l,所以窃密者很隑־到解密后的代码?/p> <p>  ׃把原始字节码转换成Class对象的过E完全由pȝ负责Q所以创建定制ClassLoader对象其实q不困难Q只需先获得原始数据,接着可以进行包含解密在内的M转换?/p> <p>  Java密码体系和Java密码扩展</p> <p>  Java密码体系(JCA)和Java密码扩展(JCE)的设计目的是为Java提供与实现无关的加密函数API。它们都用factoryҎ来创建类的例E,然后把实际的加密函数委托l提供者指定的底层引擎,引擎中ؓcL供了服务提供者接口在Java中实现数据的加密/解密Q是使用其内|的JCE(Java加密扩展)来实现的。Java开发工具集1.1为实现包括数字签名和信息摘要在内的加密功能,推出了一U基于供应商的新型灵zd用编E接口。Java密码体系l构支持供应商的互操?同时支持g和Y件实现?/p> <p>  Java密码学结构设计遵循两个原?</p> <p>  (1)法的独立性和可靠性?/p> <p>  (2)实现的独立性和怺作用性?/p> <p>  法的独立性是通过定义密码服务cL获得。用户只需了解密码法的概?而不用去兛_如何实现q些概念。实现的独立性和怺作用性通过密码服务提供器来实现。密码服务提供器是实C个或多个密码服务的一个或多个E序包。Y件开发商Ҏ一定接?各U算法实现后,打包成一个提供器,用户可以安装不同的提供器。安装和配置提供?可将包含提供器的ZIP和JAR文g攑֜CLASSPATH?再编辑Java安全属性文件来讄定义一个提供器。Javaq行环境Sun版本? 提供一个缺省的提供器Sun?/p> <p>  下面介绍DES法及如何利用DES法加密和解密类文g的步骤?/p> <p>  DES法?/p> <p>  DESQData Encryption StandardQ是发明最早的最q泛使用的分l对U加密算法。DES法的入口参数有三个QKey、Data、Mode。其中Key?个字节共64位,是DES法的工作密钥;Data也ؓ8个字?4位,是要被加密或被解密的数据QMode为DES的工作方式,有两U:加密或解密?/p> <p>  DES法工作程如下Q若Mode为加密模式,则利用Key Ҏ据Dataq行加密Q?生成Data的密码Ş式(64位)作ؓDES的输出结果;如Mode密模式,则利用Key对密码Ş式的数据Dataq行解密Q还原ؓData的明码Ş式(64位)作ؓDES的输出结果。在<a ><font color="black">上v针型阀</font></a>通信|络的两端,双方U定一致的KeyQ在通信的源点用KeyҎ心数据进行DES加密Q然后以密码形式在公共通信|(如电话网Q中传输到通信|络的终点,数据到达目的地后Q用同样的Key对密码数据进行解密,便再C明码形式的核心数据。这P便保证了核心数据在公共通信|中传输的安全性和可靠性?/p> <p>  也可以通过定期在通信|络的源端和目的端同时改用新的KeyQ便能更q一步提高数据的保密性?br />  利用DES法加密的步?/p> <p>  Q?Q生成一个安全密钥。在加密或解密Q何数据之前需要有一个密钥。密钥是随同被加密的应用E序一起发布的一D|据,密钥代码如下所C?/p> <p>  【生成一个密钥代码?/p> <p>view plaincopy to clipboardprint?<br />// 生成一个可信Q的随机数?br />SecureRandom sr = new SecureRandom();<br />// 为我们选择的DES法生成一个KeyGenerator对象<br />KeyGenerator kg = KeyGenerator.getInstance ("DES" );<br />Kg.init (sr);<br />// 生成密钥<br />Secret Key key = kg.generateKey();<br />// 密钥数据保存ؓ文g供以后用,其中key FilenameZ存的文g?br />Util.writeFile (key Filename, key.getEncoded () );<br />// 生成一个可信Q的随机数?br />SecureRandom sr = new SecureRandom();<br />// 为我们选择的DES法生成一个KeyGenerator对象<br />KeyGenerator kg = KeyGenerator.getInstance ("DES" );<br />Kg.init (sr);<br />// 生成密钥<br />Secret Key key = kg.generateKey();<br />// 密钥数据保存ؓ文g供以后用,其中key FilenameZ存的文g?br />Util.writeFile (key Filename, key.getEncoded () );</p> <p>  Q?Q加密数据。得到密钥之后,接下来就可以用它加密数据。如下所C?/p> <p>  【用密钥加密原始数据?/p> <p> </p> <p>view plaincopy to clipboardprint?<br />// 产生一个可信Q的随机数?br />SecureRandom sr = new SecureRandom();<br />//从密钥文件key Filename中得到密钥数?br />Byte rawKeyData = Util.readFile (key Filename);<br />// 从原始密钥数据创建DESKeySpec对象<br />DESKeySpec dks = new DESKeySpec (rawKeyData);<br />// 创徏一个密钥工厂,然后用它把DESKeySpec转换成Secret Key对象<br />SecretKeyFactory key Factory = SecretKeyFactory.getInstance("DES" );<br />Secret Key key = keyFactory.generateSecret( dks );<br />// Cipher对象实际完成加密操作<br />Cipher cipher = Cipher.getInstance( "DES" );<br />// 用密钥初始化Cipher对象<br />cipher.init( Cipher.ENCRYPT_MODE, key, sr );<br />// 通过ȝ文g获取需要加密的数据<br />Byte data = Util.readFile (filename);<br />// 执行加密操作<br />Byte encryptedClassData = cipher.doFinal(data );<br />// 保存加密后的文gQ覆盖原有的cL件?br />Util.writeFile( filename, encryptedClassData );<br />// 产生一个可信Q的随机数?br />SecureRandom sr = new SecureRandom();<br />//从密钥文件key Filename中得到密钥数?br />Byte rawKeyData = Util.readFile (key Filename);<br />// 从原始密钥数据创建DESKeySpec对象<br />DESKeySpec dks = new DESKeySpec (rawKeyData);<br />// 创徏一个密钥工厂,然后用它把DESKeySpec转换成Secret Key对象<br />SecretKeyFactory key Factory = SecretKeyFactory.getInstance("DES" );<br />Secret Key key = keyFactory.generateSecret( dks );<br />// Cipher对象实际完成加密操作<br />Cipher cipher = Cipher.getInstance( "DES" );<br />// 用密钥初始化Cipher对象<br />cipher.init( Cipher.ENCRYPT_MODE, key, sr );<br />// 通过ȝ文g获取需要加密的数据<br />Byte data = Util.readFile (filename);<br />// 执行加密操作<br />Byte encryptedClassData = cipher.doFinal(data );<br />// 保存加密后的文gQ覆盖原有的cL件?br />Util.writeFile( filename, encryptedClassData );</p> <p> </p> <p>  Q?Q解密数据。运行经q加密的E序ӞClassLoader分析q解密类文g。操作步骤如下所C?/p> <p>  【用密钥解密数据?/p> <p>view plaincopy to clipboardprint?<br />// 生成一个可信Q的随机数?br />SecureRandom sr = new SecureRandom();<br />// 从密钥文件中获取原始密钥数据<br />Byte rawKeyData = Util.readFile( keyFilename );<br />// 创徏一个DESKeySpec对象<br />DESKeySpec dks = new DESKeySpec (rawKeyData);<br />// 创徏一个密钥工厂,然后用它把DESKeySpec对象转换成Secret Key对象<br />SecretKeyFactory key Factory = SecretKeyFactory.getInstance( "DES" );<br />SecretKey key = keyFactory.generateSecret( dks );<br />// Cipher对象实际完成解密操作<br />Cipher cipher = Cipher.getInstance( "DES" );<br />// 用密钥初始化Cipher对象<br />Cipher.init( Cipher.DECRYPT_MODE, key, sr );<br />// 获得l过加密的数?br />Byte encrypted Data = Util.readFile (Filename);<br />//执行解密操作<br />Byte decryptedData = cipher.doFinal( encryptedData );<br />// 然后解密后的数据{化成原来的类文g?br />// 生成一个可信Q的随机数?br />SecureRandom sr = new SecureRandom();<br />// 从密钥文件中获取原始密钥数据<br />Byte rawKeyData = Util.readFile( keyFilename );<br />// 创徏一个DESKeySpec对象<br />DESKeySpec dks = new DESKeySpec (rawKeyData);<br />// 创徏一个密钥工厂,然后用它把DESKeySpec对象转换成Secret Key对象<br />SecretKeyFactory key Factory = SecretKeyFactory.getInstance( "DES" );<br />SecretKey key = keyFactory.generateSecret( dks );<br />// Cipher对象实际完成解密操作<br />Cipher cipher = Cipher.getInstance( "DES" );<br />// 用密钥初始化Cipher对象<br />Cipher.init( Cipher.DECRYPT_MODE, key, sr );<br />// 获得l过加密的数?br />Byte encrypted Data = Util.readFile (Filename);<br />//执行解密操作<br />Byte decryptedData = cipher.doFinal( encryptedData );<br />// 然后解密后的数据{化成原来的类文g?/p> <p>  上qC码与自定义的c装载器l合可以做到边解密边运行,从而vC护源代码的作用?/p> <p>  l束?/p> <p>  加密/解密是数据传输中保证数据安全性和完整性的常用ҎQJava语言因其q_无关性,在Internet上的应用非常之广泛。用DES法加密Java源码在一定程度上能保护Y件的产权?/p> <p> </p><img src ="http://www.tkk7.com/cangshi004/aggbug/369665.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.tkk7.com/cangshi004/" target="_blank">cangshi</a> 2012-02-09 13:34 <a href="http://www.tkk7.com/cangshi004/archive/2012/02/09/369665.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Java如何通过q程Ҏ调用RMIhttp://www.tkk7.com/cangshi004/archive/2012/02/09/369645.htmlcangshicangshiThu, 09 Feb 2012 02:53:00 GMThttp://www.tkk7.com/cangshi004/archive/2012/02/09/369645.htmlhttp://www.tkk7.com/cangshi004/comments/369645.htmlhttp://www.tkk7.com/cangshi004/archive/2012/02/09/369645.html#Feedback0http://www.tkk7.com/cangshi004/comments/commentRss/369645.htmlhttp://www.tkk7.com/cangshi004/services/trackbacks/369645.htmlrmi的服务端Q必要使用接口Q同时还有接口的实现c!所以下面的两个文g是接口类和接口的实现c!

UserDao 接口Q?/p>

  1. /**  
  2.  * q程接口     必须l承与Remote对象  
  3.  * @author spring sky  
  4.  * date: 2012q???nbsp;10:55:05  
  5.  * Email:vipa1888@163.com  
  6.  * QQ:840950105  
  7.  */ 
  8. public interface UserDao extends Remote{  
  9.     /**  
  10.      * 单的试Ҏ  
  11.      * @param name  
  12.      */ 
  13.     public void sayName(String name) throws RemoteException;   
  14.  
  15.  

UserDaoImpl实现c?/p>

  1. /**  
  2.  *   
  3.  *  接口的实现类    必须l承UnicastRemoteObject(单一q程对象)   实现UserDao自己的接? 
  4.  * @author spring sky  
  5.  * date: 2012q???nbsp;10:56:05  
  6.  * Email:vipa1888@163.com  
  7.  * QQ:840950105  
  8.  */ 
  9. public class UserDaoImpl extends UnicastRemoteObject implements UserDao {  
  10.  
  11.     public UserDaoImpl() throws RemoteException {  
  12.     }  
  13.     @Override 
  14.     public void sayName(String name) {  
  15.         if(name!=null&&!name.equals(""))  
  16.         {  
  17.             System.out.println("我的名字是:"+name);  
  18.         }else{  
  19.             System.err.println("名字不ؓI?...");  
  20.         }  
  21.     }  
  22.  

对外的提供一个服务,服务中已l共享了urll外界访?/p>

  1. /**  
  2.  * 使用mainҎ启动一个服务,用于外界环境讉K  
  3.  * @author spring sky  
  4.  * date:2012q???nbsp;10:57:37  
  5.  * Email:vipa1888@163.com  
  6.  * QQ:840950105  
  7.  */ 
  8. public class StartService {  
  9.     private static final String IP = "127.0.0.1";  
  10.     private static final int PORT = 9999;  
  11.     private static final String REMOTE_NAME = "userDao";  
  12.     private static final String REMOTE_URL = "rmi://"+IP+":"+PORT+"/"+REMOTE_NAME;  
  13.     public static void main(String[] args) {  
  14.         try {  
  15.             UserDao userDao = new UserDaoImpl();    //实例化对? 
  16.             LocateRegistry.createRegistry(PORT);    //注册端口  
  17.             Naming.bind(REMOTE_URL, userDao);       //l定q程服务对象  
  18.             System.out.println("q程"+REMOTE_NAME+"启动成功....");  
  19.         } catch (RemoteException e) {  
  20.             System.err.println("q程对象出错");  
  21.             e.printStackTrace();  
  22.         } catch (MalformedURLException e) {  
  23.             System.err.println("URL出错?);  
  24.             e.printStackTrace();  
  25.         } catch (AlreadyBoundException e) {  
  26.             System.err.println("l定的对象已l存在了");  
  27.             e.printStackTrace();  
  28.         }  
  29.     }  

上面是服务端的代码,如果启动没有M问题Q就可以做客L讉K了,其实上v旋塞阀客户端的讉K更加的简单,只需要远E的接口cd查询rmi中的url可以了Q?/p>

代码如下Q?/p>

  1. /**  
  2.  * q程Ҏ调用试  
  3.  * @author spring sky  
  4.  * date:2012q???nbsp;11:12:46  
  5.  * Email:vipa1888@163.com  
  6.  * QQ:840950105  
  7.  * name:x? 
  8.  */ 
  9. public class TestRemote {  
  10.     public static void main(String[] args) {  
  11.         try {  
  12.             //在rmi服务中查询userdao的对? 
  13.             UserDao userDao = (UserDao) Naming.lookup("rmi://127.0.0.1:9999/userDao");     
  14.             //调用q程服务的方? 
  15.             userDao.sayName("spring sky");  
  16.         } catch (MalformedURLException e) {  
  17.             System.err.println("URL出错");  
  18.             e.printStackTrace();  
  19.         } catch (RemoteException e) {  
  20.             System.err.println("q程对象出错");  
  21.             e.printStackTrace();  
  22.         } catch (NotBoundException e) {  
  23.             System.err.println("没有扑ֈl定的对?);  
  24.             e.printStackTrace();  
  25.         }  
  26.     }  

以上是所有的rmiq程调用代码了!q行l果如下Q?/p>

好了Q本Z只是单的了解了rmiQ如果以后有目做rmi可以深入了Q?呵呵  Q在q里我突然感觉,想web service也应该和他一L原理的把Q?/p>




cangshi 2012-02-09 10:53 发表评论
]]>
JAVA J2ME~程 横竖屏切换知识ȝhttp://www.tkk7.com/cangshi004/archive/2012/02/07/369516.htmlcangshicangshiTue, 07 Feb 2012 02:53:00 GMThttp://www.tkk7.com/cangshi004/archive/2012/02/07/369516.htmlhttp://www.tkk7.com/cangshi004/comments/369516.htmlhttp://www.tkk7.com/cangshi004/archive/2012/02/07/369516.html#Feedback0http://www.tkk7.com/cangshi004/comments/commentRss/369516.htmlhttp://www.tkk7.com/cangshi004/services/trackbacks/369516.html随着手机的功能越来越丰富Q支持横竖屏切换的手来越多,在手Y件开发中也必要处理q个功能了。下面对于?strong>J2ME技术进行编E时对于横竖?转屏)切换时的相关知识q行一下小l?/p>

1、如何判断横竖屏切换

横竖屏切换由手机pȝ自动完成的,在J2ME中只能检到q种变换Q判断横竖屏切换的方法有2U:

A)U程中每ơ检法(轮询方式)

q种方式是在E序的线E中每隔一定的旉间隔Q就获得一ơ屏q的宽度和高度,然后判断宽度和高度是否变化,如果宽度和高度和已有的宽度和高度相比发生了变化,至于是变化成横屏q是竖屏则只需要比较宽高就可以实现。在判断到横竖屏切换Ӟ执行逻辑代码卛_?/p>

使用q种方式׃每次U程循环都需要检,所以执行效率不高,但是׃一些{屏手Z支持sizeChanged的方法回调,所以用这U方式的通用性是最高的Q是l常被用的Ҏ?/p>

B)sizeChanged?中断方式)

q种方式是指如果转屏手机对于MIDP支持比较规范Q则当横竖屏切换时会自动调用CanvascM的sizeChangedҎQ这样就需要在Canvas的子cM覆盖该方法即可,在该Ҏ内部书写横竖屏切换的逻辑处理代码卛_?/p>

使用q种方式׃是系l自动调用,所以执行效率很好,但是׃部分手机实现的不规范Q所以通用性没有第一U方式高?/p>

说明Q高U用L面自动切换,不需要书写处理的代码?/p>

2、如何处理横竖屏切换

在检到横竖屏切换以后,需要对于横竖屏切换q行处理了,处理的方式一般有也有两种Q?/p>

A)单提C法

q种处理方式时指只实CU屏q模式下的逻辑Q而在另外一U屏q方式下昄提示。例如只实现竖屏模式的界面,在横屏模式下Q只出现提示Q?#8220;请在竖屏模式下用本E序”?/p>

使用q种方式E序实现比较单,只需要实C套界面即可,适合于比较简单的E序?/p>

B)实现两套UI?/strong>

q种处理方式时指在一个程序中实现两套界面Q一套横屏一套竖屏。可以在E序中设|一个screenType的参敎ͼ在每个节目的l制上v늣阀Ҏ中根据该参数判断是横屏还是竖屏,然后执行不同的绘制代码即可?/p>

使用q种方式E序实现比较友好Q但是程序开发和试的工作量都要E微大一点,而且横竖屏切换时数据的变换也比较ȝ?/p>

3、其它说?/strong>

在实现横竖屏切换Ӟ有些知识会帮助你实现一些很实用的功能:

在Nokia手机上禁止横竖屏切换Q?/strong>

在S60 5th 及以上版本中Q可以通过在jad或manifest文g中通过指定如下属性来指定E序q行时的屏幕cdQ?/p>

竖屏QNokia-MIDlet-App-OrientationQportrait

横屏QNokia-MIDlet-App-OrientationQlandscape

不之处希望大家U极指正、交和完善Q?/p>




cangshi 2012-02-07 10:53 发表评论
]]>
在NetBeans Java ME polish环境下开发BlackBerry应用http://www.tkk7.com/cangshi004/archive/2012/02/03/369347.htmlcangshicangshiFri, 03 Feb 2012 14:32:00 GMThttp://www.tkk7.com/cangshi004/archive/2012/02/03/369347.htmlhttp://www.tkk7.com/cangshi004/comments/369347.htmlhttp://www.tkk7.com/cangshi004/archive/2012/02/03/369347.html#Feedback0http://www.tkk7.com/cangshi004/comments/commentRss/369347.htmlhttp://www.tkk7.com/cangshi004/services/trackbacks/369347.html  在网上广为流传的一份BlackBerry应用E序开发者指南里边详l介l如何用BlackBerry API开发BlackBerry application的各斚w内容?/p>

  但是我们一般都是用Java ME开发,开发出来的E序是jar格式Q可以运行在大部分型L手机上。可是BlackBerry是不支持jar的,它支持的是cod格式。所以如果你想你开发的Java MEE序q行在BlackBerry上,必d把它转ؓcod格式?/p>

  要把一般Java MEE序转ؓcod可以在程序开发编译过E序中{Q也可以Ҏ包好的jar转?/p>

  ◆对已l打包好的jar文g转ؓBlackBerrycod格式:q入jar文g所在目录,在cmd(命o?中进入相应目录,输入下边命o可以了Q引用rapc import="C:\Program Files\Research In Motion\BlackBerry JDE 4.2.1\lib\net_rim_api.jar" codename=TestBB jad=TestBB.jad TestBB.jar

  (注:q里rapc ?C:\Program Files\Research In Motion\BlackBerry JDE 4.2.1\bin\ 目录里的 rapc.exe, 如果环境变量没有讄Q这里就要用l对路径QC:\Program Files\Research In Motion\BlackBerry JDE 4.2.1\bin\rapc, 当然你可以把它写成一?bat文g来执行。而网上你可以搜烦C个名为Java2Cod.exe的小E序可以直接转换?

  ◆在JDE中编译程?无论你是用BlackBerry API或者Java ME/midp API来开发Java MEE序Q都可以在JDE上编译。最l他会自动打包成cod文g?/p>

  ◆在其IDE中编译打包:因ؓ我是用NetBeans来开发的Q所以本人只能提供NetBeans开发BlackBerryE序的见解。而本人是?NetBeans中用Java ME polish来整合开发的。下边介lJava ME polish中开发BlackBerryE序

  Q可以参?a rel="nofollow">http://www.j2mepolish.org/docs/platform-blackberry.htmlQ?/p>

  一、在Java ME polish安装目录里找到platforms.xml,在里边的BlackBerry部分中,加上<capability name="build.Finalizer" value="jar2cod" />Q我用的是Preview 2.0版本Q里边这一句是注释掉,所以要把它activateQ也可以在devices.xml中在你想用的emulator 属性里加上q一句。如果没有这一句编译时׃会自动把jar转换为cod文g?Q?/p>

  polish里支持的版本最新系4.2.0,如果你安装BlackBerry版本最新的?.2.1/4.3.0,哪么你要?{BlackBerry目录}/lib/net_rim_API.jar copy?{Java MEpolish}/import里,在platforms.xml的BlackBerry中修?lt;capability name="build.BootClassPath" value="net_rim_API.jar" />

  二、在工程的build.xml中添加blackberry.home属性(你安装的BlackBerry JDE目录Q?/p>

  Java代码

  1. <property        name="blackberry.home" 
  2.  location="C:/Program Files/Research In Motion/BlackBerry JDE 4.2.1" /> 

  三、如果你~译后打包的jad文g中缺MicroEdition-Configuration和MicroEdition-Profile两个属性是不能成功转成cod文g的。这可以在工E的build.xml中的<build>属性里?lt;jad>元素中添加:

  Java代码

  • <jad>     <attribute target="jad" name="
    MicroEdition-Configuration"
     value="CLDC-1.1" 
  • if="polish.cldc11"/>     <attribute target="jad" 
    name=
    "MicroEdition-Profile" value="MIDP-2.0"/>    
  • </jad>

  •   四、如果你用了h器的QobfuscatorQ,要把它unactivate,不要用它Q因为BlackBerry中的rapc转换q程中会对程序؜淆的?/p>

      Java代码

  • <obfuscator name="ProGuard" unless="test or polish.blackberry" >    
  • </obfuscator>
  •   五、在工程的build.xml中的<Java MEpolish>属性requirements用你想编译的BlackBerryemulator,如:

      Java代码

  • <deviceRequirements>      
    <requirement name="Identifier" value="BlackBerry/8800" />              
  • </deviceRequirements>
  •   如果你的E序是一般的Java MEE序Q那么就可以~译q行了。但如果你是用BlackBerry API开发的上v柱塞阀Q就要就把build.xml?lt;build>元素中的<midlet>,改ؓ<main>Q同时要dpolish.classes.midlet-1的variable。如Q?/p>

      Java代码

  • <!-- midlets definition -->   
    <main 
    class="com.protel.BlackBerryim.ui.BlackBerryIMMidlet" />     
  • <!-- project-wide variables - used for preprocessing  -->   
    <variables> <variable name=
    "polish.classes.midlet-1" value=" " />    
  • </variables>
  •   (注:polish.classes.midlet-1的value? "Q中间有一个空格的Q我试过了,如果没有q个定义变量或者这个g间没有空|jar是不能{为cod格式?

      q是我初接触BlackBerry时的一点心得。我用BlackBerry API在NetBeans+Java ME polish的环境下写过一个test appQ是能成功运行的Q希望对初接触BlackBerry的朋友有帮助?/p>

     


     



    cangshi 2012-02-03 22:32 发表评论
    ]]>
    如何通过Java调用C/C++~写W三方dll动态链接库解决Ҏ分析http://www.tkk7.com/cangshi004/archive/2012/02/02/369270.htmlcangshicangshiThu, 02 Feb 2012 14:44:00 GMThttp://www.tkk7.com/cangshi004/archive/2012/02/02/369270.htmlhttp://www.tkk7.com/cangshi004/comments/369270.htmlhttp://www.tkk7.com/cangshi004/archive/2012/02/02/369270.html#Feedback0http://www.tkk7.com/cangshi004/comments/commentRss/369270.htmlhttp://www.tkk7.com/cangshi004/services/trackbacks/369270.html如何通过Java调用C/C++~写W三方dll动态链接库解决Ҏ分析?br />最q在用weka做一个数据挖掘相关的目Q不得不_wekaq是一个不错的开放源代码库,提供了很多最常用的分cd聚类法?/p>

    在我的项目中要用C个聚cȝ法,Affinity PropagationQAPQ,由多伦多大学的Brendan J. Frey发表?007q。相比其他的聚类法QAP法的聚cȝ果更加准?/p>

    在AP的官方网站公布了AP法的动态链接库Q我的目标就是实现在Java工程中调用这个动态链接库?/p>

    在网上查了资料,发现Q如果仅仅是惌用Windows的Native APIq是比较省事的,q里我主要针对第三方dll的调用?/p>

    下面q入正题?/p>

    q里主要用的Ҏ是JNI。在|上查资料时看到很多用JNI非常的复杂,不仅要看很多的文,而且要非常熟悉C/C++~程。恐怕有很多人在看到诸如此类的评论时已经军_l道用其他方法了。但是,假如你要实现的功能ƈ不复杂(单的参数传递,获取q回值等{)Q我q是支持使用q个Ҏ的?/p>

    Java Native InterfaceQ简UJNIQ是Javaq_的一部分Q可用于让Java和其他语a~写的代码进行交互。下面是从网上摘取的JNI工作C意图?/p>


    ? JNI的工作模?/p>

    下面׃D具体的例子说明一下用步骤:

    1Q?~写一个类Q声明nativeҎ

    1. public class APCluster {   
    2.     public native int[] CallAPClusterDll( int         arg_Int,   
    3.                                           double[]    arg_DoubleArray,   
    4.                                           boolean     arg_boolean);  
    5.     static 
    6.     {  
    7.         System.loadLibrary("APClusterDllMedium");  
    8.     }  

    上面是APCluster.java文gQ定义了一个APClusterc,其中有一个方法CallAPClusterDll()Q需要传递三U不同类型的参数Qƈ且返回一个整型数l?/p>

    注意Q这里只需要声明这个方法,q不需要实玎ͼ具体实现在APClusterDllMedium中?/p>

    APClusterDllMedium像中介一PJava通过调用q个中介Dll中的CallAPClusterDllҎQ间接调用真正的W三方Dll?/p>

    2Q编译生?h文g

    W一步:

    javac APCluster.java 生成APCluster.class

    W二步:

    javah APCluster 生成APCluster.h头文Ӟ内容如下Q?/p>

    1. /* DO NOT EDIT THIS FILE - it is machine generated */ 
    2. #include <jni.h>  
    3. /* Header for class APCluster */ 
    4. #ifndef _Included_APCluster  
    5. #define _Included_APCluster  
    6. #ifdef __cplusplus  
    7. extern "C" {  
    8. #endif10 /*  
    9.  * Class:     APCluster  
    10.  * Method:    CallAPClusterDll  
    11.  * Signature: (I[DZ)[I  
    12.  */ 
    13. JNIEXPORT jintArray JNICALL Java_APCluster_CallAPClusterDll  
    14.   (JNIEnv *, jobject, jint, jdoubleArray, jboolean);  
    15. #ifdef __cplusplus  
    16. }  
    17. #endif21
    18. #endif 

    注意QAPCluster.hq个头文件的内容是不能修改的Q否则JNI会找不到相对应的CallAPClusterDll()的实现?/p>

    3Q创建C/C++工程Q实现CallAPClusterDll()Ҏ?/strong>

    创徏一个C/C++工程Q工E名为APClusterDllMediumQ其实,生成的dll名ؓAPClusterDllMedium卛_Q,导入APCluster.hq个头文Ӟq创Z个CPP文gQ实?h文g中的Ҏ?/p>

     
    ? 新徏工程l构

    ׃我创建的工程是win32控制台程序,所以最后默认生成的?exe文gQ所以还要做一步工E属性修改,让它生成.dll后缀文g?/p>

    打开Project Property ->GeneralQ做以下修改Q?/p>

     
    ? 修改工程属?/font>

    下面是实现 JNIEXPORT jintArray JNICALL Java_APCluster_CallAPClusterDll (JNIEnv *, jobject, jint, jdoubleArray, jboolean); q个Ҏ了。先贴代码再慢慢解释吧?/p>

    1. #include "APCluster.h"   
    2. #include <stdio.h>   
    3. #include <windows.h>  
    4. #ifdef __cplusplus   
    5. extern "C" {  
    6. #endif  
    7. typedef int*  (__stdcall *APCLUSTER32)(double*, unsigned int, bool);  
    8. JNIEXPORT jintArray JNICALL Java_APCluster_CallAPClusterDll  
    9.   (JNIEnv *env, jobject _obj, jint _arg_int, jdoubleArray _arg_doublearray, jboolean _arg_boolean)  
    10. {  
    11.     HMODULE dlh = NULL;  
    12.     APCLUSTER32 apcluster32;  
    13.     if (!(dlh=LoadLibrary("apclusterwin.dll")))        //W三方DLL位置  
    14.     {  
    15.         printf("LoadLibrary() failed: %d\n", GetLastError());   
    16.     }  
    17.     if (!(apcluster32 = (APCLUSTER32)GetProcAddress(dlh, "apcluster32")))    //具体调用apcluster32Ҏ  
    18.     {  
    19.         printf("GetProcAddress() failed: %d\n", GetLastError());   
    20.     }  
    21.     int        m_int = _arg_int;  //cd转换  
    22.     double*    m_doublearray = env->GetDoubleArrayElements(_arg_doublearray, NULL);  
    23.     bool       m_boolean = _arg_boolean;  
    24.     int* ret = (*apcluster32)(m_doublearray, m_int, m_boolean); /* actual function call */ 
    25.     jintArray result = env->NewIntArray(_arg_int);  
    26.     env->SetIntArrayRegion(result, 0, _arg_int, (const jint*)ret);  
    27.     FreeLibrary(dlh); /* unload DLL and free memory */ 
    28.     if(ret)   
    29.     {  
    30.          free(ret);   
    31.     }  
    32.     return result;  
    33. }  
    34. #ifdef __cplusplus  
    35. }  
    36. #endif 

    aQ首先ؓ?include <jni.h>Q必L加JNI所在的目录?/p>

    打开Project Property -> C/C++ -> General -> Additional Include Directoriesd相应目录Q?/p>

     
    ? dJNI目录

    bQ在APCluster.h文g中自动生成的函数Q只标识了函数参数类型,Z引用q些参数Q自pv一个相应的名字Q?/p>

    JNIEXPORT jintArray JNICALL Java_APCluster_CallAPClusterDll
    (JNIEnv *env, jobject _obj, jint _arg_int, jdoubleArray _arg_doublearray, jboolean _arg_boolean) ......

    cQ声明函数指针,是你要调用的第三方dll中函数的cd?/p>

    dQLoadLibraryQ导入真正的W三方DllQƈ扑ֈ要调用的Ҏ的函数地址?/p>

    把这个函数地址赋值给函数指针Q接下来可以通过q个函数指针调用真正的apcluster函数了!

    eQ类型{换:

    读读jni.h文gq道jdouble和double其实是一个东西,jboolean是unsigned charcdQjni.h中是q么声明的:

    1. typedef unsigned char    jboolean;  
    2. typedef unsigned short   jchar;  
    3. typedef short            jshort;  
    4. typedef float            jfloat;  
    5. typedef double           jdouble; 

    但是数组cd没有这么简单,获取数组要用类型相对应的env->GetTypeArrayElement(jTypeArray...)?/p>

    最后,要返回一个jintcd的数l,p新创Z个此cd的数l,再ؓ其赋|

    1. jintArray result = env->NewIntArray(_arg_int);  
    2. env->SetIntArrayRegion(result, 0, _arg_int, (const jint*)ret); 

    其中Q_arg_int代表的是创徏数组的长度?/p>

    最后return result?/p>

    4QBuildq个工程?/strong>

    BuildQ生成相应的APCluster.dll文gQ将q个dll攑ֈjava工程目录下?/p>

     
    ? 生成的dll攑ֈjava工程?/p>

    5Q编写测试javaE序Q调用dll库?/strong>

    以下为测试程序,Test.javaQ?/p>

    1. public class Test    
    2. {  
    3.     public static void main(String[] args)   
    4.     {   
    5.         double     arg_doublearray[] = {0.10.20.3};   
    6.         int        arg_int = 3;   
    7.         boolean    arg_boolean = true;   
    8.         int[]  result = new APCluster().CallAPClusterDll(arg_int, arg_doublearray, arg_boolean);  
    9.         .....  
    10.     }  

    到此Qjava调用W三方dll基本完成了?/p>

    本文也主要是介绍大概的操作流E,至于具体应该使用哪些API只有去研究官方文了?/p>

    另外q有一些需要注意的问题Q比?4位的E序去调?2位的dll会报错啊{等...q些都是l节问题了?/p>

    最后,个h认ؓQ自己动手实践还是很重要Q网上都说这个复杂那个难Q但是至于难q是不难Q还是要实践了才知道...不能不去试...



    cangshi 2012-02-02 22:44 发表评论
    ]]>
    վ֩ģ壺 fc2ѹƵվ| һ| ëƬAV뾫Ʒҹ| ˵ĺÿѹۿƵ | ŮɫëƬѿ| ѾþþƷƬ㽶| ҳڻӭ| ޾ƷŮ߹ۿ| Ůˬ̼ƵѲ| ޳_վͼƬ| Ů߿ѹۿ| ɫһëƬ| 츾AVһ˳| ޳aƬ߲| 㶮ַѹ| þþƷAV뽿ɫ| 1000Ƶ| պAVһ| ޾ƷƵ߿| ҹվ߹ۿۿ | һ| ձѹۿ| ֮4δɾ| ƷۺϾþ| www77777| Ůרhd| ޹˳߹ۿ| ޾߹ۿ| avպavۺ| þ99޸ۿҳ| ҳվ߿| Ƶ˻վƵ| ԴԴѹۿ| ޾Ʒ㶮| ޹Ʒۿþ| ޾Ʒѹۿ| ڵƵ| ˾վ߹ۿ| ۲ӰԺ߲wwwѹۿ| ɫ͵͵޵һۺ| һaƬþëƬ|