среда, 15 января 2014 г.

Java String Array Example

Это простой пример как обявить и проинициализировать массив(Array) в Java.

Итак, создадим JavaStringArrayExample.java класс с кодом:

package com.androidnn.javabasics.stringarray;
public class JavaStringArrayExample 
{
   public static void main(String args[]) 
   {
      // declare a string array with initial size
      String[] schoolbag = new String[4];
   
      // add elements to the array
      schoolbag[0] = "Books";
      schoolbag[1] = "Pens";
      schoolbag[2] = "Pencils";
      schoolbag[3] = "Notebooks";
   
      // this will cause ArrayIndexOutOfBoundsException
      // schoolbag[4] = "Notebooks";
   
      // declare a string array with no initial size
      // String[] schoolbag;
   
      // declare string array and initialize with values in one step
      String[] schoolbag2 = { "Books", "Pens", "Pencils", "Notebooks" };
   
      // print the third element of the string array
      System.out.println("The third element is: " + schoolbag2[2]);
   
      // iterate all the elements of the array
      int size = schoolbag2.length;
      System.out.println("The size of array is: " + size);
      for (int i = 0; i < size; i++) 
      {
         System.out.println("Index[" + i + "] = " + schoolbag2[i]);
      }
   
      // iteration provided by Java 5 or later
      for (String str : schoolbag2) 
      {
         System.out.println(str);
      }
   }
}

Explanation :
Есть 3 способа для объявления массивов :

  • String[] schoolbag = new String[4];
  • String[] schoolbag;  
  • String[] schoolbag2 = { "Books", "Pens", "Pencils", "Notebooks" };

В первом случае мы создаем массив используя "количество элементов".
Во втором случае мы просто объявлением переменную "Массив". Но, перед использованием мы обязаные его проинициализировать (schoolbag = new String[4]).
В третем же случае, мы перечислям все значения переменных. Размер же будет автоматически подсчитан.

Хотелось бы сразу подметить, Array в Java всегда имеет фиксированный размер. В том случае, если мы будем пытаться записать значение в несуществующую ячеку мы получим ArrayIndexOutOfBoundsException

Если же вам нужен массив с динамически изменяемым количеством ячеек, используйте ArrayList

Для прохода по элементам массива используется for в двух эпостасиях :) Последние 2 блока кода в примере.

Output

The third element is: Pencils
The size of array is: 4
Index[0] = Books
Index[1] = Pens
Index[2] = Pencils
Index[3] = Notebooks
Books
Pens
Pencils

Notebooks


воскресенье, 5 января 2014 г.

Only try optimization when you have knowledge of the actual bottleneck

I have seen architects who spend great effort on:

  • Fine-tuning logging statements
  • Replacing Vectors in legacy code
  • Replacing + operators with StringBuffers in loops
  • Refactoring existing, stable, mature and bug-free code for the sake of “performance”
  • …and other fancy stuff

Sadly, this is done without actually measuring what effect these efforts might have. Even if the application runs a bit faster, most of the times there are other more serious problems (like database locking, memory leaks, streams that are never closed/flushed) that nobody pays attention to.

Spending time to fix logging and gain 3% in speed is not very helpful when fixing the SQL queries would give 200% gains in speed.

Therefore, it’s important to keep in mind that any change that happens for performance reasons is actually a four-step process:
  1. Measure the current system (valid benchmarks are a big task on their own)
  2. Apply the change
  3. Measure again
  4. Evaluate the effort given and the performance gained ratio.

Remember the mantra for optimizations – measure, don’t guess.

пятница, 13 декабря 2013 г.

Notes about build version

What Makes Version Information Useful?

Here are the things we wanted from version information:

  • Determine if two builds come from the same source (even if built on different machines, at different times).
  • Easily find the code associated with a particular build.
  • Easily determine approximately how old a build is; compare age of versions.
  • Provide an easy mechanism for the user to tell different versions of builds apart.

A Decent Solution

After a bit of messing around with our build system and our source control tools, we ended up using these 4 values as our “version” information:


  • Commit Hash – Makes it trivial to figure out the source that the build is derived from. If you were using a SVN or something, you could use your repo path and revision instead.
  • Most Recent Tag – Not necessary, but nice for applying traceable easily-human-readable version numbers. Any code built from a commit after the tag would have this.
  • A Local Changes Flag – Indicates if there are uncommitted changes that are not reflected in the commit hash, which would also indicate that this is unsafe for production use.
  • Change Date – If local changes is false, this is the date-time of the commit, otherwise it is the date-time at the start of the build.

среда, 11 декабря 2013 г.

Setting up your application server with maven


In many cases there is no way to deploy an application without the need to setup your application before. In JBoss AS 7.x you may want to configure for example your database connection. Or you have to configure a security realm. Maybe you also want to adjust the SLSB pool… In any of these cases all developers in the team have to share a common or at least a similar configuration.

Often this information can be found in sporadically sent emails or on some wiki page. But what happens sometime after a release, when you have to check out a branch to fix some bug or to add a new feature? You will have to reconstruct the configuration that was valid for this branch. So why not add the configuration files to your version control system and together with the mere configuration files, a maven configuration that sets up the whole application server?

Let’s try to keep it simple and use only public available and commonly used plugins. First of all let’s add all versions that we will need in the following to the properties part of the pom.xml:

<properties>
  <jboss.install.dir>${project.build.directory}/jboss</jboss.install.dir>
  <jboss.version>7.2.0.Final</jboss.version>
  <app.version>${project.version}</app.version>
  <ojdbc.version>11.2.0.1.0</ojdbc.version>
</properties>

We also define here the installation directory of the JBoss AS. This way we can change it, if we want, using the command line option -D. Now we add a new profile, such that we have to explicitly switch the setup procedure on and that it is not part of the normal build:

<profile>
  <id>setupAs</id>
  <build>
    <plugins>
    ...
    </plugins
  </build>
</profile>

If we have the current JBoss version as a maven artifact deployed in our maven repository, we can use the maven-dependency-plugin to download and unpack the JBoss to the installation directory given above:

<plugin>
  <groupId>org.apache.maven.plugins</groupId>
  <artifactId>maven-dependency-plugin</artifactId>
  <version>2.8</version>
  <executions>
    <execution>
      <id>unpack-jboss</id>
      <phase>package</phase>
      <goals>
        <goal>unpack</goal>
      </goals>
      <configuration>
        <artifactItems>
          <artifactItem>
            <groupId>org.jboss</groupId>
            <artifactId>jboss-as</artifactId>
            <version>${jboss.version}</version>
            <type>zip</type>
            <outputDirectory>${project.build.directory}/jboss</outputDirectory>
          </artifactItem>
        </artifactItems>
      </configuration>
    </execution>

Now that the application server is unpacked, we have to add the JDBC driver as well as our application (or anything else you need). We set this up by adding another execution block to the maven dependency plugin:

<execution>
  <id>copy</id>
  <phase>package</phase>
  <goals>
    <goal>copy</goal>
  </goals>
  <configuration>
    <artifactItems>
      <artifactItem>
        <groupId>our-company</groupId>
        <artifactId>our-application-ear</artifactId>
        <version>${app.version}</version>
        <type>ear</type>
        <outputDirectory>${jboss.install.dir}/jboss-as-${jboss.version}/standalone/deployments</outputDirectory>
      </artifactItem>
      <artifactItem>
        <groupId>com.oracle</groupId>
        <artifactId>ojdbc6</artifactId>
        <version>${ojdbc.version}</version>
        <outputDirectory>${jboss.install.dir}/jboss-as-${jboss.version}/standalone/deployments</outputDirectory>
        <destFileName>ojdbc6.jar</destFileName>
      </artifactItem>
    </artifactItems>
  </configuration>
</execution>

Last but not least, we also want to adjust the standard configuration files to our needs. We can use the maven-resources-plugin to substitute variable values within each file. Therefore we add templates for these files to the resources folder of our JBoss module and call the goal copy-resources:

<plugin>
  <artifactId>maven-resources-plugin</artifactId>
  <version>2.6</version>
  <executions>
    <execution>
      <id>copy-jboss-configuration</id>
      <phase>package</phase>
      <goals>
        <goal>copy-resources</goal>
      </goals>
      <configuration>
        <outputDirectory>${jboss.install.dir}/jboss-as-${jboss.version}/standalone/configuration</outputDirectory>
        <resources>
          <resource>
            <directory>src/main/resources/jboss/standalone/configuration</directory>
            <filtering>true</filtering>
          </resource>
        </resources>
      </configuration>
    </execution>
    <execution>
      <id>copy-jboss-bin</id>
      <phase>package</phase>
      <goals>
        <goal>copy-resources</goal>
      </goals>
      <configuration>
        <outputDirectory>${jboss.install.dir}/jboss-as-${jboss.version}/bin</outputDirectory>
        <resources>
          <resource>
            <directory>src/main/resources/jboss/bin</directory>
            <filtering>true</filtering>
          </resource>
        </resources>
      </configuration>
    </execution>
  </executions>
</plugin>

The values for the filtering can be given on the command line with the -D option. If the team has more than a few members, it is also possible to create for each user a properties file that contains his/her specific configuration values. If we use the OS user as filename, we can easily choose the file by the name of the currently logged in user. This way each team member can easily setup its own completely configured application server instance by simply running:

mvn clean install -PsetupAs

In order to prevent that the newly configured server is deleted with the next clean invocation, we disable the maven clean plugin for the normal build:

<plugin>
  <artifactId>maven-clean-plugin</artifactId>
  <version>2.5</version>
  <configuration>
    <skip>false</skip>
  </configuration>
</plugin>

Within the setupAs profile created above, we have to enable it of course, such that we can delete the whole installation just by calling “mvn clean -PsetupAs”. Now switching to an older branch is easy as we don’t lose any time searching for the right configuration…

воскресенье, 24 ноября 2013 г.

When and how to use a ThreadLocal


As our readers might already have guessed, I deal with memory leaks on a daily basis. A particular type of the OutOfMemoryError messages has recently started catching my attention – the issues triggered by misused ThreadLocals have become more and more frequent. Looking at the causes for such leakages, I am starting to believe that more than half of those are caused by developers who either have no clue what they are doing or who are trying to apply a solution to the problems which it is not meant to solve.

Instead of grinding my teeth, I decided to open up the topic by publishing two articles, first of which you are currently reading. In the post I explain the motivation behind ThreadLocal usage. In the second post currently in progress I will open up the ThreadLocal bonnet and look at the implementation.

Let us start with an imaginary scenario in which ThreadLocal usage is indeed reasonable. For this, say hello to our hypothetical developer, named Tim. Tim is developing a webapp, in which there is a lot of localized content. For example a user from California would expect to be greeted with date formatted using a familiar MM/dd/yy pattern, one from Estonia on the other hand would like to see a date formatted according to dd.MM.yyyy. So Tim starts writing code like this:
public String formatCurrentDate() {
   DateFormat df = new SimpleDateFormat("MM/dd/yy");
   return df.format(new Date());
}

public String formatFirstOfJanyary1970() {
   DateFormat df = new SimpleDateFormat("MM/dd/yy");
   return df.format(new Date(0));
}
After a while, Tim finds this to be boring and against good practices – the application code is polluted with such initializations. So he makes a seemingly reasonable move by extracting the DateFormat to an instance variable. After making the move, his code now looks like the following:
private DateFormat df = new SimpleDateFormat("MM/dd/yy");

public String formatCurrentDate() {
   return df.format(new Date());
}

public String formatFirstOfJanyary1970() {
   return df.format(new Date(0));
}
Happy with the refactoring results, Tim tosses an imaginary high five to himself, pushes the change to the repository and walks home. Few days later the users start complaining – some of them seem to get completely garbled strings instead of the former nicely formatted dates.

Investigating the issue Tim discovers that the DateFormat implementation is not thread safe. Meaning that in the scenario above, if two threads simultaneously use the formatCurrentDate() and formatFirstOfJanyary1970() methods, there is a chance that the state gets mangled and displayed result could be messed up. So Tim fixes the issue by limiting the access to the methods to make sure one thread at a time is entering at the formatting functionality. Now his code looks like the following:
private DateFormat df = new SimpleDateFormat("MM/dd/yy");

public synchronized String formatCurrentDate() {
   return df.format(new Date());
}

public synchronized String formatFirstOfJanyary1970() {
   return df.format(new Date(0));
}
After giving himself another virtual high five, Tim commits the change and goes to a long-overdue vacation. Only to start receiving phone calls next day complaining that the throughput of the application has dramatically fallen. Digging into the issue he finds out that synchronizing the access has created an unexpected bottleneck in the application. Instead of entering the formatting sections as they pleased, threads now have to wait behind one another.

Reading further about the issue Tim discovers a different type of variables called ThreadLocal. These variables differ from their normal counterparts in that each thread that accesses one (via ThreadLocal’s get or set method) has its own, independently initialized copy of the variable. Happy with the newly discovered concept, Tim once again rewrites the code:

public static ThreadLocal df = new ThreadLocal() {
   protected DateFormat initialValue() {
      return new SimpleDateFormat("MM/dd/yy");
   }
};

public String formatCurrentDate() {
   return df.get().format(new Date());
}

public String formatFirstOfJanyary1970() {
   return df.get().format(new Date(0));
}
Going through a process like this, Tim has through painful lessons learned a powerful concept. Applied like in the last example, the result serves as a good example about the benefits.

But the newly-found concept is a dangerous one. If Tim had used one of the application classes instead of the JDK bundled DateFormat classes loaded by the bootstrap classloader, we are already in the danger zone. Just forgetting to remove it after the task at hand is completed, a copy of that Object will remain with the Thread, which tends to belong to a thread pool. Since lifespan of the pooled Thread surpasses that of the application, it will prevent the object and thus a ClassLoader being responsible for loading the application from being garbage collected. And we have created a leak, which has a chance to surface in a good old java.lang.OutOfMemoryError: PermGen space form

Another way to start abusing the concept is via using the ThreadLocal as a hack for getting a global context within your application. Going down this rabbit hole is a sure way to mangle your application code with all kind of unimaginary dependencies coupling your whole code base into an unmaintainable mess.


Original link : http://plumbr.eu/blog/when-and-how-to-use-a-threadlocal

пятница, 14 декабря 2012 г.

Javascript - memory leaks

Hi reader,

Hm...  I'm investigating leaks in java script code. I've never thought that it's possible, but
in real live it's enough real issue.

To start, I've  found one interesing article: http://learn.javascript.ru/memory-leaks

I'll update this post if I get new info about this issue.

суббота, 17 марта 2012 г.

Unlocking HUAWEI E173


Добрый день,
Сегодня так приключилось, что в моих руках оказался 3G модем мегаФона... Поскольку я не фанат дорогого интернета ограничений, я его перепрошил под любые сим карты, что б быть более гибким в своем выборе.
Обзор модема можно глянуть тут

Здесь я опишу шаги что и как я делал:
Убедитесь что поставили Мегафоновский dashboard:
1. Втыкаем модем
2. Срабатывает автозапуск
3. Проходим инсталляцию

P.S. Все это нужно было только для того, что б поставились необходимые драйвера.
Если этот шаг пропустите, то в дальнейшем, во время апгрейда, можете увидеть такую ошибку:
Huawei_e173_Proshivka_firmware3_error1
Начинаем колдовать:
Все делается на свой страх и риск, автор ответственности не несет.

ВНИМАНИЕ! ОБЯЗАТЕЛЬНО выходим из всех программ, выключаем антивирус, интернет. ПРОШИВАТЬ необходимо БЕЗ СИМ-КАРТЫ и карты памяти!!! Всё извлекаем из модема!!!


Крайне желательно прошиваться на ноутбуке или нетбуке, или на ПК с источником бесперебойного питания — иначе при аварийном отключении питания вы рискуете потерять свой 3G-модем!!!

1. Выкачиваем весь необходимый софт отсюда 
2. После того, как всё необходимое скачано — списываем с модема IMEI-код, запускаем программу huawei_unloсker_by_souhail_gsm_and_maverick_lp28.exe и вводим списанный раннее IMEI, затем нажимаем Unlock. В чёрном окне появятся данные типа:
Huawei_Modem_Unlocker_2
3. Запускаем файл прошивки (firmware) —  huawei_e173_e173u-1_firmware_update_11.126.85.00.209_B427_win_mac.exe
Если программа прошивки СРАЗУ не запросит код разблокировки, следуем указаниям программы, жмем далее (Next) и далее, весь ваш путь последовательно показан на скринах ниже:
4. Отключаем модем от ПК и подключаем заново. 
Прошиваем Менеджер подключений (dashboard) нашего модема, чтобы при вставке неродной СИМ-карты у нас появилось окно ввода кода блокировки -запускаем файл прошивки dashboard -1_huawei_e173_dashboard_utps_11.300.05.21.343_B416_v. 3.17.00_by_helpower.narod.ru.exe — весь процесс прошивки ниже на скринах:
5. После прошивки извлекаем модем из пк/ноутбука, вставляем в него сим карту и вставляем заново. 
6. Нам заново предложат на автозапуске установить новую версию dashboard. Устанавливаем.
7. Во время запуска у нас запросят пин код и еще вылетит окно типа:
Huawei_e173_Unlock1
8. Вводим NSK-код, который мы сгенерировали ранее.
Huawei_e173_Unlock2_imei_nsk

9. Все, работа сделана! Модем разлочен, можно использовать в своих целях.

DashBoard_3_mms_voice

VisualSVN server: How to change Repository's root without reinstalling

Greeting everyone!

Today, terrible situation was happened to me.
My VisualSVN server not found path to root of repository. It means I lost access to all my source code of whole my projects. :(

By analyze, I found that It happened because I use external hard drive like root of repositories...
My windows was changed disk Name to a new value (e.g. L character) today..
Therefore, when VisualSVN tries to get root of repositories it can not find one because of old path contains previous disk name.

Much more easy way:
1. Open VisualSVN Server Manager
2. Right-click on root node and select properties
3. Change repositories location on general page
4. Click OK 


I've found 2 ways how to take this situation in my hands:

First one: change disk name to old letter.
For this one we should go to windows management and change it using Disk Management functionality.

Second one: change old path in windows register.
So, for this case, we should invoke "regedit" from run line and then using searching (Ctrl+F and F3 keys)  find and change old value.

Finaly: restart VisualSVN server application (close/open it)

Thanks for your attention :)