cayhorstmann's bloghttp://www.java.net/blog/cayhorstmann
enBack from the JCrete Unconferencehttp://www.java.net/blog/cayhorstmann/archive/2015/07/27/back-jcrete-unconference
<!-- 1199 | 0 --><img src="/images/people/cay_horstmann.jpg" border="0", align="left" /><p>Some time ago, I got an invitation from Heinz Kabutz (the man behind the Java Specialists newsletter, to which you should subscribe right away if you haven't already), to join the JCrete conference. ♦</p>
<!--break--><!--break--><p>My wife took a dim view of this. “You mean, there is no program? You'll just stand around and drink beer and chat?” I tried to explain to her that it's no different for me when I go to Java One, where I learn more from the hallway conversations than from the sessions. The solution was to take the entire family along.</p>
<p>It turned out to be great. To see what JCrete is all about, read the blogs by <a href="https://blogs.oracle.com/geertjan/entry/jcrete_2014">Geertjan Wielenga</a> and <a href="https://blog.codecentric.de/en/2014/09/jcrete-java-unconference-cretan-beaches/">Fabian Lange</a> who explain the “unconference” approach very nicely. Here you can see it in action. The clusters of folks in the water at the beach of Falarnassa are conference attendees, who, being geeks, mostly talk tech. I learned a bunch about <a href="http://mishadoff.com/blog/java-magic-part-4-sun-dot-misc-dot-unsafe/">sun.misc.Unsafe</a> while swimming. </p>
<p><img src="http://www.java.net/sites/default/files/jcrete.jpg"/></p>
<p>I co-lead a discussion on what one would like to see in java.util.stream in the future. Compared for example with the <a href="http://www.scala-lang.org/api/current/index.html#scala.collection.Seq">Scala API</a>, streams are missing quite a few useful operations. For example, there is no zip (it was <a href="http://mail.openjdk.java.net/pipermail/lambda-libs-spec-observers/2013-June/002028.html">removed</a>). There is no convenient way of turning iterators or iterables into streams (also <a href="http://mail.openjdk.java.net/pipermail/lambda-libs-spec-experts/2013-June/002031.html">removed</a>). </p>
<p>There are good reasons for these omissions. Zipping is best done with pairs, and pairs are best done with <a href="http://cr.openjdk.java.net/~jrose/values/values-0.html">value types</a>. A <code class="prettyprint">stream</code> method on iterables might work better when we have <a href="http://cr.openjdk.java.net/~briangoetz/valhalla/specialization.html">specialization</a> of generics. It makes sense to wait until these features are ready, perhaps in Java 10. (Nothing much is going to happen with streams in JDK 9. I only found one new stream-related method: <code class="prettyprint"><a href="http://download.java.net/jdk9/docs/api/java/util/Optional.html#stream--">Optional.stream</a></code> turns an <code class="prettyprint">Optional</code> into a stream of length 0 or 1.)</p>
<p>What can you do in the meantime? We found a number of libraries that provide stream-like abstractions with richer APIs: <a href="https://github.com/nurkiewicz/LazySeq">LazySeq</a>, <a href="https://github.com/poetix/protonpack">ProtonPack</a>, <a href="http://blog.jooq.org/2014/09/10/when-the-java-8-streams-api-is-not-enough">jOOλ</a>, <a href="http://javaslang.com/">JavaSlang</a>.</p>
<p>Personally, I like to use streams for the “what, not how” API, not so much for parallel streams. Sure, parallel streams are impressive, but they are also quite specialized. They work well when you want to keep all cores busy, with data from an in-memory data structure that is efficiently splittable, and stream operations that are computationally intensive. I don't have many situations like that in practice, which explains why my teaching examples always seem to involve factoring <code class="prettyprint">BigInt.</code>
<p>Some of the attendees reported from their consulting jobs where they saw eager stream users add <code class="prettyprint">.parallel()</code> everywhere. Clearly, that's a terrible idea. If the data come from a file or database, it won't be split efficiently with the fork-join framework. If the stream operations block, the fork-join pool can starve. And in an app server, does one really want to go full bore on all cores? (It is possible to constrain the pool, but <a href="http://stackoverflow.com/questions/21163108/custom-thread-pool-in-java-8-parallel-stream">not obvious</a>.) </p>
<p>Other than telling people to be careful about parallel streams, what did I learn? I'll have to figure out how to build <a href="http://openjdk.java.net/projects/valhalla/">Project Valhalla</a> so that I can learn all about value types and generic specialization. I won't have to learn about sun.misc.Unsafe. <a href="https://dukescript.com/">DukeScript</a> looks cool, and I'll have to check it out. </p>
<p>Most importantly, I learned about JCrete. The unconference format is great, the location is unbeatable, and the attendees have been amazing. Check out some videos from Steven Chin's blog <a href="http://nighthacking.com/category/jcrete-2015/">here</a>.</p>
http://www.java.net/blog/cayhorstmann/archive/2015/07/27/back-jcrete-unconference#commentsMon, 27 Jul 2015 19:46:52 +0000cayhorstmann932276 at http://www.java.netThe Curious Case of the char Typehttp://www.java.net/blog/cayhorstmann/archive/2015/06/22/curious-case-char-type
<!-- 355 | 0 --><img src="/images/people/cay_horstmann.jpg" border="0", align="left" /><p>It's been almost twenty years that Gary Cornell contacted me to tell me “Cay, we're going to write a book on Java.” Those were simpler times. The Java 1.0 API had 211 classes/interfaces. And Unicode was a 16-bit code. ♦</p>
<!--break--><!--break--><p>Now we have over 4,000 classes/interfaces in the API, and Unicode has grown to 21 bits.</p>
<p><img style="float: right; margin-left: 1em;" src="http://www.fileformat.info/info/unicode/char/1f379/tropical_drink.png"/></p>
<p>The latter is an inconvenience for Java programmers. You need to understand some pesky details if you have (or would like to have) customers who use Chinese, or you want to manipulate emoticons or symbols such as <code class="prettyprint">&#039;TROPICAL DRINK&#039; (U+1F379)</code>. In particular, you need to know that a Java <code class="prettyprint">char</code> is <em>not</em> the same as a Unicode “code point” (i.e. what one intuitively thinks of as a “Unicode chracter”). </p>
<p>A Java <code class="prettyprint">String</code> uses the UTF-16 encoding, where most Unicode code points take up one <code class="prettyprint">char</code> value, and some take up two. For example, the tropical drink character, erm, code point is encoded as the sequence <code class="prettyprint">&#039;\uD83C&#039; &#039;\uDF79&#039;</code>. </p>
<p>So, what does that mean for a Java programmer? First off, you have to be careful with methods such as <code class="prettyprint">substring</code>. If you pass inappropriate index values, you can end up with half a code point, which is guaranteed to cause grief later. As long as index values come from a call such as <code class="prettyprint">indexOf</code>, you are safe, but don't use <code class="prettyprint">str.substring(0, 1)</code> to get the first initial—you might just get half of it.</p>
<p>The <code class="prettyprint">char</code> type is now pretty useless for application programmers. If you call <code class="prettyprint">str.charAt(i)</code>, you might not get all of the code point, and even if you do, it might not be the <code class="prettyprint">i</code>th one. Tip: If you need the code points of a string, call:</p>
<pre class="prettyprint"><code>int[] codePoints = str.codePoints().toArray();</code></pre>
<p><img style="width: 100px; float: right; margin-left: 1em;" src="http://horstmann.com/javaimpatient/cover.jpg"/></p>
<p>I recently finished the book “Core Java for the Impatient”, where I cover the “good parts” of Java, for programmers who come from another language and want to get to work with Java without sorting through twenty years of historical baggage. In that book, I explain the bad news about <code class="prettyprint">char</code> in somewhat mindnumbing detail and conclude with saying “You probably won’t use the <code class="prettyprint">char</code> type very much.” </p>
<p>All modesty aside, I think that's a little better than what the <a href="https://docs.oracle.com/javase/tutorial/java/nutsandbolts/datatypes.html">Java tutorial</a> has to offer on the subject:</p>
<ul>
<li> <code class="prettyprint">char</code>: The <code class="prettyprint">char</code> data type is a single 16-bit Unicode character. It has a minimum value of <code class="prettyprint">&#039;\u0000&#039;</code> (or 0) and a maximum value of <code class="prettyprint">&#039;\uffff&#039;</code> (or 65,535 inclusive). </li>
</ul>
<p>Uffff. What is a “single 16-bit Unicode character”???</p>
<p>A few days ago, I got an email from a reader who had spotted a somewhat unflattering review of the book in <a href="http://www.oraclejavamagazine-digital.com/javamagazine/may_june_2015#pg12">Java Magazine</a>. Did the reviewer commend me on giving readers useful advice about avoiding <code class="prettyprint">char</code>? No sir. He kvetches that I say that Java has four <strong>integer</strong> types (<code class="prettyprint">int</code>, <code class="prettyprint">long</code>, <code class="prettyprint">short</code>, <code class="prettyprint">byte</code>), when in fact, according to the <a href="https://docs.oracle.com/javase/specs/jls/se8/html/jls-4.html#jls-4.2.1">Java Language Specification</a>, it has five <strong>integral</strong> types (the last one being <code class="prettyprint">char</code>). </p>
<p>That's of course correct, but the language specification has an entirely different purpose than a book for users of a programming language. The spec mentions the <code class="prettyprint">char</code> type 113 times, and almost all of the coverage deals with arithmetic on <code class="prettyprint">char</code> values and what happens when one converts between <code class="prettyprint">char</code> and other types. Programming with strings isn't something that the spec cares much about.</p>
<p>So, it is technically true that <code class="prettyprint">char</code> is “integral”, and for a spec writer that categorization is helpful. But is it helpful for an application programmer? It would be a pretty poor idea to use <code class="prettyprint">char</code> for integer values, even if they happen to fall in the range from 0 to 65535.</p>
<p>I like to write books for people who put a programming language to practical use, not those who obsess about technical minutiae. And, judging from Core Java, which has been a success for almost twenty years, that's working for the reading public. I'll raise a glass of <code class="prettyprint">&#039;TROPICAL DRINK&#039; (U+1F379)</code> to that!</p>
http://www.java.net/blog/cayhorstmann/archive/2015/06/22/curious-case-char-type#commentsMon, 22 Jun 2015 09:57:22 +0000cayhorstmann932134 at http://www.java.netTrying out the Java 9 REPLhttp://www.java.net/blog/cayhorstmann/archive/2015/05/25/trying-out-java-9-repl
<!-- 752 | 0 --><img src="/images/people/cay_horstmann.jpg" border="0", align="left" /><p>One of the joys of programming with a dynamic language such as Lisp or Python is the instant feedback you get from the interpreter. You try out a thing or two, something starts working, you move on to the next issue, and before you know it, your task is done. Technically, the program that reads and evaluates the language statements is called a REPL, for “read-evaluate-print loop”.</p>
<p>And it's not just dynamic languages. Scala is statically typed, and it comes with a REPL. Behind the scenes, the statements that you enter are compiled and executed. </p>
<p>(As a potentially entertaining aside, make a Google image search for REPL. Perhaps because I am on sabbatical in Switzerland, I get an ad for “Hypower Musli capsules”.)</p>
<p><img src="http://weblogs.java.net/sites/default/files/Repl_0.jpg" style="float:right; margin-left:1em;"/></p>
<p>Why can't we get a REPL with Java? Good question. There are some ways of coming close. Way back when, <a href="http://www.beanshell.org/">BeanShell</a> was a plausible solution, but it never caught up to Java 5. Some educational environments, such as <a href="http://bluej.org">BlueJ</a> and <a href="http://www.drjava.org">Doctor Java</a>have perfectly reasonable facilities for interactively evaluating Java code. But somehow, even people who use and love these environments don't seem to use that feature a lot.</p>
<p>Personally, whenever I need to run some experiments with some new Java API, I use the Scala REPL. But I get frustrated because things like varargs, collections, and lambdas are tedious to bridge and get in the way of rapid exploration. I tried using the Nashorn REPL that comes with Java 8, and that's worse—the chasm between Java and JavaScript is just too great.</p>
<p>So, after more than twenty years, Java is finally going to do it right in Java 9. For now, you still have to build the REPL by hand—it's not yet in the binary distribution. But it's not hard to do.</p>
<p><a href="http://blog.arungupta.me/jdk9-repl-getting-started/">These instructions</a> should get you going on Mac OS X. But if you use Linux, your life is even simpler. (I haven't found any instructions for Windows, and in general, the Windows build process for the JDK seems fiddly. If you run Windows and want to check this out, just use a Linux VM.) Here goes:</p>
<ol>
<li>Visit <a href="https://jdk9.java.net/download/">https://jdk9.java.net/download/</a>, download the most current JDK 9 build, and untar it in your home directory. It ends up in <code class="prettyprint">~/jdk1.9.0</code></li>
<li>In your home directory, run <pre class="prettyprint"><code>hg clone <a href="http://hg.openjdk.java.net/kulla/dev" title="http://hg.openjdk.java.net/kulla/dev">http://hg.openjdk.java.net/kulla/dev</a> jshell<br />cd jshell<br />wget <a href="http://repo1.maven.org/maven2/jline/jline/2.12/jline-2.12.jar<br />sh" title="http://repo1.maven.org/maven2/jline/jline/2.12/jline-2.12.jar<br />sh">http://repo1.maven.org/maven2/jline/jline/2.12/jline-2.12.jar<br />sh</a> get_source.sh<br />export JAVA_HOME=~/jdk1.9.0<br />export PATH=$JAVA_HOME/bin:$PATH<br />export JLINE2LIB=~/jshell/jline-2.12.jar<br />cd langtools/repl<br />sh scripts/compile.sh</code></pre> </li>
<li>To run the shell, execute these commands: <pre class="prettyprint"><code>export JAVA_HOME=~/jdk1.9.0/<br />export PATH=$JAVA_HOME/bin:$PATH<br />export JLINE2LIB=~/jshell/jline-2.12.jar<br />cd ~/jshell/langtools/repl<br />sh scripts/run.sh</code></pre> </li>
</ol>
<p>Now you are ready to roll. Let's say you want to run some experiments with streams. First import some packages.</p>
<pre class="prettyprint"><code>import java.util.stream.*;<br />import java.nio.file.*;</code></pre>
<p>Let's read all words from <code class="prettyprint">/usr/share/dict/words</code> into a stream:</p>
<pre class="prettyprint"><code>-&gt; Files.lines(Paths.get(&quot;/usr/share/dict/words&quot;))<br />| Expression value is: java.util.stream.ReferencePipeline$Head@6108b2d7<br />| assigned to temporary variable $1 of type java.util.stream.Stream&lt;String&gt;</code></pre>
<p>As you can see, this is a rather verbose REPL, but maybe that's not a bad thing for users who aren't accustomed to one.</p>
<p>You can now work with the temporary variable <code class="prettyprint">$1</code> and process it further:</p>
<pre class="prettyprint"><code>$1.filter(w -&gt; w.length() &gt; 20)<br />| Expression value is: java.util.stream.ReferencePipeline$2@180bc464<br />| assigned to temporary variable $2 of type Stream&lt;String&gt;</code></pre>
<p>Why not make an explicit variable? You can, but then you have to know its type:</p>
<pre class="prettyprint"><code><strong>Stream&lt;String&gt; res</strong> = Files.lines(Paths.get(&quot;/usr/share/dict/words&quot;))</code></pre>
<p>In a dynamically typed language, where variables don't have types, this issue doesn't arise. And in Scala, types are inferred for variables, so you don't have to worry about declaring their types either. But in the Java REPL, you are likely to use the $n variables a lot.</p>
<p>So, to complete our example, you might type</p>
<pre class="prettyprint"><code>$2.collect(Col<!-- ) --></code></pre>
<p>Then you can hit the TAB key, and you get autocompletion suggestions: <pre class="prettyprint"><code>Collection Collections Collector Collectors</code></pre>
<p>When you complete to <code class="prettyprint">Collectors.to</code>, you get more suggestions:</p>
<pre class="prettyprint"><code>toCollection( toConcurrentMap( toList() toMap( <br />toSet() <!-- ))) --> </code></pre>
<p>Type <code class="prettyprint">L</code> TAB <code class="prettyprint">)</code> to get</p>
<pre class="prettyprint"><code>$2.collect(Collectors.toList())<br />| Expression value is: [Andrianampoinimerina's, counterintelligence's, counterrevolutionaries, counterrevolutionary's, electroencephalogram's, electroencephalograms, electroencephalograph, electroencephalograph's, electroencephalographs]<br />| assigned to temporary variable $3 of type List&lt;String&gt;</code></pre>
<p>Now we can be bolder and try it all at once, this time yielding an array: <pre class="prettyprint"><code>Files.lines(Paths.get(&quot;/usr/share/dict/words&quot;)).filter(w -&gt; w.length() &gt; 20).toArray()<br />| Expression value is: [Ljava.lang.Object;@153f5a29<br />| assigned to temporary variable $4 of type Object[]</code></pre>
<p>Ok, that's interesting—we get the Java weirdness that arrays inherit a useless <code class="prettyprint">toString</code> method. It's easy enough to recover:</p>
<pre class="prettyprint"><code>Arrays.toString($4)<br />| Expression value is: &quot;[Andrianampoinimerina's, counterintelligence's, counterrevolutionaries, counterrevolutionary's, electroencephalogram's, electroencephalograms, electroencephalograph, electroencephalograph's, electroencephalographs]&quot;<br />| assigned to temporary variable $5 of type String</code></pre>
<p><img src="http://www.java.net/sites/default/files/hope_0.jpeg" style="float:right; margin-left:1em;"/></p>
<p>Maybe they could relent and print arrays for us.</p>
<p>Also. it's a bit of a pain that one needs to pay close attention to the numbers with the temporary variables. Maybe <code class="prettyprint">$</code> or <code class="prettyprint">$0</code> could refer to the last result?</p>
<p>Overall, the REPL is quite nice, but with a bit of polish, it could be even nicer. These are early days, so there is hope.</p>
<p>(As an aside, try a Google image search for hope.)</p>
<p>Check it out and let them know what you think! There is some documentation <a href="/sites/all/modules/pubdlcnt/pubdlcnt.php?file=https://java.net/downloads/adoptopenjdk/REPL_Tutorial.pdf&nid=931952">here</a>, and the mailing list is <a href="http://mail.openjdk.java.net/mailman/listinfo/kulla-dev">here</a>.</p>
<table id="attachments" class="sticky-enabled">
<thead><tr><th>Attachment</th><th>Size</th> </tr></thead>
<tbody>
<tr class="odd"><td><a href="http://www.java.net/sites/default/files/Repl_0.jpg">Repl.jpg</a></td><td>72.35 KB</td> </tr>
<tr class="even"><td><a href="http://www.java.net/sites/default/files/hope_0.jpeg">hope.jpeg</a></td><td>5.76 KB</td> </tr>
</tbody>
</table>
http://www.java.net/blog/cayhorstmann/archive/2015/05/25/trying-out-java-9-repl#commentsMon, 25 May 2015 11:56:47 +0000cayhorstmann931952 at http://www.java.netHello Java 8 (and how it makes GlassFish speechless...)http://www.java.net/blog/cayhorstmann/archive/2014/03/20/hello-java-8-and-how-it-makes-glassfish-speechless-0
<!-- 3 | 0 --><img src="/images/people/cay_horstmann.jpg" border="0", align="left" /><p><img style="float: left; margin-right: 1em;" width="100px" src="http://horstmann.com/java8/cover.jpg"/>After all these years, Java 8 is finally available. Of course, I have used it for about a year, while writing my book <a href="http://horstmann.com/java8/">Java SE 8 for the Really Impatient</a>. But I switched <code class="prettyprint">JAVA_HOME</code> and the <code class="prettyprint">PATH</code> whenever I worked on the book. Now I downloaded the official release and changed <code class="prettyprint">JAVA_HOME</code> and the <code class="prettyprint">PATH</code> one last time. Eclipse came up fine, and my Scala-based tools for e-book production worked without a hitch, and I forgot all about it. That's the nice thing about backwards compatibility.</p>
<p>These days, the blogosphere is awash in blogs that sing the praises of Java 8. I don't think I add any value by writing my own. It's a major release—the biggest change in the Java language since Java 1.0 and the biggest change in the Java API since Java 1.2 (Or was that Java 2? Or Java 2 version 1.2?) Here is a <a href="http://www.baeldung.com/java8">great list of links</a>. Or, if you'd rather learn from a book than a list of links, you know what to do...</p>
<p>As my wife knows, if there is one person who can wring a drop of unhappiness from even the happiest event, that's me. So, this morning, I made a small fix to my side-project, the <a href="http://code-check.org">code-check</a> autograder. It worked locally, and I ran the script to upload the WAR. Being a conscientious (and slightly pessimistic) person, I pointed my browser to the server, and whoa:</p>
<p><img src="http://www.java.net/sites/default/files/20140320T0834_0.png"/></p>
<p><img style="float: left; margin-right: 1em;" src="http://weblogs.java.net/blog/cayhorstmann/archive/2006-09-08/hell.png"/>Ugh, not again! Time to check out the logs. Now if there is one thing that I really hate in life it is the <a href="https://weblogs.java.net/blog/cayhorstmann/archive/2006/09/the_power_and_p.html">Stack Trace from Hell</a>. Why can't GlassFish be like Play or Rails, and give the file name and line number of the offending artifact?</p>
<p>But there is something worse than the Stack Trace from Hell. That would be Nothing At All. And that's what I got. Instead of noisily squawking about what ails its innards, it had turned into the strong and silent type:</p>
<pre class="prettyprint"><code>[2014-03-20T15:08:41.869+0000] [glassfish 4.0] [WARNING] [NCLS-DEPLOYMENT-00041]<br />[javax.enterprise.system.tools.deployment.autodeploy]<br />[tid: _ThreadID=69 _ThreadName=AutoDeployer]<br />[timeMillis: 1395328121869] [levelValue: 900] <br />[[Attempt to create file /opt/domains/domain1/autodeploy/.autodeploystatus/codecheck.war failed;<br />no further information.]]</code></pre>
<p>For an hour I tried This And That, to no avail. The app ran on my machine and not on the server. “The requested resource is not available”</p>
<p>Finally, instead of using autodeploy, I logged into the server and deployed manually:</p>
<pre class="prettyprint"><code>$ asadmin deploy codecheck.war<br />remote failure: Error occurred during deployment: Exception while loading the app :<br /> java.lang.IllegalStateException: ContainerBase.addChild: start:<br /> org.apache.catalina.LifecycleException: java.lang.IllegalArgumentException:<br /> java.lang.UnsupportedClassVersionError: Class Initializer has unsupported major or minor version<br /> numbers, which are greater than those found in the Java Runtime Environment version 1.7.0_40.<br />Please see server.log for more details.<br />Command deploy failed.</code></pre>
<p>Oh good grief! Of course. I had compiled the WAR for Java 8. Now why could that information not be prominently displayed in the web page? Or at least in the logs? Dear reader, if you work on developing tools for developers, please put every irregularity in their face. You'd think that nobody would be stupid enough to make errors such as compiling the WAR with the wrong version of Java, but you'd be wrong.</p>
<p>I don't know how many hundreds of hours I have wasted with fiddly configuration stuff like this. To me, it's by far the worst part of Java EE . I would pay real money for an EE app server that serves developers and mercilessly traces every failure to a file name and line number in one of the app's artifacts. <a href="http://www.playframework.com/documentation/1.1/firstapp">Like Play does:</a> “No route found. In /app/views/Application/index.html (around line 4)”. </p>
<p><img src="http://www.playframework.com/documentation/1.1/images/firstapp-2" width="640px"/></p>
http://www.java.net/blog/cayhorstmann/archive/2014/03/20/hello-java-8-and-how-it-makes-glassfish-speechless-0#commentsThu, 20 Mar 2014 16:39:28 +0000cayhorstmann901573 at http://www.java.netStill Using Applets? Sign Them, Or Elsehttp://www.java.net/blog/cayhorstmann/archive/2014/01/16/still-using-applets-sign-them-or-else
<!-- 1716 | 0 --><img src="/images/people/cay_horstmann.jpg" border="0", align="left" /><p>When Sun Microsystems introduced Java in 1995, applets were considered the killer feature for the business success of Java. Don’t believe it? Check out <a href='http://sunsite.uakom.sk/sunworldonline/swol-07-1995/swol-07-java.html'>this article</a>. Imagine a boring business program with buttons and text fields, the kind that in 1995 had a Visual Basic frontend that connected to the backend database. What a nightmare that was. Whenever the app changed, the clients had to be redeployed on thousands of machines. With Java, the equivalent program would be hosted on a server, the user would visit a web page, the applet would be downloaded, and it would then run securely in the sandbox.
<p>Of course, for that to happen, the sandbox had to be really secure. And in 1995, it was. There was discomfort by academic researchers who felt that the security model was pretty complex. <a href="http://sip.cs.princeton.edu/pub/secure96.html">This is a typical paper</a> from that era. But nobody paid much attention since exploits were rare and quickly patched.</p>
<p>Of course, applets never were as prominent as originally envisioned. There are many reasons: machinations by Microsoft, the ubiquity of Flash, the rise of JavaScript, and the increasing sophistication of hackers who did exploit the weaknesses that the academics had grumbled about 15 years earlier. But there are lots of applets out there. In my line of work, teaching computer science, I see them all the time. For example, Professor Amruth Kumar has a <a href="http://problets.org">nice site</a> with exercises for Computer Science 101 students. </p>
<p>In fact, yesterday I headed to that site, and was greeted with this scary message: </p>
<p><img src="http://www.java.net/sites/default/files/applet-security-error.png" alt="applet security error dialog"/></p>
<p>So it has finally happened. I have a few blast-from-the-past applets on my <a href="http://horstmann.com">home page</a>, and the time has come to sign them. In case you are in the same boat, here is what you have to do.</p>
<ol>
<li>Get a certificate. A self-signed certificate won’t do. This is not so easy for an individual, and there is a fee that ranges from modest to astounding, depending on the provider. The least expensive route seems to be to use a Comodo reseller. I had good experience with <a href="http://ksoftware.net/">K Software</a>. Not only do they offer a decent discount, but they also yell at Comodo when they pigheadedly follow their outdated procedure and won’t authenticate you. In my case, I don’t have a land line (who does these days?), and my phone number isn’t in any online directory. This so baffled Comodo that they refused to issue the certificate, until the reseller intervened.</li>
<li>Install the certificate into a JKS keystore. This is a somewhat <a href="http://certhelp.ksoftware.net/support/articles/17158-how-do-i-export-my-code-signing-certificate-from-firefox-">byzantine process</a>, and <a href="http://jackstromberg.com/2013/05/importing-a-ssl-certificate-into-a-java-keystore-via-a-pkcs12-file/">even more so on Linux</a>.</li>
<li>Put your classes in a JAR file. The old way of having the browser load the classes one at a time no longer works. And add a manifest to the JAR with the contents <pre class="prettyprint"><code>Manifest-Version: 1.0<br />Permissions: sandbox</code></pre> Or, if your app actually requires all permissions, and you previously used a self-signed certificate, use <code class="prettyprint">Permissions: all-permissions</code> instead. The <code class="prettyprint">jar</code> command is something like <pre class="prettyprint"><code>jar cvfm MyApplet.jar manifest.mf mypackage/*.class</code></pre> In the <code class="prettyprint">applet</code> tag of your HTML file, add an attribute <code class="prettyprint">archive=&quot;MyApplet.jar&quot;</code>. </li>
<li>Finally, sign your applet. You get a warning if you don’t timestamp it, so you should do that too. Here is how to do that with Comodo. <pre class="prettyprint"><code>jarsigner -keystore path/to/keystore.jks -tsa <a href="http://timestamp.comodoca.com/rfc3161" title="http://timestamp.comodoca.com/rfc3161">http://timestamp.comodoca.com/rfc3161</a> MyApplet.jar keyalias</code></pre> </li>
</ol>
<p>So, I did all that and looked at my ancient applets with amazement. This <a href="http://horstmann.com/applets/RoadApplet/RoadApplet.html">traffic jam applet</a> is as fascinating/depressing as ever. But the weather applet? Time has passed it by. Check out those pre-Swing list boxes! </p>
<p><img src="http://www.java.net/sites/default/files/weather-applet.png" alt="Weather applet"/></p>
<p>Then again, it is amazing that it is working at all. The Perl script from NOAA still produces a text report (now wrapped into some gratuitous HTML), and will hopefully continue to do so for all eternity, just like the transponder in <a href="">2001</a> that relayed the excavation of the lunar monolith, millions of years after it was put into place.</p>
<p><img src="http://www.java.net/sites/default/files/2001_NAL.jpg" alt="2001 book cover"/></p>
http://www.java.net/blog/cayhorstmann/archive/2014/01/16/still-using-applets-sign-them-or-else#commentsThu, 16 Jan 2014 18:10:52 +0000cayhorstmann900847 at http://www.java.netJava 8 for the Really Impatienthttp://www.java.net/blog/cayhorstmann/archive/2013/12/06/java-8-really-impatient
<!-- 4227 | 0 --><img src="/images/people/cay_horstmann.jpg" border="0", align="left" /><p>In my French class, we are reading Marcel Pagnol’s “La gloire de mon père”. It never ceases to amaze me how much more complex and arbitrary human languages are compared to programming languages. Could you imagine a programming language with irregular verbs or the <a href='http://french.about.com/library/verb/bl-subjunctivator.htm'>subjunctive mood</a>?</p>
<p>As an aside, when I teach the introductory programming class, my students are aghast that they need to submit several programming homeworks per week. Clearly, they haven’t taken French. My French professors have routinely ruined my weekends with demands for written summaries of fifty+ page readings, or a couple hundred mind-numbing exercises on the subjunctive mood.</p>
<p>Back to topic, Marcel's dad claims that the longest word in the French language is “anticonstitutionnellement”. So, how would we verify this in Java? </p>
<p>In Linux, <code class="prettyprint">/usr/share/dict/french</code> has French words from <code class="prettyprint">a</code> to <code class="prettyprint">zygomatiques</code>, one per line. So, let's read them and print the longest, using the latest features of Java 8: </p>
<pre class="prettyprint"><code>Path path = Paths.get("/usr/share/dict/french");<br />try (Stream&lt;String&gt; lines = Files.lines(path)) {<br /> Optional&lt;String&gt; longest = lines.max(Comparator.comparingInt(String::length));<br /> longest.ifPresent(System.out::println);<br />}</code></pre>
<p>That’s certainly more concise than the traditional way:</p>
<pre class="prettyprint"><code>Scanner in = new Scanner(new File("/usr/share/dict/french"), "UTF-8");<br />String longest = null;<br />while (in.hasNextLine()) {<br /> String line = in.nextLine();<br /> if (longest == null || longest.length() &lt; line.length()) {<br /> longest = line;<br /> }<br />}<br />if (longest != null) {<br /> System.out.println(longest);<br />}</code></pre>
<p>It is also just as efficient. The stream doesn't actually store all lines, but lazily fetches them when needed.</p>
<p>But there is a fair amount of new jargon to master.</p>
<ul>
<li>An <code class="prettyprint">Optional&lt;T&gt;</code> is a <code class="prettyprint">null</code>-safe wrapper. Since it's possible for a stream to be empty, <code class="prettyprint">max</code> returns an <code class="prettyprint">Optional</code> result.</li>
<li>The <code class="prettyprint">ifPresent</code> method takes a function argument. If the <code class="prettyprint">Optional</code> contains a value, that value is passed to the function. Here, we use the function that maps <code class="prettyprint">x</code> to <code class="prettyprint">System.out.println(x)</code>, which can be more concisely written as a method expression <code class="prettyprint">System.out::println</code>.</li>
<li>The <code class="prettyprint">max</code> method takes a comparator. The <code class="prettyprint">Comparator</code> interface has a static (!) method <code class="prettyprint">comparing</code>. It makes a comparator from a function that extracts “key information” from objects in some way. In our case, the key that we want to use for comparison is the string length, again written as a method expression <code class="prettyprint">String::length</code>. (Actually, if you look closely, you'll see that I used <code class="prettyprint">comparingInt</code>, not <code class="prettyprint">comparing</code>. That avoids boxing <code class="prettyprint">int</code> into <code class="prettyprint">Integer</code> values.)</li>
<li>The <code class="prettyprint">Files.lines</code> method produces a stream of lines for a given path. Mercifully, the default character encoding is UTF-8, not the platform encoding. Previous APIs for readers and scanners used the platform encoding by default, which has bitten me more than once.</li>
<li>Finally, note the Java 7 <code class="prettyprint">Path</code> class and <code class="prettyprint">try</code>-with-resources block so that the stream (and the underlying file) is closed automatically.</li>
</ul>
<p><img src='http://www.java.net/sites/default/files/9780133430202_xs.jpg'/></p>
<p>So, how is one to pick up all that new jargon? I wanted a short book that covers everything that is new in Java 8, without also teaching me what I already know. No such book existed, so I had to write it.</p>
<p>If you or your company subscribes to Safari Books Online, check out the <a href='http://my.safaribooksonline.com/book/programming/java/9780133430202'>Rough Cut</a> of “Java 8 for the Really Impatient”. In a short 200 pages, I cover lambdas, streams, concurrency, the new date/time API, Nashorn, Java FX, and more. No religion, just the facts, for experienced Java programmers, and organized for easy learning and easy reference. (In fact, I had to look up a couple of details from the book for writing the code in this blog. I had no trouble finding them :-))</p>
<table id="attachments" class="sticky-enabled">
<thead><tr><th>Attachment</th><th>Size</th> </tr></thead>
<tbody>
<tr class="odd"><td><a href="http://www.java.net/sites/default/files/9780133430202_xs.jpg">9780133430202_xs.jpg</a></td><td>20.17 KB</td> </tr>
</tbody>
</table>
http://www.java.net/blog/cayhorstmann/archive/2013/12/06/java-8-really-impatient#commentsFri, 06 Dec 2013 19:45:17 +0000cayhorstmann900403 at http://www.java.netScanners live in vainhttp://www.java.net/blog/cayhorstmann/archive/2013/10/14/scanners-live-vain
<!-- 43 | 0 --><img src="/images/people/cay_horstmann.jpg" border="0", align="left" /><p style="float:left; margin-right: 1em;">
<img src="http://horstmann.com/blogs/images/scanners.jpeg">
</p>
<p>Do you remember the olden days when reading lines from a file was as easy as eating soup with a fork? </p>
<pre class="prettyprint"><code>BufferedReader reader = new BufferedReader(new InputStreamReader(someInputStream));<br />String line;<br />while ((line = reader.readLine()) != null)<br /> process(line);</code></pre>
<p>Just about ten years ago, Java 5 put an end to that nonsense.</p>
<pre class="prettyprint"><code>Scanner in = new Scanner(/*just about anything at all that makes sense here */)<br />while (in.hasNextLine())<br /> process(in.nextLine());</code></pre>
<p>Right now, I am putting the final touches on "Java 8 for the Impatient" and I describe the changes in the I/O API. You can read a file into a <code class="prettyprint">Stream&lt;String></code>. That is nice. The stream is lazy. Once you have found what you are looking for, nothing else is read.</p>
<pre class="prettyprint"><code>try (Stream&lt;String> lines = Files.lines(path, StandardCharsets.UTF_8)) {<br /> String passwordEntry = lines.filter(s -> s.startsWith("password=")).findFirst();<br /> ...<br />}</code></pre>
<p>What if you want to read from an URL instead? Did they retrofit <code class="prettyprint">Scanner</code>? No sir. <code class="prettyprint">Scanner</code>s lives in vain, in the <code class="prettyprint">java.util</code> package. (Extra credit if you know where that comes from.) Instead, someone went back into the graveyard and retrofitted <code class="prettyprint">BufferedReader</code>. Does <code class="prettyprint">BufferedReader</code> have a constructor that takes an <code class="prettyprint">InputStream</code>? No sir. It hasn't been touched for ten years. So, here we are, in 2013, and have to write</p>
<pre class="prettyprint"><code>try (Stream&lt;String> lines = new BufferedReader(new InputStreamReader(url.openStream())).lines())<br /> ...</code></pre>
<p>I realize the Java API is vast, but really, it isn't that vast. All the file stuff is in <code class="prettyprint">java.io</code> and <code class="prettyprint">java.nio</code>, and yes, <code class="prettyprint">java.util.Scanner</code>, and every year or two I get to revisit it as I update a book. If I can keep track of it, so should the folks at Oracle. Moving forward, it would be good to keep a few principles in mind.</p>
<ul>
<li>Everyone loves the convenience methods in <code class="prettyprint">Files</code> Keep them coming.</li>
<li>Nobody loves the layered stuff, like <code class="prettyprint">new BufferedReader(new InputStreamReader(...))</code>. That was a bad idea from the start, and I said so almost twenty years ago in the early editions of Core Java, where I pointed out that for the preceding twenty years programmers had been able to open files and got buffering behind the scenes without any of that nonsense.</li>
<li>Maybe the age of scanners has come to an end, and streams are the new way for consuming input. But learn from the scanners. One thing that made them attractive was that they are omnivores. You could construct them from a file. An input stream. A string. A <code class="prettyprint">ReadableByteChannel</code>. That is how it should be. If you feel the urge to ignore <code class="prettyprint">Scanner</code> and resurrect <code class="prettyprint">BufferedReader</code>, just add those constructors. </li>
</ul>
http://www.java.net/blog/cayhorstmann/archive/2013/10/14/scanners-live-vain#commentsTue, 15 Oct 2013 04:22:25 +0000cayhorstmann899400 at http://www.java.netJavaOne for the Impatienthttp://www.java.net/blog/cayhorstmann/archive/2013/09/26/javaone-impatient
<!-- 1856 | 0 --><img src="/images/people/cay_horstmann.jpg" border="0", align="left" /><p>Here are my impressions from the 18th Java One. Java SE 8 is around the corner, Java EE 7 was just released, and both are a joy to use. NetBeans 7.4 is awesome. And yet, people were strangely blasé at the conference. I still remember how much excitement there was at Java One when Java was in its infancy, and the promises greatly exceeded the reality. (Do you remember Jini? Or the original Java EE?) Nowadays, that excitement is lavished on other technologies whose promises exceed the reality, and Java has grown up.</p>
<p>Apparently people do remember the original Java EE. Not the promise, but the reality. I am amazed how many people <em>still</em> think that Java EE is unbearably cumbersome, and to what lengths they go to avoid it. My favorite presentation of the conference was Adam Bien’s “ Lean and Opinionated Java EE 7 Applications”. He described pretty much what I have found myself doing: Use JAX-RS with stateless beans, don’t use ancient design patterns (DAO, DTO), don’t use Apache Commons when you can use a standard library, focus on the business logic and use the standard EE mechanisms for plumbing. It works for me, but the fact that it works for his customers is a lot more meaningful. He is a funny guy too (for a German at least...) Check him out if you get a chance.</p>
<p>As in the previous five Java Ones, there was much talk about JavaFX. I found it interesting that JavaFX runs so well on the Raspberry Pi, which has the horsepower of an Intel CPU from about 15 years ago. But its GPU is quite good, and JavaFX knows how to work with a GPU much better than Swing did. Oracle has publicly stated that Swing is in maintenance mode, so desktop developers (yes, there still are some left) were hungry for advice on how to transition their apps. Unfortunately, there doesn’t seem to be a silver bullet. </p>
<p><img src='http://horstmann.com/blogs/images/java-impatient.jpg' style='float: left; margin-right: 1em;'/></p>
<p>There was a lot of interest in the Java 8 features—all the talks about lambdas were packed. But I sensed more curiosity than excitement, which surprised me a bit since this is easily the biggest Java language change since, well, since Java 1.0. Java 8 is on track for early 2014, with <a href='https://jdk8.java.net/download.html'>regular snapshots</a> that you can, and should, try out. I have used them without any problems for some time now, as I am writing <strong>Java 8 for the Really Impatient</strong> (which should be out in a few weeks). I guess we have been waiting for it so long that the excitement has dissipated.</p>
<p>What is my favorite Java 8 feature, other than lambdas and streams? Now, when you keep a <code class="prettyprint">ConcurrentHashMap</code> of counters, you can increment the counter as</p>
<pre class="prettyprint"><code>map.merge(key, 1, Integer::sum);</code></pre>
<p>If the key isn't present, it is put into the map with a value of 1. Otherwise, it is replaced with 1 + the old value. And yes, it’s threadsafe. (Try doing that in Java 7. The only safe way I know uses <code class="prettyprint">AtomicInteger</code>.)</p>
<p>Ok, that’s not fair—that code actually uses lambdas since <code class="prettyprint">Integer::sum</code> is <code class="prettyprint">(x, y) -> x + y</code>. So, my favorite feature that doesn’t use lambdas is the new Date/Time API. Call</p>
<pre class="prettyprint"><code>ZonedDateTime nextMeeting = meeting.plus(Period.ofDays(7));</code></pre>
<p>If <code class="prettyprint">meeting</code> falls on Monday at 10 am, then <code class="prettyprint">nextMeeting</code> is 10 am a week later, <em>even if there was a daylight savings time change</em>. That API is a joy to use and, yes, it too is threadsafe. In this example, the <code class="prettyprint">plus</code> method is immutable.</p>
<p>My favorite Java tool of the show is NetBeans 7.4. The HTML 5/JavaScript implementation is awesome. You write your client code in JavaScript, your server code in Java EE, with autocompletion in both, click on debug, set breakpoints in the client or server, and it all works. Without installing any plugins. Without hours of configuration. Check it out <a href='https://netbeans.org/community/releases/74/'>here</a>!</p>
<p><img src='http://horstmann.com/blogs/images/raspberrypi.jpg' style='float: left; margin-right: 1em;'/></p>
<p>For me, the most fun presentation was the Raspberry Pi hands-on lab. They didn’t have enough devices, so we had to work with a lab mate. This is something I always do with my students since I figure that four eyes see more than two. It has been over thirty years that I had touched any hardware other than a PC, and I had never done any embedded programming, so those extra eyes were great. Our momentous achievement? We made the green light blink, using Java.</p>
<p>And the winner in the “wild and crazy” category is “The Chuck Norris Experiment: Running Java in Any Browser Without a Plug-in”. Anton Epple and Jaroslav Tulach (one of the founders of NetBeans) showed off <a href='http://wiki.apidesign.org/wiki/Bck2Brwsr'>bck2brwser</a>, a strange and ambitious project to bring Java back into the browser. (There is no question that Java in the browser is effectively dead, except for legacy applications in corporate intranets. Multiple Oracle employees told me that nobody should develop new applets or WebStart applications.) Jaroslav wrote a Java virtual machine in JavaScript. You write your code in (a rather stringent subset of) Java and compile it to a JAR. His JavaScript code unpacks and executes it. Today, you can access the DOM and write games with Canvas. Tomorrow, perhaps the sky will be the limit. I hope it works out.</p>
http://www.java.net/blog/cayhorstmann/archive/2013/09/26/javaone-impatient#commentsThu, 26 Sep 2013 23:09:52 +0000cayhorstmann899005 at http://www.java.net I Didn't Ask for a Toolbar with That Javahttp://www.java.net/blog/cayhorstmann/archive/2013/02/02/i-didnt-ask-toolbar-java
<!-- 904 | 0 --><img src="/images/people/cay_horstmann.jpg" border="0", align="left" /><p><em>Summary: </em>In these unhappy days where Oracle is working hard to regain the trust of users, it seems a staggeringly bad idea that the Java updater installs the Ask toolbar by default. It's plainly bad for Java and can't possibly be worth the few clams in additional revenue. If you agree, please sign the petition</p>
<hr/>
<p>These are unhappy days for desktop Java. Java is under constant attack by hackers. Operating systems and browsers now disable Java by default. (Just yesterday, I had a Webex call and for the life of me, I could not find out how to get Webex—which uses Java—to work in Firefox. We switched to Flash-based Adobe Connect instead.) </p>
<p>Could it get worse? Sadly, yes. The Windows installer for the JRE now <a href="http://www.zdnet.com/a-close-look-at-how-oracle-installs-deceptive-software-with-java-updates-7000010038/">installs crapware by default.</a></p>
<p><img src="http://www.java.net/sites/default/files/Capture2.PNG"></img></p>
<p>This may have been going on for a while. I don't really know. On Linux, I just run <code class="prettyprint">tar xvfz ~/Downloads/jdk-7u*.tar.gz</code> ever so often (which apparently is <a href="https://xkcd.com/1168/">a challenge to many)</a>. And the JDK installer, which I run ever so often, doesn’t seem to do this.</p>
<p>Now I don't know whether the Ask toolbar is actually evil, but it <a href="http://download.cnet.com/Ask-Toolbar/3000-12512_4-10201062.html">certainly is unloved</a>. So, where is the win? Right now, people don't trust Java very much. Oracle is working hard to regain trust by providing timely security updates. Why undermine that effort? You don’t earn people’s trust by “recommending” to install stuff that they are likely to hate.</p>
<p>I feel particularly strongly about this because many students need to use Java-based software. You can't expect students to parse and question every screen of every installer. For example, here is the first screen of the JDK installer:</p>
<p><img src="http://www.java.net/sites/default/files/jdk1.png"></img></p>
<p>Should students have to worry whether it is bad that the JavaFX SDK is now included as part of the JDK? Should instructors have to reinstall Java every few weeks to see what might trip up their students next?</p>
<p>Come on, Oracle. Tear down this toolbar!</p>
<p>If you agree, please sign <a href="https://www.change.org/petitions/oracle-corporation-stop-bundling-ask-toolbar-with-the-java-installer">this petition</a> to help things along.</p>
http://www.java.net/blog/cayhorstmann/archive/2013/02/02/i-didnt-ask-toolbar-java#commentsSat, 02 Feb 2013 16:37:45 +0000cayhorstmann894393 at http://www.java.netA First Look at Scala Macroshttp://www.java.net/blog/cayhorstmann/archive/2013/01/14/first-look-scala-macros
<!-- | 0 --><p>The final version of Scala 2.10 was released on January 4, 2013. Martin Christensen, a visiting scholar in our department, and myself have been playing with some of the new features, and I'll be blogging about some of our discoveries in my copious spare time.</p>
<p>Today, I'll show you how to write a simple macro in Scala. You may have seen macros in C, such as #define swap(x, y) { int temp = x; x = y; y = temp; }</p>
</pre><p>C macros are just text substitutions. If you call <code class="prettyprint">swap(first, last)</code>, the result is <code class="prettyprint">{ int temp = first; first = last; last = temp; }</code>, which is fine. But if you call <code class="prettyprint">swap(first, temp)</code> or <code class="prettyprint">swap(a[i++], a[j])</code>, bad things will happen. That's why C++ programmers are told to avoid macros and to use inline functions instead.</p>
<p>In Scheme, macros are much more commonly used. Here is a <code class="prettyprint">swap</code> macro in Scheme:</p>
<pre class="prettyprint"><code>(define-syntax-rule (swap x y)<br /> (let ([temp x]) (set! x y) (set! y temp)))</code></pre>
<p>If you call<code class="prettyprint">(swap first last)</code>, then you get <code class="prettyprint">(let ([temp first]) </code><code class="prettyprint">(set! first last) </code><code class="prettyprint">(set! last temp))</code>. This loooks just like <code class="prettyprint">#define</code> in C, but there is an important difference. If you call <code class="prettyprint">(swap first temp)</code>, then the <code class="prettyprint">temp</code> in the macro will automatically be renamed. Macros in Scheme are “hygienic”. In Scheme, it's easy to write macros, even complex ones, because Scheme programs are just lists.</p>
<p>Scala 2.10 has an experimental macro facility. It's not as easy as in Scheme, of course, because Scala programs aren't just lists. You have to know how to manipulate Scala parse trees. </p>
<p>First off, the mechanics. You define a macro as if it was a function, but then you use the <code class="prettyprint">macro</code> keyword to link it to an actual function that works on parse trees.</p>
<pre class="prettyprint"><code> def swap(a: Any, b: Any): Unit = macro swap_impl<br /> def swap_impl(c: Context)(a: c.Expr[Any], b: c.Expr[Any]): c.Expr[Unit] = ...</code></pre>
<p>This particular macro is willing to take as arguments expressions of any type, so the corresonding parse trees have type <code class="prettyprint">c.Expr[Any]</code>. The “context” <code class="prettyprint">c</code> encapsulates the compile-time services that are available in the macro implementation, such as type checking, logging errors, and many others. </p>
<p>Now we need to know how to construct a parse tree. Fortunately, there are some functions that let us display parse trees. For example, run this in the REPL:</p>
<pre class="prettyprint"><code>import scala.reflect.runtime.universe._<br />print(showRaw(reify{println(&quot;Hello&quot;) }.tree))</code></pre>
<p>The result is</p>
<pre class="prettyprint"><code>Apply(Select(Select(This(newTypeName(&quot;scala&quot;)), <br />newTermName(&quot;Predef&quot;)), newTermName(&quot;println&quot;)), <br />List(Literal(Constant(&quot;Hello&quot;))))</code></pre>
<p>If you squint at it, you can see how this is <code class="prettyprint">scala.Predef.println(&quot;Hello&quot;)</code>.</p>
<p>So, next I tried the following in the REPL:</p>
<pre class="prettyprint"><code>var a = 3<br />var b = 4</code></pre> <pre class="prettyprint"><code>print(showRaw(reify{var temp = a; a = b; b = temp }.tree))</code></pre>
<p>I was rewarded with this beauty:</p>
<pre class="prettyprint"><code>Block(List(ValDef(Modifiers(MUTABLE), <br />newTermName(&quot;temp&quot;), TypeTree(), Select(Select(Select(Select(Select(Select(Ident($line4), <br />newTermName(&quot;$read&quot;)), newTermName(&quot;$iw&quot;)), newTermName(&quot;$iw&quot;)), <br />newTermName(&quot;$iw&quot;)), newTermName(&quot;$iw&quot;)), newTermName(&quot;a&quot;))), <br />Apply(Select(Select(Select(Select(Select(Select(Ident($line4), newTermName(&quot;$read&quot;)), <br />newTermName(&quot;$iw&quot;)), newTermName(&quot;$iw&quot;)), newTermName(&quot;$iw&quot;)), <br />newTermName(&quot;$iw&quot;)), newTermName(&quot;a_$eq&quot;)), <br />List(Select(Select(Select(Select(Select(Select(Ident($line8), newTermName(&quot;$read&quot;)), <br />newTermName(&quot;$iw&quot;)), newTermName(&quot;$iw&quot;)), newTermName(&quot;$iw&quot;)), <br />newTermName(&quot;$iw&quot;)), newTermName(&quot;b&quot;))))), <br />Apply(Select(Select(Select(Select(Select(Select(Ident($line8), newTermName(&quot;$read&quot;)), <br />newTermName(&quot;$iw&quot;)), newTermName(&quot;$iw&quot;)), newTermName(&quot;$iw&quot;)), <br />newTermName(&quot;$iw&quot;)), newTermName(&quot;b_$eq&quot;)), <br />List(Ident(newTermName(&quot;temp&quot;)))))</code></pre>
<p>Ugh. Apparently, when you write</p>
<pre class="prettyprint"><code>var a = 3</code></pre>
<p>in the REPL, you declare <code class="prettyprint">$line4.$read.$iw.$iw.$iw.a</code> or some such thing. Let's try something simpler, defining the variables in a block.</p>
<pre class="prettyprint"><code>print(showRaw(reify { var a = 3; var b = 4; { var temp = a; a = b; b = temp }}.tree))</code></pre>
<p>That's better:</p>
<pre class="prettyprint"><code>Block(List(ValDef(Modifiers(MUTABLE), newTermName(&quot;a&quot;), TypeTree(),<br />Literal(Constant(3))), ValDef(Modifiers(MUTABLE), newTermName(&quot;b&quot;), TypeTree(),<br />Literal(Constant(4)))), Block(List(ValDef(Modifiers(MUTABLE), newTermName(&quot;temp&quot;),<br />TypeTree(), Ident(newTermName(&quot;a&quot;))), Assign(Ident(newTermName(&quot;a&quot;)),<br />Ident(newTermName(&quot;b&quot;)))), Assign(Ident(newTermName(&quot;b&quot;)), Ident(newTermName(&quot;temp&quot;)))))</code></pre>
<p>Now we can get going. We need to construct a </p>
<pre class="prettyprint"><code>Block(List(ValDef(Modifiers(MUTABLE), newTermName(&quot;temp&quot;), TypeTree(), Ident(...), Assign(Ident(...), Ident(...)))),<br />Assign(Ident(...), Ident(newTermName(&quot;temp&quot;)))))</code></pre>
<p>You want to know how the macro is called so you know what expressions you receive. The <code class="prettyprint">print/showRaw/reify</code> incantation works for that too:</p>
<pre class="prettyprint"><code>def swap(x: Int, y: Int) {}<br />print(showRaw(reify{var a = 3; var b = 4; swap(a, b)}.tree))</code></pre>
<p>yields</p>
<pre class="prettyprint"><code>...Apply(Select(Select(Select(Select(Select(Select(Ident($line12), <br />newTermName(&quot;$read&quot;)), newTermName(&quot;$iw&quot;)), newTermName(&quot;$iw&quot;)), <br />newTermName(&quot;$iw&quot;)), newTermName(&quot;$iw&quot;)), newTermName(&quot;swap&quot;)), <br /><b>List(Ident(newTermName(&quot;a&quot;)), Ident(newTermName(&quot;b&quot;)))))</b></code></pre>
<p>Again, the mysterious <code class="prettyprint">$read.$iw.$iw.$iw.swap</code>—the list of <code class="prettyprint">$iw</code> gets longer as you keep working in the REPL. But you can clearly see what you get: two expressions of the form <code class="prettyprint">Ident(new TermName(&quot;...&quot;))</code>.</p>
<p>That's enough information to write the <code class="prettyprint">swap_impl</code> method:</p>
<pre class="prettyprint"><code>def swap_impl(c: Context)(a: c.Expr[Any], b: c.Expr[Any]): c.Expr[Unit] = {<br /> import c.universe._<br /> import c.universe.Flag._<br /> val unitResult = c.Expr[Unit](Literal(Constant(())))<br /> a.tree match { <br /> case ia : Ident =&gt; b.tree match {<br /> case ib : Ident =&gt; c.Expr[Unit](Block( // Had to take out List<br /> ValDef(Modifiers(MUTABLE), newTermName(&quot;temp&quot;), TypeTree(), ia),<br /> Assign(ia, ib), <br /> Assign(ib, Ident(newTermName(&quot;temp&quot;)))))<br /> case _ =&gt; unitResult<br /> }<br /> case _ =&gt; unitResult <br /> }<br />}</code></pre>
<p>And it works:</p>
<pre class="prettyprint"><code>object SwapTest extends App {<br /> import Swap._<br /> { // Need to define the variables in a block<br /> var a = 3 <br /> var b = 4 <br /> swap(a, b)<br /> println(a)<br /> println(b)<br /> } <br />}</code></pre>
<p><strong>Exercise 1:</strong> What happens if you call <code class="prettyprint">swap(first, temp)</code>? How can you fix it?</p>
<p>To my surprise, you get perfectly good error messages when you abuse the macro. For example, declare</p>
<pre class="prettyprint"><code>var a = &quot;Fred&quot;</code></pre>
<p>The error message says “type mismatch”. That makes sense. You can't swap a <code class="prettyprint">String</code> and an <code class="prettyprint">Int</code>. </p>
<p>Declare</p>
<pre class="prettyprint"><code>val a = 3</code></pre>
<p>and the error message says “reassignment to <code class="prettyprint">val</code>”.</p>
<p>But not all is well yet. Try</p>
<pre class="prettyprint"><code>var a = Array(3, 4)<br />swap(a(0), a(1))</code></pre>
<p>Clearly, this can't work. Now the macro doesn't get an <code class="prettyprint">Ident(...)</code>. Recall that <code class="prettyprint">a(0)</code> means <code class="prettyprint">a.apply(0)</code>. The macro gets an <code class="prettyprint">Apply(Select(..., newTermName(&quot;apply&quot;)), List(...))</code>, as you can find out by using <code class="prettyprint">print/showRaw/reify</code>. </p>
<p><strong>Exercise 2:</strong> Do this. What happens? And what exactly is passed to the macro?</p>
<p>In this case, we want to call</p>
<pre class="prettyprint"><code>int temp = a(0)<br />a(0) = a(1)<br />a(1) = temp</code></pre>
<p>where the last two expressions are really</p>
<pre class="prettyprint"><code>a.update(0, a.apply(1))<br />a.update(1, temp)</code></pre>
<p>In other words, we are passed a tree containing <code class="prettyprint">a.apply(...)</code>, and we need to make a tree calling <code class="prettyprint">a.update(..., ...)</code>. </p>
<p>Finally, what if we do get fields of a class? </p>
<pre class="prettyprint"><code>object SwapTest extends App {<br /> import Swap._<br /> var a = 3 <br /> var b = 4 <br /> swap(a, b)<br /> println(a)<br /> println(b)<br />}</code></pre>
<p>Now, the call to <code class="prettyprint">swap</code> receives the tree for the getter methods <code class="prettyprint">SwapTest.a</code> and <code class="prettyprint">SwapTest.b</code>. </p>
<p><strong>Exercise 3:</strong> Verify this. What exactly is passed to the macro?</p>
<p>We want to generate calls to those getter methods for reading the value, and to the setter methods when writing:</p>
<pre class="prettyprint"><code>int temp = SwapTest.a<br />SwapTest.a_$eq(SwapTest.b)<br />SwapTest.b_$eq(temp)</code></pre>
<p>Here, <code class="prettyprint">a_$eq</code> and <code class="prettyprint">b_$eq</code> are the setter methods that are automatically generated for a <code class="prettyprint">var</code> field. (If you defined them in Scala to replace the defaults, you'd call them <code class="prettyprint">a_=</code> and <code class="prettyprint">b_=</code>.)</p>
<p>To summarize, we'd like the <code class="prettyprint">swap</code> macro to deal with three different kinds of arguments:</p>
<ul>
<li>variables, passed as <code class="prettyprint">Ident(...)</code></li>
<li>locations in arrays or other collections, passed as <code class="prettyprint">Apply(Select(obj, &quot;apply&quot;), index)</code></li>
<li>mutable fields, passed as <code class="prettyprint">Apply(Select(obj, fieldname))</code></li>
</ul>
<p>Here is the implementation of the macro that handles all three. The <code class="prettyprint">assign</code> helper function deals with the three cases, turning them into an assignment, a call to <code class="prettyprint">update</code>, or a call to the setter.</p>
<pre class="prettyprint"><code>def swap_impl(c: Context)(a: c.Expr[Any], b: c.Expr[Any]): c.Expr[Unit] = {<br /> import c.universe._<br /> import c.universe.Flag._<br /><br /> def assign(l: c.Expr[Any], r: c.Expr[Any]) = {<br /> l.tree match {<br /> case il : Ident =&gt; Assign(il, r.tree)<br /> case Apply(Select(obj, sel), List(index)) if sel.toString == &quot;apply&quot; =&gt; <br /> Apply(Select(obj, newTermName(&quot;update&quot;)), List(index, r.tree)) <br /> case Select(obj, sel) =&gt; Apply(Select(obj, sel.toString + &quot;_$eq&quot;), List(r.tree))<br /> case _ =&gt; c.abort(l.tree.pos, &quot;Expected variable or variable(index)&quot;)<br /> }<br /> }<br /><br /> c.Expr[Unit](Block(<br /> ValDef(Modifiers(MUTABLE), newTermName(&quot;$temp&quot;), TypeTree(), a.tree),<br /> assign(a, b),<br /> assign(b, c.Expr[Any](Ident(newTermName(&quot;$temp&quot;))))))<br />}</code></pre>
<p>Note how to report an error if none of the three cases occur. If you call <code class="prettyprint">swap(a + 1, b)</code>, then the tree won't match, and the <code class="prettyprint">abort</code> method of the <code class="prettyprint">Context</code> trait will cause an error report that points to the offending location. </p>
<p><strong>Exercise 4:</strong> Call</p>
<pre class="prettyprint"><code>val a = List(3, 4)<br />swap(a(0), b(0))</code></pre>
<p>What error report do you get? Why?</p>
<p>Now you have seen a very basic macro, and you have seen that writing macros is no fun in Scala. But, to put it in perspective, it's a lot better than byte code engineering in Java. </p>
<p>But hope is on the way. The fellow who implemented all this, Eugene Burmako, is working on the <a href="http://docs.scala-lang.org/overviews/macros/paradise.html">macro paradise</a> that should make common cases easier. Personally, I'll be happy when I can write</p>
<pre class="prettyprint"><code>def swap_impl(c: Context)(a: c.Expr[Any], b: c.Expr[Any]) = {<br /> c.universe.reify { var temp = a; a = b; b = temp } <br />}</code></pre> <pre class="prettyprint"><code></code></pre>
http://www.java.net/blog/cayhorstmann/archive/2013/01/14/first-look-scala-macros#commentsTue, 15 Jan 2013 05:32:44 +0000cayhorstmann893864 at http://www.java.net