20
I Use This!
Activity Not Available

News

Posted over 14 years ago
The Space and the GridLayout components have been added in Android 4 (also known as Ice Cream Sandwich or ICS) : Space allows to add an empty area in an Android screen. GridLayout allows to organize screen elements in a grid. But how can you use ... [More] these 2 components if you must develop for an older Android version ? There is a compatibility library developed by google to backport some functionalities introduced by ICS. The problem is it doesn’t contain Space and GridLayout. Luckily, Daniel Lew has managed to backport these 2 components. This project is called android-layout and you can get its sources on github. As mentionned in project’s readme (see “Caveats” part), the only drawback is the inability to automatically manage the changes in visibility of the GridLayout‘s child views (it’s probably for that reason google didn’t integrate this component in the compatibility library). Bookmark and Share More »Powered by Bookmarkify™ [Less]
Posted over 14 years ago
I unintentionally posted this before I verified everything, so once I have verified it all works, I'll updated this post. But this is what should work... Most Interesting Builder in the World: "I don't always build the jdk, but when I do, I ... [More] prefer The New JDK8 Build Infrastructure. Stay built, my friends." So the new Build Infrastructure changes have been integrated into the jdk8/build forest along side the older Makefiles (newer in makefiles/ and older ones in make/). The default is still the older makefiles. Instructions can be found in the Build-Infra Project User Guide. The Build-Infra project's goal is to create the fastest build possible and correct many of the build issues we have been carrying around for years. I cannot take credit for much of this work, and wish to recognize the people who do so much work on this (and will probably still do more), see the New Build Infrastructure Changeset for a list of these talented and hard working JDK engineers. A big "THANK YOU" from me. Of course, every OS and system is different, and the focus has been on Linux X64 to start, Ubuntu 11.10 X64 in particular. So there are at least a base set of system packages you need. I decided to use Ubuntu 12.04, hot off the press, you should run the following after getting into a root permissions situation (e.g. have run "sudo bash"): apt-get install aptitude aptitude update apt-get purge openjdk-6* aptitude install mercurial openjdk-7-jdk rpm ssh expect tcsh csh ksh gawk g++ ccache build-essential lesstif2-dev Then get the jdk8/build sources: hg clone http://hg.openjdk.java.net/jdk8/build jdk8-build cd jdk8-build sh ./get_source.sh Then do your build: chmod a+x common/bin/* cd common/makefiles bash ../autoconf/configure make We still have lots to do, but this is a tremendous start. -kto [Less]
Posted over 14 years ago
Test driven development is all nice and dandy, but there are some areas that most people find notoriously difficult to test, and often dismiss them as not worth it. The main() method, entry point for any application, is one of them. The problem with ... [More] main methods is that they combine at least two of the patterns that make testing difficult: static method calls and many constructor calls. Let me illustrate it with a snippet of code from Thermostat: public static void main(String[] args) { CommandContextFactory cmdCtxFactory = CommandContextFactory.getInstance(); CommandRegistry registry = cmdCtxFactory.getCommandRegistry(); ServiceLoader cmds = ServiceLoader.load(Command.class); registry.registerCommands(cmds); if (hasNoArguments()) { runHelpCommand(); } else { runCommandFromArguments(); } } This is a rather common way to implement a main method: setup a bunch of things by calling factories and constructors, then launch whatever needs to be launched. The first thing that needs to be done to make this testable is to reduce the problematic static method and constructor calls by moving them into a separate class. How does this look? public static void main(String[] args) { new Launcher().run(args); } This way, we can now test the bulk of the functionality using fairly normal testing techniques such as mocking, injection, etc. We still want to test the actual main method though (even though many will now cry out that this is so trival that it’s not worth even thinking about it… but wait, the solution is not so difficult either). What would need to be tested here? Obviously, there is no state change, only interactions. Therefore, the test would need to be a verification of interaction of the main class with the Launcher class. More specifically, it would need to verify that the run() method is called on the newly constructed Launcher with the correct arguments (and not, say, null). However, we need to somehow get rid of the construction itself and open a way to inject the Launcher instance. That’s how I solved it: public class Thermostat { private static Launcher launcher = new Launcher(); public static void main(String[] args) { launcher.run(args); } static void setLauncher(Launcher launcher) { Thermostat.launcher = launcher; } } This way, we can override the launcher to be tested with a mock launcher, and verify the correct interaction: public class ThermostatTest { @Test public void testThermostatMain() { Launcher launcher = Mockito.mock(Launcher.class); Thermostat.setLauncher(launcher); Thermostat.main(new String[] { "test1", "test2" }); PowerMockito.verifyNew(Launcher.class).withNoArguments(); Mockito.verify(launcher).run(new String[] { "test1", "test2" }); } } The verifyNew() call verifies that we actually create a new instance of Launcher in the static initializer of Thermostat (the main class), and the last call verifies that run() is called on our mock launcher with the correct arguments. And if you are interested in how the rest of the launching code now looks like, and how we test it (in fairly normal unit testing style), take a look at the Launcher and LauncherTest classes. If you have other solutions to the problem of unit testing main methods, I would be very interested in hearing from them in the comments! [Less]
Posted over 14 years ago
I'm back home after a really great Lang.NEXT conference. The video of my talk is available on Channel 9. The slides are here.
Posted about 15 years ago
Updated: Removed all links.Every now and then, when a blog post of mine gets wider exposure on the Internet, I tend to get this question: Why doesn't my personal blog allow comments to be posted to entries?The short is answer is: because I live in ... [More] Hamburg, Germany. And like some other German bloggers who deliberately don't have a facility for comments on their blogs, I don't want to have to spend any of my time pre-censoring blog comments (and dealing with the additional fallout annoyances arising out of having to do that) in order to protect myself from the potential consequences of local judicative's decisions.The long answer is that I think that blog comments are a relic of the web's past, given that better alternatives for comments exist, and the interesting conversations have moved on there. One of them is Twitter. There is something to be said for compressing a comment into 140 chars: it seems to make it a bit harder for comments to turn into what John Gruber calls "cacophonous shouting matches". A great example of what Gruber refers to are YouTube comments - and that's why rather then spending my time screening and pre-censoring comments (see short answer above), I prefer to spend it having more interesting conversations. [Less]
Posted over 15 years ago
In the last blog post about Daneel I mentioned one particular caveat of Dalvik bytecode, namely the existence of untyped instructions, which has a huge impact on how we transform bytecode. I want to take a similar approach as last time and look at ... [More] one specific example to illustrate those implications. So let us take a look at the following Java method. public float untyped(float[] array, boolean flag) { if (flag) { float delta = 0.5f; return array[7] + delta; } else { return 0.2f; } } The above is a straightforward snippet and most of you probably know how the generated Java bytecode will look like. So let’s jump right to the Dalvik bytecode and discuss that in detail. UntypedSample.untyped:([FZ)F: [regs=5, ins=3, outs=0] 0000: if-eqz v4, 0009 0002: const/high16 v0, #0x3f000000 0004: const/4 v1, #0x7 0005: aget v1, v3, v1 0007: add-float/2addr v0, v1 0008: return v0 0009: const v0, #0x3e4ccccd 000c: goto 0008 Keep in mind that Daneel doesn’t like to remember things, so he wants to look through the code just once from top to bottom and emit Java bytecode while doing so. He gets really puzzled at certain points in the code. Label 2: What is the type of register v0? Label 4: What is the type of register v1? Label 9: Register v0 again? What’s the type at this point? You, as a reader, do have the answer because you know and understand the semantic of the underlying Java code, but Daneel doesn’t, so he tries to infer the types. Let’s look through the code in the same way Daneel does. At method entry he knows about the types of method parameters. Dalvik passes parameters in the last registers (in this case in v3 and v4). Also we have a register (in this case v2) holding a this reference. So we start out with the following register types at method entry. UntypedSample.untyped:([FZ)F: [regs=5, ins=3, outs=0] uninit uninit object [float bool The array to the right represents the inferred register types at each point in the instruction stream as determined by the abstract interpreter. Note that we also have to keep track of the dimension count and the element type for array references. Now let’s look at the first block of instructions. 0002: const/high16 v0, #0x3f000000 u32 uninit object [float bool 0004: const/4 v1, #0x7 u32 u32 object [float bool 0005: aget v1, v3, v1 u32 float object [float bool 0007: add-float/2addr v0, v1 float float object [float bool Each line shows the register type after the instruction has been processed. At each line Daneel learns something new about the register types. Label 2: I don’t know the type of v0, only that it holds an untyped 32-bit value. Label 4: Same applies for v1 here, it’s an untyped 32-bit value as well. Label 5: Now I know v1 is used as an array index, it must have been an integer value. Also the array reference in register v3 is accessed, so I know the result is a float value. The result is stored in v1, overwriting it’s previous content. Label 7: Now I know v0 is used in a floating-point addition, it must have been a float value. Keep in mind that at each line, Daneel emits appropriate Java bytecode. So whenever he learns the concrete type of a register, he might need to retroactively patch previously emitted instructions, because some of his assumptions about the type were broken. Finally we look at the second block of instructions reached through the conditional branch as part of the if-statement. 0009: const v0, #0x3e4ccccd u32 uninit object [float bool 000c: goto 0008 float uninit object [float bool When reaching this block we basically have the same information as at method entry. Again Daneel learns in the process. Label 9: I don’t know the type of v0, only that it holds an untyped 32-bit value. Label 12: Now I know that v0 has to be a float value because the unconditional branch targets the join-point at label 8. And I already looked at that code and know that we expect a float value in that register at that point. This illustrates why our abstract interpreter also has to remember and merge register type information at each join-point. It’s important to keep in mind that Daneel follows the instruction stream from top to bottom, as opposed to the control-flow of the code. Now imagine scrambling up the code so that instruction stream and control-flow are vastly different from each other, together with a few exception handlers and an optimal register re-usage as produced by some SSA representation. That’s where Daneel still keeps choking at the moment. But we can handle most of the code produced by the dx tool already and will hunt down all those nasty bugs triggered by obfuscated code as well. Disclaimer: The abstract interpreter and the method rewriter were mostly written by Rémi Forax, with this post I take no credit for it’s implementation whatsoever, I just want to explain how it works. [Less]
Posted almost 17 years ago
I wanted to manipulate a few PDF files recently and was on the lookout for suitable tools. More specifically, I wanted to convert a few double-page PDF files (containing two pages of text on a single page) into single-page PDF files. I also wanted to ... [More] drop some of the pages in order to have the files contain just the text that I was interested in. Fortunately for me, there are several freely-available tools that do the job well. The Perl PDF::API2 CPAN module is fairly versatile and quite handy if you know a bit of programming. For example, this script by "iblis" converts a double-page PDF into a single-page PDF. (There is a slight bug in that script - you should remove the quotes on line #28 or your output files will always literally be named "$newfilename".) According to its web-site the PDF::API2 is unfortunately no longer being maintained, though that certainly does not diminish its utility. The pdftk command-line tool is quite useful for a number of tasks on PDF files. For example, to extract pages 2 to 10 and 15 to 23 from a PDF file named "foo.pdf" and create a PDF file named "bar.pdf", you can execute:   pdftk A=foo.pdf cat A2-10 A15-23 output bar.pdf See its web-site for a number of other examples that show its power. Its command-line syntax takes a little while to get used to, but that's worth the effort. Note that the author of the tool uses GCJ to create standalone executables, especially on Windows - it is gratifying to realise that yours truly had a part to play, however small, in making this happen. I also looked at some other tools, notably PDF Split and Merge (PDFsam) and PDFill. PDFsam is written in Java and looks promising; unfortunately for me, a warning tone was all that I could get out of it as I tried out its different plug-ins. I didn't get around to trying PDFill as pdftk and PDF::API2 were more than enough for my purpose. [Less]
Posted over 17 years ago
There seems to be a certain confusion in the community about the motivation of the JNode project and specifically the unusual choice of the Java language for implementing it. I think some explanation is necessary.JNode is an operating system based on ... [More] Java technology. Its implementation language is Java because this is the standard language of the Java platform. The Java language has many advantages (as being type safe, relatively readable ) but many of the advantages come from the Java byte code and the Java virtual machine. JNode is not based on the Java platform for the sake of writing it in the Java language as some people might think. One of the most important points of JNode is that the overwhelming majority of its code is compiled to and executed as Java byte code in a safe environment. JNode aims to achieve increased stability, robustness, reliability and performance by choosing the Java byte code as executable code format and executing it within an appropriate virtual machine. The past one and a half decade demonstrated the superior runtime characteristics and reliability of the Java byte code based programs compared to native programs. Moreover this has proven to be so successful that practically the mainstream domains of application software development have largely adopted the execution model where the program translated to a more or less safe byte code run within a dedicated virtual machine. It's among the goals of JNode to extend this model to the complete software stack including the operating system. By JNode itself being translated to Java byte code which is also its primary executable code format, JNode is a metacircular execution environment with respect to the Java byte code This has deep implications regarding future capabilities which can be built into the system and combined with the dynamic, flexible and object oriented nature of the Java byte code opens perspectives to solutions which are impossible or hard to implement in traditional operating systems. Reflection, manageability, dynamic profiling, byte code instrumentation, dynamic class reloading, to mention a couple of remarkable properties of Java code, extended to the level of the whole system and applied by the system to itself opens the road towards self-managing, adaptive, self-inspecting, self-diagnosing and self-healing capabilities in JNode. Here the point is to gather the information from the running system, that is usually gathered by a human operator from a well tooled Java application today, automatically feed it back to the system in a meaningful way and then let the system make appropriate decisions and take actions based on that information.The JNode operating system internally is based on a virtual machine specially developed for this purpose. This virtual machine takes care of running its own code as well as the code of the rest of the JNode operating system and the applications running on top of it. Sharing of code and resources is maximized among all components and layers of the system. JNode has a flat memory model and protection is based on the inherent safety and type-safety of the Java byte code and the built-in security of the system. These characteristics eliminate the need for context switching and native interface. The executable code is byte code managed by the system-wide unique virtual machine, compiled to native code dynamically with the possibility to make advanced optimization across layers of the system impossible to achieve in the traditional dichotomy of a statically compiled native operating system with statically compiled platform specific native Java virtual machine running on top of it. In JNode the overhead of starting a new Java application can be largely reduced due to the fact that most of the resources needed to run the application have already been set up, warmed up and are ready to be reused within the operating system itself.JNode also aims to provide an outstanding platform for running Java applications. JNode is a platform created from the ground up by Java programmers with Java tools and Java technology specially for running Java programs. Java programs are currently run on many platforms but on all platforms very often they look & feel like somewhat foreign citizens. Any enthusiast of a particular platform will tell it and most of them will avoid Java and make choices specific to that platform for their tasks. This situation is most visible in desktop use-cases and command line based utilities. In contrast with this, a Java program on JNode is the native program of the platform.So these are just a couple of ideas to demonstrate that JNode is not being developed simply because 'Java is cool' and 'pure Java' is a supreme value in itself sufficiently compelling to build an operating system around it. JNode by taking the unique path of creating a complete Java program execution environment starting from the most fundamental operating system services up to the application level based on the Java technology itself aims to explore and extend the powerful capabilities of the Java platform to the level of a whole completely standalone and self-sufficient software system and staring from this foundation explore new holistic possibilities in a self-contained, high performance, safe, secure still flexible and dynamic self-managing, adaptive systems design. JNode is not about the Java based development of a Java virtual machine, device driver, JIT compiler, thread scheduler, memory manager or any other particular component of a software system. JNode is about the development of the combination of all these based on the powerful capabilities of the Java platform using a metacircular approach. The focus of JNode is the whole not the part. [Less]
Posted over 17 years ago
Earlier last week JNode 0.2.8 was released. We could also call it the yearly FOSDEM release, which used to happen sometime before this much anticipated free software conference. Unfortunately FOSDEM attendance didn't work out for me this year because ... [More] I had to cancel the whole trip in the last minute due to a sudden illness. So, my meeting with four other JNode developers and with other free Java developers, my JNode talk & demo and watching quite a few interesting presentations, important for my future work on JNode, didn't happen. Fortunately Peter still made the JNode talk, so our allocated time slot was not lost and I hope the presentations from other talks and maybe several videos will be available soon on the website. I plan to share certain information about JNode in the upcoming blog posts perhaps in more detail than they could have been in my talk. Regarding JNode 0.2.8, it has many stability improvements backed by Mauve based regression tests and bug fixes but no major completed new features this time, though we made progress with isolates, bjorne shell, and hfs+ file system support among others (see release notes). These features should be available in the upcoming one or two releases.Improvements in the GUI have made JNode capable of running JEdit as you can see in the screenshot. Most features are working in it, but editing is still hard to use due to problems in the underlaying font support in JNode. Also the result of general improvents is that besides the recent Servlet and JSP examples PHP code is starting work under JNode by the means of Jetty and the pure Java PHP engine, Quercus. Based on this stack we want to set up an experimental version of the jnode.org portal (which is based on Drupal) as a step towards powering jnode.org by a fully JNode based system sometime in the future. [Less]
Posted almost 18 years ago
As anyone working on GCC would know, GCC bootstrap times are getting worse. It is so excruciating on some platforms that it is nearly impossible to keep those platforms up-to-date even if people want to. Of course, many more optimisations, new ... [More] languages and their ever-bloating runtimes, more comprehensive support for language standards, etc. make it inevitable that bootstrap times increase, but does it really have to increase so much?On my home PC, a "c,c++,java" bootstrap takes more than three hours and a complete testsuite run takes a lot of time as well. Considering that any change to the main compiler needs a complete bootstrap and testsuite run twice over (once without and once with your patch), that too in the best case of no regressions, is it small wonder that many people who might want to otherwise volunteer to help with GCC development just cannot afford to? I have only so much free time left after my job and my family and many a time I feel I am much better off reading a good book or watching a good movie, for example, than literally losing sleep over GCC. Small wonder then that almost all of the prolific contributors to GCC either work on it as a part of their job or on really fast machines with loads of memory (or both).Perhaps it is not a good idea after all to have a single compiler codebase support so many languages and runtimes at the same time. Perhaps it would be better to start over by creating a well-defined (in terms of the structure and contract) set of language and platform-independent intermediate languages (different avatars of GENERIC and RTL) and have the front-ends and the back-ends as separate projects from the core framework. Of course, if things were this simple people would have done it already, but a man can dream, can't he?(Originally posted on Advogato.) [Less]