1. How I installed a Java development environment in my Ubuntu 20.04 machine
  2. In late April 2021 I had to install a Java development environment in my Ubuntu 20.04 machine and be able to use my Ant/Ivy-based build machinery with local IVY repositories. What follows is a writeup of how I proceeded.

    The Java 11 runtime was already installed so I only needed to install the JDK with:

    sudo apt install javac
    This installed JDK 11

    It should be noted that in the previous Java developement environment I had on the T460 ThinkPad machine I had Java 8. This caused a problem further down the road (read on).

    I then installed Ant with:

    sudo apt install ant
    That gave me version 1.10.7 (instead of 1.9.6 I had on T460)

    The next question was how to install Ivy. Here, I tried various approaches and even though some initial ones were successful, in the end I used a different method. As documented, Ivy is simply a jar and it can be installed in two ways:

    1. locally, for the current user, at ~/.ant/lib
    2. in some global location which you can google

    Furthermore, in Ubuntu 20 there's also a third way:

    1. by using
      sudo apt install ivy
      which places the ivy.jar under /usr/share/java

    I tried methods #1 and #3 and both seemed to, sort of, work (not without problems). But, later, when I had to copy the entire /proj/DS.ots/ directory, this became moot as the Ivy jar is picked up from OTS and so I both purged the ivy package and removed the Ivy jar from ~/.ant/lib

    Next, I had to install some auxiallary Ant tasks (ant-contrib) which is some sort of abandonware available at: sourceforge. This project only makes the sources available (not the compiled library) and I had some issues getting the code to compile. Fortunately, once I copied over the /proj/DS.ots directory as mentioned above, this point too became moot as the ant-contrib library is available there too, as well, as an OTS dependency.

    I then had to edit the various build.xml scripts as in the T460 laptop they used absolute paths to reach the home of the archetype-java-ant-ivy/build-system-machinery whereas in the P320 desktop I am using relative paths. In the same spirit, I also had to change certain symlinks to use relative, instead of absolute, paths (the latter never being a good idea).

    In the save vein I had to change some hardcoded executables, e.g. the javac.executable property in file /repos/prj/archetype-java-ant-ivy/build-system-machinery/build-env.properties

    Finally, another issue I had to solve was that in Java 11 the javax.activation package is not available (it has actually been retired since Java 9). As such I was getting a compilation error in the ~/repos/prj/js-react-leaflet/common project. The solution was found in SO. To implement the SO solution I had to add the following ivy dependency in the ivy,xml file of the above-mentioned project.

    <dependency org="com.sun.activation" name="javax.activation" rev="1.2.0" conf="compile-time->master"/> 

    However, adding the above depenency wasn't enough. By default, the various projects only rely on the Local File-System Based Ivy Repository (LFSBIR). This is for security and determinism / reproducability purposes. Since this was a new dependency it wasn't available in the LFSBIR I copied over from the ThinkPad T460 laptop. As such to enable direct retrieval of repos from the Maven central repository (if they can't be found in the LFSBIR) I had to further modify the build.xml of the ~/repos/prj/js-react-leaflet/common project mentioned above so as to define the property enable-ibiblio and set its value to "true". This was done as follows:
    <property name="enable-ibiblio" value="true"/>

    After the above modifications, I was able to fully build the js-react-leaflet project. However, I also wanted to recreate the entire LFSBIR from scratch as opposed to copying it over from the ThinkPad T460 machine and also include this new dependency there (in the LFSBIR) as opposed to setting the enable-ibiblio property to true. To that end I modified file ~/repos/prj/archetype-java-ant-ivy/ivy-importation-to-local-fs/build-ivy-install-local.xml and discoverd, in the process, that I had to further retrieve a couple of more additional packages there. During this process I also changed the properties in the /data/asc3/mperdike/ directory to make it writable. I was then able to fetch a fresh /data/asc3/mperdike/local-ivy-repository and I verified that its size profile was similar to the previous one.

    I then removed the enable-ibiblio property from the build.xml file in the ~/repos/prj/js-react-leaflet/common project , cleaned the Ivy cache, re-build everything (including the sibling rest-backend project and so successfully concluded this process.

    update June 25 2021

    When trying to implement the new Java-based IACS backend I ended up adding:
    <dependency org="javax.activation" name="activation" rev="1.1" conf="compile-time->master"/>
    … which also worked. Initially I had tried to use rev="1.1.1" (from some other SO answer I won't bother linking to) but that failed as that exact version was not present in the LFSBIR.

  3. How to install OpenJDK 1.8 in Ubuntu 16.04
  4. The following worked like a charm in June, 2019

    $ sudo apt-get install openjdk-8-jdk
    $ sudo apt-get install openjdk-8-jre
    $ sudo update-alternatives --config java
    $ sudo update-alternatives --config javac

    With hindsight it was probably uncessary to install the JRE once I had already installed the JDK but then again it didn't hurt either.

    NB: even after updating the alternatives, the JAVA_HOME environment in my shell was:

     $ echo $JAVA_HOME
    … the above was on account of a file in /etc/profile.d with the following content:
    $ cat /etc/profile.d/jdk.sh
    export J2SDKDIR=/usr/lib/jvm/java-8-oracle
    export J2REDIR=/usr/lib/jvm/java-8-oracle/jre
    export PATH=$PATH:/usr/lib/jvm/java-8-oracle/bin:/usr/lib/jvm/java-8-oracle/db/bin:/usr/lib/jvm/java-8-oracle/jre/bin
    export JAVA_HOME=/usr/lib/jvm/java-8-oracle
    export DERBY_HOME=/usr/lib/jvm/java-8-oracle/db

  5. How to compare Java JARs or WARs
  6. Java JAR files may be compared with the awesome package change analyzer pkgdiff — which in fact can be used to visualize changes in any kind of Linux software package.

    $ pkgdiff dist/cxcaccount-1.0.0.war dist.safe/cxcaccount-1.0.0.war
    reading packages ...
    comparing packages ...
    creating changes report ...
    result: CHANGED (0.01%)
    see detailed report:
    $ echo $?

  7. How to deal with: There is insufficient memory for the Java Runtime Environment to continue.
  8. While compiling (using Ant) on a machine with 12 cores I encountered the following failure while running ant build:

        [javac] # There is insufficient memory for the Java Runtime Environment to continue.
        [javac] # Cannot create GC thread. Out of system resources.
        [javac] # An error report file with more information is saved as:
        [javac] # /tmp/jvm-21655/hs_error.log

    Following the advice given in this SO answer I did:

    export _JAVA_OPTIONS="-XX:ParallelGCThreads=2"
    NB: there is, indeed, an underscore at the beginning. The name of the variable is _JAVA_OPTIONS, not JAVA_OPTIONS. Read up more on this (undocumented) environment variable here.

    That fixed it. Apparently the JVM was creating too many garbage collection threads (because of the high number of cores) and that caused the memory exhaustion.

  9. awesome tools to probe stack traces inside running JVMs
  10. jstack and jinfo. jstack in particular shows you the stack trace of every thread running in the particular JVM whose pid you provide as argument.
  11. java.lang.NoClassDefFoundError: junit/framework/JUnit4TestAdapterCache in Ant version ≤ 1.9.4
  12. installing Java 7 64bit on Ubuntu 14.04.5
  13. On August 2016 I followed the following procedure (source mutatis mutandis) to install Oracle Java 1.7 after I had downloaded from the Oracle site file jdk-7u80-linux-x64.tar.gz

    NB: I have copied the below instructions from the article linked above and I haven't replaced all filenames and version names, but the procedure should be obvious.

    1. Download the 32-bit or 64-bit Linux from "http://www.oracle.com/technetwork/java/javase/downloads/index.html" "compressed binary file" - it has a ".tar.gz" file extension.
    2. Uncompress it:
      tar xvfz jdk-7u80-linux-x64.tar.gz
      … the JDK 7 package is extracted into ./jdk1.7.0_75 directory.
    3. Now move the JDK 7 directory to /usr/lib
      sudo mkdir -p /usr/lib/jvm
      sudo mv ./jdk1.7.0_75 /usr/lib/jvm/
    4. Now run
      sudo update-alternatives --install "/usr/bin/java" "java" "/usr/lib/jvm/jdk1.7.0_75/bin/java" 1
      sudo update-alternatives --install "/usr/bin/javac" "javac" "/usr/lib/jvm/jdk1.7.0_75/bin/javac" 1
      sudo update-alternatives --install "/usr/bin/javaws" "javaws" "/usr/lib/jvm/jdk1.7.0_75/bin/javaws" 1
      This will assign Oracle JDK a priority of 1, which means that installing other JDKs will replace it as the default. Be sure to use a higher priority if you want Oracle JDK to remain the default.
    5. Correct the file ownership and the permissions of the executables:
      sudo chmod a+x /usr/bin/java
      sudo chmod a+x /usr/bin/javac
      sudo chmod a+x /usr/bin/javaws
      sudo chown -R root:root /usr/lib/jvm/jdk1.7.0_75
    6. Run
      sudo update-alternatives --config java
      You will see output similar to the one below - choose the number of jdk1.7.0_75 - for example 3 in this list (unless you have have never installed Java installed in your computer in which case a sentence saying "There is nothing to configure" will appear):
      $ sudo update-alternatives --config java
      There are 3 choices for the alternative java (providing /usr/bin/java).
        Selection    Path                                  Priority   Status
      * 0            /usr/lib/jvm/java-6-oracle1/bin/java   1047      auto mode
        1            /usr/bin/gij-4.6                       1046      manual mode
        2            /usr/lib/jvm/java-6-oracle1/bin/java   1047      manual mode
        3            /usr/lib/jvm/jdk1.7.0_75/bin/java      1         manual mode
      Press enter to keep the current choice[*], or type selection number: 3
      update-alternatives: using /usr/lib/jvm/jdk1.7.0_75/bin/java to provide /usr/bin/java (java) in manual mode
      Repeat the above for:
      sudo update-alternatives --config javac
      sudo update-alternatives --config javaws
  14. how to find the 32-bit or 64-bit memory model status of an existing Java process
  15. The following command provides a wealth of information provided the PID is known:
    NB: if the process was run as a service you need to sudo that.
    So for instance the following can be done:
    $ sudo jinfo 1752 | grep arch.data.model
    Attaching to process ID 1752, please wait...
    Debugger attached successfully.
    Server compiler detected.
    JVM version is 24.80-b11
    sun.arch.data.model = 32
  16. how to find whether the java program is the 32 or 64 bit
  17. on 32-bit vs. 64-bit with respect to java and javac
  18. Java bytecode is platform independent. So code compiled with either 32 or 64-bit javac should play with either 32 or 65-bit java.
  19. NoRouteToHostException
  20. It sometimes transpires that, even when socket connections are properly closed, one can still run out of ephemeral ports (if a large number of connections are rapidly opened and closed) due to the (otherwise properly closed) sockets remaining in the TIME_WAIT state. I've actually encountered this problem when I was opening and closing a great number of database connections to the PostgreSQL database (database connections which naturally, under the hood, relied on TCP connections).
    NB:This problem occurs even when database or socket connections are properly closed. It is NOT an issue of connection leakage!
    The way to monitor for this problem progressively (and watch the population of TIME_WAIT sockets grow alarmingly) is via (in Ubuntu):
    netstat -a | grep TIME_WAIT | wc -l
    In my case I was met with an NoRouteToHostException exception (actual trace at the end of this note) when the count exceeded 20,000 or so. This is more or less consistent with the available port range in my machine which was reported as:
    $ cat /proc/sys/net/ipv4/ip_local_port_range 
    Apparently the solutions to this problem fall in four categories:
    The latter was the approach I followed in my case (by implementing an application-level result cache for some values I was fetching from the DB).

    Some useful links: SO question, Wikipedia article on ephemeral ports, article on TIME_WAIT in the TCP state machine.
    Actual real-world trace below:
    Exception in thread "main" _int.esa.esavo.common.ShowStopper: org.postgresql.util.PSQLException: The connection attempt failed.
              at _int.esa.esavo.dbbusiness.Statistics.repoNameFromIvoid(Statistics.java:216)
              at _int.esa.esavo.dbbusiness.RepoNameFromIvoidTransformer.transform(RepoNameFromIvoidTransformer.java:54)
              at _int.esa.esavo.dbbusiness.RepoNameFromIvoidTransformer.transform(RepoNameFromIvoidTransformer.java:18)
              at _int.esa.esavo.consoleutils.valgraph.VALGRAPHStatsPlot.transform2(VALGRAPHStatsPlot.java:419)
              at _int.esa.esavo.consoleutils.valgraph.VALGRAPHStatsPlot.produce(VALGRAPHStatsPlot.java:255)
              at _int.esa.esavo.consoleutils.valgraph.VALGRAPHStatsPlot.produce(VALGRAPHStatsPlot.java:180)
              at _int.esa.esavo.consoleutils.esaknife.MonthlyReports.produceStatisticsByResource(MonthlyReports.java:234)
              at _int.esa.esavo.consoleutils.esaknife.MonthlyReports.produceStatistics(MonthlyReports.java:194)
              at _int.esa.esavo.consoleutils.esaknife.MonthlyReports.produceReports(MonthlyReports.java:184)
              at _int.esa.esavo.consoleutils.esaknife.MonthlyReports.produce(MonthlyReports.java:136)
              at _int.esa.esavo.consoleutils.esaknife.EsavoSwissKnife.main(EsavoSwissKnife.java:78)
    Caused by: org.postgresql.util.PSQLException: The connection attempt failed.
           at org.postgresql.core.v3.ConnectionFactoryImpl.openConnectionImpl(ConnectionFactoryImpl.java:150)
           at org.postgresql.core.ConnectionFactory.openConnection(ConnectionFactory.java:66)
           at org.postgresql.jdbc2.AbstractJdbc2Connection.(AbstractJdbc2Connection.java:125)
           at org.postgresql.jdbc3.AbstractJdbc3Connection.(AbstractJdbc3Connection.java:30)
           at org.postgresql.jdbc3g.AbstractJdbc3gConnection.(AbstractJdbc3gConnection.java:22)
           at org.postgresql.jdbc4.AbstractJdbc4Connection.(AbstractJdbc4Connection.java:30)
           at org.postgresql.jdbc4.Jdbc4Connection.(Jdbc4Connection.java:24)
           at org.postgresql.Driver.makeConnection(Driver.java:393)
           at org.postgresql.Driver.connect(Driver.java:267)
           at org.apache.commons.dbcp.DriverConnectionFactory.createConnection(DriverConnectionFactory.java:38)
           at org.apache.commons.dbcp.PoolableConnectionFactory.makeObject(PoolableConnectionFactory.java:582)
           at org.apache.commons.pool.impl.GenericObjectPool.borrowObject(GenericObjectPool.java:1148)
           at org.apache.commons.dbcp.PoolingDataSource.getConnection(PoolingDataSource.java:106)
           at org.apache.commons.dbcp.BasicDataSource.getConnection(BasicDataSource.java:1044)
           at _int.esa.esavo.dbbusiness.BaseDBFacade.getConnection(BaseDBFacade.java:16)
           at _int.esa.esavo.dbbusiness.Statistics.repoNameFromIvoid(Statistics.java:172)
           ... 10 more
    Caused by: java.net.NoRouteToHostException: Cannot assign requested address
           at java.net.PlainSocketImpl.socketConnect(Native Method)
           at java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:339)
           at java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:200)
           at java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:182)
           at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:392)
           at java.net.Socket.connect(Socket.java:579)
           at java.net.Socket.connect(Socket.java:528)
           at java.net.Socket.(Socket.java:425)
           at java.net.Socket.(Socket.java:208)
           at org.postgresql.core.PGStream.(PGStream.java:62)
           at org.postgresql.core.v3.ConnectionFactoryImpl.openConnectionImpl(ConnectionFactoryImpl.java:76)
           ... 25 more
  21. Ant failing to find Ivy jar
  22. It appears that Ant 1.7 fails to find the Ivy jar if placed in the user-specific location (e.g. ~/.ant/lib/ivy-2.3.0.jar).
    E.g. the following build.xml file:
        name="test" default="test-ivy">
    <target name="test-ivy">
        <ivy:settings />
    … fails with
    $ whoami
    $ ant
    Buildfile: build.xml
    /home/voops/test/build.xml:7: Problem: failed to create task or type antlib:org.apache.ivy.ant:settings
    Cause: The name is undefined.
    Action: Check the spelling.
    Action: Check that any custom tasks/types have been declared.
    Action: Check that any / declarations have taken place.
    No types or tasks have been defined in this namespace yet
    This appears to be an antlib declaration. 
    Action: Check that the implementing library exists in one of:
            -a directory added on the command line with the -lib argument
    Total time: 0 seconds

    In this case, and for Ant 1.7, the problem is solved by adding the following element:
        <taskdef uri="antlib:org.apache.ivy.ant" resource="org/apache/ivy/ant/antlib.xml" classpath="${user.home}/.ant/lib/ivy-2.3.0.jar"/>
    … resulting in the following build.xml file that "builds" correctly:
        name="test" default="test-ivy">
        <taskdef uri="antlib:org.apache.ivy.ant" resource="org/apache/ivy/ant/antlib.xml" classpath="${user.home}/.ant/lib/ivy-2.3.0.jar"/>
    <target name="test-ivy">
        <ivy:settings />
    Since Ant is supposed to look in ~/.ant/lib for libraries in any case (and the error message indicates as such), it is a mystery why the location of the Ivy jar has to be explicitly spelled out. See also my SO question on the matter. At any rate, as noted in my question, this problem does not appear with Ant versions 1.8.2 and 1.9.4.
  23. Ivy installation locations
  24. Ivy is just a jar file. This jar can be placed in two locations depending on whether we want to do a system-wide or a user-specific installation:
    NB. user-specific installation (if present) obviously trumps the system-wide. So, in the above case the version of Ivy installed is 2.3, not 2.2.

  25. sometimes you just have to use find to invoke a series of Ant files ..
  26. In those cases the below archetype will prove helpful:
    #!/usr/bin/env bash
    START=$(/bin/date +%s)
    while IFS= read -r -u3 -d $'\0' file; do
            echo -n "building $file ..."
            ant -f "$file" build > "$file.log" 2>&1 &&
               echo "success" ||
               { echo "failure" && cat "$file.log" ; RESULT=1 ; break; }
            COUNTER=$((COUNTER + 1))
    done 3< <(find a b c d -iname build.xml -print0)
    END=$(/bin/date +%s)
    if [ $RESULT -eq 0 ]
        echo "! build successfully concluded for all $COUNTER projects in $DIFF seconds"
        echo "X build failed after $COUNTER projects"
  27. simple solution to quickly profile a Java program
  28. Use the "random pause" technique with the help of the jstack program. So, if the java process id (easily obtained with jps) is 30600, invoking the follow a few (~10) times:
    jstack -l 30600
    ... should give you a pretty good idea of where the performance bottleneck is. SO posts: here and here.
  29. how to see the stack of a frozen Java program if jconsole and jvisualvm don't work for some reason.
  30. StackOverflow question here. Java sample code (to test kill -3, kill -11, ulimit -c unlimited and jstack) in:
  31. monitor and examine JVMs in the system
  32. There's a number of graphical utilities that allow one to view stacks, profile, examine memory usage etc.: I tend to prefer jvisualvm over jconsole since in addition to the latter's graphs it can provide snapshots of number of objects created (broken down per class) showing total # of instances and total bytes allocated for each class, as shown below:

    (click to enlarge)
  33. list JVMs running in the system
  34. jps
    ... to also print the arguments passed to their main method use:
    jps -p
  35. how to find from the command line if Java is 64 bit
  36. java -d64 -version
  37. JAX-WS 2.2.8 RI documentation and wsimport Ant task
  38. The documentation for the latest (at the time of this writing) JAX-WS RI (GlassFish Metro), including wsimport Ant task is found here.
  39. how to configure **wsgen** as Ant task
  40. This SO post is useful. Also, check out the playground examples: +++
  41. how to find executable and Java version used by Ant
  42. There are three ways:
    1. I've created script ant_mod in ~/tools which echoes the java executable used to spawn ant
    2. use: ant -verbose
    3. use: ant -diagnostics | grep java.vm
  43. installOracle JDK 7 on Ubuntu 12.04 (precise)
  44. On 2013-09-19 I followed these instructions and it worked fine. Basically I executed the following steps:
    sudo add-apt-repository ppa:webupd8team/java
    sudo apt-get update
    sudo apt-get install oracle-java7-installer

    NB: following the above, don't forget to update the JAVA_HOME, PATH and CLASSPATH variables, if set in .bashrc.

    2014-06-02 UPDATE: I tried again the above procedure (this time only the apt-get update/install part) and it smoothly updated Java from 7u40 to 7u60. Also, after the update, the installation directory remained the same (/usr/lib/jvm/java-7-oracle), so no updating of JAVA_HOME, PATH and CLASSPATH was required.

    See some bullet points below for an alternative way that also seemed to have worked in the past.
  45. SAX vs DOM parsing in a nutshell
  46. source
  47. yet another way to install Apache ivy in Ubuntu
  48. NB: there's other notes on the same subject offering alternative ways. At the very least see this note on Ivy locations.
    This was discovered by way of experimentation, I am not sure how well advised it is:

    1. download and explode the ivy tarball (apache-ivy-2.2.0-bin.tar.gz)
    2. copy the file ivy-2.2.0.jar to where the Ant libs are kept:
    3. sudo cp ivy-2.2.0.jar /usr/share/ant/lib/
    4. run the install target in an Ant project of mine:
    5. cd ~/esavo-reg/playground/ivy/02-install
      ant install
    6. you're good to go!
  49. install Apache ivy in Ubuntu
  50. NB: there's other notes on the same subject offering alternative ways. At the very least see this note on Ivy locations.
    original article here

    After doing an:
    sudo apt-get install ivy
    ... the ivy.jar doesn't show up where it's supposed to (/usr/share/ant/lib) but is instead found in folders like /usrshare/doc/ivy and /usr/share/java/.

    So one has to do a:
    sudo ln -s -T /usr/share/java/ivy.jar /usr/share/ant/lib/ivy.jar
  51. install Oracle Java JDK 7 on Ubuntu 12.04 (precise)
  52. Original article here

    1. download the JDK tar.gz and extract it
    2. create a new folder:
    3. sudo mkdir -p /usr/lib/jvm/jdk1.7.0
    4. move the extracted contents of the JDK to the new location:
    5. sudo mv /* /usr/lib/jvm/jdk1.7.0/
    6. run the following commands one by one:
    7.      sudo update-alternatives --install "/usr/bin/java" "java" "/usr/lib/jvm/jdk1.7.0/bin/java" 1
           sudo update-alternatives --install "/usr/bin/javac" "javac" "/usr/lib/jvm/jdk1.7.0/bin/javac" 1 
           sudo update-alternatives --install "/usr/bin/javap" "javap" "/usr/lib/jvm/jdk1.7.0/bin/javap" 1
           sudo update-alternatives --install "/usr/bin/javaws" "javaws" "/usr/lib/jvm/jdk1.7.0/bin/javaws" 1
           sudo update-alternatives --install "/usr/bin/jar" "jar" "/usr/lib/jvm/jdk1.7.0/bin/jar" 1
           sudo update-alternatives --install "/usr/bin/wsimport" "wsimport" "/usr/lib/jvm/jdk1.7.0/bin/wsimport" 1
           sudo update-alternatives --install "/usr/bin/xjc" "xjc" "/usr/lib/jvm/jdk1.7.0/bin/xjc" 1

    2013-06-05 update:

    In an Ubuntu machine that had the OpenJDK JVM already installed (i.e. java but not javac, the first of the above series of instructions failed to change the version of java used (although it produced an exit code of 0). So I had to create the symbolic link myself. The rest of the commands succeeded. Maybe there exists a switch in update-alternatives that allows one to override previous alternatives (if that was the cause of this failure).
  53. Monitor a running JVM
  54. Use the jvisualvm Oracle program to attach to a running instance of the JVM and display various graphs. See below a possible use that tries to attach to the JBoss process (running in [s]tandal[one] mode):
    jvisualvm --openpid $(ps aux | grep java | grep tandal | awk '{print $2}'
  55. JBoss Application Server configuration directory
  56. This comes handy for storing JBoss-specific configuration parameters that cannot be part of an EAR:
    String serverConfUrl = System.getProperty("jboss.server.config.dir") ;
  57. UTF8 encoding in Java
  58. In general problems may occur both in the compile stage (javac) and in the execution stage (java). The following flags are pertinent:
    javac -encoding utf-8 X.java // or utf8, UTF-8, UTF8
    java -Dfile.encoding=UTF8 X
    Even the two settings above may not solve the problem if the font used by the terminal doesn't contain a rendering for a particular character (e.g. the 0x0222 character in the example below).
    public class X {
        public static void main (String args[]) {
    Also, the file.encoding trick may be ok for a small console program but maybe not with a server. You may want to use a special PrintStream instead. That is because the JVM runtime does attempt to find out what character encoding the environment outside the JVM uses, and apparently in your environment it gets a native character set of something else that UTF8. So, even if you have funky UTF-8 characters in your source, Java may be able to print them out in environments with some other native character encoding, if that other encoding happens to have a code point for the same character glyph. For example, source code with UTF-8 may contain the byte sequence [0xc3, 0xa4], signifying lower-case a-diaeresis character glyph. Now, if that source code is compiled properly, letting the compiler know that the source is in UTF-8 character set, and subsequently the code is run in an environment with ISO-8859-1 character set, the program will output just one byte, 0xE4. Also, if the same code is run in an environment configured for plain US-ASCII character set, it will output only a question mark (as US-ASCII character set does not have a glyph for the a-diaeresis character). See here for the full discussion.
  59. error:unmappable character for encoding Cp1252
  60. This is a problem that plagues Windows OS when compiling Java sources. Setting the following environment properties fixed the problem in one occassion:
  61. useful bash scriplet to generate Java classpath
  62. Often a number of jars are located inside a given folder (folder 'repo-wide-libs' in the example below). To construct a Java classpath that will include them all, do a:
    echo repo-wide-libs/*jar | sed 's, ,:,g'
    Alternatively one can use tr instead of sed:
    java -cp $(echo lib/*.jar | tr ' ' ':') ..
  63. how to solve 'unmappable character' problems in javac
  64. The problem is usually solved by adding the following line in the <javac> Ant task invocation:
    <compilerarg line="-encoding utf-8"/>
    (see examplary java-se build.xml in archetypes/ant)

    On some occassions I've also used:

    <compilerarg line="-encoding ISO-8859-1"/>
  65. install Oracle Java in Ubuntu
  66. (source)
    To install the latest Oracle Java 7 in Ubuntu (supports Ubuntu 12.04, 11.10, 11.04 and 10.04), use the commands below:
    sudo add-apt-repository ppa:webupd8team/java
    sudo apt-get update
    sudo apt-get install oracle-java7-installer
    After the installation finishes, if you wish to see if it was successful, you can run the following command:
    java -version
    It should return something like this:
    java version "1.7.0_04"
    Java(TM) SE Runtime Environment (build 1.7.0_04-b20)
    Java HotSpot(TM) Server VM (build 23.0-b21, mixed mode)