It's rare, but people ask what is jPrime. Well here's the just of it:
jPrime is a community driven technology conference organized once a year by the Bulgarian JUG in Sofia, Bulgaria. Obviously it focuses on the world of Java.
Surrender your ego
It's rare, but people ask what is jPrime. Well here's the just of it:
jPrime is a community driven technology conference organized once a year by the Bulgarian JUG in Sofia, Bulgaria. Obviously it focuses on the world of Java.
Antoine spent a while day with us explaining CDI 1.2 and the upcoming 2.0. We discussed CDI extensions and he wrote some live code.
Links:
These are the slides from the last session. The most interesting part.
I did a short presetation on JShell - Java9's new REPL environment.
Here's the video (in Bulgarian)
Here's the code for nashorn:
import java.net.http.*; import java.util.stream.* import javax.script.* // URL to fetch JSON for weather data for Pravets, Bulgaria String url = "http://api.openweathermap.org/data/2.5//forecast/daily?q=Pravets,BG&appid=27fc9aa7cc0af902105a9c4c2d97845c&mode=json&units=metric&cnt=7"; //java 9 http api String json = HttpRequest.create(new URI(url)).GET().response().body(HttpResponse.asString()) // create nashorn engine ScriptEngine e = new ScriptEngineManager().getEngineByName("js") // expose weather data JSON as global variable to nashorn engine e.put("str", json) // massage JSON using nashorn and get the max. temp values double[] values = (double[]) e.eval("Java.to(JSON.parse(str).list.map(function(val) val.temp.max), Java.type('double[]'))") printf(Arrays.toString(values)+"\n") // stat on max. temp values printf(DoubleStream.of(values).summaryStatistics().toString()) |
Usually I do the review of what we do in our JUG, but Dmitry did quite a good job and he has the best pictures.
Some minor additions from me:
Venkat Subramaniam also known simply as Venkat was here. Venkat is a rockstar (JavaOne Rockstar is someone who did an amazing session at JavaOne. Venkat is 16 (sixteen!!!) times J1 Rockstar in just 4 years).
Venkat did two sessions and a workshop. The two sessions (one on lambdas and one soft-code session on bad code) were highly popular, probably 150-200 people came.
Then there was a workshop that turned into a discussion on lambdas and quality code in general. Which was awesome.
More info on the event page in facebook and on our jProfessionals social page. Photo album.
Some highlights:
I have JDK8 and JDK9. I mostly use JDK8 for new projects. But all new projects are with JDK9 and with language level 6
How do I fix the default settings:
Go to File -> Other Settings -> Default Project Structure and then change them.
JRE for browsers (mine was 1.8.0_101, 160mb, was up to date):
/Library/Internet Plug-Ins/JavaAppletPlugin.plugin/Contents/Home/bin/java
JDK, JRE installed with installer:
/Library/Java/JavaVirtualMachines/
I had only:
$ du -d1 -h
312M ./jdk1.8.0_25.jdk
Was not up to date.
After installing U101, I had:
$ du -d1 -h
338M ./jdk1.8.0_101.jdk
312M ./jdk1.8.0_25.jdk
I removed the old one.
I did a talk on Jigsaw at BGOUG.
The talk is for a very important new feature in Java SE 9. Code named Jigsaw, this feature modularizes the Java SE platform.
The coolest thing I do at the talk is to create a custom JRE.
Of course the jug and jPrime were mentioned.
Code: https://bitbucket.org/stybz/jigsaw.sty/src/
Video:
Presentation:
There's a column on the Bulgarian JUG at:
http://www.javamagazine.mozaicreader.com/MarApr2016/Default/19/
(It's very annoying that you have to login)
Today we had a session by Christoph Engelbert on jCache (and hazelcast). He was forced to wear our official jug.bg wear:
Then we had a hands-on-lab (link to be added later) created by Ivan.
It was pretty awesome
So I'll do a talk about Http/2.0 at Riga Dev Day Conference. I'll be there representing the jug.bg. I'm pretty psyched to check out Latvia.
My session is on the first day
Update: my talk didn't go too well, because of projector issues. 15 min gone, flickering screen and me nervous ... overshot my time.
And to top it all of they recorded it and said it will go to youtube in a couple of months. 🙁
Not that it matters, but all my demos worked, kind of a Pyrrhic victory.
Update2: Riga is awesome and very beautiful.
Today Oleg presented a very interesting session about how class loaders work. He even remotely loaded classes from images (I imagine steganography).
Oleg works for Zero Turnaround, the company behind jRebel. Code examples here. The presentation is here.
One of the most interesting sessions so far IMHO.
A bit of introduction - we as a jug (java user group) got more active at the end of 2013 in no small part thanks to Ivan. We managed to build openjdk, import it in 3 major IDEs (eclipse, intellij and netbeans) and contributed a Virtual Machine with buildable openjdk 9 (both in fedora and ubuntu) and organized a couple of events, we decided we were ready for the next part.
At the end of 2014 we started timidly to try to contribute in the Adopt OpenJDK program. Adopt OpenJDK allows everyone* to participate in building and writing the java platform itself (or at least that's how we understood it *back then*).
We knew that LJC (London Java Community - their most popular jug) heavily participated in the new Date/Time API and soujava (Brasil's most popular jug) also managed to include code in the OpenJDK. Elated by these guys' successes we decided we had enough free time and sheer energy to contribute to the OpenJDK and thus put ourselves on the OpenJDK map.
In December 2014 we asked for something to work on. Nobody answered.
We decided to work on a simple Throwable convenience method (JDK-5050783). We had a hackaton. We submitted our fix. We were given some feedback and we submitted another. And we were told not to play with grown up stuff. That was a bit discouraging. But we didn't give up.
In February 2015 we started working on jaxp warnings. We fixed 43 easy warnings and submitted a patch. Then we fixed more harder warnings and submitted another patch. The great Joe Darcy answered but unfortunately we got nowhere again. That sucks.
A bit before that (Dec 2014) jug.bg member Doychin Bonzhev found a bug in the NetworkInterface and submitted a solution. He even submitted to another mail-list. He got a response (saying it is reasonable solution) and answered, but that was it. Nothing AFAIK followed.
So that was it for us. We gave up. Probably we didn't know the right people, but I argue that shouldn't matter. From time to time we get mentioned as collaborators in the Adopt OpenJDK by our dear friend Mani. We don't feel like that at all.
* Now you understand why the asterisk, right?
Today was the second edition of the jProfessionals format we started 5 months ago.
jProfessionals is a one-day free conf. Smaller than jPrime (our star yearly event).
In the first version we invited Koshuke Kawaguchi. (the creator of Jenkins CI).
Today the first presenter was Richard Warburton.
The session was about java 8 lambdas and even though it started as a very introductory session it turned out to be quite interesting. We discussed currying, Optional and the elvis operator.
What I learned is that Optional with value types is going to be fast (all in stack, no heap). Elvis is going in another direction - just a simple !=null check. Optional is kind of an explicit contract (preferred despite the verbosity and the extra object).
The second speaker was Vlado Tsanev aka tsachev.
He talked about Spring REST Docs. The talk was one big live demo. REST Docs is a way to document a rest api automatically by extracting the info from the tests - it creates cURL commands, headers, params as so called snippets, and it allows the use of a adoc files with links to the REST Docs snippets.
After a tasty lunch it was time for "The Seven Deadly Sins of Microservices" by Daniel Bryant.
It was a soft session with a lot of links and cool ideas of what microservices are good for and what they are not. There was a discussion on where people fail mostly using them. Very interesting and engaging - I bookmarked a lot of books that I'm never going to read.
Doychin Bondzev talked about Firebird (an alternative to postgres) - free, has triggers and is embeddable with nice tools and binary backup that is fast enough on windows.
Richard Warburton was next with another session for the future of Generics which was really fun.
I finally understood why enums are defined recursively (Enum<E extends Enum<E>>).
Next was a talk about Jenkins Builds with Docker Containers by Petar Velikov from e-card.bg.
It was quite interesting especially the docker part (he even used dockviz).
Finally there were two lightning talks. Martin Toshev talked about RxJava and RxJS.
Another guy - Teodor Tunev talked about Activiti - a java BPM platform far better than jBPM in his words.
Finally some beer was due.
(has not arrived yet)
My first fosdem this year. I found a lot of interesting things mostly on the opensource tracks. The "free java" track IMHO was a bit unpopular even though Stephen Chin and Mark Reinhold were there.
I guess I'm used to a better treatment on a conference (I go mostly as a speaker). Here it was rainy and cold and even though the french fries were awesome, I'm used to better food.
Antoan presented a session about Spring Boot running on Docker and how to use the docker maven plugin inside a Spring Boot application.
Actually we talked mostly about running Docker and application from the ecosystem. There was a statement that uninstalling Kitematic requires payment, which started a discussion about this model.
Today we had a meeting that discussed a way to automate deployments on AWS.
SDL's Behrooz Nobakht came especially for our event to explain how that is automated within their own products.
The first edition of jProfessionals is happening right now.
We managed to bring over Koshuke Kawaguchi. He's the creator of Hudson and after leaving Oracle, creator of the open source Jenkins. The topic was Jenkins 2.0.
The next speaker is Vladimir Tsanev. He'll talk about JMH with examples. Very interesting topic. He actually showed how to create a simple benchmark and to how to execute it.
Update: After the plentiful lunch Svetlin Nakov was awesome presenting HTTP/2. He was great at explaining the inner workings of the new protocol. Emil Doychev presented Groovy. There was a little bashing on JPA.
Some time for coffee and Doychin Bondzhev presented JavaFX in a very accessible way.
Trayan Iliev talked about high performance reactive programming with java 8. It was very interesting. Especially the demo at the end.
Wow.
Writing this I'm listening to Alan Bateman and Mark Reinhold deliver a session on the new Jigsaw (their third attempt?). This time it might work.
There's a lot of beer, more than I can handle (it turns out that a teenage girl handles her liquor better than I can) . A lot of awesome sessions - even one on the history of the universe.
The JUG is represented by Ivan, Krasi, Vladi and a bunch more awesome folks that make my trip here awesome.
It was a surprise to me, but I got invited to a forum organized by HP to explain to young women that a career in IT is not scary, doesn't suck at all and why it might be something that they may enjoy.
There were around 50 guests.
I was invited as an example of a "young" "successful" person. It was an honor sitting next to the Iravan Hira (CEO of HP Bulgaria), Preslav Pavlov (Global Deliveries Director for HP), Rumyana Trencheva (CEO of SAP Bulgaria), Zornica Iankova (HP's HR Director), Kristina Stoitsova (R&D at VMware).
Modrator was webcafe.bg's owner Sibina Grigorova.
The event was highly entertaining for me. The public initially wasn't keen on asking too many questions. But the discussion afterwards proved interesting. I was happy to hear that female CEOs didn't feel male colleagues treated them differently. Still there are far more males than females in IT.
Of course I wore a @bgjug t-shirt.
Jug.mk's leader Pance Cavkovski is talking today about how to put java on a raspberry pi and then automate your home.
There is also a slide about NodeMCU that helps you distribute GPIO around your home and control different devices. NodeMCU is a wifi-to-GPIO for $5 basically, which is awesome:
Today was a busy day, the beer was over in seconds and that sucks because Ivan and I only had a beer.
I brought a Odroid C1. But pi4j doesn't work, so I used jOdro.
We have a new banner that we didn't forget to bring today, so there it is:
On 30.09.2015 we did a workshop that showcased the very beta of MVC 1.0 implemented in ozark.
We had to use glassfish, which I somehow dislike, because I don't understand it and it didn't run very smooth, but in glassfish's defense I have to say that reloading the application without restarting worked like a charm. That is awesome.
MVC is promising and I like how simple it is.
The code is here: https://github.com/bgjug/mvc10-workshop.
So this weekend the Bulgarian Java User Group (jug.bg) organized a hackaton to try to create a JBoss Forge plugin to create Spring Boot applications.
JBoss Forge is a tool to ease development. Main traits are it can create JPA entities, It can create an example REST interface to those entities, a web interface to those entities and it integrates with Eclipse and IntelliJ IDEA:
The code is here. Here are a couple of pictures from the event:
A bug report here: https://bugs.openjdk.java.net/browse/JDK-8065424
Information:Using javac 1.8.0_25 to compile java sources Information:java: An exception has occurred in the compiler (1.8.0_25). Please file a bug at the Java Developer Connection (http://java.sun.com/webapps/bugreport) after checking the Bug Parade for duplicates. Include your program and the following diagnostic in your report. Thank you. 'xj-conc-j8' Information:7/14/15, 11:22 - Compilation completed with 1 error and 0 warnings in 2s 319ms Error:java: Compilation failed: internal java compiler error |
Today we had a BGJUG event.
Martin presented RabbitMQ - Spring Framework's default message broker.
I followed the presentation and using Docker's GUI for OSX called Kitematic, easily created a rabbitmq server and a client in a maven project:
Again there was a lot of beer, but since we have been accused of advertising beer brands, there will be no pics.
So, jprime.io is over, let's see how well we did:
---
---
Also in my inbox:
Tова което вчера казвах на Найден, че още от първата конференция бяхте много добри.
Поздрави,
—Филип
Translation: Basically Phillip is saying we are the best java conf here.
---
Another one:
Здрасти,Браво за конфа. Получи се доста добре.Готиното беше, че хората наистина се събираха и си говореха.Аз трябваше да тръгна по-рано, че имах малко лични ангажименти,и изпуснах всичко след предпоследната лекция, но това на което бях,наистина беше готино и се усещаше приятелската атмосфера 🙂Браво,Стеф
From: "Stefan Vartolomeev"
Translation: Stef is saying it was nice that people communicated and that the atmosphere was friendly and the feeling altogether was cool.
---
...
I think we did well.
Every morning I wake up to this: and this: . Every day I wage a fruitless war to go down to zero on both fronts and I fail miserably. But I'm getting better.
Recently we managed to "inject" a company as a gold sponsor after all the deadlines have passed. We did it in 20 minutes after 6 phone calls.
The server firewall failed. Someone fixed it on a Saturday morning.
Our invoicing architecture after so many patches fails to follow all the complex branches of the process of issuing an invoice. We somehow manage to still use it fruitfully. And I have big plans for rewriting most of it.
ePay integration was a pain it the ass. Very bad documentation, different undocumented services, support could be better. But it was fun encrypting and decrypting a ton of messages until we stabilized it. We even "support" credit cards (in a way).
Our Turkish speaker delayed his visa application. I called the Bulgarian embassy in Ankara. They were nice, didn't forget to call me back. Actually they kept me updated the whole time. And they issued the visa in less than a day. So kudos to them.
We fight less, work more, plan better, became team players and learned a lot. Organizing a conference is fun.
Go buy a ticket at jprime.io.
Simon Scholz from Vogella presented Eclipse RCP development, the new Eclipse Mars (to be published in a month) and tips and tricks on migrating from eclipse 3 to eclipse 4.
There were also examples on Maven Tycho, SWTBot UI testing. Simon bragged about fixing issues on the dark theme of Eclipse, which I adore, so now it's even better.
Pretty funny, I had to pick Simon from the airport, so I had to have a sign:
March 20th will be the start of the annual SoftUni Conf. I will present Java SE 8' s lambda feature. I expect it to be a fun event.
Today (2015.02.25) we had a bgjug sponsored "intro to nashorn" event.
Mitya, presented nashorn and avatar.js. Gave a lot of examples and had a hands-on - a node.js server working with hibernate.
So we in the Bulgarian Java User Group wanted to build Valhalla, and no IDE (Eclipse, Intellij Idea) supports it. We needed some simple text editor with some java support. And Sublime Text 3 (with Javatar) is the one we chose.
Sublime is a fancy editor written in C and Python. Javatar is a plugin that adds some Java support.
Installing Sublime Text 3 beta is straight forward. Installing Javatar is:
[openjdk@localhost valhalla]$ cd ~/.config/sublime-text-3/Packages/ [openjdk@localhost Packages]$ git clone git://github.com/spywhere/Javatar.git |
Setting up the correct java is: Ctrl+Shift+P --> "javatar" --> Javatar Settings - Default
Then change the javac and java locations:
Creating projects is a bit uneasy - create new project is actually called "Project -> Save as".
Today we had a second bgjug hackaton for the month. Its topic was Valhalla.
Project Valhalla will probably be part of Java 10 (expected 2018). Among other things it allows using primitives as generic arguments.
Here's how you can build Valhalla yourself.
Here's a virtual machine with valhalla if you're lazy (virtual box).
This is the valhalla presentation by Ivan. And this is the video of the talk (in Bulgarian).
Here are some of the code we ran:
Ivan created a simple ArrayList
public class SpecialArrayList { private static int INITIAL_SIZE = 10; private T[] elements = null; private int length = 0; public SpecialArrayList() { elements = new T[INITIAL_SIZE]; } public T get(int position) { if(position >= length) { throw new ArrayIndexOutOfBoundsException(); } return elements[position]; } public void add(T element) { // Check whether array is full elements[length] = element; length++; } } public class Main { public static void main(String[] args) { SpecialArrayList intList = new SpecialArrayList<>(); intList.add(1);intList.add(2);intList.add(3);intList.add(4); System.out.println(intList.get(2)); SpecialArrayList stringList = new SpecialArrayList<>(); stringList.add("1");stringList.add("2");stringList.add("3");stringList.add("4"); System.out.println(stringList.get(3)); } } |
Nayden tested a bit of crazy code - which is supposed to fail (IA impl = new IAImpl();):
public class B { protected T t; protected T[] ts; public B(){} public B(T t){ this.t = t; this.ts = new T[100]; // System.out.println(this.t.getClass()); } public T[] getTs(){ return this.ts; } public T getT(){ return this.t; } public static void main(String[] args){ B b = new B<>(100); System.out.println(b.getT()); System.out.println(b.getClass()); System.out.println((new B("dada")).getClass()); System.out.println(c.getClass()); IAImpl ludnica = new IAImpl(); ludnica.setT(100); System.out.println(ludnica.getT() instanceof Object); IABase base = new IAChild(); base.setT("dada"); System.out.println(base.getT()); System.out.println(base.getClass()); IA impl = new IAImpl(); impl.setT("dada"); System.out.println(impl.getT()); System.out.println(impl.getClass()); } } interface IA{ public T getT(); public void setT(T t); } class IABase{ private T t; public T getT(){ return this.t; } public void setT(T t){ this.t = t; } } class IAChild extends IABase { } class IAImpl implements IA { private Object t; public Object getT(){ return this.t; } public void setT(Object t){ this.t = t; } } |
This is a tiny tutorial on how to build your own copy of OpenJDK 9 from the current sources.
Preparation
├─Install a package system
├─Install ccache
└─Command Line Tools
Download OpenJDK 9
Build OpenJDK 9
JTREG
├─JTREG: The variables
└─Running tests
webrev
Install brew or macports. I prefer brew. Both are package systems for OS X.
ccache is a compiler cache - speeds up the build.
$ brew install ccache |
We need them so we have a C compiler and other tools.
Install Xcode Command Line tools ( you don't need the whole Xcode, only the command line tools)
Get the sources, in the console type:
$ mkdir jkd9 $ cd jdk9 $ hg clone http://hg.openjdk.java.net/jdk9/dev jdk9.hg |
Takes 10-20 secs. This downloads basically a couple of scripts that we will execute to get the actual sources.
Now we execute the script we downloaded:
$ cd jdk9.hg $ chmod u+x get_source.sh $ ./get_source.sh |
The last command can can take 10-20 minutes depending on the connection speed.
$ chmod u+x configure $ ./configure $ make clean images |
The second command took a bit less than 20 minutes. The first command is fast.
The result: we have this created: build/macosx-x86_64-normal-server-release/images/jdk/
- this is the built OpenJDK 9 - SUCCESS.
jtreg is a "testing harness" (whatever that means) made specially for OpenJDK. We need it to run the tests written for the OpenJDK
Download from https://adopt-openjdk.ci.cloudbees.com/view/OpenJDK/job/jtreg/ (not the Snapshot version, the other one).
unzip in jdk9, so we have jdk9/jtreg.
The official instructions suggest we edit ~/.bashrc. I don't like changing global (for your user) settings, so we can put these settings in jdk9/.bashrc
$ nano .bashrc |
Add the following lines:
export SOURCE_CODE=/Users/steve/jdk9/ export JTREG_INSTALL=$SOURCE_CODE/jtreg/ export JT_HOME=$JTREG_INSTALL export JTREG_HOME=$JTREG_INSTALL export JPRT_JTREG_HOME=${JT_HOME} export JPRT_JAVA_HOME=${PRODUCT_HOME} export JTREG_TIMEOUT_FACTOR=5 export PRODUCT_HOME=$SOURCE_CODE/jdk9.hg/build/macosx-x86_64-normal-server-release/images/jdk export PATH=$PATH:$PRODUCT_HOME/bin:$JT_HOME/linux/bin/ |
NOTE: Change /Users/steve/jdk9/ with your folder on the top line.
NOTE: Check the correctness of PRODUCT_HOME too.
To execute this file, do:
$ source .bashrc |
$ cd jdk9.hg/test
$ make jdk_util
Webrev crawls over your changes to generate a set of web-based views of the differences in your code. The different views allow reviewers to easily look at your proposed changes, selecting the appropriate difference format based on the type of file, the type of change, and their own preferences.
webrev.ksh is a 70kb kshell script. Pretty weird.
Go to jdk9.hg
and:
jdk9.hg# wget http://hg.openjdk.java.net/code-tools/webrev/raw-file/tip/webrev.ksh jdk9.hg# chmod u+x webrev.ksh |
To prepare a webrev, make some changes. For example in the jaxp folder. Then we commit locally in the mercurial repo.
jdk9.hg# cd jaxp jaxp# hg commit -m "BGJUG: Fix compiler warnings in jaxp repository" jaxp# ../webrev.ksh |
It will prepare a webrev/ dir and webrev.zip. The folder is then uploaded somewhere and sent to the appropriate mail list inside openjdk. Example:
http://bgjug.sty.bz/bgjug/~bgjug/fix-warnings-jaxp-part1/webrev.00/
Note: execution times come are measured on a pretty recent Macbook Air.
Source: https://java.net/projects/adoptopenjdk/pages/AdoptOpenJDKBuildInstructions
Project Valhalla will probably be part of Java 10 (expected 2018). Among other things it allows using primitives as generic arguments.
On a linux/unix/osx box we start with:
hg clone http://hg.openjdk.java.net/valhalla/valhalla cd valhalla bash get_source.sh #this one takes some time bash configure make clean images # this one takes some cpu |
We can have a class like this:
public class Program { public static void main(String[] args) { // this one still doesn't work, List not updated to List // List l = new ArrayList(); // l.add(5); // System.out.println(l.get(0)); Box b = new Box(6); System.out.println(b.get()); } } class Box { private final T t; public Box(T t) { this.t = t; } public T get() { return t; } } |
Running javap gives
$ javap -c Program.class gives: [openjdk@localhost bin]$ ./javap -c Program.class Compiled from "Program.java" public class Program { public Program(); Code: 0: aload_0 1: invokespecial #1 // Method java/lang/Object."":()V 4: return public static void main(java.lang.String[]); Code: 0: new #2 // class "Box${0=I}" 3: dup 4: bipush 6 6: invokespecial #3 // Method "Box${0=I}"."":(I)V 9: astore_1 10: getstatic #4 // Field java/lang/System.out:Ljava/io/PrintStream; 13: aload_1 14: invokevirtual #5 // Method "Box${0=I}".get:()I 17: invokevirtual #6 // Method java/io/PrintStream.println:(I)V 20: return } |
Running our pretty simple app gives:
[openjdk@localhost bin]$ ./java Program Specializing Box${0=I}; searching for Box.class (not found) Specializing Box${0=I}; searching for Box.class (found) 6 [openjdk@localhost bin]$ |
Notes: List is still not parameterized with because ... issues.
So we had a hackaton a month ago to fix a bug in the OpenJDK. Today we continued with the fix - using streams, benchmarking different solutions, and prepared a patch to send to the jdk team.
So yesterday was a memorable day.
We gathered the Bulgarian Java User Group and, as a hands-on-lab, in 3 hours we created a pretty complex patch on a open issue in the JDK Bug System. We plan to submit a webrev patch after we polish the code and supply better tests.
We've been playing with the OpenJDK code for quite some time. We have setup an easily distributable virtual machine (actually two virtual machines - fedora and ubuntu) that can be found here:
http://bgjug.sty.bz
They have everything in there with clear instructions on how to build the code and start IntelliJ IDEA as the IDE.
The issue is this one:
https://bugs.openjdk.java.net/browse/JDK-5050783
That has been a request for quite some time. Apache Commons Lang even has an utility method.
Here are the slides of the hackaton:
http://www.slideshare.net/IvanIvanov138/first-adoption-hackathon
And here are the instructions:
http://bgjug.sty.bz/bgjug/OpenJDK-hol.pdf
The patch included a pretty heated discussion on whether we should use the Apache's Commons Lang approach:
public static String getStackTrace(Throwable throwable) { StringWriter sw = new StringWriter(); PrintWriter pw = new PrintWriter(sw, true); throwable.printStackTrace(pw); return sw.getBuffer().toString(); } |
or we should rewrite some private classes inside java.lang.Throwable
.
Here's the updated Throwable
code:
First we added a method:
/** * Returns string representation of this throwable and it's backtrace. * * @return string representation of this {@code Throwable} and it's backtrace */ public String getStackTraceString() { final StringBuilder sb = new StringBuilder(); printStackTrace(new WrappedStringBuilder(sb)); return sb.toString(); } |
We renamed the ill-named PrintStreamOrWriter
to StackTraceFacade
and added another implementation:
private static class WrappedStringBuilder extends StackTraceFacade { private static final String NEW_LINE = System.getProperty("line.separator"); private final StringBuilder builder; WrappedStringBuilder(StringBuilder builder) { this.builder = builder; } @Override Object lock() { return builder; } @Override void println(Object o) { builder.append(o).append(NEW_LINE); } } |
We decided to reimplement and change the private inner class, because the Commons Lang uses StringWriter
that internally uses the StringBuffer which is synchronized and we don't want that, since we sync on an upper level.
Here's a small JTREG test we created:
import static org.testng.Assert.assertTrue; import org.testng.annotations.Test; import java.lang.Throwable; /* * @test * @bug 5050783 * @summary Basic test of serialization of stack trace information * @author Bulgarian JUG * @run testng java.lang.Throwable.GetStackTraceString */ public class GetStackTraceString { @Test public void doTest() { try{ double a =100/0; }catch (Throwable t){ assertTrue(t.getStackTraceString().length()>0); } } } |
FYI: Eclipse Luna (4.4) is currently beta.
<dependency> <groupId>net.sourceforge.htmlcleaner</groupId> <artifactId>htmlcleaner</artifactId> <version>2.6</version> </dependency> <dependency> <groupId>org.apache.httpcomponents</groupId> <artifactId>httpclient</artifactId> <version>4.3.4</version> </dependency> |
package sty.qainjava.xpath.on.html; import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStreamReader; import java.io.OutputStreamWriter; import java.net.URL; import java.nio.charset.Charset; import javax.xml.parsers.ParserConfigurationException; import javax.xml.transform.Transformer; import javax.xml.transform.TransformerException; import javax.xml.transform.TransformerFactory; import javax.xml.transform.dom.DOMSource; import javax.xml.transform.stream.StreamResult; import javax.xml.xpath.XPath; import javax.xml.xpath.XPathConstants; import javax.xml.xpath.XPathExpressionException; import javax.xml.xpath.XPathFactory; import org.apache.http.HttpEntity; import org.apache.http.client.methods.CloseableHttpResponse; import org.apache.http.client.methods.HttpGet; import org.apache.http.entity.ContentType; import org.apache.http.impl.client.CloseableHttpClient; import org.apache.http.impl.client.HttpClients; import org.htmlcleaner.CleanerProperties; import org.htmlcleaner.DomSerializer; import org.htmlcleaner.HtmlCleaner; import org.htmlcleaner.SimpleHtmlSerializer; import org.htmlcleaner.TagNode; import org.w3c.dom.Document; /** * QAinJava: how to do an xpath on html in java. * * We use <a href="http://htmlcleaner.sourceforge.net/">HtmlCleaner</a> * and <a href="https://hc.apache.org/">HttpClient</a>. * * @author Mihail STY */ public class Program { /** * We're not using any methods so that the source code is as straight * forward as possible. * * No exception handling at all for simplicity */ public static void main(String[] args) throws IOException, ParserConfigurationException, XPathExpressionException, TransformerException { String address = "https://www.google.com/"; String html; { // the httpclient part CloseableHttpClient httpclient = HttpClients.createDefault(); HttpGet httpGet = new HttpGet(address); CloseableHttpResponse response = httpclient.execute(httpGet); HttpEntity entity = response.getEntity(); ContentType contentType = ContentType.getOrDefault(entity); Charset charset = contentType.getCharset(); BufferedReader r = new BufferedReader(new InputStreamReader( entity.getContent(), charset)); // we can directly plug the input to HtmlCleaner, // but we put it in a string so we can print it, // or save it to a file String line = null; StringBuilder builder = new StringBuilder(); while ((line = r.readLine()) != null) { builder.append(line); } html = builder.toString(); } {// write html to a file BufferedWriter bf = new BufferedWriter(new OutputStreamWriter( new FileOutputStream("google.html.xml"))); bf.write(html); // exception handling is not exceptionally good, but that's not our // focus here bf.flush(); bf.close(); } // HtmlCleaner part TagNode tagNode = new HtmlCleaner().clean(html); String cleanHtml = new SimpleHtmlSerializer(new CleanerProperties()) .getAsString(tagNode); // System.out.println(cleanHtml); {// write cleanHtml to a file BufferedWriter bf = new BufferedWriter(new OutputStreamWriter( new FileOutputStream("clean.html.xml"))); bf.write(cleanHtml); // exception handling is not exceptionally good, but that's not our // focus here bf.flush(); bf.close(); } // we need a DOM document to execute xpath, HtmlCleaner helps in creating one Document doc = new DomSerializer(new CleanerProperties()) .createDOM(tagNode); {// save dom to file with a transformer (just for testing purposes) TransformerFactory factory = TransformerFactory.newInstance(); Transformer transformer = factory.newTransformer(); transformer.transform(new DOMSource(doc), new StreamResult( new File("dom.html.xml"))); } // the xpath part XPath xpath = XPathFactory.newInstance().newXPath(); String imgURL = (String) xpath.evaluate("//img/@src", doc, XPathConstants.STRING); //using two URLs we can make sure we get the absolute URL even if relative. System.out.println(new URL(new URL(address), imgURL).toString()); } } |
Source: http://nedbatchelder.com/blog/201204/two_problems.html
CodingBat is a nice website that tests basic java and python skills.
How can one highlight (use a code color scheme) for source code or xml or html and do the following and do it in any html page?
Like this:
One can use a javascript library. Instead of explaining how it works, here's the trick:
<pre name="code" class="xml:nogutter:nocontrols"> <?xml version="1.0" encoding="UTF-8"?> <urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9" xmlns:news="http://www.google.com/schemas/sitemap-news/0.9"> <url> <loc>http://www.kenoshanews.com/news/on_target_archer_sets_county_fair_record_472937185.html</loc> <news:news> <news:publication> <news:name>Kenosha News</news:name> <news:language>en</news:language> </news:publication> <news:access>Subscription</news:access> <news:publication_date>2013-08-18</news:publication_date> <news:title>On target: Archer sets county fair record</news:title> </news:news> </url> </urlset> </pre> <link type="text/css" rel="stylesheet" href="http://syntaxhighlighter.googlecode.com/svn-history/tags/1.5.1/Styles/SyntaxHighlighter.css" /> <script language="javascript" src="http://syntaxhighlighter.googlecode.com/svn-history/tags/1.5.1/Scripts/shCore.js"></script> <script language="javascript" src="http://syntaxhighlighter.googlecode.com/svn-history/tags/1.5.1/Scripts/shBrushXml.js"></script> <script language="javascript"> dp.SyntaxHighlighter.HighlightAll('code'); </script>
The important part is:
class="xml:nogutter:nocontrols"
xml
= the language
nogutter
, nocontrols
= options
http://syntaxhighlighter.googlecode.com/svn-history/tags/1.5.1/
= I don't want to include these in my project, so I use them remotely, you can download them locally, but download all.
Add the js libraries for the languages you use. For xml I added shBrushXml (see the code).
Supported languages: https://code.google.com/p/syntaxhighlighter/wiki/Languages
Configuration options: https://code.google.com/p/syntaxhighlighter/wiki/Configuration
public class Peshev { public static void main(String... args) { String[] fff = new String[]{"a", "b",}; System.out.println(fff[0]+fff[1]); } } |
Do you see the trailing comma after "b"? That's allowed. Unexpected from a strongly-typed lang as Java.
This is ver1 of this manual. Ver2 is updated with a better torrent client.
A 1080p movie is around 4 -8GB in size. Downloading this takes a while even on 50mbit connection.
What if it is possible to watch while downloading? So watching starts right away.
Previously I used BitThief. It is developed by a technology institute in Zurich. It didn't have a polished GUI and took a little bit too much CPU while downloading.
The new client I found thanks to diimdeep. It is called qbittorrent and it is awesome.
You can see that while downloading it downloads as a normal torrent client - the parts are downloaded randomly:
But there is an option:
After that we can see that the rest of the file is being downloaded sequentially (blue - downloaded, green - requested):
How can we tell if the speed is good enough? By the estimated time of arrival (ETA):
If the movie is 1.5 hours and the ETA is 17 minutes, then the speed is sufficient.
The player is and always has been mplayer. I use MplayerX because it comes with a nice OSX gui. Download and associate movie files with mplayer (avi, mkg):
The final step is to to play the file after the downloading started:
That's it.
Happy watching.
Eclipse is the best IDE ever. It's the most stable, most popular, most- a lot of things. The developers that write the Eclipse code have T-shirts that say that - they are that proud. The code-base is said to be awesome - I don't have time to check. But, there are some longstanding issues.
First, SVN client. There's a CVS client that comes with Eclipse. SVN is way more popular. Put the client inside finally. I'm sick of solving numerous JavaHL issues. Fix it. I don't care how, just do it.
Second, Tomcat is the best web container ever and most popular in development. Integrate it better. There are numerous issues with debugging, redeployment and so on. These problems are so old. Fix 'em NOW.
Third, installing plugins is soooo slow. So very slow.
Fourth, web development is not that well integrated. WTP is still buggy, there are issues with configurations, deployment and so on.
Update: Fifth, autocomplete should put jdk classes/interfaces first!!! This is so important. Screenshot:
WTF is antlr.collections?! Are you kidding me?
Now, I'm trying to launch a main method without the "String... args" parameters and Eclipse cannot find it. This is also a longstanding problem.
This works:
public static void main(String... args) |
This does not (eclipse cannot find the method):
public static void main() |
I'm pretty sure there's a solution, but I'm not going to waste time searching for it.
I've wasted time with compilation, memory, various configurations with xml and whitespace also.
There are always solutions, but this is wasted time. What are the developers working on? Stupid pointless features? Fix these please. Please.
Postgres for Mac OS X has three install options:
Problem running post-install step. Installation may not complete correctly
The database cluster initialisation failed.