Weighing in on Java native compilation

via_wizard ViaWizard3.1_setup 立即下载
Weighing in on Java native compilation
Discuss 74KB e-mail it!
Contents:
Code compilation basics
About the test setup
Test 1: Prime.java
Test 2: SciMark 2
Pros and cons
Conclusion
Resources
About the author
Rate this article
Related content:
Bridging the gap to COM
Debugging integrated Java and C/C++ code
Subscriptions:
dW newsletters
dW Subscription
(CDs and downloads)
The pros and cons of generating native code from Java source

Martyn Honeyford (martynh@uk.ibm.com)
Software Engineer, IBM UK Labs
01 Jan 2002

When it was first introduced, it seemed that Java native compilation would surely topple the JVM, taking with it the Java platform's hard-fought platform independence. But even with its growing popularity and the increasing number of native compilers on the market, native compilation has a way to go before it poses a real threat to Java code's portability. Unfortunately, it also may be a while before the technology is mature enough to resolve the Java performance issues so many of us struggle with today. Share your thoughts on this article with the author and other readers in the discussion forum by clicking Discuss at the top or bottom of the article.

Despite its many high points, there are still several issues with the Java language that rule out its use in key projects. These include execution speed, memory footprint, disk footprint, and JVM availability. JIT compilers do much to improve the platform's execution speed and J2ME greatly reduces its memory footprint, but in many domains Java applications simply cannot compete with their native (typically C/C++) counterparts. To resolve these problems, many developers have turned to Java native compilers, which allow applications to be written in the Java language and then compiled into native executables. This solution will cost you in terms of platform independence, but it can result in the faster execution and smaller footprint essential to so many of today's applications.

To bring you up to speed on Java native compilation technology, we'll start with a discussion of the basics of code compilation, including a brief overview of why many developers are employing Java native compilers for their applications. Next, we'll test the results of Java native compilation, using a free software compiler and two different applications (one very simple, the other more sophisticated). These examples and the resulting metrics will serve as a first-hand look at how the recent Java native compilers compare with the JVM.

Code compilation basics
To follow the discussion in this article, you should be familiar with the three most common methods of code compilation:

  • Compiling Java code with a Java compiler such as javac

  • Compiling native code such as C/C++ targeted to a specific hardware/operating system (OS) platform

  • Compiling Java code using a Java native compiler targeted to a specific hardware/OS platform

Compiling Java code using a Java compiler is straightforward. We simply write the source code in the Java language, use a Java compiler to compile the source into Java bytecode, and execute the results on any hardware/OS platform that has a JVM installed. Java's reliance on the JVM for its signature "write once, run anywhere" portability is its downside; not only must a JVM be available for any platform on which you want to run your Java apps, but there must be significant system resources (memory and disk space) to support that JVM. As a result, many developers continue to rely on less flexible but more targeted languages such as C/C++.

Compiling source in C/C++ is similar to doing so in Java. Once the code is written, we run it through a compiler and linker targeted to a specific hardware/OS platform. The resulting application will be executable only on the targeted platform, but will not require that a JVM be installed (though it may require some supporting shared libraries, depending on language used). All but the most simple applications developed using this method must be tailored individually to each hardware/OS platform on which you want them to run.

The third method attempts to bridge the best of each of the above solutions, allowing developers to write applications in the Java language and compile them into native executables. Once the Java code is written, it can be run through a Java compiler to produce Java bytecode, which is then compiled into native code, or it can be run directly into a Java native compiler. The number of steps involved depends on the requirements of the compiler used.

The advantage of this approach is that the resulting code can be executed on the targeted platform without the JVM. This is intended to result in Java applications that execute at much improved speeds and require significantly less disk space and memory to run (though it may be necessary to provide supporting libraries for the Java native compiler).

Compilers vary in the platforms they target, the level of Java support they provide, and the amount of system resources they use. You'll find a listing of some of the currently available native compilers in this article's Resources section.

About the test setup
It is well beyond the scope of this article to compare the features and performance of every native compiler on the market. Instead, I've used one compiler, the GNU Compiler for the Java Programming Language (GCJ), as an example to detail the process and results of native compilation. GCJ is one of the compilers developed for the GNU Compiler Collection (GCC), which is part of the GNU project. As is true of all the software that comes out of the GNU project, GCJ is free software in both senses of the term, and therefore can easily be obtained (see Resources). If you're seriously considering the native compilation route for your product, you should obviously evaluate as many compilers as you can, perhaps using the criteria established in this article.

My test system hardware consists of a PC with a Pentium II processor running at 450 MHz and containing 320 MB of memory. The OS is a recent install of the Mandrake 8.1 Linux distribution. This distribution comes with version 3.0.1 of GCJ, which is included in GCC 3.0.1 and ships as part of the 8.1 Mandrake distribution.

I've run two separate applications, one very simple and one that is more complex. To compare the system's performance against that of the Java platform, I compiled the applications into Java bytecode. I compiled the Java code using the Sun JDK version 1.3.1.02 for Linux, then tested the resulting class on the following JVMs:

  • Kaffe 1.0.6

  • Sun JVM 1.3.1_02

  • IBM JRE 1.3.1

For the purpose of this article, I've measured execution speed, execution memory overhead, and disk space.

Test 1: Prime.java
The first test application is very simple, consisting of a single class, prime.java. This application implements a very basic algorithm to search for prime numbers. Listing 1 shows the source code for prime.java.


import java.io.*;
class prime 
{
   private static boolean isPrime(long i)
   {
       for(long test = 2; test < i; test++)
       {
     if(i%test == 0)
     {
    return false;
     }
       }       
       return true;
   }

   public static void main(String[] args) throws IOException 
   {
       long start_time = System.currentTimeMillis();

       long n_loops =  50000;
       long n_primes = 0;

       for(long i = 0; i < n_loops; i++)
       {
     if(isPrime(i))
           {
         n_primes++;
           }
       }
   
       long end_time = System.currentTimeMillis();

       System.out.println(n_primes + " primes found");       
       System.out.println("Time taken = " + (end_time - start_time));
   }
}

As you can see, the code loops from 0 to 50000. As it goes, it attempts to divide each number it encounters by every number up to itself, to find out if there is a remainder. (This is, admittedly, the brute-force method of ferreting out primes, but it will suffice for the example.)

I compiled prime.java into a native executable with the command:

gcj prime.java -O3 --main=prime -o prime

The argument -O3 means "optimize for speed"; argument --main tells GCJ which class contains the main method to be used when the application is run; and argument -o Prime names the resulting executable. For a full set of command-line arguments, see the GCJ documentation.

To compile the Java bytecode test, I used the command:

/usr/java/jdk1.3.1_02/bin/javac -O prime.java

Next, I invoked the code for each of our test JVMs, using the following commands:

  • Native: ./prime

  • Kaffe: /usr/bin/java prime

  • Sun JDK: /usr/java/jdk1.3.1_02/bin/java prime

  • IBM JRE: /opt/IBMJava2-13/jre/bin/java prime

Test results for prime.java
As previously mentioned, I tested for execution speed, memory use, and disk space use. The following tables detail the results of the first test.

Table 1. Prime.java: Execution speed

ImplementationTime in milliseconds (average of three runs -- lower score is better)
Native40180
Kaffe75456
Sun JDK67315
IBM JRE18188

Table 2. Prime.java: Memory usage

ImplementationVM size (KB) VM RSS (KB)
Native70243528
Kaffe88883564
Sun JDK1695606636
IBM JRE819366288

Note that the VM size equals the total size of the image of the process. This includes all code, data, and shared libraries used by the process, including pages that have been swapped out. VM resident set size (RSS) is equal to the size of the part of the process (code and data) that actually resides in RAM, including shared libraries. This gives a fair approximation of how much RAM a process is using.

In simple terms, if a process allocates a large amount of memory it will show up in the VM size, but it won't show up in VM RSS until it is actually being used (for example, read or written). VM RSS is actually the more important measure, because it gives a greater indication of the performance hit on the system.

Table 3. Prime.java: Disk space usage

ImplementationTotal compiled size (bytes)
Native 22268
Java classes962

Note that the measurements shown in Table 3 exclude shared libraries and the JVM, and are measured with the executable stripped.

Test 2: SciMark 2
For the second test I employed a more complicated Java application, the SciMark 2 Java benchmark. The command-line version used for this article is available for free (see Resources). SciMark 2 is quite a sophisticated application. It implements a number of benchmarks that are intended to accurately measure the efficiency of a JVM.

I used the following command to compile SciMark 2 into a native executable:


gcj-3.0.1 -O3 commandline.java Random.java FFT.java SOR.java Stopwatch.java 
  SparseCompRow.java LU.java kernel.java MonteCarlo.java 
    --main=jnt.scimark2.commandline -o scimark

And I used this command to compile the application into Java bytecode:


/usr/java/jdk1.3.1_02/bin/javac -O *.java

The SciMark 2 benchmark can be run in two modes, normal and large. The mode you use determines the size of the problem sets used. I've run the tests in both modes.

To invoke the code in normal mode, I used the following commands:

  • Native: ./scimark

  • Kaffe: /usr/bin/java jnt.scimark2.commandline

  • Sun JDK: /usr/java/jdk1.3.1_02/bin/java jnt.scimark2.commandline

  • IBM JRE: /opt/IBMJava2-13/jre/bin/java jnt.scimark2.commandline

For the larger problem sets I used these commands:

  • Native: ./scimark -large

  • Kaffe: /usr/bin/java jnt.scimark2.commandline -large

  • Sun JDK: /usr/java/jdk1.3.1_02/bin/java jnt.scimark2.commandline -large

  • IBM JRE: /opt/IBMJava2-13/jre/bin/java jnt.scimark2.commandline -large

Test results for SciMark 2
The following tables show the results of compiling SciMark 2. Note the difference in results for the normal and large modes.

Table 4. SciMark 2, mode normal: Execution speed

ImplementationComposite score (average of three runs -- higher score is better)
Native15.22
Kaffe7.01
Sun JDK22.86
IBM JRE25.29

Table 5. SciMark 2, mode normal: Memory usage

ImplementationVM size (KB) VM RSS (KB)
Native97885956
Kaffe88884092
Sun JDK1696927428
IBM JRE819647408

Table 6. SciMark 2, mode large: Execution speed

ImplementationComposite score (average of three runs -- higher score is better)
Native8.78
Kaffe5.72
Sun JDK12.04
IBM JRE15.04

Table 7. SciMark 2, mode large: Memory usage

ImplementationVM size (KB) VM RSS (KB)
Native6288859072
Kaffe5805656988
Sun JDK16969264624
IBM JRE8196457704

Table 8. SciMark 2: Disk space usage for both modes

ImplementationCompiled size (bytes)
Native49588
Java Classes16318

Once again, the measurements in Table 8 exclude shared libraries and the JVM, and are measured with the executable stripped.

Pros and cons of native compilation
As should be apparent from the above test results, the success or failure of Java native compilation is far from clear cut. Some of the benchmarks show the natively compiled executables to be faster than some of the JVM versions; others are slower. Similarly, the speed of some operations varies wildly between different JVMs. The "working set" memory tests performed show that there isn't a vast amount of difference in the memory usage during execution. Tests employing different garbage collection schemes on both the native and JVM tests could further explore this area.

The native version is a clear winner over the JVM version only when it comes to disk space, and this is true only when the size of the JVM is taken into account. While the classes themselves are very small, the JVMs tested were huge (a recursive directory listing in the jre subdirectory of both the IBM and Sun JVMs shows that the JREs alone take up over 50 MB of disk space). But bear in mind that there are much smaller JVMs available and, while the combination of JVM and a single application was much larger than that of a native executable and the GCJ runtime library, libgcj.so (which is under 3 MB), the executable size for the native version was much larger. Thus, in situations where a large number of applications are required, the JVM version may ultimately be the winner.

In addition to these somewhat nebulous results, a number of potential problems can arise from the use of Java native compilers. They are as follows:

  • Loss of platform independence: In reality, this isn't so much of a problem. Because the source is written in the Java language, you still have the option to produce a Java bytecode version that will run anywhere, then use native compilers on certain platforms as required.

  • Class support/compiler maturity: Some of the compilers are still relatively immature and may not support all the Java classes required by your application. For example, while GCJ supports most Java language constructs up to v1.1 of the specification, it doesn't support all the Java class libraries that typically ship with a JVM. Most notably, there is very little support for AWT, making GCJ unsuitable for GUI applications. Different compilers support differing levels of class library; Excelsior JET is one compiler that claims to completely support AWT and Swing.

  • Support/complexity: As this field is a relatively new one, it is often not very well understood by developers. Diagnostic tools can be somewhat thin on the ground, which makes it potentially more difficult to diagnose problems that occur in natively compiled Java apps (particularly if the error doesn't occur in the Java bytecode version!).

Conclusion
As is generally the case when it comes to application development, the only way to really determine if Java native compilation is the answer to your particular set of circumstances is to run through a problem-solving cycle:

  1. Determine exactly what problem (or problems) you are hoping to solve with native compilation.

  2. Take a look at the available native compilers and come up with a handful that look like they could solve your problem.

  3. Try all the compilers you've selected with your application and see what happens.

Despite the relative immaturity of the technology and the lack of clear-cut results, Java native compilation is an exciting new area for the Java language. The best way to take advantage of the existing options is to research and test them yourself, perhaps using some of the methods and criteria established in this article.

While native compilation isn't the JVM killer that many people thought it would be, it has proven to be just the right solution for some applications and environments. Native compilation extends the use of Java language into domains where it simply wasn't applicable just a few short years ago. This can only be a good thing for the Java language and for the Java community as a whole.

Resources

  • Participate in the discussion forum on this article. (You can also click Discuss at the top or bottom of the article to access the forum.)

  • To learn more about GCJ and the GNU Compiler Collection, visit the GNU Compiler for the Java Programming Language homepage.

  • SciMark 2.0 is a composite Java benchmark for measuring the performance of numerical code in scientific and engineering applications. See the SciMark 2.0 home page to learn more about this sophisticated application.

  • Learn how to reuse code that wasn't written in the Java language in "Bridging the gap to COM" (developerWorks, October 2001).

  • When you cannot employ a pure Java language solution in an application, you can still effectively debug the Java/C hybrid. Matthew White explains how in "Debugging integrated Java and C/C++ code" (developerWorks, November 2001).

  • Find more Java resources on the developerWorks Java technology zone.

About the author
Martyn Honeyford graduated from Nottingham University with a BS in Computer Science in 1996. He has worked as a software engineer at IBM UK Labs in Hursley, England, ever since. His current role is as a developer in the WebSphere MQ Everyplace development team. When not working, Martyn can usually be found either playing the electric guitar (badly) or playing video games more than most people would consider healthy. You can contact Martyn at martynh@uk.ibm.com.
e-stage 6.6 制作3d模型支撑时,必备工具。 3D打印机的完美搭配,Materialise Magics。 3D打印magics 21对接e-stage 6.6实现一键自动加支撑 立即下载

相关推荐

程序员实战:DINOv3 权重文件下载与本地化部署全流程指南

Meta开源的DINOv3视觉大模型凭借70亿参数和17亿图像训练,在语义分割、目标检测等任务表现优异。本文详解预训练权重的获取渠道、校验方法和加载实践。开发者可通过HuggingFace或GitHub获取不同版本权重,包括针对服务器端的ViT系列和边缘设备的ConvNeXt系列。文章提供MD5校验代码确保文件完整性,并给出PyTorch和Transformers两种加载方式。特别强调7B模型需16GB GPU内存,建议根据硬件条件选择合适版本,如边缘设备使用ConvNeXt-Tiny。最后指出DINOv3

xiugou3365的博客 5903

android 18 footjob,Android 8/9 default trust manager: OOM when getting "https://icloud.com"

When using okhttp (which uses the platform default custom manager, which seems to be provided by Conscrypt) to GET (or PROPFIND) https://icloud.com (without www) with code like that:// compileSdkVersi...

weixin_39927508的博客 43万+

Kettle安装与使用

Pentaho Data Integration作为一个端对端的数据集成平台,可以对多种数据源进行抽取(Extraction)、加载(Loading)、数据落湖(Data Lake Injection)、对数据进行各种清洗(Cleasing)、转换(Transformation)、混合(Blending),并支持多维联机分析处理(OLAP)和数据挖掘(Data mining)。勺子(spoon.bat/spoon.sh):是一个图形化的界面,可以让我们用图形化的方式开发转换和作业。

jnrjian的博客 1万+

EuroLLVM’19 developers’ meeting program

EuroLLVM’19 developers’ meeting program The LLVM Foundation is excited to announce the program for the EuroLLVM’19 developers’ meeting (April 8 - 9 in Brussels / Belgium) ! Keynote MLIR: Multi-Le...

ronnie88597的博客 3520

MTK平台TP驱动设备树与GPIO配置实战解析

本文详细解析了MTK平台TP驱动开发中的设备树与GPIO配置实战。通过DCT工具配置GPIO引脚,结合设备树节点定义触摸参数,并分享驱动移植、编译调试技巧及常见问题解决方案,帮助开发者快速掌握MTK触摸驱动开发核心。

ice55的博客 233

从‘静态拍照’到‘动态录像’:用Malmquist指数讲好你的效率变化故事(附Stata/R代码)

本文深入探讨了如何利用Malmquist指数构建动态效率分析框架,从静态数据到动态叙事的转变。通过分解技术效率变化(EC)和技术进步(TC),结合Stata/R代码实现四种动态可视化方法,帮助研究者更直观地展示效率变化的动态特征。文章还提供了诊断性叙事结构和比较叙事技巧,助力决策者理解效率提升的来源与趋势。

weixin_32678995的博客 603

Altium Designer 10 介绍、原理图及其模板常规设计

作者:卢老师,华清远见嵌入式学院讲师。 1、Altium Designer 10 入门知识 1.1.1 什么是 Altium Designer Altium Designer 提供了统一的应用方案,是 Protel(经典版本为 Protel 99se)的升级版本,其综合电子产品一体化开发所需的所有必须技术和功能。Altium Designer 在单一设计环境中集成板级和 FPGA 系统设计、

华清远见 | 程序员的学习天堂 6万+

【具身算法】VLA算法-Diffusion Policy

《扩散策略:多模态机器人控制的新方法》摘要 本文提出了一种基于扩散模型的机器人控制策略(DiffusionPolicy),用于解决视觉运动控制中的多模态行为、高维动作空间和训练稳定性问题。该方法利用去噪扩散概率模型(DDPM)生成动作序列,通过迭代优化处理复杂动作分布,显著提升了性能。实验表明,在15项机器人操作任务中,扩散策略平均性能提升46.9%,有效解决了传统显式/隐式策略的局限性。其核心优势在于:1)优雅建模多模态动作分布;2)适应高维动作空间;3)训练过程稳定。未来工作将探索与强化学习的结合及计算

puzhinan7781的博客 1390

android 18 footjob,GitLab 11.2 released with live preview in the Web IDE and Android project import

We are super excited to deliver new features with 11.2 that will help youget started and iterate faster. Today we deliver enhancements to the Web IDE,support for manifest files to import Android proje...

weixin_39966225的博客 9万+

YOLOv11-seg 改进系列 | 引入原创 RSCD 重参数共享卷积分割头,增强 Head 表达力并压低计算量

本文提出一种改进的YOLOv11-seg分割头Segment_RSCD,通过重参数共享卷积增强表达能力。该模块在LSCD共享检测头基础上引入DiverseBranchBlock重参数卷积,保留三尺度预测与Proto掩码原型接口不变。相比原始Segment头,Segment_RSCD参数增加4%但计算量降低1.3%,在共享卷积结构中通过多分支补偿表达能力损失,同时利用Scale层保持尺度差异校准。该方法不改动Backbone/Neck结构,仅重构检测/分割头,实现训练期多路径聚合与部署期等效单分支的平衡。

qq_44224801的博客 181

一篇文章足够你学习Bluez,提供史上最全的Bluez教程,让你告别Bluez从入门到放弃

Bluez是真的难,说“入门到放弃”真的毫不夸张,Bluez的学习曲线陡峭,要求对Linux 系统/驱动概念、D-Bus 通信和蓝牙协议都有要求,加上网络上其实没有一个完整的介绍Bluez系列的文档,所以不管是蓝牙初学者还是蓝牙从业人员,都有不小的难度。

朝气蓬勃 2535

Java关键字之native详解

native 用来修饰方法,用 native 声明的方法表示告知 JVM 调用,该方法在外部定义,我们可以用任何语言去实现它。简单地讲,一个native Method就是一个 Java 调用非 Java 代码的接口。

Java搜索工程技术栈 4183

【RT-DETR涨点改进】全网独家创新、细节涨点改进篇 | ICML 2024 | RT-DETR引入ICB交互式卷积模块和ASB自适应频谱模块,助力目标检测、异常检测有效涨点、含多种创新改进点

RT-DETR目标检测模型通过引入ICB和ASB模块实现性能提升。ICB模块采用多尺度卷积交互,有效捕获局部和长程依赖特征;ASB模块通过自适应频域滤波优化特征表示,降低噪声干扰。两者结合使模型在复杂场景中表现更优,显著提升检测精度和鲁棒性。文章详细介绍了模块原理、代码实现及配置方法,并提供了8种改进版本的YAML配置文件,适用于不同网络结构。这些创新改进为RT-DETR模型提供了高效涨点方案,特别适合复杂背景和高噪声环境下的目标检测任务。

Ai缝合怪、助力小伙伴高效发论文 212

linux 装交叉编译过程,交叉编译环境的概念以及建立步骤

什么是交叉编译?交叉编译(cross-compilation)是指,在某个主机平台上(比如PC上)用交叉编译器编译出可在其他平台上(比如ARM上)运行的代码的过程。具体:交叉编译这个概念的出现和流行是和嵌入式系统的广泛发展同步的。我们常用的计算机软件,都需要通过编译的方式,把使用高级计算机语言编写的代码(比如 C代码)编译(compile)成计算机可以识别和执行的二进制代码。比如,我们在 Wind...

weixin_31668255的博客 759

android 蓝牙通讯demo

android 下蓝牙通讯demo,实现了发现蓝牙,使能蓝牙,通过蓝牙发送消息。

廖雪峰Python教程[完整版]

廖雪峰的python教程整理的,已经排好版了,而且还是完整的,适合小白

有什么比较好也比较好获得的Java Native Compiler

主要目的是想提高Java程序的运行效率,希望把Java程序编译成Native Code

Dominator的专栏 823

NTscan扫描工具

ntscan是一个扫描器,可以扫描没有密码和弱密码的共享,先到配置文件中填写猜测的用户名和密码,扫描过程中右侧出现的是扫描日志。

交叉编译详述

交叉编译工具链

csdnwxhw的博客 699

数学建模模型总结

这是本人在两年内准备参加数学建模竞赛搜集到的模型资料,已经经过了本人的筛选和整理,希望能够对准备参加数学建模竞赛的学弟学妹们提供一些帮助!

简单的网页关键词匹配工具

简单的网页关键词匹配工具作者:Monica Pawlan2003年7月 你是否曾经使用大量的详细信息创建网页,然后希望读者可以使用一种简单的方法,根据特定于用户的关键词分析和进入相应页面?本文解释了如何使用HTML表单和JSP技术来正确地实现上述要求。即使你从没希望得到这种效果,你可能也会发现本文的演示例子和代码练习十分有用,因为这些例子和代码涵盖了如何检索请求的值,并将这些值与静态文件中

fraternity_java的专栏 2409

使用JFreeReport生成报表

使用JFreeReport生成报表作者:肖菁文章摘要JFreeReport用于生成报表。JFreeReport的数据继承自Swing组件的TableModel接口,使用基于XML的报表格式定义文件对报表进行格式化。JFreeReport生成的报表可以分页预览、打印或者保存为多种格式的文件如pdf、Excel、html等。作者在本文中详细的介绍了如何定义报表格式定义文件、如何使用JF

fraternity_java的专栏 2144

Performance of Java versus C++

Performance of Java versus C++ On the Persistence of (Java) Performance Myths -->J.P.Lewis and Ulrich Neumann Computer Graphics and Immersive Technology Lab University of Southern Californ

fraternity_java的专栏 1705

Java Performance: the top 5 pigs

  Home    Books    Boards    Newsletter    Resources    About    ContactsJava Performance: the top 5 pigs(from September Bitter Java newsletter)I recently com

fraternity_java的专栏 1151

SOA 比 Web Services 涵义更广

标题:SOA 比 Web Services 涵义更广 浏览次数: 12 时间:2004-08-31作者:Steve Wilkes无论何时在街上问一个了解点技术的普通人有关面向服务的架构(SOA)的概念,首先反应到他的头脑中的东西将是Web Services。尽管SOA已经存在一段

fraternity_java的专栏 1115

Design Patterns 入門 - 職責鏈(Chain of Responsibility) [精華]

Design Patterns 入門 - 職責鏈(Chain of Responsibility) [精華] 其實職責鏈(Chain of Responsibility)的概念,即使是一個剛學程式設計的新手也會用到,一個簡單的 if...else if ... else 流程控制就有職責鏈的概念:if(/* 符合請求條件一 */) // 執行請求一el

fraternity_java的专栏 1048

JSP学习心得

标题:JSP学习心得 浏览次数: 1443 时间:2003-08-30作者:徐春金下面是本人在学习JSP时的一些心得: 一、JSP工作原理在一个JSP文件第一次被请求时,JSP引擎把该JSP文件转换成为一个servlet。而这个引擎本身也是一个servlet,在JSWDK

fraternity_java的专栏 1045

测试J2EE Web Services

标题:测试J2EE Web Services 浏览次数: 46 时间:2004-08-31作者:Abhijit Patil 和 Seetharam Param我们已经了解了很多关于Web Services开发方面的知识,而对于Web Services测试所面临的挑战却知之甚少。本

fraternity_java的专栏 1031

用JAVA访问共享文件系统

用JAVA访问共享文件系统作者:薛谷雨前言在Microsoft 网 络 系 统 中,SMB(Server Message Block, 服 务 信 息 块) 协 议 是Windows for Workgroup(WfWg)、Windows 95、Windows NT 和LanManager 用 来 实 现 共 享 局 域 网 上 文 件 和 打 印 机 的 协 议。 对 于 利 用

fraternity_java的专栏 926
上一篇: 12个最重要的J2EE最佳实践(一)
下一篇: 用ASP将数据读数导出EXCEL文件的四种方法
fraternity_java
博客等级 码龄22年 1粉丝 30原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值