Odi's astoundingly incomplete notes
New entriesCode
back | nextJDK nio Bug
It's once a year or so that I find a bug in the Java library. This time it's in the
By the way, most sample code on the net for copying data with nio is wrong. The following is the correct way of doing it. The crux is that the read and write method may not read/write all of the buffer!
java.nio.Channels.newChannel
method. It contains a buggy check for a class name:
String inClass = in.getClass().toString();
if (inClass.equals("java.io.FileInputStream"))
This test will never succeed because toString does not return the class name. They should have used getClass().getName()
instead. It's not a very bad bug, but it prevents some optimizations with FileChannels.By the way, most sample code on the net for copying data with nio is wrong. The following is the correct way of doing it. The crux is that the read and write method may not read/write all of the buffer!
java.nio.ByteBuffer buffer = java.nio.ByteBuffer.allocate(bufsize); buffer.clear(); // the loop is safe for partial reads and writes while (in.read(buffer) >= 0 || buffer.position() > 0) { buffer.flip(); out.write(buffer); buffer.compact(); }Similar with transferTo/From:
FileChannel fc = ... long len = fc.size(); long pos = 0L; while (pos < len) { pos += fc.transferTo(pos, len, outch); }
FileChannel fc = ... long len = fc.size(); long pos = 0L; while (pos < len) { pos += fc.transferFrom(inch, pos, len); }
Alegedly fixed in 1.6
Add comment
Oracle: convert LONG to VARCHAR
Seems hard, but is simple (at least with 10g):
mystring := substr(mylong, 1);With older Oracle versions your milage may vary.
This only seems to work in PLSQL. A SQL variant still eludes me...
Todd Brook
Todd Brook
Making JSP content assist work in Eclipse
Eclipse has had nice HTML, JavaScript and JSP editor for a while now. They are part of the J2EE Standard Tools (JST) of the Web Tools Platform (WTP). When I create webapps I usually have the JSP pages in a WAR-like directory structure. This way I can point a Tomcat Context directly to this directory.
src +- java-webapps +- app1 +- index.jsp +- WEB-INF +- jsp | +- home.jsp | +- form.jsp | +- lib | +- taglibs-input-1.0.jar | +- taglibs-standard-1.1.2.jar | +- spring-1.2.8.jar +- web.xml +- spring-servlet.xml +- applicationContext.xmlIf in the JSP editor you get warning marks on all tags from a taglib, then you need to put the taglib JARs into the
WEB-INF/lib
directory.
It's not enough to have them in the classpath! It looks like the editor somehow recognizes the WAR structure and tries to get the libraries from it.Source code management best practices
One of the best articles about this topic I have ever read. Once again it's speaking deeply from my heart.
Diffing by date on a CVS branch
I wanted to compare my current working copy of a CVS branch to a previous version by date. I had to discover that Eclipse does not provide this possibility: you can specify CVS revisions by date, but only on CVS HEAD. So I had no other choice but do this from the command line:
cvs co -r BRANCH_abc -D '2006-09-25 12:25' mymodule cvs diff -r BRANCH_abc
Thanks, I found this out the hard way too.
- Mike
- Mike
Import an oracle dump into any tablespace
Oracle is a great DB. But when it comes to tablespaces its management features suck. There is no easy way to move all objects (tables, indexes, sequences, LOBs etc.) between tablespaces at once for instance. (You need to generate SQL for every object type.) Another big problem is when you move data with export / import between different DB instances. Usually tablespace names are completely different between different DB instances. But Oracle's imp utility does not directly support import into a tablespace of a different name. So you have to do some nasty workaround:
- Use the imp utility's INDEXFILE= option to create a script.
- Edit this script: remove the REM from the CREATE TABLE statetments, get rid of the spurious "... 123 rows", replace all TABLESPACE XXX clauses with the appropriate ones, replace all schema names with yours if necessary.
- Run this script to create the empty schema.
- Disable all constraints.
- Remove the UNLIMITED_TABLESPACE privilege from the user.
- Give the user unlimited table space quota on the tablespaces you want.
- Import the dump with IGNORE=y and FROMUSER and TOUSER options if necessary.
- Enable all constraints.
- Revert your tablespace quota settings.
SELECT 'ALTER TABLE '|| table_name ||' MOVE TABLESPACE USERS;'Execute the generated statements. After that the new tablespace should be empty and can be removed again.
FROM user_tables WHERE tablespace_name='xxx';
SELECT 'ALTER INDEX '|| index_name ||' REBUILD TABLESPACE USERS;'
FROM user_indexes WHERE tablespace_name='xxx';
SELECT 'ALTER TABLE '|| table_name ||' MOVE LOB ('
|| column_name ||') STORE AS (TABLESPACE USERS);'
FROM user_lobs WHERE tablespace_name='xxx';
Copy to an SMB share
Here is how to copy a file from a Linux machine to a remote Windows share without mounting. It uses the smbclient:
smbclient '\\host\share' password -D 'the/directory' \Or if you like it more secure, use an auth file:
-U username -c 'put myfile.txt'
cat smb.auth username = marvin password = valium domain = galaxy smbclient '\\host\share' -D 'the/directory' \
-A smb.auth -c 'put myfile.txt'
Cloneable does not supersede the copy constructor
Common misconception: "Copy constructors are a relic from the C++ ages. In Java we have the Cloneable interface."
The clone method is handy when one has an object of an unknown (sub)class and you need a copy. You will most likely end up with an object of the same class. Consider the following scenario: You have a business object and you need to "split" it. So you need to copy parts of this structure. Some of the objects will be of a subtype of the declared field. So only their clone method can correctly perform the copy.
The copy constructor is much more type-safe. You know exactly which class you create and its constructor accepts an object of a well-known class. A copy constructor for example allows you do "downcast" an object. Consider the following scenario: You have an object of the last final class in a class hierarchy. Now you have to pass this object on to an XML serialization but you only want fields of a superclass to be serialized. A copy constructor of that superclass will solve the problem.
A variant of the copy constructor is the template pattern. In the template pattern the copy constructor accepts a template object of a superclass to initialize its state.
The clone method is handy when one has an object of an unknown (sub)class and you need a copy. You will most likely end up with an object of the same class. Consider the following scenario: You have a business object and you need to "split" it. So you need to copy parts of this structure. Some of the objects will be of a subtype of the declared field. So only their clone method can correctly perform the copy.
The copy constructor is much more type-safe. You know exactly which class you create and its constructor accepts an object of a well-known class. A copy constructor for example allows you do "downcast" an object. Consider the following scenario: You have an object of the last final class in a class hierarchy. Now you have to pass this object on to an XML serialization but you only want fields of a superclass to be serialized. A copy constructor of that superclass will solve the problem.
A variant of the copy constructor is the template pattern. In the template pattern the copy constructor accepts a template object of a superclass to initialize its state.
Future desktop interaction
There is a nice video about how future interaction with your PC's desktop may look like. What seems fancy and amazing to you, may feel very natural for your kids.