Mittwoch, 24. August 2022

Getting the google-java-format plugin to run in Eclipse with JDK >= 16

The google-java-style plugin can be found here. You can download the newest version in their release folder. Installation is pretty straight forward - just copy it into the dropins folder of your Eclipse installation folder.

but if you are running on a JDK with a version >= 16 it simply will not work. Going through the release history of the plugin you'll find a comment for version 1.10.0. If you are running the Java formatter, you'll hhave to add some VM args, when you start your Java application.

In order to get this working with your whole Eclipse IDE you'll have to edit the eclipse.ini in the following way. Took me a little bit, because I forgot the equals after the add-exports:

-vmargs

-Dosgi.requiredJavaVersion=11
-Dosgi.instance.area.default=@user.home/eclipse-workspace
-Dsun.java.command=Eclipse
-XX:+UseG1GC
-XX:+UseStringDeduplication
--add-modules=ALL-SYSTEM
-Dosgi.requiredJavaVersion=11
-Dosgi.dataAreaRequiresExplicitInit=true
-Dorg.eclipse.swt.graphics.Resource.reportNonDisposed=true
-Xms256m
-Xmx2048m
--add-modules=ALL-SYSTEM
--add-exports=jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED
--add-exports=jdk.compiler/com.sun.tools.javac.file=ALL-UNNAMED
--add-exports=jdk.compiler/com.sun.tools.javac.parser=ALL-UNNAMED
--add-exports=jdk.compiler/com.sun.tools.javac.tree=ALL-UNNAMED
--add-exports=jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED

The first part might differ. The important lines are the --add-exports.

Dienstag, 28. August 2018

Decompiling an Android APK file

I recently needed to look into another Android app to see how they implemented some strange UI behaviour. There are a few steps neccessary to get the source code of an app.


  1. Download the APK from the device.
  2. Convert the APK file to a JAR
  3. Decompile the JAR

Download the APK from the device


This can be done using the Android SDK platform tools. Go to your SDK directory and find platform-tools/adb.

If you don't know where your application is installed on your device follow these instructions:

Type 

adb shell

This gives you a Linux shell on your device. Now type:

pm list packages -f

This will give you a list of all your installed applications and the paths where they are located in the filesystem.

Exit the shell and download the APK via:

adb pull <Path to the APK file on the device>

Now you can find the APK file in your current directory.

Convert the APK file to a JAR


Now we use the dex2jar tool to convert the Dalvik executable files into class files inside a JAR. Download the tool from the github repository and run

sh d2j-dex2jar.sh -f ~/path/to/apk_to_decompile.apk

This creates the JAR archive in the current directory.

Decompile the JAR


Now we can use the Java Decompiler to view the contents of the JAR archive. Just open the JAR archive in the Decompiler and browse the classes.


Montag, 4. Juni 2018

Create an icon for an Eclipse e4 RCP application (Windows).

Trying to give your new Eclipse e4 application a new Windows icon is more complex than one might think.

The solution I am presenting here works for my application that is build with Tycho 1.0.0. I don't know if you run into the same problems when doing an export from Eclipse as I have never tried that.

When I tried to change the icon I ran into two different problems:

  1. Creating an Windows ICO file that contains all images in the correct formats.
  2. Adding the icon to the product definition.

Creating the Window ICO file

The Windows ICO file has to contain 7 images in different resolutions and depths:
  • 48x48, 8 bits
  • 32x32, 8 bits
  • 16x16, 8 bits
  • 48x48, 32 bits
  • 32x32, 32 bits
  • 16x16, 32 bits
  • 256x256, 32 bits
You can find many tools to create an ICO file for you. But you always have to export all your files in the right format and add them to the ICO file. I tried that with several tools and never got it working right.

So I went to Linux and just used ImageMagick convert to convert all my images into the format Eclipse needs and than use icoutils to create the ICO file.

Using GIMP I created four versions of the image I wanted to use as my icon: 256x256, 48x48, 32x32 and 16x16.

Then I just ran these commands and got my ICO file.

convert -colors 256 myicon_16x16.png tmp.gif
convert -colors 256 tmp.gif icon_16x16_8.png
convert -colors 256 myicon_32x32.png tmp.gif
convert -colors 256 tmp.gif icon_32x32_8.png
convert -colors 256 myicon_48x48.png tmp.gif
convert -colors 256 tmp.gif icon_48x48_8.png
icotool -c icon_16x16_8.png myicon_16x16.png icon_32x32_8.png myicon_32x32.png icon_48x48_8.png myicon_48x48.png myicon_256x256.png > icon.ico

Adding the icon to the product information

In the product definition of your Eclipse e4 application you can select an ICO file that should be used for the generated executable. When I clicked browse and selected the icon file I had previously generated I got this:



The IconExe tool that is used for replacing the icons during the Tycho buiold was not able to find the ICO file. I had to change that to a local path for it to work.


Mittwoch, 8. Mai 2013

C++: improved string tokenizer

Using templates the old string tokenzier can be further improved:

template  void tokenize(const std::string &str,
              T &tokens,
              const std::string &delimiters = " ") {
  string::size_type lastPos = str.find_first_not_of(delimiters, 0);
  string::size_type pos = str.find_first_of(delimiters, lastPos);

  while (std::string::npos != pos || std::string::npos != lastPos) {
    tokens.push_back(str.substr(lastPos, pos - lastPos));
    lastPos = str.find_first_not_of(delimiters, pos);
    pos = str.find_first_of(delimiters, lastPos);
  }
}

This allows any container with a push_back() method to receive the extracted tokens.

std::list tokens;
tokenize("I want to tokenize this!", tokens);

tokenize("2012-02-20", tokens, "-");

or

std::vector tokens;
tokenize("I want to tokenize this!", tokens);

tokenize("2012-02-20", tokens, "-");

Freitag, 21. September 2012

Web: Placeholder.it

I found this very useful site on the internet a few days ago. Placeholder.it provides a very simple service. You can request an image from them specifying a width and height and they will provide a grey image at your requested size.

If you are lazy like me, you can use these images to quickly build spacers or blind images to layout your site.

This will generate an image with 350x150 pixels.

http://www.placehold.it/350x150

Mittwoch, 22. August 2012

C++: String startsWith function

This function checks if the supplied string starts with the specified prefix.

bool string_startsWith(const std::string &str, const std::string &prefix) {
  return std::equal(prefix.begin(), prefix.end(), str.begin());
}

Freitag, 17. August 2012

ActionScript: Distance between line and a point

/**
 * Computes the difference vector between two vectors.
 * @param p1 First vector (from (0,0).
 * @param p2 Second vector (from (0,0).
 * @return  The difference vector between p1 and p2.
 */
public static function differenceVector(p1 : Point, p2 : Point) : Point {
 return new Point(p2.x - p1.x, p2.y - p1.y);
}
  
/**
 * Projects a point onto a line. Returns the projected point or null if
 * the projection does not fall within the segment. 
 * 
 * @param lineStart First point of the line.
 * @param lineEnd Second point of the line.
 * @param p Point that should be projected onto the line given by 
 *              lineStart and lineEnd.
 * @return      The projected point on the line or null if the projection line
 *              falls not between lineStart and lineEnd.
 */
public static function projectPointOntoLine(lineStart : Point, 
                                            lineEnd : Point, 
                                            p : Point) : Point {
 // Difference vector is the line.
 var l : Point = differenceVector(lineEnd, lineStart);
   
 // Determine determinant and divide it by the length of the line.
 var u : Number = (((p.x - lineStart.x) * (lineEnd.x - lineStart.x)) + 
                          ((p.y - lineStart.y) * (lineEnd.y - lineStart.y))) / 
                         (l.length * l.length);
   
 // Check whether the projection lies between lineStart and lineEnd.
 if ((u < 0) || (u > 1)) {
  return null;
 }
   
 // Compute projection point.
 var pp : Point = new Point(lineStart.x + u * (lineEnd.x - lineStart.x),
                                   lineStart.y + u * (lineEnd.y - lineStart.y));
   
 return pp;
}
  
/**
 * Computes the shortest distance between a line and a point. If the 
 * point cannot be projected onto the line segment specified by
 * lineStart and lineEnd, the function will return -1.
 * 
 * @param lineStart First point of the line.
 * @param lineEnd Second point of the line.
 * @param p Point that should be projected onto the line given by
 *              lineStart and lineEnd.
 * @return      The distance between p and the line or -1 if p cannot be
 *              projected onto the line.
 */
public static function distanceLinePoint(lineStart : Point, 
                                         lineEnd : Point, 
                                         p : Point) : Number {
 var projection : Point = projectPointOntoLine(lineStart, lineEnd, p);
 if (projection != null) {
  return differenceVector(p, projection).length;
 } else {
  return -1;
 }
}