Note that there is an RMI FAQ at http://java.sun.com/products/jdk/1.2/docs/guide/rmi/faq.html
If your distributed programs are wholly written in the Java programming
language, then RMI provides a simpler
mechanism that allows the transfer of code, pass-by-value of
objects, and automatic garbage collection of remote objects.
If you need to connect to C++ (or other language) systems or you need
CORBA-specific services, then CORBA is your choice.
In Java 1.3 Sun has aligned RMI to work more closely
with CORBA. Sun has simply added an IIOP transport layer to RMI to support
interoperability with CORBA. Java technology-enabled
programs can now use RMI to access
CORBA-based objects through IIOP, the OMG's CORBA-based protocol.
This is very good
news for those building heterogenous Enterprise systems, although it will
take some additions to IIOP to support the pieces that RMI uses.
Microsoft spokespeople have tried to promote DCOM by spreading
misinformation that RMI is changing or being dropped. That is totally
wrong. The RMI API continues unchanged in its current form. Using DCOM
would restrict your code to only ever run on Microsoft platforms using
Intel hardware, and negates the "write once, run anywhere" Java philosophy.
You would have to recompile your DCOM code to run it on other
Microsoft platforms like Compaq's (formerly DEC's) alpha computer.
Non-portable, single vendor code should be avoided. DCOM/DNA has
limitations for use in the enterprise.
Other sites:
Similar to the proxy answer in a section below;
you must tell the program where
to find the server. In this case start up the client with this
commandline option:
-Djava.rmi.server.hostname=hostname.domainname
The rules for where the client looks for a stub class seem to have changed
making it necessary to reset your class path on the client after starting
the RMI registry. In particular, it looks like rmic was not updated to the
new "don't need $CLASSPATH for current dir" convention as the compiler was.
You are best off setting classpath explicitly.
Other sites:
There are several very good sources available from Sun which cover many
simple and advanced RMI problems.
You are hitting the default limit of 64 open file descriptors. Try
increasing the limit in your OS.
In addition there is currently a practical RMI connection limit imposed by
the scalability of the VM and the performance of object serialization. This
is addressed in JDK 1.2. The actual number of active clients you will be
able to support will depend on the workload mix you have (i.e. the number
of clients, how often they talk to the server, and how much work must be
done per call).
You're getting an error message about version compatability, right?
The RMI Compiler has a -v1.1 option for generating
1.1 compatible stubs and skeletons. It should work with that
.
(See also the first answer in next section below, and note that
this Windows workaround has never worked for some people).
Try adding a definition for the machine in your "hosts" file.
Typically, this file will be named c:\windows\hosts (if it doesn't
exist, there should be a file called c:\windows\hosts.sam). The
hosts file is searched by your TCP/IP stack before it resorts
to DNS, so adding an entry in this file can speed up your lookups
considerably. The hosts file is used to map IP addresses to
symbolic addresses. To enter the name "localhost" with address
127.0.0.1 (the IP loopback address), enter the following line in
your hosts file.
127.0.0.1 localhost
The Java language has networking support built in. When the program starts the
Winsock DLL automatically gets loaded. The first thing this does is to try
to resolve the fully qualified domain name for your machine under the name
"localhost". If your system doesn't have this name mapped, it will try to
query a nameserver on the internet, which is typically (on a PC) your
dialup ISP. So it either prompts you to connect to the ISP, or waits till
the attempt times out.
Some people say you can avoid the Win95 problem by giving your system another
way to resolve DNS names. This tip has never worked for me.
Edit the hosts file for your system so that
localhost and the full domain name are both mentioned. On Windows 95
systems the hosts file is: %windir%\HOSTS (for example, C:\WINDOWS\HOSTS).
On Windows NT systems the hosts file is:
%windir%\System32\DRIVERS\ETC\HOSTS (for example,
C:\WINNT\System32\DRIVERS\ETC\HOSTS).
One gotcha under Win95 is that if the last entry in the hosts file is not
concluded with a carriage-return/line-feed then the hosts file will not be
read at all. So if my system is called goober.best.com change the hosts
file from
127.0.0.1 localhost
to
127.0.0.1 goober.best.com localhost
Showing more of the file:
# Hosts file
127.0.0.1 localhost
129.146.77.177 goober
Another alternative is to dial up with a PPP connection to your ISP
whenever you want to run networking programs.
Fundamentally the experience of some people has been that networking is not completely satisfactory on Windows95 using Winsock 1.1, and has intermittent unexplained failures. You could try downloading Winsock 2.0. To get Winsock 2.0, you need to drag in all the other junk from Microsoft Windows Sockets 2.0 Software Development Kit. This free software can be downloaded from the following addresses: http://www.microsoft.com/win32dev/netwrk/winsock2/ws295sdk.html or ftp://ftp.microsoft.com/bussys/WinSock/winsock2/
The patches needed to improve Win95 networking are already in Win98.
Socket sock = new Socket("155.152.5.1", 23);
triggers the exception. Why?
This is a platform difference that arises out of different semantics in the
underlying network libraries, and is [said to be, but subject to
confirmation] fixed in JDK 1.1. On Solaris and Windows NT, the IP address
string only works for IP addresses that have an associated hostname. On
Linux and Windows 95, the IP address string works in all cases.
When InetAddress is instantiated with an IP address, a reverse DNS lookup
is done. If the IP address is not associated with a valid hostname, the
instantiation will fail. This is part of anti DNS-spoofing, and in JDK 1.1
works because the reverse lookup will not occur until the hostname is asked
for. So in JDK 1.1,
InetAddress in = InetAddress.getByName("155.152.5.1");
[Note: this info is still to be confirmed. Net gurus?]
You could use a trick: put your .class file(s) in a .zip archive and use
showDocument() on the URL. A person accessing this will get a dialog box
put up asking them about saving the file to their local hard disk.
Other sites:
This is typically needed for any net access to another domain.
Tell the run time system what you are trying to do, by using these
commandline arguments when you start the program.
java -DproxySet=true -DproxyHost=SOMEHOST -DproxyPort=SOMENUM classnameNote proxyPort is optional and it defaults to 80. Without this, you will see an exception like java.net.UnknownHostException or java.net.NoRouteToHostException
The proxy settings work for java.net.URLConnection, but apparently not for java.net.Sockets. Update! The proxyHost and proxyPort systems properties (from 1.0.2) are deprecated, you should use http.proxyHost and http.proxyPort. They are for HTTP proxies only. If you are using java.net.Socket you are not using the URL classes, and cannot get the proxy behavior.
Netscape's and IE's JVMs (at least in versions 4.x+) take the proxy settings for applets from the browser's proxy configuration. You can also do URL proxies in applications (not applets) with the following code
// set up to use proxy
System.getProperties().put("proxySet", "true");
System.getProperties().put("proxyHost", "myproxy.server.name");
System.getProperties().put("proxyPort", "80");
But how do I know the name of the proxy server?
Also note there are corresponding socksProxyPort and socksProxyHost for when socks is used instead of proxy. The default socks port is 1080.
It means serialize. To swizzle an object is to recursively serialize or
flatten composed objects.
java.io.InvalidClassException: MacroData; Local class not compatible
You need to add a declaration such as
static final long serialVersionUID = 4021215565287364875L;
in the modified class. The actual value of this long is supplied by the
"serialver" utilitity suppied with the JDK. Any versions of a class other
than the first version require this static to be defined in the class. This
is how versioning is achieved.
When using sockets you typically open both inward and outward streams.
A TCP connection is full duplex, but either the send or receive side may
be closed independently. By default, the remote end will take the close as
indicating that the connection has simply been closed, and will close
its end as well.
Check whether
this is happening for you, by adding the matched pair.
Use tcpdump to check this.
In Java 1.1 (earlier releases were buggy) use:
String host = InetAddress.getByName("211.10.2.119").getHostName();
Like this:
URL url = new URL("http://www.my_domain.com/my_page.html");
URL anchor = new URL(url, "#section2");
this.getAppletContext().showDocument(anchor);
POST passes the form data to the next page as part of the HTTP headers,
while GET sends the data appended to the URL as a querystring.
in the manner of http://www.someurl.com/page.htm?varname=value.
POST and GET are different ways of transmitting form data to a
server-side application. GET is limited to a small amount of text
data that can be appended to the address.
POST handles larger amounts of text and binary data and does not
show up in the address URL.
Why have two access methods if the only difference is in syntax? The real difference is that GET is "idempotent", meaning that you can call it again and again with absolutely no side-effects for the retrieval of the page. If you do GET on the same page twice, the page may legally be sent to you from your browser cache, a proxy cache, or the webserver itself.
If you do a POST the browser knows the page must always be retrieved by going through all the layers to the server and extracting the data again. If it is a webpage that is being fetched this doesn't matter, but if you're calling a script (CGI, servlet, or similar) then the difference is huge. If the script has side-effects that should be done on each access of the webpage (such as access control, or making the user pay something) you will definitely want to invoke the script each time it is called. See http://www.rfc-editor.org/rfc.html for RFC 1945 (HTTP/1.0) or RFC 2068 (HTTP/1.1) to get the absolute formal meanings of the difference between GET and POST.
When you do a GET, since the data is actually added onto the end of the URL string, the user can actually bookmark it, and submit the same info later by going to the bookmarked site. This is why search engines often use GET.
Note that (in Java) POST is more troublesome than it might seem at first, and that GET is preferred. For an untrusted applet, the CGI script can only be on the server that served the applet. POSTing to the server involves sending key/value pairs, not just a message. Also values must be encoded. To send "words to the server" you might try:
StringBuffer sb = new StringBuffer();
String str="words to the server";
sb.append("message=");
sb.append(java.net.URLEncoder.encode(str));
URLConnection cn = url.openConnection();
// set properties
cn.setDoOutput(true);
cn.setUseCaches(false);
cn.setAllowUserInteraction(false);
cn.setRequestProperty("content-type","application/x-www-form-urlencoded");
// send parameters
PrintWriter out = new PrintWriter(cn.getOutputStream());
out.print(sb.toString());
out.close();
// read stuff
BufferedReader in = new BufferedReader(
new InputStreamReader(
cn.getInputStream()));
sb = new StringBuffer();
String inputLine;
while ((inputLine = in.readLine()) != null){
sb.append(inputLine);
sb.append("\n");
}
in.close();
Note, if you request a URL via the URLConnection/HttpURLConnection, the server sets the content type, and your applet can use URLConnection.getContentType() to get the type. Alternatively, use setRequestProperty to set it, like this:
url = new URL(cgiUrl);
urlc = url.openConnection();
urlc.setRequestProperty(
"Content-type",
"application/x-www-form-urlencoded");
Other sites:
CGI (the Common Gateway Interface for web servers) is an API for writing
programs that use the web as its user interface. By far, the most popular
language for this task is Perl, because of its powerful text handling
capabilities, and excellent resources available for making the jobs of CGI
programmers easier. CGI programs can be written in any language, including
Java.
Unfortunately, the interface between the web server and the CGI program
uses environment variables extensively. Use of environment variables has
always been deprecated in Java programming langauge,
because of portability issues (not all
systems have environment variables). The way to get around this is to write
a "wrapper" for the Java program in a language that supports environment
variables, and can then invoke the Java technology-enabled
program with the appropriate
environment data passed in as Java properties.
Because the Java runtime environment is not a lightweight process, it might
take a moment for the CGI program to get started before anything happens.
This is particularly true on operating systems, like NT, that have a large
overhead to spawning new processes.
In preference to using Java for CGI on the server, you might consider using
the Java servlet API in Netscape's Enterprise Server. This allows you to
develop server-side programs without suffering the same performance
restrictions and other limitations of the CGI API.
Other sites:
See
http://search.netscape.com/comprod/server_central/
query/eval_guide/enterprise/advantage.html
for more details.
You can't do it directly. Quoting from the Java Networking FAQ,
Ping requires ICMP packets. These packets can only be created via a socket of the SOCK_RAW type. Currently, Java only allows SOCK_STREAM (TCP) and SOCK_DGRAM (UDP) sockets. It seems unlikely that this will be added very soon, since many Unix versions only allow SOCK_RAW sockets to be created by root, and winsock does not address ICMP packets (win32 includes an unsupported and undocumented ICMP.DLL).
You could write a program that handshakes with a remote system, to
simulate ping, or you could use native code for the raw socket.
Other sites:
There is an additional Java Networking FAQ (which is being modified and reposted regularly) at http://www.davidreilly.com/java/java_network_programming/
You are probably reusing a Datagram packet, and it has no way to
grow its buffer if a longer packet comes in. Take care of it by
calling setLength(max) before reuse.
Failing to do this is a very common mistake.
You shouldn't println to a socket. This is the subject of Apple
Technical Note 1157 at
http://developer.apple.com/technotes/tn/tn1157.html
The problem is that many socket protocols expect CR+LF to terminate
a string, but println delivers a platform-specific EOL mark. On
the Mac, it is just CR. Therefore the server hangs waiting for the
Mac to send a LF. It never does. But the program works fine on
platforms that send CR+LF.
There are two timeouts at issue here.
Use the ServerSocket.setSoTimeout(int millis)
for timing out your 'accept()' calls.
For a select() like mechanism, you can poll InputStreams of your connections for available() > 0
URLConnection doesn't have a method for this, but you can do it by using multiple threads. Create a timer thread that would just track time and close the connection after your specified timeout period. Check the URLConnection to see if it's got any data flowing through it (calling URLConnection.connected() is probably a sufficient test). The URLConnection should be in a separate thread.
That approach will be inefficient for a large number of streams. A lower overhead implementation would be to create a thread to do a blocking read for the stream in that thread and then process it asynchronously. See http://www-ast.man.external.lmco.com/lm-tds/kqml/ for an example.
JDK 1.1 introduced the notion of a "trusted applet" which is one that has
been cryptographically signed to guarantee its origin and make it
tamper-resistant. Trusted applets can be granted more system access
privileges than untrusted applets.
You preconfigure your browser with a list of whose X.509 certificate you
trust, and then applets arrive with X.509's attesting to their keys. It's
easier than it sounds.
The technology was designed with security in mind.
The security features make it very
difficult, probably impossible, to attach a virus (self-copying code) to a
Java applet. There has never been a Java virus carried from system to system
by applets.
There has been mention of a "Java virus" called "BlackWidow" in the media
(it was mentioned in Unigram in late 1996, and obliquely on the RISKS
newsletter in February 1997). A request to the editor of Unigram for more
information brought the answer that there was no more information, it was
just a report of a rumor. As far as is known, this story exists
only as
rumors reported on by the press. There is no actual Java virus or
blackwidow virus (there was a legitimate commercial product of that name,
since renamed).
In spring 1998 there were press reports of a "Java applet" called White
Ghost. It turns out that it relies on security flaws in ActiveX, and the
only susceptible systems are Microsoft's Active Desktop. If anyone has a
URL for a copy of this code, and an analysis of it, please contact the FAQ
author.
In August 1998, Symantec had some information about a Java program (application) that could append itself to some other Java program. They termed it "Strange Brew". That is just normal file processing, no different to a program written in C, C++, Fortran, COBOL, etc. What makes PC viruses dangerous is when they have a hidden means of travelling between places, such as being attached to code that is automatically executed, like boot sector code, or Word macro initialization files. No one has yet produced a virus that does this in Java.
In March 1999, reports surfaced of a virus called BeanHive. Again this
was not Java-related, but relied on the browser user explicitly
accepting an unknown certificate as trusted when prompted.
If the user allowed that, then any code from that
source will be uploaded and run without further input from the user.
Don't remove security for untrusted code simply because it asks for it,
is the lesson here.
If anyone has more concrete information about a virus that can attack an
applet (again, this is thought to be impossible), please contact the
FAQ author.
This is a security feature, to make certain that users can always tell that
a window asking for their password and credit card details (or whatever) is
from an applet. There should be no way for an untrusted applet to work
around this message.
Also in the FAQ:
See also the answer to
Q12.7.
Please take a look at the "Code Signing for Java Applets" page at
http://www.suitable.com/Doc_CodeSigning.shtml.
The page explains how to sign your Java applet so that it can be used
in both Navigator/Communicator and Internet Explorer.
Cryptographic libraries are not part of the release because US
Government policy classifies strong cryptography under the same rules as
munitions. Its export is regulated under the International Traffic in Arms
Regulations. Many people regard this as a Kafka-esque (and futile) attempt
to stem the use of cryptography inside the US.
Late in 2000, the US government relaxed the "crypto software" export
regulations somewhat, permitting certain formerly forbidden products to
be exported.
Other sites:
Read Bruce Schneier's excellent book "Applied Cryptography 2nd Ed." for
more info on what these terms mean. Read David Kahn's excellent (and
exhaustive) book "The Codebreakers" for more info on the history and
background of encryption.
Javasoft's security FAQ can be found at:
http://java.sun.com/sfaq/index.html
Other sites:
Gary McGraw and Ed Felten's book Securing Java
can be found on the web at
http://www.securingjava.com/
When you want to pick up a password from the console, you don't want
to have the characters echoed as the user types them.
There is no way to accomplish this in Java using console I/O. You have an easy approach and a hard approach. The easy approach is to use the AWT (Textfield) or Swing (JPasswordField). The harder approach is to write native code to disable and enable echoing to the console.
Note that the obvious use of Process process = runtime.exec("stty -echo"); will not work because it turns off echo in the spawned child process not the process running the JVM.
In general it is not simple to translate C/C++ into Java programming language,
as Java
lacks the arbitrary pointer arithmetic of those languages. If your C code
does not use pointer arithmetic, automatic translation gets a lot simpler.
Try these URLs:
Going the other way there are currently three freely-available tools to translate Java programming language into C. It seems that these have been done for hacking value, rather than practical purposes.
None of them support the AWT yet, and both j2c and JCC have additional restrictions.
There are several products to convert Visual Basic to Java. Details at
This program dumps info about the class file:
Chuck McManis was one of Sun's original Java implementors.
Java programming language objects are not explicitly deleted
and do not have destructors.
Instead they are implicitly garbage collected when the JVM realizes your
program can no longer access them. This technology is not
based on reference counting and will cope with circular references.
Every object has a routine called finalize() which will be called before the object is collected. This is the nearest equivalent to C++'s destructor. However, it is not a good idea to rely on finalization for the timely freeing of resources. This is because garbage collection and hence finalization may be arbitrarily delayed, and may never happen at all if the program terminates before it runs out of memory. You should instead provide your objects with methods similar to Graphics.dispose() to free resources, and call the dispose() method explicitly when you have finished using them - typically within the "finally" clause of a "try/catch" block. You may then call your dispose() method from within your finalize() method as a last-ditch attempt to free the resource if someone forgets.
Alas, all this means the C++ idiom of "object construction is resource aquisition" does not translate well to the Java programming language. However, note that 90% of destructors in C++ are there to free memory, and the GC means you don't need to do that. As well as fixing an important source of bugs, the GC is essential to Java's security model; without it you could forge object references by preserving the reference after the object has been deleted.
If your program appears to be crashing due to running out of some system resource (like File, Window or Graphics handles), it probably because the system is running out of handles before it has run out of memory. Check that you have called the dispose() method (or equivalent) on every object that uses system resources. You can help the GC a little bit more by explicitly NULLing out references that you've finished with.
There isn't one. sizeof() in C and C++ is
used in three main places:
For all these reasons, there is no need for a Java sizeof() operator. Some people have suggested that you can find out the size of an object by having the object serialize itself to a ByteArrayOutputStream, and looking at the bytearray.length.
That won't work because a lot of additional data is written when an object is serialized. The additional data includes a description of the class, any objects referenced by the serialized object, null references (written as a single byte), etc. If you write another instance of the same class, the amount of data written can differ dramatically. And if you serialize the same object again, it isn't written at all -- even if its data fields have changed! Instead, a one byte token and a four byte "sequence number" that refer to the first writing are output. Using Object Serialization to determine the size of an object does not (except by coincidence) give the right answer.
Java 1.1 adds the ability to use the "final" keyword to make arguments
constant. When used to qualify a reference type, however, this keyword
indicates that the reference is constant, not that the object or array
referred to is constant. For example, the following Java code:
void foo(final MyClass c, final int a[]) {
c.field = 7; // allowed
a[0] = 7; // allowed
c = new MyClass(); // final means this is NOT allowed
a = new int[13]; // final means this is NOT allowed
}
is roughly equivalent to the following C/C++ code:
void foo(MyClass * const c, int * const a) {
c->field = 7; // allowed
a[0] = 7; // allowed
c = new MyClass(); // const means this is NOT allowed
a = new int[13]; // const means this is NOT allowed
}
Java does not have any equivalent to the following C/C++ function declarations:
void foo(const MyClass *c); // a pointer to a const class void foo(const int *a); // a pointer to a const int void foo(const int a[]); // a pointer to an array of const ints
Certainly! There are always hacks around stuff.
One way of enforcing constant values is to have two interfaces, a constant
one and a non-constant one, e.g.
public interface ConstFoo {
int getValue();
}
public interface Foo extends ConstFoo {
int getValue();
void setValue(int i);
}
Then when you want to receive a parameter that cannot be modified you have:
void noChange(ConstFoo foo);
For a parameter that can be modified
void change(Foo foo);
The two classes shown below provide an assertion facility. Set
Assert.enabled to true to enable the assertions, and to false to disable
assertions in production code. The AssertionException is not meant to be
caught--instead, let it print a trace. Since the exception is not meant to
be caught, we just extend Error instead of RuntimeException. As with
RuntimeException, a method does not need to declare that it throws Error.
In addition programmers are less likely to write "catch(Error) ..." than
"catch(RuntimeException)".
With a good optimizing compiler there will be no run time overhead for many uses of these assertions when Assert.enabled is set to false. However, if the condition in the assertion may have side effects, the condition code cannot be optimized away. For example, in the assertion
Assert.assert(size() <= maxSize, "Maximum size exceeded");
the call to size() cannot be optimized away unless the compiler can see that the call has no side effects. C and C++ use the preprocessor to guarantee that assertions will never cause overhead in production code. Without a preprocessor, it seems the best we can do in the Java programming language is to write
Assert.assert(Assert.enabled && size() <= maxSize, "Too big");Alternatively, use
if (Assert.enabled)
Assert.assert( size() <= maxSize, "Too big" );
In this case, when Assert.enabled is false, the method call can always be optimized away totally, even if it has side effects. The relevant sections of the JLS are Section 13.4.8, final Fields and Constants and Section 14.19, Unreachable Statements. 13.4.8 requires that primitive constants ("a field that is static, final, and initialized with a compile-time constant expression") be inlined. So everywhere Assert.enabled is refered it is replaced at compile time with its value. Writing:
if (Assert.enabled) Assert.assert(size() <= maxSize, "Too big");
is exactly the same as writing:
if (false) Assert.assert(size() <= maxSize, "Too big");
... assuming Assert.enabled is false at compile time. Section 14.19
discusses compiling away such dead code.
To sum up: the inlining of the primitive constant is required
by the spec. The subsequent optimization of not generating code masked
by (what turns into) an "if (false) ..." is not required but is
implemented by many existing Java compilers.
public class AssertionException extends Error {
public AssertionException(String s) {
super(s);
}
}
public final class Assert {
public static final boolean enabled = true;
public static final void assert(boolean b, String s) {
if (enabled && !b)
throw new AssertionException(s);
}
}
float x = 12345.6789;
printf("%6.3f/n", x);
You can break a string like "5 loaves 2 fishes" into its parts by using
java.util.StringTokenizer. This is the Java programming langauge
equivalent of sscanf().
StreamTokenizer does a similar thing on a file or any stream (i.e, what scanf() and fscanf() do in C).
To do formatted character output, create a format string, and then use that to format your binary value, e.g.
import java.text.*; float fi = 1234.56789F; DecimalFormat mydf = new DecimalFormat( "###0.000" ); mydf.setMinimumIntegerDigits(3); // for example System.out.println( mydf.format(fi) );
gives:
If you want to see a float print out as "0.0000001" instead of "1E-7", use:
java.text.DecimalFormat myFmt = new
java.text.DecimalFormat("#,###,###,###.############");
System.out.println(myFmt.format(myFloat));
There are lots of different characters you can feed to the DecimalFormat
constructor, not just "0" and "#".
See $JAVAHOME/src/java/text/DecimalFormat.java source for details.
The always excellent Acme site has an sprintf() package written in Java
See http://www.acme.com.
See also "Henrik Bengtsson's Java printf, sprintf and fprintf" library
which is downloadable from http://www.braju.com.
The keyword "friend" in C++ is a hack to allow a piece of code to access
the private member declarations of another class. In the Java programming
language, you would do
this by labelling, not the friend, but the private members. Instead of
making them private, make them either protected or package (no keyword) or
public.
The four different protection levels are: private, package, protected, and public.
Yes, only it's better and simpler to use. It's called the Java
Generic Library. This library (JGL) is freely downloadable from
http://www.objectspace.com/
It includes about a dozen nice data structures (including sets and bags) and algorithms like unions, searching, and sorting.
It has over 100,000 users and 11 OEM distributors. [Some Java vendors are bundling it with their next release]
If you have the code:
array[i++] = foo();
and foo() throws an exception, i will be incremented anyway. This can
cause problems if sometimes foo() throws an exception and you don't want i
incremented in cases when it does.
This is a consequence of JLS 15.25.1 and 15.6.1 "the left-hand operand of a binary operator appears to be fully evaluated before any part of the right-hand operand is evaluated." (assignment is taken as a binary operator). Note that this is not how C++ behaves.
See also the list of Java Design Patterns at
http://c2.com/cgi/wiki?JavaIdioms
The naming conventions are straightforward:
No. A String constant such as "" or "hello" is already a String, so there's
no need to write code like:
String s = new String("");
You can instead write the simpler
String s = "";
Note that Strings are immutable (unchangeable),
so there is no danger of accidentally
modifying a String that is pointed to by another reference.
Code like this seems to show that the calls don't work!
String s = " hello ";
s.trim();
s.toUpperCase();
Note again that Strings are immutable. This means that once a String
has been initialized, its contents won't change. In the code above, the
method calls return a different String with the desired alterations. But
this new String is not assigned to anything, so the results are discarded.
To see the changes, assign the results of the method call to the original
String or to another String.
String s = " hello ";
s = s.trim();
s = s.toUpperCase();
There are several ways. The most straightforward is:
String myString = numString.trim();
int i = Integer.parseInt(myString);
long l = Long.parseLong(myString)
or
String myString = numString.trim();
i = Integer.parseInt(myString,myIntRadix);
Note 1: There is a gotcha with parseInt - it will throw a
NumberFormatException for String values in the range "80000000" to
"ffffffff". You might expect it to interpret them as negative, but it does
not. The values have to be "-80000000" .. "-ffffffff" to be properly
recognized as negative values. This is true for all radixes. According to
Bug Parade bug report 4068580, the proper way to generate negative-valued
hex Strings for eventual use by parseInt() is with Integer.toString(i, 16).
Once that high "sign bit" is on, without the accompanying character,
parseInt() says "too big".
int i = Integer.valueOf(my_str).intValue();
also works but involves the creation of an extra object.
Note: the
parseDouble and parseFloat methods were introduced in
JDK 1.2.
float f = Float.valueOf(my_str).floatValue();
double d = Double.valueOf(my_str).doubleValue();
Try any of these:
String s = String.valueOf(i);
or
String s = Integer.toString(i);
or
String s = Integer.toString(i, radix);
or
// briefer but may result in extra object allocation.
String s = "" + i;
Note: There are similar classes for Double, Float, Long, etc.
You can print the hex equivalent of an int with:
int i = 0xf1;
System.out.println("i is hex " + Integer.toHexString(i) );
OK, how do I read a hex string into an int?
int i = Integer.valueOf(myHexString, 16).intValue();
Simple answer: use a "callback". Make the parameter an interface and pass
an argument instance that implements that interface.
public interface CallShow { public void Show( ); }
public class ShowOff implements CallShow {
public void Show( ) { .... }
public class ShowOff2 implements CallShow {
public void Show( ) { .... }
public class UseShow {
CallShow savecallthis;
UseShow( CallShow withthis ) {
savecallthis = withthis;
}
void ReadyToShow( ) { savecallthis.Show( ); }
}
// in some other class that uses all this stuff:
UseShow use_1 = new UseShow( new ShowOff() );
UseShow use_2 = new UseShow( new Showoff2() );
and then the ReadyToShow() method on use_1 or use_2 will call the
appropriate method, as if you had stored a pointer to the method.
Use
Runtime.getRuntime().exec( myCommandString )
where myCommandString is something like "/full/pathname/command".
An applet will need to be signed in order to allow this.
If the pathname contains spaces, e.g. "c:\program files\windows\notepad",
then enclose it in quotes within the quoted string.
From JDK1.3 there are two new overloaded Runtime.exec() methods. These allow you to specify starting directory for the child process.
Note, there is a gotcha associated with reading output from commands. When the runtime exec's the process, it passes to it 3 streams, for stdin, stdout, and stderr; the out and err are buffered but the buffer size isn't very big. When your process runs, it reads (if needed) from in, and writes to out and err. If it doesn't write more than the buffer-size, it can run to completion.
But if it tries to write more data to one or the other stream than the buffer can hold, the write blocks, and your process hangs, waiting for you to empty the buffer so it can write some more.
So after the exec call, get the streams, and read from them in a loop until they both hit end-of-stream (don't block on either one, just read whatever is available from each, each loop iteration). Then when the streams have ended, call the process.waitFor() method to let it finish dying.
This solution works on Unix platforms using either JDK 1.0.2, or JDK 1.1.
The trick is to use an array of Strings for the command line:
String[] command = {"/bin/sh", "-c", "/bin/ls > out.dat"};
If you don't do this, and simply use a single string, the shell will see
the -c and /bin/ls and ignore everything else after that. It only expects a
single argument after the -c.
import java.io.*;
import java.util.*;
class IoRedirect {
public static void main(String Argv[]) {
try {
String[] command = {"/bin/sh", "-c", "/bin/ls > out.dat"};
Process p = Runtime.getRuntime().exec(command);
p.waitFor();
System.out.println("return code: "+ p.exitValue());
} catch (IOException e) {
System.err.println("IO error: " + e);
} catch (InterruptedException e1) {
System.err.println("Exception: " + e1.getMessage());
}
}
}
The reason is that many of the DOS commands are not individual programs,
but merely "functions" of command.com. There is no DIR.EXE or COPY.EXE for
example. Instead, one executes the command processor (shell) explicitly
with a request to perform the built-in command,
like so:
Runtime.getRuntime().exec("command.com /c dir") for example. On
NT, the command interpreter is "cmd.exe", so the statement would be
Runtime.getRuntime().exec("cmd /c dir")
And you could bring the command output into the program with code like:
Process p = runtime.exec ("cmd /c dir");
DataInputStream procIn = new DataInputStream(p.getInputStream());
while ( true ) {
String line = procIn.readLine();
if ( line == null ) break;
// do something with lin
}
As above (18.6, 18.7), adjusted like this:
BufferedReader pOut= new BufferedReader(
new InputStreamReader(p.getInputStream()));
try {
String s = pOut.readLine();
while (s != null) {
System.out.println(s);
s = pOut.readLine();
}
} catch (IOException e) { }
Another possibility is to read chunks of whatever length as they come in:
...
p = r.exec(cmd);
InputStream is = p.getInputStream();
int len;
byte buf[] = new byte[1000];
try {
while( (len = is.read(buf)) != -1 ) {
String str = new String(buf,0,0,len);
System.out.println( "Process out: " + str );
}
} catch( java.io.EOFException eof ) { ...
} catch( java.io.IOException ioe ) { ... }
However, you cannot read output from some DOS commands on Windows 95/98. This is bug 4211683 at Sun, but it is actually a Microsoft bug/poor design. Windows programs that explicitly use a handle to the console ("CON" or "CON:") instead of stdin and stdout cannot be used as subprocesses to Java. The Win95 FTP program is an example of such a program. Windows provides no convenient way for Java to redirect the input and output of such processes from the console to input and output pipes. The only workaround is to use a different implementation of the program that does not use the console directly.
Microsoft documents a difference in DOS Console stream handling between 95 and NT: see http://support.microsoft.com/support/kb/articles/q150/9/56.asp
So capturing output from GNU ls on Win95 works, but the output from "command.com /c dir" is not captured.
You throw both classes at the compiler at the same time.
javac pkg1/X.java pkg2/Y.java
A better approach is to remove the cyclic dependency by redesigning the class structure, or using interfaces.
This code is from the 1.0 AWT, and the programmer was probably pretty
skilled.
public synchronized void layout() {
LayoutManager layoutMgr = this.layoutMgr;
if (layoutMgr != null) {
layoutMgr.layoutContainer(this);
}
}
The code makes a local copy of a global variable for one or both of two
reasons.
this.layoutMgr = someOtherLayoutMgr;
This method will still have a pointer to the original layoutMgr.
Use bytes, shorts, chars, ints or longs if you need to manipulate no
more than 64 bits at once.
Use ~ for NOT, & for AND, | for OR, and ^ for XOR. Beware that the
precedence for & | and ^ is not intuitive; they have lower precedence
than == and !=, so you must write:
if ((a & 1) == 1)
rather than:
if (a & 1 == 1)
You can also shift bits with the <<, >> and >>> operators; >> is a signed
shift and >>> is an unsigned shift.
If you use bytes or shorts, beware that they will be sign extended
to ints when they're used in operations. Thus, in the code
byte b = (byte) 0x80;
short s = (short) (b | 1);
the result in s is 0xFF81 instead of the expected 0x0081. The easiest way
to convert a byte or a short to an without sign extension is to AND with
0xFF or 0xFFFF.
If you need to manipulate more than 64 bits, you can use arrays of
booleans, ints, or longs. Beware that arrays of booleans are inefficient,
as they take one byte of storage per bit. Alternatively, you can use the
java.util.BitSet class.
"a & b" takes two boolean operands, or two integer operands. It always
evaluates both operands. For booleans, it ANDs both operands together
producing a boolean result. For integer types, it bitwise ANDs both
operands together, producing a result that is the promoted type of the
operands (i.e. long, or int). "|" is the corresponding bitwise OR
operation. "^" is the corresponding bitwise XOR operation.
"a && b" is a "conditional AND" which only takes boolean operands. It always avoids evaluating its second operand if possible. If a is evaluated to false, the AND result must be "false" and the b operand is not evaluated. This is sometimes called "short-circuited" evaluation. "||" is the corresponding short-circuited OR operation.
Possible mnemonic: The longer operators "&&" or "||" try to shorten themselves by not evaluating the second operator if they can.
The code looks like this:
Thread t = new Thread( my_runnable_obj );
t.start();
...
t = null; // what happens to the thread?
The answer is that you may no longer have a reference to the thread,
but the JVM still does and it keeps running.
Once a thread is started, and as long as it keeps
running, it is a root object. Root objects are the starting points for
"things in use" that the garbage collector will skip over.
Look at the java.version system property with:
String ver = System.getProperty("java.version");
There isn't a lot of standardization on the string contents however.
Another possibility is to try { ... } to load a class that is
unique to one release, like this:
boolean isJDK1_1 = true;
try {
// java.awt.Cursor is available only in the 1.1.x JDK
Class cls = Class.forName("java.awt.Cursor");
} catch (Exception e) {
// we should have written 'ClassNotFoundException e',
// but Communicator generates security exception instead.
isJDK1_1 = false;
}
This approach has the advantage that it can be compiled by any
version compiler.
JDK 1.2 has
System.setProperty( "property", "new value" );
Until then, you can get all the properties, and set just the one you want
with code like this:
System.getProperties().put("property", "new value" );
Look at the code below, submitted by expert programmer John Dumas. It uses
serialization to write an object into a byte array, and reads it back to
reconstitute a fresh copy. This is a clever hack!
import java.io.ByteArrayOutputStream;
import java.io.ByteArrayInputStream;
import java.io.ObjectOutputStream;
import java.io.ObjectInputStream;
public class Cloner {
private Cloner() {}
public static Object cloneObject(Object o) throws Exception {
ByteArrayOutputStream bOut = new ByteArrayOutputStream();
ObjectOutputStream out = new ObjectOutputStream(bOut);
out.writeObject(o);
ByteArrayInputStream bIn =
new ByteArrayInputStream(bOut.toByteArray());
ObjectInputStream in = new ObjectInputStream(bIn);
return(in.readObject());
}
public static void main(String args[]) throws Exception {
java.util.Vector v = new java.util.Vector();
v.addElement(new StringBuffer("Hello"));
java.util.Vector vClone =
(java.util.Vector)Cloner.cloneObject(v);
// Changing the StringBuffer int the cloned vector has no
// effect on the original StringBuffer object --
// demonstrating that we have indeed done a deep copy
((StringBuffer)vClone.elementAt(0)).append(" world");
StringBuffer sb = (StringBuffer)v.elementAt(0);
System.out.println(sb.toString());
sb = (StringBuffer)vClone.elementAt(0);
System.out.println(sb.toString());
int array[] = { 1, 2, 3, 4, 5 };
int arrayClone[] = (int [])Cloner.cloneObject(array);
// Again, changes to an element in the cloned array do not
// have any effect on the original
arrayClone[0]++;
System.out.println(array[0]);
System.out.println(arrayClone[0]);
}
}
The main() routine is just a driver. All the cleverness is in the very
brief cloneObject(). It does a "deep" clone, which is what you usually want
(though Java gives you a "shallow" clone by default).
The only way in pure Java to create globally unique ids is to set up a
server, accessible by all interested parties, which supplies the ids.
There are classes in Java which may supply 'probably' unique ids, with varying levels of reliability --- but a dual processor machine with two JVMs running could easily generate duplicate ids.
Note that a global server issuing a token (and periodic "are you still using it" messages) is a pretty good way to do cooperative file locking too.
It is an abbreviation of "Got you!" It is the triumphant exclamation that a
bug or programming idiom makes as it traps the unwary programmer. This
section details some of the popular "gotcha's" of the Java programming language.
See also the list of Gotcha's at
http://mindprod.com/gloss.html
It's a known bug. FileDialog doesn't call FilenameFilter.accept().
The bug id is 4031440, and it can be seen at the Java Developer Connection.
There is no way to implement FilenameFilter support with the current reliance on the Win32 common file dialog. To support FilenameFilter, the FileDialog needs to issue a callback for each file it wants to display, which the FilenameFilter can veto. But the Win32 common FileDialog doesn't have any way to issue callbacks. Instead it accepts simple wildcard patterns for choosing files which match a certain pattern. That's a reasonable alternative to FilenameFilters, but that model isn't supported by the current API.
JFC has a JFileChooser class that is a better bet for you to use for file dialogs.
This is the "expected" behavior. If you have this in one file
class Flags { final static boolean debug = true; }
and you change it to, and recompile just this file:
class Flags { final static boolean debug = false; }
Then the rest of your Java .class files will still see it as "true".
When you declare a "static final int" (or any other primitive), the compiler turns that into a compile time constant whose value can be substituted wherever it is used in your program. If you update the value in the source file, you'll need to recompile every class that uses it.
See Java Language Specification, section 13.4.8 "final Fields and Constants": "We call a field that is static, final, and initialized with a compile-time constant expression a primitive constant. If a field is a primitive constant, then deleting the keyword final or changing its value will not break compatibility with pre-existing binaries by causing them not to run, but they will not see any new value for the constant unless they are recompiled."
The "substring trap" is the name for a mistake that is all too easy to make
when using the substring() method of class String. The method signature is:
public String substring(int beginIndex, int endIndex)
The name "endIndex" suggests that is the index where the Substring ends.
But in fact, the substring extends only to the character at position
(endIndex-1)!
Example: the substring of 'xabcdef' from 1..3 is 'ab'
Char 'a' is at position 1 in the String, and 'b' is at 2, which is 3-1.
It seems to be done this way so that
s.substring(0,s.length()) is equal to s. If so, the name of the second
parameter should be something like endIndxPlusOne. But not the
confusing and misleading endIndex. Beware of the substring trap.
The following code
class MyFrame extends Frame {
MyFrame() {
Image offscreen = createImage(100,100);
Graphics offg = offscreen.getGraphics();
}
...
}
will usually not work, since the peer will not exist at this time. Without the peer for the Frame, you cannot succeed in creating offscreen Images. (There's no problem creating Produced Images without a peer. Trying to draw them, of course, is another matter).
One "standard" form of offscreen code looks like this: (note the reuse of the Graphics and Image objects for as long as possible)
class Gumble extends java.awt.Something {
private Image offi;
private Graphics offg;
public void update(Graphics g) {
if (g == null) return; // Paranoia
Dimension size = size();
if ( offi == null
|| offi.getWidth()!=size.width
|| offi.getHeight()!=size.height ) {
if (offg!=null) offg.dispose();
offi = createImage(size.width, size.height);
offg = offi.getGraphics();
// Regenerate offi here...
}
// If you use getClipBounds() here,
// check that for being null, too!
// several implementations have been known to pass them....
g.drawImage(offi);
}
public void paint(Graphics g) {
update(g);
}
}
See also the question about "When I initialize a component,I call MyComponent.getImage() to get its image, but createImage() returns null!"
Correct. Generally, if you invoke a method on an object, the object's actual
runtime type, not the type of the reference that you used to reference it,
determines which method is invoked. This is regular polymorphism.
It's not the same for object parameters: the compiler decides at compile time, depending on the types of the parameter expressions, which method signature to use, and this is "hardwired" into the bytecode. The compiler does not look at the object argument at runtime and say "ah, this is a derived type, so I will choose the method that takes the derived type as an argument."
This is best seen in a code example:
class Base { }
class Derived extends Base { }
public class foo {
public static void method(Base b) {
System.out.println("In the base method...");
}
public static void method(Derived d) {
System.out.println("In the derived method...");
}
public static void test(Base b) {
if (b instanceof Derived)
System.out.print("Derived: ");
else
System.out.print("Base: ");
method(b); // which method? method(base) or method(derived)?
}
public static void main(String args[]) {
Base b = new Base();
Derived d = new Derived();
System.out.println("test calls.");
test(b);
test(d);
}
}
Running the program gives an output of
test calls. Base: In the base method... Derived: In the base method...
See JLS section 15.11.4.4 and 15.11.3:
"If class S contains a declaration for a method named m with the same
descriptor (same number of parameters, the same parameter types, and the
same return type) required by the method invocation as determined at
compile time then this is the method to be invoked."
Quoting from the object serialization specification at:
http://www.javasoft.com/products/jdk/1.1/docs/
guide/serialization/spec/serial-arch.doc.html#4176
Within a stream, the first reference to any object results in the object being serialized or externalized and the assignment of a handle for that object. Subsequent references to that object are encoded as the handle.
In other words, changing an object and then writing it again does not really write it twice. Instead it just writes a reference back to the first occurrence, losing any fields that have changed in the meantime.
There are three ways around this: (1) (inefficient) Reset (or close and
reopen) the stream, and start again by writing the new value of the object.
This is drastic -- you are throwing away all the serialization that you
have already done.
(2) (kludgey) Create a new object and write that.
(3) (could be a lot of work) Write your own protocol for object
serialization. Have something like a data stream where the contents of an
object are marked by special identifiers. Each "end" of the stream can
decide whether it will use a new object each time or reuse an existing
object.
This happens with a java.awt.Frame. The best answer is to use
a javax.swing.JFrame where closing is the default behavior.
If you have to stick with Frame, you
need to add the code to listen for a window closing event, and take the
appropriate action (hide the window, exit the program if the top level
frame, etc).
The window closing event handler is simple:
Frame mf = new Frame("binky");
mf.addWindowListener( new WindowAdapter() {
public void windowClosing(WindowEvent we) {
System.exit(0); // or setVisible(false); etc.
} });
This really should be the default behavior of an AWT Frame. So you'll be delighted to hear that JavaSoft has "made it so" for the JFrame Swing component. That leads to a slightly different problem. See Question 4.3.3. See also Question 13.9.
The most common use of super is the call "super()" to invoke a constructor
in the superclass.
The keyword "super" is also used to access fields of any superclass (not
just the immediate superclass) that are hidden by an identically named
feature in the current class.
However there is no way to "chain" several super's together, and reach back higher into the parent class hierarchy. E.g. do not think that "super.x" means the "x of parent" and "super.super.x" means the "x of grandparent". This is a very common mistake. There is no "super.super.x". Looking at the generated byte code, if you have
class Parent { }
class Child extends Parent { }
then, in Child "super.someParentMethod();" means "invokespecial
X.someParentMethod()" in the JVM, not "invokevirtual".
Invokespecial means "call the exact method I am telling you."
Invokevirtual means "call the right method for whatever object this is".
You need to add a call to the paintImmediately(x,y,w,h) method of
JComponent. That repaints the component completely before continuing
execution. On pre-JDK 1.2 systems, use:
invalidate(); validate();
They cause the component hierarchy to be marked as needing to be laid out again, and the validate causes that to be done. It may be expensive, but is a way of getting the peers to recalculate size and to do what is needed to bring the display up to date. It has limitations: it doesn't cause an immediate screen update when invoked from an event handler, where paintImmediately() does.
On Windows, the pop-up trigger is a mouse release (except in certain
programs like Netscape Communicator). On Unix, the pop-up trigger is a
mouse press.
Therefore you need to ask the question isPopupTrigger() in both the mousePressed() and mouseReleased() methods when implementing the MouseListener interface. Alternatively override Component's processMouseEvent as a central place for handling mouse input.
Code like this:
if (c == '\n')
fin = true;
is not cross-platform. On Unix the line terminator is "\n", on Windows, it is frequently "\r\n", on the Mac it is "\r".
The call System.getProperty("line.separator") will return a string containing the platform-specific line separator character(s), and you then need to compare it according to how your data is formatted (e.g. compare 2 characters or one). There is also a property for the separator character in file pathnames, and other values too.
This can screw-up your networking programs too. Most ASCII based protocols like HTTP expect \r\n to terminate a request. They will hang on a request from a Mac that only sends \r.
The most common Inset problem is not an Inset problem at all, but rather
that people just assume
the x,y location of a Graphics.drawString() actually refers to the top
left part of the string image. In fact it refers to the baseline. So
you'll need to take the font metrics into account:
g.drawString("Hello World",0,getFontMetrics(getFont()).getAscent());
This question and answer comes directly off comp.lang.java.programmer, and
deserves to be immortalized for posterity.
When I use fillPolygon with the following points I get two inverted
triangles instead of a rectangle. Why?
int xPoints[] = {71, 78, 71, 78};
int yPoints[] = {147, 147, 130, 130};
g.fillPolygon(xPoints, ypoints, xPoints.length);
Developer Felix Pahl supplied the answer in limerick form:
You must put the points in the order you would encounter them in if you went round the polygon's border. The filling algorithm is doing the right thing! Try drawing the points on paper to see:
71,130 78,130 O--------O | | | | | | o--------o 71,147 78,147
Under JDK1.1, the two endpoints are connected automatically and you would order the array elements as:
int xPoints[] = { 71, 78, 78, 71};
int yPoints[] = {130, 130, 147, 147};
Under JDK1.0.2, you have to explicitly connect the two endpoints, and you would write the array elements as:
int xPoints[] = { 71, 78, 78, 71, 71};
int yPoints[] = {130, 130, 147, 147, 130};
If you have code like:
Frame myframe = new Frame("Child Frame");
myframe.resize(512,384);
myframe.add(new Label("Child"));
myframe.show();
The default layout manager for Frame is BorderLayout. Components positioned with a BorderLayout should include a positioning constant to be correct. If you don't include one, "Center" is assumed. You could change the add to
myframe.add( new Label("Child"), "Center" );
to be explicit.
if (s1 == s2)is giving me funny results.
The comparison using "==" on objects, like Strings, is asking the question
"do these two objects have the same reference?". That is, do they have the
same address, and hence are not two object but one? What you most probably
meant is "do these two Strings have the same contents?" which you can
express this way:
if ( s1.equals(s2) )
This is a very, very easy mistake to make and impossible to spot until you have had it explained to you.
People talk about "interning" a String. That means calling the intern() method on a String. This places the String in the runtime constant pool if it was not already there. The compiler is required to intern() all literal Strings [JLS section 3.10.5 "String literals - or, more generally, strings that are the values of constant expressions (§15.27) - are "interned" so as to share unique instances, using the method String.intern (§20.12.47).]
If you intern() all your Strings as well then all duplicates are shared and comparisons can be done by the (much faster) address comparison rather than content comparison. It's a performance optimization. See also Q3.22.
Note that this comparison error also occurs with other objects, not just Strings. The code:
if (getBackground() == Color.black)
is a test for object identity, rather than content identity. It will work
if you originally setBackground(Color.black). To avoid difficult debugging
in the future, you almost certainly want to say
if (getBackground().equals( Color.black ) )
or even (in this visual case) compare the darkness of the RGB values of the
pixels.
You have code like this
final StringBuffer s = new StringBuffer("don't change me");
// ...
s.append(", but I did");
System.out.println(s);
And the new value of s is "don't change me, but I did". The reason is that the "final" modifier makes the reference variable (here, s) final, not the object that s points to. It means that the reference variable cannot be changed to point to some other StringBuffer. The state of the StringBuffer can still be modified by calling methods on it or directly assigning to its public fields.
The right way to think about final is that it prevents you assigning to that particular variable. The only way to make the fields of an object constant (unchanging) is to make all its data fields private, and not provide any set methods for them, only get methods. Even that won't stop other objects of the same class adjusting it.
When trying to compile a file in a package you get a compiler error like:
DBTest.java:10: Class database.Table not found in type declaration.The file Table.java and DBTest.java are in the same directory. They both have "package database;" at the top of the file. The current directory is included in the classpath.
The reason is that when compiling packages, you have to be at the 'top' of the directory/package hierarchy. So to compile both Table.java and DBTest.java, you have to be in the directory that contains the database directory (i.e. where the package hierarchy starts), and just:
javac database/Table.java
javac database/DBTest.java
and it should all compile fine.
The VM sets the focus on the first traversible object in the UI. If you
want the button not to be assigned focus by default, you must subclass the
button and override the isFocusTraversable() method to return false.
Another approach is to manually set the focus on some other component (say the Frame) when you show the window. To do so you have to jump through hoops to outsmart the VM that is trying to set it on the button. One approach is to listen for the windowActivated event and set a Swing Timer to do a requestFocus() on the frame about 0.1 seconds after the activated message. This seems convoluted, but it is the only thing found that consistently works cross platform.
Another reader suggests that if the frame normally gets the focus first, you can override its gotFocus() event and set the focus to the component you want. Don't forget to return true!
If you wish to Serialize a string, be alert to the restriction that:
A possible workaround that is to strip the string down to "byte[]" and pass it around in RMI that way. The code with this restriction is in DataOutputStream
public final void writeUTF(String str)
...
[perform the size-after-conversion-to-UTF computation]
...
if (utflen > 65535)
throw new UTFDataFormatException();
...
RMI relies on serialization, so RMI has the same String size limitation.
This limitation was removed in JDK 1.3
Here the problem is probably that you have initialized the array
with N references to the same one object.
This is easy to overlook, because arrays in Java only contain references to objects, not objects. (Or they can contain primitives).
No. java.awt.Graphics.drawRect draws a rectangle that's 1 pixel wider
and 1 pixel taller than a rectangle drawn by fillRect.
It is possible to exactly follow the instructions given in the
documentation and yet still get the following error message when
attempting to run the .jar file: "Failed to load Main-Class manifest
attribute from myapp.jar"
There has to be a carriage return after the Main-Class definition in the manifest file, otherwise it does not work! Example, in a file called manifest.txt:
Main-Class: MyClass // does not work Main-Class: MyClass // does workThen, when the manifest file is merged into the jar file like this:
jar cmfv manifest.txt myapp.jar *.classit works fine.
Almost certainly, you have written your constructor with a return
type or void or something. I.e. you have written:
public MyClass Myclass() { ...}
instead of:
public Myclass() { ...}
Giving a constructor a return type makes it into a regular
method that happens to have the same name as the class. The
language should ideally outlaw this, but it doesn't.
Although Java will automatically manage your memory use, there are
certain non-memory resources which you need to explicitly manage.
In particular, if you do not keep track of the following OS resources,
and free them up when no-longer in use, your program may well slow down
or stop.
There are also dispose methods for ComponentPeer and MenuComponentPeer, but you only need worry about those if your code allocates them.
Some people originally thought not.
Please see the site http://hem.passagen.se/carebear/fraggame.htm which has the Frag Island game (a quake-style game) written in 100% Java. You play it as an applet, by browsing the above site. If you do it at work, watch out -- it's noisy!
Take a look at the Java Collection Framework, a group of classes that are
part of Java 1.2. These classes implement general-purpose data structures,
and they will become widely used.
The documentation for JDK 1.2 explains that the Collection Framework defines three kinds of things:
The standard interfaces are Collection, Set, List and Map, plus the more specialised SortedSet and SortedMap. Lists have duplicate elements whereas Sets do not. Finer distinctions such as immutability are defined in the implementor classes, enforced by throwing runtime exceptions. See the JDK 1.2 documentation for a full discussion.
For more about sorting prior to JDK 1.2, look at the class SortDemo in the demo directory of the JDK. Alternatively, use one of the several classic sorts available from Roedy Green. They are supplied free with heavily commented Java source code.
See "QuickSort", "HeapSort" and "RadixSort" in the Java glossary at http://mindprod.com/index.html.
Also, try the Java Generic Library. This library (JGL) is freely downloadable from http://www.objectspace.com/
Also Visual Engineering has JChart at: http://www.ve.com. No licensing fees.
Visual Numerics has its Java Numeric Library available for download at http://www.vni.com/products/wpd/jnl/jnl_1_0.html. They offer the JNL as a proposed standard library for numerical functions missing from Java.
Somebody has done just that. Look at
http://www.tardis.ed.ac.uk/~skx/java/Shell/
Indeed, there are. The Java3D Repository
http://java3d.sdsc.edu/
There is one from ORO Inc. They dissolved as a corporation,
but one of the founders maintains the software at
http://www.quateams.com/oro.
For other sources, see
http://www.meurrens.org/ip-Links/Java/regex/index.html
And don't forget to check out Lava -- a set of Java classes designed to support programmers who develop console-mode applications and/or C programmers who are converting to Java. The first release of Lava has printf and other text formatting, encryption, parsing and miscellaneous I/O. Lava can be downloaded from http://www.newbie.net/sharky/lava/
Also consider the Java programming langauge version of the Unix find command. It offers Regex filename matching, mindepth, maxdepth, symlink follow / no follow, file type matching all cross-platform. The package is at http://www.rule-of-eight.com/en/components/
There are several possibilities.
Jazilla is Mozilla (Netscape Communicator free source) ported to Java.
In other words, a free source browser that supports Java programming language
and Javascript,
written in the Java programming language!
You can get more information, and volunteer to help with the project at http://www.jazilla.org/
In the June 1999 JavaOne conference, Palm Pilot V's were available with
a small JVM known as KJava installed on them. KJava was an early
access release, and is expected to become generally available later
in 1999.
This is an astonishing piece of work as the Pilot has
such a small memory footprint.
There is a Java-PalmPilot Project called "jSyncManager"
which allows PalmPilot synchronization and jConduit development in
pure Java. See
http://yaztromo.idirect.com/java-pilot.html.
If you can run Java 1.1 and Sun's Communications API,
you can run jSyncManager.
Dippy Bird is Java documentation in WinHelp format, which can be used
directly on Windows desktops, and has a searching utility.
The developer of the Dippybird project, Bill Bercik, has stopped further
work on the project due to lack of time and funds.
Instead you can use
http://www.confluent.fr/javadoc/JavadocE.htm
which has a more up to date Java WinHelp doc.
You can get still get the Dippy Bird download at
http://www.dippybird.com/jdk111.exe (JDK 1.1).
Note that on NT 4.0 you need to change the generated shortcut to
point to NT's 32-bit WinHelp.
Take a look at GraphMaker -- a complete full-featured Java application
for creating and searching graphs. It is available under GPL with source,
and uses the latest Swing JFC features.
See
http://home.earthlink.net/~nfiedler/graph/
Public spirited programmer and Java supporter Dean S. Jones has
created a collection of over 100 icons for use in Java technology freeware.
They are available on the Java Lobby site at
http://webart.javalobby.org/jlicons/.
UML is the Unified Modeling Language. It is unified in the sense that it
draws together ideas from a couple of earlier software design languages.
UML is an emerging standard for diagrams of object-oriented classes.
It was devised by Grady Booch, Ivar Jacobsen, and James Rumbaugh, and
it unifies several popular existing notations.
A UML product is available from Rational Software, who are the biggest people behind UML, and who also offer a tutorial CD for free. See http://www.rational.com/uml/index.jtmpl There are some whitepapers too, but there don't seem to be any free online tutorials.
See http://www.togetherj.com/ for information on Together/J. That is a platform-independent UML product that supports round-trip engineering for Java. Whiteboard version is free.
The JCampus site at
http://www.jcampus.org
has links and connections to Java CS Dept. courses, assignments,
academic papers and Java-related events. JCampus is a non-profit,
online Community for CS Dept. professors, students and staff who
are teaching, learning and using the Java programming language.
It is the Java list of Infrequently Answered Questions, a FAQ
maintained by Peter Norvig, author of the book "Artificial
Intelligence - A Modern Approach". Take a look at the Java IFAQ
at
http://www.norvig.com/java-iaq.html
There's a lot of good information in that document.
PDF (Portable Document Format) is the text publishing format
defined by Adobe. Acrobat is
the technology to display and print PDF files. Adobe supplies
the client (document reading) software for free. There is a
PDF toolkit written in the Java programming language
at
http://www.etymon.com. Even better it is GPL'd. It is more a
toolkit for programmers embedding PDF in their products, than
an end-user technology though. It doesn't have a GUI for
displaying PDF for example.
IBM has a very good search engine for developers
http://www.ibm.com/java
Quite a lot of languages compile to Java bytecode, more than 60
at the last count. See the webpage
http://grunge.cs.tu-berlin.de/~tolk/vmlanguages.html
See www.distinct.com.
It implements a subset of RPC, and is a commercial, supported
product. You can review RFCs 1831 and 1832 for information on
the full protocol. Java programming language uses the same endianness as RPC's
external data representation (network byte order), so all the Java technology
file reads/writes can be used directly.
Netbula recently released Java RPC, a fully compatible port of ONC RPC to Java technology. The binary package can be downloaded for evaluation from http://netbula.com/javarpc/
See also http://www.nc-labs.com
The specifications are in RFC 1831 (the RPC protocol spec) and RFP 1832 (the XDR spec).
Yes. See
http://www.mindspring.com/~chroma/docwiz/docwizApplet.html
for a Java development tool called DocWiz. It is the easiest way to
add JavaDoc comments to your code.
Yes. See
http://developerlife.com
It shows you how to use:
There is a great website that maintains descriptions and links to
descriptions of hundreds of file formats. The site is at:
http://www.wotsit.org/
It shows you how the files are structured, and makes it a lot
simpler for you to write code that creates/decodes such a file.
If the JVM takes about 15MB (say) in overhead, and a program takes 3MB,
then starting up a fresh JVM for each program is slow and wasteful.
If a single copy of the JVM and libraries could instead be shared
among multiple Java applications there would be less overhead and
everything would run faster.
That observation was the guiding force behind the echidna project to support a JVM that could run multiple applications. See the site http://www.javagroup.org/echidna/ for more details.
The JaWavedit java code lets you edit .wav and .au files.
It can be found at
http://www.bome.com/JaWavedit/. It's free to use.
If you are inspired to write freeware like this yourself, many file formats are explained and described at http://www.wotsit.org
Java programmer Jason Shattu has released Java2HTML Tool
which is a simple-to-use tool which converts Java Source Code
into colorized and browsable HTML. You can find the details
at
http://www.vaegar.f9.co.uk/java2html.html
The Java2HTML tool has many features, and was JARS rated in the top 25%. Take a look and check it out for yourself!
The FAQ for Java on the Apple Mac is at
http://www.outlawcafe.org/MRJ-FAQ/
A jolly little song that explains how to solve commonly-encountered problems in Java.
The FAQ Melody
by Antranig Basman.
On the First Day of Christmas, my true-love said to me:
Read the F-A-Q.
On the Second Day of Christmas, my true-love said to me:
My Image isn't drawing;
Read the F-A-Q.
On the Third Day of Christmas, my true-love said to me:
My Pixels are not grabbing,
My Image isn't drawing,
Read the F-A-Q.
On the Fourth Day of Christmas, my true-love said to me:
My Layout is not laying,
Pixels are not grabbing,
Image isn't drawing,
Read the F-A-Q.
On the Fifth Day of Christmas, my true-love said to me:
Null - Pointer - Exception!
My Layout is not laying,
Pixels are not grabbing,
Image isn't drawing,
Read the F-A-Q.
On the Sixth Day of Christmas, my true-love said to me:
Netscape will not run it,
Null - Pointer - Exception!
Layout is not laying,
Pixels are not grabbing,
Image isn't drawing,
Read the F-A-Q.
On the Seventh Day of Christmas, my true-love said to me:
J++ don't mind it,
Netscape will not run it,
Null - Pointer - Exception!
Layout is not laying,
Pixels are not grabbing,
Image isn't drawing,
Read the F-A-Q.
On the Eighth Day of Christmas, my true-love said to me:
Threads they are a-blocking,
J++ don't mind it,
Netscape will not run it,
Null - Pointer - Exception!
Layout is not laying,
Pixels are not grabbing,
Image isn't drawing,
Read the F-A-Q.
On the Ninth Day of Christmas, my true-love said to me:
Dialogs-a-hanging,
Threads they are a-blocking,
J++ don't mind it,
Netscape will not run it,
Null - Pointer - Exception!
Layout is not laying,
Pixels are not grabbing,
Image isn't drawing,
Read the F-A-Q.
On the Tenth Day of Christmas, my true-love said to me:
Time-zone's in Pacific,
Dialogs-a-hanging,
Threads they are a-blocking,
J++ don't mind it,
Netscape will not run it,
Null - Pointer - Exception!
Layout is not laying,
Pixels are not grabbing,
Image isn't drawing,
Read the F-A-Q.
On the Eleventh Day of Christmas, my true-love said to me:
Docs are not specific,
Time-zone's in Pacific,
Dialogs-a-hanging,
Threads they are a-blocking,
J++ don't mind it,
Netscape will not run it,
Null - Pointer - Exception!
Layout is not laying,
Pixels are not grabbing,
Image isn't drawing,
Read the F-A-Q.
On the Twelfth Day of Christmas, my true-love said to me:
File I/O's horrific,
Docs are not specific,
Time-zone's in Pacific,
Dialogs-a-hanging,
Threads they are a-blocking,
J++ don't mind it,
Netscape will not run it,
Null - Pointer - Exception!
Layout is not laying,
Pixels are not grabbing,
Image isn't drawing;
You Should Read The-e F-A-Q!
Entire document is copyright 1997, 1998, 1999 by Peter van der Linden.
I am maintaining a FAQ list to address specifically programming issues
(not a general tutorial on the Java programming language).
Please mail suggested FAQ entries including
answer to faqidea on the site afu.com.
Question with answer gets you a credit in the FAQ.
Peter van der Linden, Sun Certified Java Programmer.