Sunday, April 17, 2011

» Workaround for Eclipse Helios JVM crashes

You might run into this too: when using Eclipse Helios (3.6.2 here), it sometimes crashes on an alleged double free in the JVM, detected by glibc.
That's actually a feature of glibc that serves to detect bugs and security issues, which kills a process that tries to free a previously allocated memory area that has already been freed.

In this case, however, it is most probably a false positive, but glibc still decides to kill the process.

The workaround is to run Eclipse with the environment variable MALLOC_CHECK_ set to 0. There are several ways to achieve this:

  1. when you run eclipse from a shell, run it like this:
    MALLOC_CHECK_=0 eclipse
  2. if you prefer to just run eclipse or by clicking on an icon, create the following file in your $HOME/bin, e.g. like this (just copy/paste into a shell):
    cat<<EOF >"$HOME/bin/eclipse"
    #!/bin/bash
    export MALLOC_CHECK_=0
    exec /usr/bin/eclipse "$@"
    EOF
    chmod 0755 "$HOME/bin/eclipse"
Note that with the latter option, you obviously need to adapt the fully qualified path to the eclipse script depending on how and where you installed it. If it comes from RPM packages, than /usr/bin/eclipse is fine. If, like me, you downloaded the tarball from eclipse.org and unpacked it somewhere under your home, you must change it accordingly -- e.g. to $HOME/apps/eclipse/eclipse

In any case, you should NOT add export MALLOC_CHECK_=0 to your ~/.profile or ~/.bashrc as that would turn off that glibc check for ALL the applications and processes you would run. And that's a bad idea.

Labels: , , ,

Friday, July 17, 2009

» TULH: latest openJDK 6 on openSUSE

(TULH = Trivial (or pointless ?) Ubuntu-Like Howto)

Purpose

Here is how to install the latest openJDK (the GPL'd branch of Sun's Java Virtual Machine) version 6 (the currently stable branch) on openSUSE 11.0-11.1

As root

You can simply copy/paste those blocks of commands into a shell. But note that they must be executed as the root user and, hence, first open a terminal (e.g. konsole on KDE, gnome-terminal on GNOME, xterm, urxvt, putty, whatever does the job), switch to the root user using the following command:
su -
Then enter the password of the root user when prompted to do so.

Install the JRE

VERSION=$(grep ^VERSION /etc/SuSE-release|cut -f3 -d" ") zypper addrepo -r \ http://download.opensuse.org/repositories/Java:/openjdk6:/Factory/\ openSUSE_$VERSION/Java:openjdk6:Factory.repo zypper refresh Java_openjdk6_Factory zypper install java-1_6_0-openjdk

Install the Java browser plugin

If you also want to install the browser plugin (to run Java applets and Webstart):
zypper install java-1_6_0-openjdk-plugin

Install the Java Development Kit

And if you also want to install the JDK to compile Java sources:
zypper install java-1_6_0-openjdk-devel

Labels: , , ,

Friday, July 10, 2009

» LOL @ Mono outpaces Java in Linux desktop development

This piece of... "art" has to be one of the most factually wrong and ridiculous pseudo-technical articles ever. Because its utterly unqualified author has 3 or 4 desktop applications running on Mono on his desktop, he states that Mono has overtaken Java (and, unlike the title of that article, he actually writes that it's not only on the desktop). I won't even go into debunking his points, they're so blatantly wrong that it's almost funny, such as MonoDevelop being a lot better than Eclipse, Eclipse not having code completion (almost spilled my coffee on that one), a buggy 64bit JVM (huh?), and that people don't develop a lot of web applications with Java any more, favouring ASP.NET and Ruby on Rails. Err... while there has clearly been quite a lot of traction for Ruby on Rails for the last couple of years, and while it certainly has its fair share of the market, neither ASP nor RoR are anywhere near the numbers of enterprise and/or web applications that have been and are still developed with Java. Oh, and "RossB" on the "SUSE Linux Enterprise in the Americas" blog, please don't relay such rubbish.

Labels: ,

Monday, October 27, 2008

» My opinion of Mono

As it seems like everyone has to voice her opinion on Mono, I'll do as well. First of all, I don't like C# as a programming language. And I think that Anders Hejlsberg is wrong on many things. Not having checked exceptions is ludicrous, recommending to use return codes rather than exceptions because of performance is stupid, and cramming every possible OOP and functional language feature into C# is pointless. I much prefer Java because of its relative simplicity, I rather like its verboseness (Eclipse and NetBeans are there to help with that) and conventions, even though I wouldn't mind closures and some syntactic sugar for lists and maps. I'm a firm believer in semi-statically typed languages with an IDE and a compiler that can throw many programming mistakes at your face, at least for medium to large sized projects. I also like using Python (although a proper block syntax would be a lot better than block grouping by indentation) and Ruby (even if it runtime patching of core libraries is a terrible idea). I even find Perl to be adequate for certain types of things. That being said, back to Mono. I believe that having Mono is a good thing, for several reasons:
  • interoperability: Microsoft has been making a huge push from its patchwork of development technologies (VB, C, C++) to its .NET platform and, hence, most software that will be written for the Windows platform is very likely to be running on the .NET runtime for a foreseeable future. Wouldn't it be great to have a compatible runtime on open operating systems (Linux, *BSD, ...) that was able to run those applications when there is no (better) alternative ? I think it is. For the same reasons, I also believe that having OOXML support in OpenOffice.org is a good thing too. In "Microsoft shops" (businesses that use lots of Microsoft software) that rely on MS Exchange, Active Directory, MS Office, Windows and MS SQL Server, it's clearly an advantage for Linux to be compatible. If not, you'll never be able to use Linux in such environments, nor push nor migrate.
  • managed runtimes are the future: for most domains, managed runtimes such as the JVM or .NET are the future of software development. Actually, they're already the present, given that a huge amount of software applications are already deployed on the JVM nowadays. Now notice that I said "most domains": it's most probably not adequate for developing a kernel or low-level network stacks.
  • GNOME needs a proper programming environment: get over it, C is a dead cow for developing frameworks and large sets of components. C++ isn't all that great either, but at least it has proper OOP support and is a lot less painful when combined with Qt. Vala ? Isn't that yet another useless language ? I don't think that's a good idea. Python ? It's rather too slow for certain things and lacks static type checking (which I think is a no-go for large frameworks). Ruby ? Even slower than Python, and doesn't have static type checking either (nor proper threading, at least as of now). C# ? Maybe, why not, it's not as good as Java in my very personal opinion, but it's certainly heaps better than C with glib
Anyhow, everyone is free to disagree, I'm not trying to convince anyone. I just wanted to state my opinion, for what it's worth. Note that I left out many fine grained details and nuances, the sort of stuff to discuss around a beer.

Labels: , , ,

Monday, June 16, 2008

» Demise of POJOs ?

As a comment to Adam Bien's "demise of POJOs", as his blog doesn't allow more then 1000 characters in comments :) I have other gripes with EJB than their weight (or lack thereof). To me, as a developer of frameworks and more or less generic components used by many developer teams, the JEE spec lacks a great amount of stuff once you go beyond the usual business logic + some database type of application. Clustering ? Not even mentioned in the JEE spec. Cluster membership (have a cluster node uniquely identify itself), sending messages to all cluster nodes (have to resort to proprietary replicated JMX), etc... Execute initialization/warmup code at startup ? Still have to resort to the servlet trick, or use proprietary mechanisms. AOP ? Dependency Injection ? only very lightly supported in EJB 3.0, clearly not sufficient for more complex approaches. Security ? JAAS ? ouch. To me EJB is a great facade technology for remoting, EJB 3 is a nice managed component model for applications where it fits... business logic, JDBC, web or Swing UI, but nothing more advanced (from a purely technical point of view) where you need a lot of flexibility or cluster awareness. And yes, while Spring doesn't help wrt clustering, it provides a much more flexible and fine-grained model to manage beans. I mean, this isn't theoretical or fanboyism, I clearly encounter situations where a fine-grained control is needed, every single day. So while EJB can be a good approach for business application level developers, especially when you need to fence them into a scarce technical frame, it just doesn't provide enough features nor flexibility for frameworks or components that need a fine grained control over lifecycle/deployment, cross-cutting concerns (security, audit logging, ...), clustering, etc.

Labels:

Saturday, May 24, 2008

» Embedded Jetty + WicketFilter - web.xml

I searched quite a bit on lazyweb but couldn't find anything conclusive so.. for posterity, here is how to start an embedded Jetty (a lightweight Java Servlet container/webserver) without any XML, add <init-param/> values without XML (Wicket's WicketFilter requires a applicationClassName init-param that contains the fully qualified class name of your WebApplication) and with Wicket:
import org.apache.wicket.protocol.http.ContextParamWebApplicationFactory;
import org.apache.wicket.protocol.http.WicketFilter;
import org.mortbay.jetty.Connector;
import org.mortbay.jetty.Server;
import org.mortbay.jetty.nio.SelectChannelConnector;
import org.mortbay.jetty.servlet.Context;
import org.mortbay.jetty.servlet.DefaultServlet;
import org.mortbay.jetty.servlet.FilterHolder;

public class EmbeddedJettyWithWicket {
   // change these accordingly:
   private static final String LISTEN_HOST = "localhost";
   private static final int LISTEN_PORT = 8888;
   private static final String WICKET_WEBAPP_CLASS_NAME =
      MyWebApp.class.getName();

   public static final void main(String[] argsthrows Exception {
      Server server = new Server();
      SelectChannelConnector connector = new SelectChannelConnector();
      connector.setHost(LISTEN_HOST);
      connector.setPort(LISTEN_PORT);
      server.setConnectors(new Connector[] { connector });
      Context root = new Context(server, "/", Context.SESSIONS);
      root.addServlet(DefaultServlet.class, "/*");
      FilterHolder filterHolder = new FilterHolder(WicketFilter.class);
      filterHolder.setInitParameter(ContextParamWebApplicationFactory.APP_CLASS_PARAM,
                                    WICKET_WEBAPP_CLASS_NAME);
      root.addFilter(filterHolder, "/*"1);
      server.start();
      server.join();
   }
}
Java2html
UPDATE: replaced with code that actually works

Labels: , ,

Saturday, January 26, 2008

» Loading a JDBC Driver at runtime

In the context of a nice mini-framework (just a few classes actually) for integration tests for Java using JUnit, DBUnit (for database initialisation and comparison against expected data) and Spring, I found myself confronted with somewhat less elegant requirement of having to specify the JDBC Driver jar filename in the CLASSPATH and having to change it depending on the target database. Whereas changing the JDBC database URL, username and password is easy (just using Spring's PropertyPlaceholderConfigurer and a .properties file), changing the CLASSPATH is annoying, because it has to be changed in the Eclipse build path (e.g. using a classpath variable) as well as in the build configuration (be it Ant or Maven). I wanted to specify the filename of the JDBC Driver jar in the same .properties file as the JDBC URL, username and password. While this may sound trivial to some, it isn't, because you cannot load jars at runtime using the default ClassLoader. This code snippet shows how one can (ab)use the URLClassLoader to load jars at runtime. But the problem is that I didn't want to set a new default ClassLoader nor pass JVM parameters at startup, i.e. use the pristine Eclipse and Ant/Maven environment and do it purely through Java code at runtime. The trick is quite simple, actually: 1) write a delegate implementation of JDBC's java.sql.Driver class, that passes each method call to a static (singleton) Driver 2) use the name of the delegate class above as the name of the JDBC Driver class 3) set the static Driver in the delegate Driver class above to an instance of the real JDBC Driver class Let's start with the delegate:
package sample; import java.sql.Connection; import java.sql.Driver; import java.sql.DriverManager; import java.sql.DriverPropertyInfo; import java.sql.SQLException; import java.util.Properties; public class DelegateDriver implements Driver {          static {         try {             DriverManager.registerDriver(new DelegateDriver());         catch (SQLException e) {             throw new RuntimeException(new StringBuffer()             .append("failed to register ").append(DelegateDriver.class.getName())             .append(" with the JDBC ").append(DriverManager.class.getName())             .append(": ").append(e.getMessage()).toString(), e);         }     }          public static Driver DELEGATE = null;     private static Driver getDelegate() {         if (DELEGATE == null) {             throw new IllegalStateException("delegate driver not set");         }         return DELEGATE;     }          public boolean acceptsURL(String urlthrows SQLException {         return getDelegate().acceptsURL(url);     }     public Connection connect(String url, Properties infothrows SQLException {         return getDelegate().connect(url, info);     }     public int getMajorVersion() {         return getDelegate().getMajorVersion();     }     public int getMinorVersion() {         return getDelegate().getMinorVersion();     }     public DriverPropertyInfo[] getPropertyInfo(String url, Properties info)             throws SQLException {         return getDelegate().getPropertyInfo(url, info);     }     public boolean jdbcCompliant() {         return getDelegate().jdbcCompliant();     } }
And here is the class to use to configure the actual JDBC Driver class as well as the JDBC driver jar file, shaped as a Spring-ready singleton bean:
package sample; import java.io.File; import java.net.URL; import java.net.URLClassLoader; import java.sql.Driver; public class JDBCDriverLoader {          private String jdbcDriverClass;     private File jdbcDriverFile;          /** Configure using Spring or Java code: */     public void setJdbcDriverFile(File jdbcDriverFile) {         this.jdbcDriverFile = jdbcDriverFile;     }          /** Configure using Spring or Java code: */     public void setJdbcDriverClass(String jdbcDriverClass) {         this.jdbcDriverClass = jdbcDriverClass;     }     public void initialize() throws Exception {         // TODO throw IllegalStateException if jdbcDriverFile or jdbcDriverClass is null         DelegateDriver.DELEGATE = (Drivernew URLClassLoader(new URL[]{}this.getClass().getClassLoader()) {{             // Have to use a subclass because addURL() is protected.             // See http://snippets.dzone.com/posts/show/3574             addURL(new URL("jar:file://" + jdbcDriverFile.getPath() "!/"));         }}.loadClass(jdbcDriverClass).newInstance();     }      }
All you need to do now is to use sample.DelegateDriver as the name of the JDBC Driver class (e.g. in your Apache Commons DBCP connection pool). Jumping through those hoops is needed because it's a different ClassLoader. I'll leave the rest of the glue as an exercise to the reader ;)

Labels:

Tuesday, October 23, 2007

» Upgrade to java-1_6_0-sun u3 on openSUSE 10.3: fixing alternatives links

If you upgrade to java-1_6_0-sun-1.6.0.u3 on openSUSE 10.3, the /etc/alternatives/ links will be broken. To quickly fix them, just copy/paste the following snippet as in a shell as root:
for f in /etc/alternatives/j*; do
  ff=$(readlink "$f")
  case "$ff" in
    */jvm*|*/share/man/*) update-alternatives --auto "${f##*/}";;
    *) echo "(skipping $f)";;
  esac
done

Labels: ,