You are on page 1of 17

JAVA SELF:

Features of java :
Simple
Code is simple and easy to understand like C and C++
Object-Oriented
Object-oriented means we organize our software as a combination of
different types of objects that incorporates both data and behaviour.
Object-oriented programming(OOPs) is a methodology that simplify
software development and maintenance by providing some rules.
Basic concepts of OOPs are:
1. Class : Collection of objects is called class. It is a logical entity.
2. Object : Any entity that has state and behavior is known as an object. For
example: chair, pen, table, keyboard, bike etc. It can be physical and
logical. An object is an instance of a Class.
3. Inheritance : When one object acquires all the properties and
behaviours of parent object i.e. known as inheritance. It provides code
reusability. It is used to achieve runtime polymorphism.
4. Polymorphism : When one task is performed by different ways i.e.
known as polymorphism. For example: to convince the customer
differently, to draw something e.g. shape or rectangle etc.
In java, we use method overloading and method overriding to achieve
polymorphism.
Another example can be to speak something e.g. cat speaks meaw, dog
barks woof etc.
5. Abstraction : Hiding internal details and showing functionality is
known as abstraction. For example: phone call, we don't know the internal
processing.
In java, we use abstract class and interface to achieve abstraction.
6.
7. Encapsulation
Platform independent

Generally the code is executed on any platform by the .exe file which
differs from OS to OS.
However unlike in other programming languages, java compiler converts
the code in to a common byte code called class file (that which is
encrypted) and it can be used on any platform which is read via a jvm
which is platform dependent that creates the platform readable .exe file.
Secured
Java is considered "safe" because:
1. Java programs run inside a virtual machine (the JVM). Though the java
program can even then have access to your files, it is pretty much safer.
They have to belong to a trusted resource with a valid signature. Even if
an untrusted application has gained this level of access, you can force quit
the JVM, the application dies (can't access your info). It works pretty much
like a sandbox, but it is exploitable to an extent. On the other hand, most
C++ or C applications can easily continue running in the background, and
even create new services to be safe from you. Obtaining the same results
from a java application is tough.
2. Everything the programmer writes in java is compiled to byte code. This
byte code is not so easy to exploit/modify by third-parties. However, there
are decompilers present which decompile the byte-code to the java code.
However, this will be again time consuming for the third-party.
3. Java code is verified before execution. This protects a java application from
running a method which is flawed, hence usually saving the application
from force exits. The variables are also null-checked to save errors in
runtime.
4. No use of pointers for memory management. Pointers can often cause
data leaks to unauthorized applications. This is rare in the case of java
(but yes, it is possible). Automatic garbage collection also plays a role
here.

5. Use of try-catch block to save a program from exiting due to exceptions.


You can specify if a particular block of code generates an exception (error),
and then tell the JVM what to do instead of closing the program in such a
case.

Other explanation for Java being more secure than other languages:
Sand box explained:
A security measure in the Java development environment. The sandbox is
a set of rules that are used when creating an applet that prevents certain
functions when the applet is sent as part of a Web page. When
a browser requests a Web page with applets, the applets are sent
automatically and can be executed as soon as the page arrives in the
browser. If the applet is allowed unlimited access to memory
and operating system resources, it can do harm in the hands of someone
with malicious intent. The sandbox creates an environment in which there
are strict limitations on what system resources the applet can request or
access. Sandboxes are used when executable code comes from unknown
or untrusted sources and allow the user to run untrusted code safely.
The Java sandbox relies on a three-tiered defense. If any one of these
three elements fails, the security model is completely compromised and
vulnerable to attack:

byte code verifier -- This is one way that Java automatically checks
untrusted outside code before it is allowed to run. When a Java source
program is compiled, it compiles down to platform-independent Java byte
code, which is verified before it can run. This helps to establish a base set
of security guarantees.

applet class loader -- All Java objects belong to classes, and the applet
class loader determines when and how an applet can add classes to a
running Java environment. The applet class loader ensures that important
elements of the Java run-time environment are not replaced by code that
an applet tries to install.

security manager -- The security manager is consulted by code in the


Java library whenever a dangerous operation is about to be carried out.
The security manager has the option to veto the operation by generating a
security exception.

Why security?
Java's security model is one of the language's key architectural features
that makes it an appropriate technology for networked environments.
Security is important because networks provide a potential avenue of

attack to any computer hooked to them. This concern becomes especially


strong in an environment in which software is downloaded across the
network and executed locally, as is done with Java applets, for example.
Because the class files for an applet are automatically downloaded when a
user goes to the containing Web page in a browser, it is likely that a user
will encounter applets from untrusted sources. Without any security, this
would be a convenient way to spread viruses. Thus, Java's security
mechanisms help make Java suitable for networks because they establish
a needed trust in the safety of network-mobile code.
Java's security model is focused on protecting users from hostile programs
downloaded from untrusted sources across a network. To accomplish this
goal, Java provides a customizable "sandbox" in which Java programs run.
A Java program must play only inside its sandbox. It can do anything
within the boundaries of its sandbox, but it can't take any action outside
those boundaries. The sandbox for untrusted Java applets, for example,
prohibits many activities, including:

Reading or writing to the local disk

Making a network connection to any host, except the host from which the
applet came

Creating a new process

Loading a new dynamic library and directly calling a native method


By making it impossible for downloaded code to perform certain actions,
Java's security model protects the user from the threat of hostile code.
The sandbox defined
Traditionally, you had to trust software before you ran it. You achieved
security by being careful only to use software from trusted sources, and by
regularly scanning for viruses just to make sure things were safe. Once
some software got access to your system, it had full rein. If it was
malicious, it could do a great deal of damage to your system because
there were no restrictions placed on the software by the runtime
environment of your computer. So, in the traditional security scheme, you
tried to prevent malicious code from ever gaining access to your computer
in the first place.
The sandbox security model makes it easier to work with software that
comes from sources you don't fully trust. Instead of security being
established by requiring you to prevent any code you don't trust from ever
making its way onto your computer, the sandbox model lets you welcome
code from any source. But as it's running, the sandbox restricts code from
untrusted sources from taking any actions that could possibly harm your
system. The advantage is you don't need to figure out what code you can
and can't trust, and you don't need to scan for viruses. The sandbox itself

prevents any viruses or other malicious code you may invite into your
computer from doing any damage.
The sandbox is pervasive
If you have a properly skeptical mind, you'll need to be convinced that a
sandbox has no leaks before you trust it to protect you. To make sure the
sandbox has no leaks, Java's security model involves every aspect of its
architecture. If there were areas in Java's architecture in which security
was weak, a malicious programmer (a "cracker") potentially could exploit
those areas to "go around" the sandbox. To understand the sandbox,
therefore, you must look at several different parts of Java's architecture
and understand how they work together.
The fundamental components responsible for Java's sandbox are:

Safety features built into the Java virtual machine (and the language)

The class loader architecture

The class file verifier

The security manager and the Java API


The sandbox is customizable
One of the greatest strengths of Java's security model is that two of the
four components shown in the above list, the class loader and the security
manager, are customizable. To customize a sandbox, you write a class that
descends from java.lang.SecurityManager. In this class, you override
methods declared in the superclass that decide whether or not to allow
particular actions, such as writing to the local disk. You will want to
establish a custom SecurityManager when you are using custom class
loaders to load class that you don't fully trust.
As a developer, you may never need to create your own customized
sandbox -- you can often make use of sandboxes created by others. When
you write and run a Java applet, for instance, you make use of a sandbox
created by the developers of the Web browser that hosts your applet.
The remainder of this article will discuss the Java virtual machine's safety
features. Subsequent articles in this series will describe the other three
prongs of Java's security architecture: class loaders, class verification, and
the security manager.
Safety features built into the JVM
Several built-in security mechanisms are operating as Java virtual machine
bytecodes. You have likely heard these mechanisms listed as features of
the Java programming language that make Java programs robust. They
are, not surprisingly, also features of the Java virtual machine. The
mechanisms are:

Type-safe reference casting

Structured memory access (no pointer arithmetic)

Automatic garbage collection (can't explicitly free allocated memory)

Array bounds checking

Checking references for null


Whenever you use an object reference, the JVM watches over you. If you
attempt to cast a reference to a different type, the JVM makes sure the
cast is valid. If you access an array, the JVM ensures the element you are
requesting actually exists within the bounds of the array. If you ever try
and use a null reference, the JVM throws an exception.
Safety features and security
Because of the safety features built into the Java virtual machine, running
programs can access memory only in safe, structured ways. This helps
make Java programs robust, but also makes their execution more secure.
Why? There are two reasons.
First, a program that corrupts memory, crashes, and possibly causes other
programs to crash represents one kind of security breach. If you are
running a mission-critical server process, it is critical that the process
doesn't crash. This level of robustness is also important in embedded
systems such as a cell phone, which people don't usually expect to have
to reboot.
The second reason unrestrained memory access would be a security risk is
because a wiley cracker potentially could use the memory to subvert the
security system. If, for example, a cracker could learn where in memory a
class loader is stored, it could assign a pointer to that memory and
manipulate the class loader's data. By enforcing structured access to
memory, the Java virtual machine yields programs that are robust -- but
also frustrates crackers who dream of harnessing the internal memory of
the Java virtual machine for their own devious plots.
Unspecified memory layout
Another safety feature built into the Java virtual machine -- one that
serves as a backup to structured memory access -- is the unspecified
manner in which the runtime data areas are laid out inside the Java virtual
machine. The runtime data areas are the memory areas in which the JVM
stores the data it needs to execute a Java application. These data areas
are: Java stacks (one for each thread); a method area where bytecodes are
stored; and a garbage-collected heap, where the objects created by the
running program are stored. If you peer into a class file, you won't find any
memory addresses. When the Java virtual machine loads a class file, it
decides where in its internal memory to put the bytecodes and other data
it parses from the class file. When the Java virtual machine starts a thread,

it decides where to put the Java stack it creates for the thread. When it
creates a new object, it decides where in memory to put the object.
Thus, a cracker cannot predict, by looking at a class file, where in memory
the data representing that class -- or objects instantiated from that class -will be kept. Furthermore, the cracker can't tell anything about memory
layout by reading the Java virtual machine specification. The manner in
which a JVM lays out its internal data is not part of the specification. The
designers of each JVM implementation decide which data structures their
implementation will use to represent the runtime data areas, and where in
memory their implementation will place them. As a result, even if a
cracker somehow were able to break through the Java virtual machine's
memory access restrictions, he or she would next be faced with the
difficult task of looking around to find something to subvert.
Safety is built in
The prohibition on unstructured memory access is not something the Java
virtual machine must actively enforce on a running program; rather, it is
intrinsic to the bytecode instruction set itself. Just as there is no way to
express an unstructured memory access in the Java programming
language, also there is no way to express it in bytecodes -- even if you
write the bytecodes by hand. Thus, the prohibition on unstructured
memory access is a solid barrier against the malicious manipulation of
memory.
There is, however, a way to penetrate the security barriers erected by the
Java virtual machine. Although the bytecode instruction set doesn't give
you an unsafe, unstructured way to access memory, through native
methods you can go around bytecodes.
The problem of native methods
Basically, when you call a native method, Java's security sandbox becomes
dust in the wind. First of all, the guarantees of robustness don't hold for
native methods. Although you can't corrupt memory from a Java method,
you can from a native method. But most important, native methods don't
go through the Java API (native methods provide a means of going around
the Java API), so the security manager isn't checked before a native
method attempts to do something that could be potentially damaging. Of
course, this is often how the Java API itself gets anything done. Many Java
API methods may be implemented as native methods, but the native
methods used by the Java API are "trusted."
Thus, once a thread gets into a native method, the security policy
established inside the Java virtual machine -- no matter what is is -doesn't apply anymore to that thread, so long as that thread continues to
execute the native method. This is why the security manager includes a
method that establishes whether or not a program can load dynamic
libraries, which are necessary for invoking native methods. If untrusted
code is allowed to load a dynamic library, that code could maliciously

invoke native methods that wreak havoc with the local system. If a piece
of untrusted code is prevented by the security manager from loading a
dynamic library, it won't be able to invoke an untrusted native method. Its
malicious intent will be thwarted. Applets, for example, aren't allowed to
load a new dynamic library and therefore can't install their own new native
methods. They can, however, call methods in the Java API, methods that
may be native but that are always trusted.
When a thread invokes a native method, that thread leaps outside the
sandbox. The security model for native methods therefore is the same
traditional approach to computer security described earlier: You have to
trust a native method before you call it.
Structured error handling
One final mechanism that is built into the Java virtual machine and that
contributes to security is structured error handling with exceptions.
Because of its support for exceptions, the JVM has something structured to
do when a security violation occurs. Instead of crashing, the JVM can throw
an exception or an error, which may result in the death of the offending
thread but shouldn't crash the system.
Throwing an error (as opposed to throwing an exception) almost always
results in the death of the thread in which the error was thrown. This is
usually a major inconvenience to a running Java program, but won't
necessarily result in termination of the entire program. If the program has
other threads doing useful things, those threads may be able to carry on
without their recently departed colleague. Throwing an exception, on the
other hand, may result in the death of the thread, but is often just used as
a way to transfer control from the point in the program where the
exception condition arose to the point in the program where the exception
condition is handled.
Structured error handling contributes to Java's security model by helping
to improve the robustness of Java programs. The Java compiler forces
programmers to deal with exceptions that methods declare they may
throw. This encourages programmers to write code that actually handles
exception conditions that may reasonably be expected to arise as their
programs run. If a program encounters a catastrophic error condition, the
structure error handling mechanism enables the program to avoid an
uncontrolled crash and make a more graceful exit.
Conclusion
The sandbox security model is an intrinsic part of Java's architecture. The
sandbox, a shell that surrounds a running Java program, protects the host
system from malicious code. This security model helps give users
confidence in downloading untrusted code across network.

The sandbox is designed into the Java virtual machine and Java API. It
touches all corners of the architecture, but can be divided into four main
components:

Safety features (covered in this article)

Class loaders (this will be covered next month)

Class verification (this will covered in the October issue)

The security manager (this will be covered in the November issue)

Java is secured because:


o

No explicit pointer

Java Programs run inside virtual machine sandbox

Classloader: adds security by separating the package for the classes of


the local file system from those that are imported from network sources.

Bytecode Verifier: checks the code fragments for illegal code that can
violate access right to objects.

Security Manager: determines what resources a class can access such


as reading and writing to the local disk.
These security are provided by java language. Some security can also be
provided by application developer through SSL, JAAS, Cryptography etc.

Everybody knows that security is a big deal for Java. Whenever a security
hole is discovered, the story blasts into the computer news (and
sometimes the business news) very quickly. You may not be surprised to
learn that the popular press monitors comp.risks and other securityrelated newsgroups. They pick security stories to highlight seemingly at
random, though since Java is so hot these days they almost always print
Java security stories.
The problem is that most news stories don't explain the holes well at all.
This could lead to a classic "cry wolf" problem where people become
habituated to seeing "this week's security story" and don't educate
themselves about the very real risks of executable content. Moreover,
vendors tend to downplay their security problems, thus further confusing
the key issues.
The good news is that the JavaSoft security team is serious about making
Java secure. The bad news is that a majority of Java developers and users
may believe the hype emanating from events like JavaOne where security
problems are not given much airplay. As we said in our book, Java
Security: Hostile Applets, Holes, & Antidotes, Sun Microsystems has a lot
to gain if it makes you believe Java is completely secure. It is true that the
vendors have gone to great lengths to make their Java implementations as
secure as possible, but developers don't want effort; they want results.
Since a Java-enabled Web browser allows Java code to be embedded in a
Web page, downloaded across the net, and run on a local machine,
security is a critical concern. Users can download Java applets with
exceptional ease -- sometimes without even knowing it. This exposes Java
users to a significant amount of risk.
Java's designers are well aware of the many risks associated with
executable content. To combat these risks, they designed Java specifically
with security concerns in mind. The main goal was to address the security
issue head-on so that naive users (say, a majority of the millions of Web
surfers) would not have to become security experts just to safely peruse
the Web. This is an admirable goal.
The three parts of the Java sandbox
Java is a very powerful development language. Untrusted applets should
not be allowed to access all of this power. The Java sandbox restricts
applets from performing many activities. The best technical paper on
applet restrictions is "Low Level Security in Java" by Frank Yellin.
Java security relies on three prongs of defense: the Byte Code Verifier, the
Class Loader, and the Security Manager. Together, these three prongs

perform load- and run-time checks to restrict file-system and network


access, as well as access to browser internals. Each of these prongs
depends in some way on the others. For the security model to function
properly, each part must do its job properly.
The byte code verifier:
The Byte Code Verifier is the first prong of the Java security model. When a
Java source program is compiled, it compiles down to platformindependent Java byte code. Java byte code is "verified" before it can run.
This verification scheme is meant to ensure that the byte code, which may
or may not have been created by a Java compiler, plays by the rules. After
all, byte code could well have been created by a "hostile compiler" that
assembled byte code designed to crash the Java virtual machine. Verifying
an applet's byte code is one way in which Java automatically checks
untrusted outside code before it is allowed to run. The Verifier checks byte
code at a number of different levels. The simplest test makes sure that the
format of a byte-code fragment is correct. On a less basic level, a built-in
theorem prover is applied to each code fragment. The theorem prover
helps to make sure that byte code does not forge pointers, violate access
restrictions, or access objects using incorrect type information. The
verification process, in concert with the security features built into the
language through the compiler, helps to establish a base set of security
guarantees.
The applet class loader:
The second prong of security defense is the Java Applet Class Loader. All
Java objects belong to classes. The Applet Class Loader determines when
and how an applet can add classes to a running Java environment. Part of
its job is to make sure that important parts of the Java run-time
environment are not replaced by code that an applet tries to install. In
general, a running Java environment can have many Class Loaders active,
each defining its own "name space." Name spaces allow Java classes to be
separated into distinct "kinds" according to where they originate. The
Applet Class Loader, which is typically supplied by the browser vendor,
loads all applets and the classes they reference. When an applet loads
across the network, the Applet Class Loader receives the binary data and
instantiates it as a new class.
The security manager:
The third prong of the Java security model is the Java Security Manager.
This part of the security model restricts the ways in which an applet can
use visible interfaces. Thus the Security Manager implements a good
portion of the entire security model. The Security Manager is a single
module that can perform run-time checks on "dangerous" methods. Code
in the Java library consults the Security Manager whenever a dangerous
operation is about to be attempted. The Security Manager is given a

chance to veto the operation by generating a Security Exception (the bane


of Java developers everywhere). Decisions made by the Security Manager
take into account which Class Loader loaded the requesting class. Built-in
classes are given more privilege than classes that have been loaded over
the net.

Robust (Strong)
Robust simply means strong. Java uses strong memory management.
There are lack of pointers that avoids security problem. There is automatic
garbage collection in java. There is exception handling and type checking
mechanism in java. All these points makes java robust.

Architecture neutral
There is no implementation dependent features e.g. size of primitive types
is fixed.
In C programming, int data type occupies 2 bytes of memory for 32-bit
architecture and 4 bytes of memory for 64-bit architecture. But in java, it
occupies 4 bytes of memory for both 32 and 64 bit architectures. It is
because the memory allocation depends on the JVM and not the
architecture.
To enable a Java application to execute anywhere on the network, the
compiler generates an architecture-neutral object file format--the
compiled code is executable on many processors, given the presence of
the Java runtime system. This is useful not only for networks but also for
single system software distribution

Portable
Because the java class file is platform independent, it is portable.
Dynamic
DYNAMIC LOADING:
(1) If a method is called, only then it gets allocated in main memory
and processed. (If you write a method in a class but don't call it anywhere,
neither any memory will be allocated to that method nor that method will
be processed)
(2) If a method allocated in main memory is in use then immediately after
the use, the memory allocated to the method will be destroyed.
any thing which loads the resources at run time called as dynamic
nature,java loads the byte code dynamically at runtime and

executes that code and doesn't reveals the object code.


so Java is considered as dynamic.
Also During the execution of a program, Java can dynamically load
class libraries.
Interpreted
Firstly java compiled(some would prefer to say "translated") to bytecode,
which then either compiled, or interpreted depending on mood of
JIT. Java is a compiled programming language, but rather than compile
straight to executable machine code, it compiles to an intermediate binary
form called JVM byte code.
In case of C/C++, the source code is directly converted to binary
code by the compiler that can be executed by the OS to get
output. This binary code generated on one OS does not execute
on other OS. That is, the binary code generated on UNIX machine
must be executed on UNIX only and similarly generated on
Windows must be executed on Windows only. For this reason,
C/C++ are known as platform-dependent languages. Now let us
see the scenario on Java with respect to Why Java both compiled
and interpreted.
But coming to Java, the scenario is completely a new one and different.
Java is platform-independent language. To achieve the platform
independency, the designers put two phases between source code to
output compilation stage and interpretation stage introducing a
new concept called bytecode.
1. Compilation stage
Here compiler do the job. The source code is converted to bytecode by the
compiler. Bytecode is a new concept introduced by Java designers not
existing in C/C++. The bytecode looks very different consisting of some
square boxes, unknown and unreadable characters and some scattered
English characters. Following figure illustrates.

Converting Java source code to bytecode is in known as


compilation. The bytecode is not in a readable format by the
Microprocessor (as Microprocessor knows only one language binary
language).
1. Interpretation stage (Execution stage)
Here, Java interpreter comes into picture. Java interpreter converts the
bytecode into processor readable binary code. The binary code is
executed by the Microprocessor and given output. Onething is to be

noticed here. Different OS will have different architectures. The Java


interpreter converts the bytecode in the binary code understood by that
OS. That is, the same bytecode, if executed on Windows gives binary code
understood by Windows OS and if executed on UNIX gets binary code
understood by the UNIX architecture. That is, interpreters are very
different. The Java interpreter working on Windows is different from UNIX
interpreter. You must load a OS compatible Java interpreter. Interpreter is a
part of JDK. So, JDKs are different for different OS. The interpreter is
known as JVM (Java Virtual Machine).
Now, I think you are sure of why Java is called both compiled and
interpreted language.
More points to understand on compiled and interpreted stages
1. Java code is compiled to bytecode. The bytecode is an intermediate
code between java and the machine code. So you need an interpreter (the
JVM) to execute the byte code.
2. Its simple, the bytecode is portable between OS. That is, the bytecode
generated on OS can be executed on a different OS (provided you load,
the compatible JDK which works on that OS).
3. At Interpretation stage, the performance increases due to JIT compiler.
4. It is very efficient to compile a high-level language into some
intermediate bytecode and then interpreting it into low-level binary code.
5. Other styles of getting output from the source code is to compile a highlevel language into native code (understood by the underlying OS) like C+
+, Pascal, FORTRAN and to interpret the high-level code directly to get
output like Python, PHP, Ruby where no bytecode or binary code file is
generated.
High Performance
Java is faster than traditional interpretation since byte code is "close" to
native code still somewhat slower than a compiled language (e.g., C++)
Multithreaded
A thread is like a separate program, executing concurrently. We can write
Java programs that deal with many tasks at once by defining multiple
threads. The main advantage of multi-threading is that it doesn't occupy
memory for each thread. It shares a common memory area. Threads are
important for multi-media, Web applications etc.
Java is inherently multi-threaded. A single Java program can have many
different threads executing independently and continuously.
Three Java applets on the same page can run together with each getting
equal time from the CPU with very little extra effort on the part of the
programmer
Java is a multi-threaded programming language which means we can
develop multi-threaded program using Java. A multi-threaded program
contains two or more parts that can run concurrently and each part can

handle a different task at the same time making optimal use of the
available resources specially when your computer has multiple CPUs.
By definition, multitasking is when multiple processes share common
processing resources such as a CPU. Multi-threading extends the idea of
multitasking into applications where you can subdivide specific operations
within a single application into individual threads. Each of the threads can
run in parallel. The OS divides processing time not only among different
applications, but also among each thread within an application.
Multi-threading enables you to write in a way where multiple activities can
proceed concurrently in the same program.

Distributed
We can create distributed applications in java. RMI and EJB are used for
creating distributed applications. We may access files by calling the
methods from any machine on the internet.
1.1. Anatomy of a Distributed Application
A distributed application is built upon several layers. At the lowest level, a
network connects a group of host computers together so that they can talk
to each other. Network protocols like TCP/IP let the computers send data to
each other over the network by providing the ability to package and
address data for delivery to another machine. Higher-level services can be
defined on top of the network protocol, such as directory services and
security protocols. Finally, the distributed application itself runs on top of
these layers, using the mid-level services and network protocols as well as
the computer operating systems to perform coordinated tasks across the
network.
At the application level, a distributed application can be broken down into
the following parts:
Processes
A typical computer operating system on a computer host can run several
processes at once. A process is created by describing a sequence of steps
in a programming language, compiling the program into an executable
form, and running the executable in the operating system. While it's
running, a process has access to the resources of the computer (such as
CPU time and I/O devices) through the operating system. A process can be
completely devoted to a particular application, or several applications can
use a single process to perform tasks.
Threads
Every process has at least one thread of control. Some operating systems
support the creation of multiple threads of control within a single process.
Each thread in a process can run independently from the other threads,
although there is usually some synchronization between them. One thread
might monitor input from a socket connection, for example, while another

might listen for user events (keystrokes, mouse movements, etc.) and
provide feedback to the user through output devices (monitor, speakers,
etc.). At some point, input from the input stream may require feedback
from the user. At this point, the two threads will need to coordinate the
transfer of input data to the user's attention.
Objects
Programs written in object-oriented languages are made up of cooperating
objects. One simple definition of an object is a group of related data, with
methods available for querying or altering the data (getName(), setName()), or for taking some action based on the data (sendName(OutputStreamo)). A process can be made up of one or more objects, and
these objects can be accessed by one or more threads within the process.
And with the introduction of distributed object technology like RMI and
CORBA, an object can also be logically spread across multiple processes,
on multiple computers.
Agents
For the sake of this book, we will use the term "agent" as a general way to
refer to significant functional elements of a distributed application.
[1] While a process, a thread, and an object are pretty well-defined
entities, an agent (at least the definition we'll use for the sake of this
book) is a higher-level system component, defined around a particular
function, or utility, or role in the overall system. A remote banking
application, for example, might be broken down into a customer agent, a
transaction agent and an information brokerage agent. Agents can be
distributed across multiple processes, and can be made up of multiple
objects and threads in these processes. Our customer agent might be
made up of an object in a process running on a client desktop that's
listening for data and updating the local display, along with an object in a
process running on the bank server, issuing queries and sending the data
back to the client. There are two objects running in distinct processes on
separate machines, but together we can consider them to make up one
customer agent, with client-side elements and server-side elements.
[1]The term "agent" is overused in the technology community. In the more
formal sense of the word, an agent is a computing entity that is a bit more
intelligent and autonomous than an object. An agent is supposed to be
capable of having goals that it needs to accomplish, such as retrieving
information of a certain type from a large database or remote data
sources. Some agents can monitor their progress towards achieving their
goals at a higher level than just successful execution of methods, like an
object. The definition of agent that we're using here is a lot less formal
than this, and a bit more general.
So a distributed application can be thought of as a coordinated group of
agents working to accomplish some goal. Each of these agents can be
distributed across multiple processes on remote hosts, and can consist of
multiple objects or threads of control. Agents can also belong to more than
one application at once. You may be developing an automated teller
machine application, for example, which consists of an account database
server, with customer request agents distributed across the network

submitting requests. The account server agent and the customer request
agents are agents within the ATM application, but they might also serve
agents residing at the financial institution's headquarters, as part of an
administrative application.

You might also like