Blog about Java, Unix/Linux and Software Development

Tag: Java

There are number of cases when standalone repository management tool like Nexus is an overkill and all you need is a simple service for providing a few maven libraries. I use Bitbucket private Git repositories for such cases several years. Setup is pretty easy and all you have to do is to modify ~/.m2/settings.xml like below:

git-repo name of the Git repository created for hosting maven libraries

releases name of the Git branch the libraries are stored in

user@exitcode.net is an email of the user that have an access to Git project (if you use App password to protect main Bitbucket password, you must use username instead of email)

This works pretty well as Bitbucket Cloud API 1.0 challenges authentication using HTTP 401 Unauthorized header while accessing secured content like private repository, when no credentials are given. Once challenged, Maven Wagon HTTP provider sends proper credentials stored in settings.xml to the server in form of Authorization header.

API 2.0

However, Bitbucket announced recently that Cloud API 1.0 is deprecated as of June 30 and what’s worse, all version 1.0 APIs will be removed permanently on 31 December 2018. So, all users are forced to switch to API 2.0. To access the same Git repository with maven artifacts you have to use following configuration:

The tricky part is the authentication. You have probably noticed that Authorization header with basic authentication credentials (value user:password encoded in base64) is passed to the server directly. This is because API 2.0 no longer challenges authentication and throws directly HTTP 403 Forbidden if it did not find credentials stored in request. With this configuration Maven Wagon HTTP provider (actually underlying Apache Http Client) won’t wait for authentication challenge that never come and sends credentials immediately.

Maven HTTP communication logs

While I was debugging whats going on under the hood, I discovered that Maven Wagon HTTP Provider bundles entire Apache HTTP Client with other Apache libraries like commons into one fat jar. This is crucial information if you want to enable trace logs of the HTTP client because bundled client is placed in different java package than the original! So, if you want to enable trace logs of the HTTP communication that maven makes, add following line into ${MAVEN_HOME}/conf/logging/simplelogger.properties (create it if not exists):

org.slf4j.simpleLogger.log.org.apache.maven.wagon=TRACE

Foremost, I started with information that Maven since v3.0.4 uses Apache Http Client 4, so I was trying to enable HTTP trace logs on logger org.apache.http as described in official documentation. That did not work so I decompiled wagon-http-2.9-shaded.jar from maven 3.5.4 installation where I found this bundled client and after going through some sources I eventually enabled tracing on the right logger.

When you profiling an application or looking for some memory leak taking heapdump is always essential. There are multiple ways how to do it manually. For instance using directly jmap command or some monitoring tool like VisualVM, JConsole, JMC etc. However when bad things happen in production it’s useful to be alerted and have a heapdump stored. For a such scenario JDK offers several useful command line options:

I think above configuration is self explaining. When OutOfMemoryError occurs, JDK will automatically save heapdump of the application into /tmp/heapdumps folder. Note that, if the heapdumps directory doesn’t exist it won’t be created and the JVM stores dump into a new file called heapdumps instead. Because the file gets overridden every time the application throws java.lang.OutOfMemoryError you should create the target directory manually otherwise the dump from previous application startup would be last forever. Moreover, shell script send_alert_email.sh is called, that actually sends an email notification.

Below is a notification script I normally use for this purpose. It sends an empty email with subject 'Java App - OutOfMemory alert!' to email recipient@domain.com using pre-configured SMTP server with authentication.

When you work with portlet applications, all request parameters must be namespaced otherwise you won’t have access to their values using Portlet API in Liferay. However, in some cases your portlet has to process URL which was not constructed using Portlet API. In this post I will show you how to map un-namespaced query parameters declaratively using Spring MVC Portlet framework.

Imagine you have a single portlet deployed on your portal page and that portlet displays content of the article whose ID is passed as a query param, for instance:

https://news.portal.my/?id=123

That’s pretty standard requirement. URL like that is clear and easily bookmarkable. However, since parameter id is not namespaced, you portlet won’t have access to it through Portlet API. So the following code prints null into log:

In portal, namespace is unique for each portlet and it’s used as a prefix for all portlet’s parameters. This mechanism helps to avoid naming collisions when several portlets are deployed on the same page. For that reason you have to put portlet’s namespace into URL to make the prior code work:

Now the URL is no longer short and clear. You would have to use Liferay’s friendly URL feature to simplify that although it would require additional XML configuration. However you have also a second option. You can access id parameter using Liferay API.

That worked fine, log revealed correct article number 123. But we can do better. We can wrap the above code into special WebArgumentResolver implementation and create additional annotation similar to @RequestParam to map un-namespaced query parameters to controller’s method arguments. Let’s call it @QueryParam. Using this approach we can utilise great annotation-based programming model in Spring.

Using declarative approach our code is now much more readable thanks to clear separation between the parts that describe the mapping (@QueryParam) and how the mapping is actually performed (QueryParamResolver).

Recently one of my colleague came to me with interesting question about builder pattern he saw in Effectiva Java I borrowed him. He implemented the pattern in the same way like Joshua Bloch in his book but no matter what, Eclipse displayed weird warning message about synthetic accessor. I have explained him theory behind synthetic classes but I was not quite sure why Eclipse allows to raise a compiler warning in such cases. In this post I would like to touch that topic and find reasons why Eclipse does that.

This is most typical builder implementation. Immutable object NutritionFacts is created by invoking its private constructor from builder method and passing builder instance as parameter. So its kind of copy constructor which copies data from builder to the created instance, that can’t be modified further.

Problem

If you change compiler severity level from ignore (default) to warning for:

Access to a non-accessible member of an enclosing type

in Eclipse IDE (Preferences->Java->Compiler->Errors/Warnings->Code Style), you will see following warnings for builder above:

Access to enclosing constructor is emulated by a synthetic accessor method (line 26)Read access to enclosing field is emulated by a synthetic accessor method (lines 31 – 36)

Syntethic constructs

Lets remind why java compiler must generate synthetic accessor methods. As you certainly know, private fields/methods are not visibile outside class. The same principle applies to nested classes as well, because on JVM level, there are no nested classes. Concept of nested classes is known only to Java language at source code level. Bytecode has no support for them. After compilation, they end up as standalone classes in their own files. Therefore on JVM, private fields/methods of enclosing class are not accessible for nested classes and enclosing class can’t access private stuff of nested classes (no matter if they are static or inner). However, Java supports access private fields/methods of nested class according JLS. So there are two opposite sides, Java language which syntax supports that and JVM which refuses to execute. For that reason java compiler must generate package-private synthetic methods, using which private stuff of enclosing class can be accessed from nested classes and vice versa, without any need to change the source code. Lets look how the generated synthetic constructor looks like:

So generated synthetic package-private constructor calls the original private constructor. But how the new synthethic constructor gets called? That’s again work of the java compiler, which modifies content of build() method inside builder to following form:

As second constructor parameter is useless, compiler can safely putt null value in it. Similar generation is done also for private builder fields, that are read within private NutritionFacts constructor. Synthetic accessor methods look following:

If you are intersted how I get to these generated stuff above, please look at Sundararajan’s post that explain some hidden options of java compiler. Simply you need to invoke compiler with -XD-printflat option:

javac -XD-printflat NutritionFacts.java -d generated-src

With this command, java compiler generates source code which already passed some internal transformation (synthetic methods, assertion etc.) into generated-src directory. Note that you must create this directory before you run compiler.

Possible warning reasons

So now, when you mastered basics about synthetic constructs, lets back to the eclipse warnings. What are the possible unwanted implications of using synthetic constructs and why eclipse probably provides such alerts to be shown?

Performance penalty – almost negligible on modern JVM if you look at syntetic code that compiler generated

Security breach – generated package-private synthetic constructor can be accessed via reflection and thus create an instance of class, which was not intended to be created from the outside on source code level. You have to take this into account when you model your class a you rely on synthetic accessors

Conclusion

On the builder example I tried to demonstrate how java compiler generates synthetic constructs. Fortunately, Eclipse doesn’t enforce such warnings and it ignores them by default, until you state otherwise. Personally, I would continue to take advantage of synthetic methods for nested classes as they lower number of code that needs to be written otherwise. Second reason is that you maintain private stuff private and non-accessible without using reflection.

Few days ago I was on a crossroad to design and implement simple notification system for one project. I was decided to go with standard interface-driven setup as common approach in Java since beginning. However after some googling I came accros another very interesting solution, EventBus. It’s a simple, annotation-driven event utility that’s part of Google Guava library.

EventBus allows publish-subscribe-style communication between components without requiring the components to explicitly register with one another (and thus be aware of each other). It is designed exclusively to replace traditional Java in-process event distribution using explicit registration. It is not a general-purpose publish-subscribe system, nor is it intended for interprocess communication.

Interface-driven solution
Before dive into EventBus, let me show you how the typical interface-based notification system could look like. First we need to define a simple immutable object that should be transferred using event from producer to consumers (reused also in EventBus example):

Than we need to create a listener and event that would carry an object of above Message type. Single listener must exists for each event (used very effective technique proposed by Laurent Simon when listener and event are bound to each other within event class):

The only thing missing there is dispatcher. Dispatcher is a component responsible for registering consumers to particular event a firing events. After specific event is fired, all registered consumers will receive the exact event fired. In our implementation dispatcher is a black box since it knows nothing about specific event or listener, it works only with SystemEvent interface.

Annotation-driven solution
On the other side, implementation of preceding example using EventBus is much easier. No specific interfaces are required. Listener has to only define public method, marked by Subscribe annotation with one parameter, the event that wants to capture.

Conclusion
If you are already utilizing Google Guava library and are looking for simple notification system, you should definitely use EventBus. For others just add Guava libray and use it too :). It’s really simple and effective way how to handle with events.

Recently one of our clients reports a bug regarding usage of czech national characters in file names within ZIP archive. They just didn’t display correctly. After some analysis I discovered something I never believed is possible nowadays. Windows 7 has no native support for UTF-8 encoded file names in ZIP archive! Common Microsoft, it’s 2011 and support for UTF-8 file name characters is arround at least 5 years (officialy introduced in v6.3.0 of ZIP specification).

The whole problem with file names encoding lies in the fact that ZIP format uses by default IBM PC character encoding set also known as IBM Code Page 437, IBM437 or CP437. Unfortunately this code page restricts storing file name characters to only those within the original MS-DOS range so it’s quite limited. Therefore if you want to use most national characters in file names within ZIP, you have basically two options:

Use UTF-8 and set language encoding flag to instruct the processing tool, that characters in file names are encoded in UTF-8

Use whatever encoding that’s native to your specific target platform

First Option
With first option you can achieve the best interoperability among operating systems. Downside of this approach is that Windows users have to use some third-party application to handle ZIP archives because compressed folder doesn’t display UTF-8 characters correctly. All well-known ZIP processing tools I tried on Windows (WinZip, WinRAR, 7-Zip) were able to display UTF-8 encoded file names properly. 7-Zip on unix-based systems has also displayed such a file names correctly. Here is the Java code snippet that creates a ZIP archive containig two empty files with slovak national characters in each file name.

This example uses Apache Commons Compress library which allow to specify encoding and set language flag. If you are lucky and already using Java 7 released last month, you can utilize classes from java.util.zip package that obtained new constructor to set encoding. In addition, these classes use UTF-8 by default and read/write language encoding flag. On Java versions <= 1.6 just stay with commons-compress library.

Second Option
Second option is way to go when you address only one operating system using specific code page (that’s our customer case and approach I eventually employed). Suppose all your users use Windows with code page 852 (CP852, IBM852 – standard code page used by central european countries). In this case you can generate ZIP archive in almost the same way as above but this time set the encoding to CP852 and omit the encoding flag.

Every tool on the platform using default code page 852 will display national characters from this ZIP file correctly, including Windows compressed folder tool. In order to find out what code page Windows currently uses simply navigate to the following node in registry:

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Nls\CodePage

and look for a key with the name OECMP.

And remember, there is no such thing as universal, always-working approach to ZIP file names encoding.

Follow Me

About Me

Marek Holly

I am a Java developer and Unix enthusiast currently working and living in Prague. When I do not sit at a computer you can catch me training on bike, swimming or practicing aikido.