Friday, July 12, 2024

Convert strings to Upper or Lower Case in bash

Very simple way to convert strings to all Upper or Lower case in bash without using any of the other tools like awk or sed
myStr="Test"
myLowerCaseStr=${myStr,,}
myUpperCaseStr=${myStr^^}
echo "String: ${myStr}"
echo "Lower Case String: ${myLowerCaseStr}"
echo "Upper Case String: ${myUpperCaseStr}"
The output would be as follows:
String: Test
Lower Case String: test
Upper Case String: TEST

Friday, March 31, 2023

Spring Data JPA Query Methods

 Spring Data JPA Queries are a great way to create queries derived from the method name without needing to write tons of boiler-plate code to create connection & query, execute it and then process the result set. This generally works fine for simple queries and method names are very explicit in pointing out what is being returned by that method so the code is more readable and maintainable. To make this work successfully, the method name has to follow certain conventions:

  1. Method names usually start with the word "find"
  2. Filter clauses are added to the function name as "findBy<ColumnName>" which creates queries of the form "where <ColumnName> = ?"
  3. Multiple Filter clauses are supported using And / Or clauses 
    1. And can be used as "findBy<Col1>And<Col2>"  which creates the query "where <Col1> = ? and <Col2> = ?"
    2. Or can be used as "findBy<Col1>Or<Col2>"  which creates the query "where <Col1> = ? or <Col2> = ?"
  4. Similarly other operators are supported on the lines of Between, After, Before, LessThan, GreaterThan, Like, etc
  5. Ordering of the results can be delegated to the database by adding "OrderBy" to the function name as "findBy<Col1>OrderBy<Col2><Asc|Desc><Col3><Asc|Desc>"
Here is a handy table of supported keywords inside method names taken from the Spring Data documentation:

KeywordSampleJPQL snippet

Distinct

findDistinctByLastnameAndFirstname

select distinct …​ where x.lastname = ?1 and x.firstname = ?2

And

findByLastnameAndFirstname

… where x.lastname = ?1 and x.firstname = ?2

Or

findByLastnameOrFirstname

… where x.lastname = ?1 or x.firstname = ?2

IsEquals

findByFirstname,findByFirstnameIs,findByFirstnameEquals

… where x.firstname = ?1

Between

findByStartDateBetween

… where x.startDate between ?1 and ?2

LessThan

findByAgeLessThan

… where x.age < ?1

LessThanEqual

findByAgeLessThanEqual

… where x.age <= ?1

GreaterThan

findByAgeGreaterThan

… where x.age > ?1

GreaterThanEqual

findByAgeGreaterThanEqual

… where x.age >= ?1

After

findByStartDateAfter

… where x.startDate > ?1

Before

findByStartDateBefore

… where x.startDate < ?1

IsNullNull

findByAge(Is)Null

… where x.age is null

IsNotNullNotNull

findByAge(Is)NotNull

… where x.age not null

Like

findByFirstnameLike

… where x.firstname like ?1

NotLike

findByFirstnameNotLike

… where x.firstname not like ?1

StartingWith

findByFirstnameStartingWith

… where x.firstname like ?1 (parameter bound with appended %)

EndingWith

findByFirstnameEndingWith

… where x.firstname like ?1 (parameter bound with prepended %)

Containing

findByFirstnameContaining

… where x.firstname like ?1 (parameter bound wrapped in %)

OrderBy

findByAgeOrderByLastnameDesc

… where x.age = ?1 order by x.lastname desc

Not

findByLastnameNot

… where x.lastname <> ?1

In

findByAgeIn(Collection<Age> ages)

… where x.age in ?1

NotIn

findByAgeNotIn(Collection<Age> ages)

… where x.age not in ?1

True

findByActiveTrue()

… where x.active = true

False

findByActiveFalse()

… where x.active = false

IgnoreCase

findByFirstnameIgnoreCase

… where UPPER(x.firstname) = UPPER(?1)


Saturday, January 21, 2023

Piping output of top through grep does not give any output

Recently I was trying to grep for "load average" in the output of top and then redirect it to a file to save for later analysis - however the output file would be totally empty for quite some time. That is the time I realized that grep was buffering its output causing the output file to be empty. So the grep command was not writing to the file immediately but was collecting large amounts of data in its buffer before flushing that out to the file.

My original command was

top -b -u myusername -d 5 | grep -i 'load average' > /tmp/load_averages.log

Because this did not write anything to the output file for quite a while, I had to change it buffer only till it saw a newline in the output and then to flush out whatever it has gathered so far in its buffer as below:

top -b -u myusername -d 5 | grep -i 'load average' --line-buffered > /tmp/load_averages.log

And lo behold, tailing the output file shows the load averages being printed every 5 seconds (because of the -d 5 flag given to the top command)

Saturday, December 31, 2022

Extract a range of lines from a file on Linux

Say you have a huge file, but want to extract only a specific range of lines from that file into another one. There are many ways to do this, but a very simple way would be to use sed as follows:

sed -n '$start_line,$end_linep;$end_lineq' input_file.txt > output_file.txt

This will print all lines from the start_line to end_line and stop processing once it reaches end_line.
Note that the p in the above command makes sed print the line and the q makes sed end once the specific line is processed. Since we have the print command inside the quotes, we suppress automatic printing of pattern space by specifying the -n switch. For example, to extract lines 1500 - 1700, we can use this command:

sed -n '1500,1700p;1700q' input_file.txt > output_file.txt


Another simple method is to use a combination of head and tail as follows:

head -n +$end_line input_file.txt | tail -n +$start_line > output_file.txt

Here the + before the line numbers tells the head to output up to that line number and for tail to output starting at that line number. So our command above uses head to get all lines till the last required line and then uses tail to get all lines including and following the required first line so we do not need to do any calculations in our head. For example, to extract lines 1500 - 1700, we can use this command:

head -n +1700 input_file.txt | tail -n +1500 > output_file.txt

Friday, December 30, 2022

Disable automatic backslash insertion before $ when using auto-complete in bash

When using bash that is not configured properly, on using tab to auto-complete paths, it automatically escapes dollar symbols by inserting a backslash symbol before them, causing the commands to fail if run after auto-completion. 

For example: 

ls -l $HOME_DIR/code/wo (TAB) becomes 
ls -l \$HOME_DIR/code/workspace/ 

To stop this from occurring, you need to add this command to your  ~/.bashrc

shopt -u progcomp 

After this, source the .bashrc again and every time after you login, bash will not automatically add the backslash to escape $ symbol - viola - problem solved!

Thursday, May 6, 2021

Extract files from RPM package without installing

An RPM package is a file consisting of a cpio archive that contains the files to be installed and a header that contains metadata information about the package.
You can use the simple utility tool rpm2cpio to convert the contents of an RPM package into a cpio archive and then use the cpio command to extract the contents of that archive without needing to install the RPM package.

rpm2cpio name_of_rpm_package.rpm | cpio -idmv

Note that this will extract the files to the current folder.
Here is an explanation of the options used for the cpio command:

  • i: extract files
  • d: create leading directories where needed
  • m: preserve previous file modification times for the extracted files
  • v: verbose

Wednesday, May 5, 2021

Handling Exceptions in EJB using Interceptors

In my previous posts Using EJB Interceptors to add functionality to existing Beans, and Using EJB Interceptors to execute code AFTER service method completes, we saw how to use EJB3 Interceptors to add common concern features like logging, etc. to J2EE service methods.
In case you want to have common exception handling logic for all service method calls, you can wrap the return context.proceed(); in a try-catch block and handle the exception in the catch block as shown below:


package com.my.ejb.interceptors;

import javax.interceptor.AroundInvoke;
import javax.interceptor.InvocationContext;

public class MyInterceptor {

    @AroundInvoke
    public Object interceptorMethod(InvocationContext context) throws Exception {
    	try {
          System.out.println("Before invoking method: " + context.getMethod());
          return context.proceed();
        } catch (Exception e) { // You can catch ALL or ONLY Specific Exceptions as per your requirement
          System.out.println("Exception in method " + context.getMethod() + ": " + e.getMessage());
        } finally {
          System.out.println("After invoking method: " + context.getMethod());
        }
    }
}

Once this interceptor is created, we just need to add an "@Interceptors" annotation to the target EJB as:

import javax.interceptor.Interceptors;

@Interceptors({com.my.ejb.interceptors.MyInterceptor.class})

Now you should see log lines "Before ..." before the the method executes and "After..." after the method executes and in case of any exceptions in the metod call, you will see "Exception ..."


Tuesday, May 4, 2021

Using EJB Interceptors to execute code AFTER service method completes

In my previous post Using EJB Interceptors to add functionality to existing Beans, we saw how to use EJB3 Interceptors to add common concern features like logging, etc. to J2EE service methods.
In case you want to run any piece of code after each service method call, you can wrap the return context.proceed(); in a try-finally block and add the "after" code in the finally block as shown below:


package com.my.ejb.interceptors;

import javax.interceptor.AroundInvoke;
import javax.interceptor.InvocationContext;

public class MyInterceptor {

    @AroundInvoke
    public Object interceptorMethod(InvocationContext context) throws Exception {
    	try {
          System.out.println("Before invoking method: " + context.getMethod());
          return context.proceed();
        } finally {
          System.out.println("After invoking method: " + context.getMethod());
        }
    }
}

Once this interceptor is created, we just need to add an "@Interceptors" annotation to the target EJB as:

import javax.interceptor.Interceptors;

@Interceptors({com.my.ejb.interceptors.MyInterceptor.class})

Now you should see log lines "Before ..." before the the method executes and "After..." after the method executes!


Tuesday, November 10, 2020

Using EJB Interceptors to add functionality to existing Beans

To add any decorations or cross-cutting features like logging, profiling or performance measurement for service method calls of existing enterprise beans, you can use EJB3 Interceptors that were provided starting with JavaEE5.

Interceptor is a method that wraps around the invocation of the actual business method call allowing you to apply the required feature and can either exist in the target class if it is very speficic to that class; or in an external class if it applies to multiple service methods. If it is a part of an external class, then it has to be the only method in that class having the annotation "@AroundInvoke"

This interceptor method takes the following form:

package com.my.ejb.interceptors;

import javax.interceptor.AroundInvoke;
import javax.interceptor.InvocationContext;

public class MyInterceptor {

    @AroundInvoke
    public Object interceptorMethod(InvocationContext context) throws Exception {
        System.out.println("Going to invoke method: " + context.getMethod());
        return context.proceed();
    }
}

Once this interceptor is created, we just need to add an "@Interceptors" annotation to the target EJB as:

@Interceptors({com.my.ejb.interceptors.MyInterceptor.class})
And viola - it simply works, no need for any additionaly libraries or frameworks!

Note: Do not forget the return context.proceed(); call at the end of the interceptor method - this will allow the chain of interceptors to proceed and the target metod to be invoked!

Monday, November 9, 2020

Undo git stash clear

You can clear git stashes using the command:
git stash drop stash@{stash_index}
### OR
git stash clear
If you need to recover very recently deleted stashes, you can try the following two commands to try to recover them:

1. List all the available stashes that can be receovered using the below command:
git fsck --unreachable | grep commit | cut -d ' ' -f3 | xargs git log --merger --no-walk
2. Choose commit id of the stash that you want to restore and run the below command:
git stash apply [commit_id]

Wednesday, June 17, 2020

Syntax Highlighting Code in Blogger

I was using Syntax Highlighter created by Alex Gorbatchev to highlight code snippets on this blog, but of late, it was not working or taking too long to load up. 
So it was time again to figure out a new way to do this and there were a few options that work in a similar fashion:
The other option was to pre-format code and then paste it into your post:

I found Code Prettifier to be the simplest option that can get me closest to Syntax Highlighter and the setup is very easy - just need to add these lines to the theme HTML code:

<script src="https://cdn.jsdelivr.net/gh/google/code-prettify@master/loader/run_prettify.js"></script>
<style>
li.L0, li.L1, li.L2, li.L3,
li.L5, li.L6, li.L7, li.L8 {
  list-style-type: decimal !important;
}
</style>

Once this is done, all you need to do is to put encoded code snippet in a pre block with the class set to prettyprint and viola!
Note that the above code has a style override which makes line numbers show up on all lines of code. Without that block of style code, only every fifth line of could would have a line number.

Here is an example of the pre block that you need to use to syntax highlight your code:
 <pre class="prettyprint linenums lang-sh"> ... your code ... </pre>

You don't need to specify the language since prettyPrint will guess it, however you can specify a language by specifying the language extension along with the prettyprint class. Languages supported out of the box are:
"bsh", "c", "cc", "cpp", "cs", "csh", "cyc", "cv", "htm", "html", "java",
"js", "m", "mxml", "perl", "pl", "pm", "py", "rb", "sh", "xhtml", "xml","xsl"
You may also use the HTML 5 convention of embedding a <code> element inside the <pre> and using language-java style classes:
  <pre class="prettyprint"><code class="language-java">...</code></pre>
Note: Remember to escape your code using HTML entities :)

Saturday, March 24, 2018

Copy specific files from within nested folders

I had a situation where I needed to save all log files that were present in nested sub-folders and copy them over to another folder for analysis.
There are many ways to do this - but here is the simplest that I could figure out using rsync:
rsync -aihv --include='*/' --include='*.log*' --exclude='*' /source_folder/to/search/in/  /destination_folder/to/copy/to/

Important thing to note here is the order of include and exclude flags passed to rsync command - it is sensitive to the order in which these flags are provided.
First include flag '*/' makes rsync look into subfolders and the second flag selects all files of the format '*.log*'.
The next exclude flag excludes any file not selected as yet and then copies them over to the destination folder.
You can provide more include flags before the exclude flag to select multiple types of files as per your requirement.

Rename multiple files in one command

If you want to rename multiple files, the trusty old Unix "mv" command can't help as it can rename only one file at a time.
This requires us to bring out something different from our Unix arsenal - the "rename" command!
Use the rename command in conjunction with find to rename multiple files:
find /source_folder/to/search/in/ -name 'myapp*.log.201*' -exec rename -v .log. .oldlog. {} \; >> /temp/rename.log

Here we are searching for files named 'myapp*.log.201*' and renaming them to 'myapp*.oldlog.201*'
In case you need to do this on multiple servers, use the for loops trick!

Running same set of commands on multiple servers using for loop

Developers as usual are very lazy and so instead of going to each server to grep for an error string in the log file and creating a report, here is a simple way to collect all the necessary log lines.
Create a file containing a list of server names on which we want to check the logs - one on each line and then run this for loop if using bash:

for s1 in $(cat servers_list.txt); do
  ssh -q ${s1} "grep 'search_string' /search/folder/*/*.log* | sed 's/^/${s1} => /'" >> /tmp/search.log
  # Other commands here if required
done

If you are using csh, then the for loop syntax is slightly different:

foreach s1 in (cat servers_list.txt)
  ssh -q ${s1} "grep 'search_string' /search/folder/*/*.log* | sed 's/^/${s1} => /'" >> /tmp/search.log
  # Other commands here if required
end

The code is simple - for each server, ssh to that server and run the grep command to find out the log lines having the specific string. The bigger trick here is to use sed to pre-pend server name to the grepped log line to make the report useful. This should return a file with lines in the format:

server_name => [log line grepped from the log file]

Tuesday, February 6, 2018

Obi keeps ringing - Calls from weird numbers - Ghost calls

Some time back my Obi Google Voice phone kept ringing constantly and the caller ids were weird numbers. Strangely, Google Voice had no history of any such calls that I could mark as spam and rebooting the Obi device would help.

Researching this problem showed that it could be SIP scanning by bots that probe standard SIP ports causing the phone to ring and caller id to show strange numbers like 1000, 1001, 0000, 123456, etc.

A simple solution to this problem is to change the value of X_InboundCallRoute.
Use Obi Expert > Voice Services > SPx Service > X_InboundCallRoute to:
{>('GV12345678901'):ph}
where GV12345678901 is your Simonics SIP Login Prefix and SPx is the service on which GV is configured

There are other possible solutions as well, but I found this solution to be the simplest - but still for sake of completeness, you can check out the other possible solutions at ObiTalk forum post and Simonics forum post.

Obi100 and Obi110 Google Voice with Simonics Gateway

Obi100 and Obi 110 devices worked great with Google Voice but Obihai declared these devices to be end of life in August 2016. So a recent Google change made these devices to stop working with GV.
To solve this, you could either buy a newer Obi 200 series device or use a paid GV gateway setup by simonics.

Here are the instructions for using simonics GV gateway from the ObiTalk forum post:

1:  Assumptions:  you have an OBi 100 or 110, running the final build 2886 firmware.  You have a working inbound Google Voice telephone number assigned to your Google account.  You've paid the fee to use the gateway, and you are on the gateway setup page.

2:  Go to your OBiTALK web dashboard:  https://www.obitalk.com/obinet/pg/obhdev.  Click the OBi device.  Find the Service Provider (SP1 or SP2) that was setup to use Google Voice.  Delete the SPx configuration by clicking the trash can icon.

3:  After waiting a few minutes for the OBi's configuration to be remotely deleted, again click on the SP1 or SP2 you want to use.  On the next page, scroll down to the bottom and select "OBiTALK Compatible Service Providers".  On the next page, scroll down and click "Generic Service Provider" and click "Next".

4:  On the next page, fill in your GVGW server name, SIP user ID and SIP password, and click "Save".

5:  Wait for the portal to remotely configure your OBi.  It will reboot once or twice (power LED will blink on then off).  Give it plenty of time to finish.

6:  Refresh the OBiTALK dashboard in your browser, and click the SPx.  You should now see that it is registered to the gatway.  You're done!

Wednesday, January 31, 2018

Use CSipSimple instead of ObiTalk ObiOn App on Android

Android app for ObiTalk - ObiOn stopped working some time back so here is my solution for using CSipSimple instead.
It requires you to sign-up for a free IP Freedom account at Callcentric and a bit of setup.

  1. Create an IP Freedom account 12341234567 at Callcentric here
  2. Create a sub-account 12341234567101 (extension 101)
  3. On your Android phone download and install CSipSimple from the Play Store
  4. Add credentials for extension 101 from step 2 in CSipSimple setting
  5. Login to your account on the ObiTalk Portal (https://www.obitalk.com/obinet/)
  6. Setup SP2 (Callcentric) with the credentials from step 1 in the ObiTalk portal
  7. Login to the management screen of your Obi on your  network using the IP Address
  8. Under Voice Services > SP2 Service - set up this rule instead of the default:
    X_InboundCallRoute= {101>12341234567:aa},{ph}

That's it! To call into your Obi's AA, dial 100 (100 is the default extension for your main Callcentric account) from CSipSimple app on your phone.
Note that this is valid for Obi100 and Obi110 for sure but may also work for other Obi models.
And don't forget to replace the 12341234567 with the Callcentric number you receive after signing up!

Thanks to the multiple posters on the ObiTalk forums for all the above info that I have condensed into a set of simple easy to follow steps that work.

Monday, May 18, 2015

Solve Spring NoUniqueBeanDefinitionException

I encountered the NoUniqueBeanDefinitionException where-in Spring was unable to which class to inject for an Autowired variable even though the it was properly qualified!

This happened because the Qualifier did not get post-processed and so multiple implementations of the Interface type of the variable being injected were now available in the classpath. So Spring found more that one instance and was unable to decide which instance to inject for the particular Autowired target.

The turn on the default AutowiredAnnotationBeanPostProcessor which processes the @Qualifier , you need to add the line to the beans section of your spring configuration. Since this was missing from the beans section of the configuration file, the Qualifier annotation was ignored in this code:

    @Autowired
    public void setDao(@Qualifier("myDaoImpl") MyDAO dao) {

And here is a snippet of the exception that was logged:

 java.lang.RuntimeException: org.springframework.beans.factory.BeanCreationException: Injection of autowired dependencies failed for class [class my.package.impl.name.MyBeanClassName]; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire method: public void my.package.impl.name.MyBeanClassName.setDao(my.package.intf.name.MyDAO); nested exception is org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type [my.package.intf.name.MyDAO] is defined: expected single matching bean but found 4: myDaoImpl,secondDaoImpl,thirdDaoImpl,fourthDaoImpl

This error was resolved after adding the below line to the beans section of spring configuration:

<context:annotation-config></context:annotation-config>

Friday, May 15, 2015

Upgrade Hibernate 3..x to Hibernate 4.3.x

NOTE: This is a partial guide to upgrade your Hibernate 3 project to Hibernate 4.3.x

Hibernate has a come a long way from version 3.x to the latest version Hibernate 4.3.x with lots of major changes, bug fixes and enhancements:
  • Started using gradle for builds
  • Redesign the way SessionFactory is built
  • Improved metamodel
  • Initial osgi-fication by package splitting (public, internal, spi)
  • Migration to i18n logging framework (using jboss logging)
  • JDK 1.6 (JDBC4) as baseline

The following hibernate jars are required to be downloaded from the Maven Repository:

  1. hibernate-core-4.3.9.Final.jar
  2. hibernate-annotations-3.5.6-Final.jar
  3. hibernate-commons-annotations-3.2.0.Final.jar (DO NOT USE 3.3.0.ga version)
  4. hibernate-entitymanager-4.3.9.Final.jar
  5. hibernate-validator-5.1.3.Final.jar
  6. jboss-logging-3.1.3.GA.jar
Do not use hibernate-commons-annotations-3.3.0.ga.jar as it is a release mistake and will create more problems.

You can download the corresponding javadoc and source files by going to the Maven website and searching for: 
g:"org.hibernate" AND a:"hibernate-core" AND v:"4.3.9.Final"

Now that all the required jars are downloaded, hibernate3.jar will need to be replaced by hibernate-core jar; here is a simple guide to when to include rest of the jars.

To resolve the below error, add hibernate-commons-annotations-3.2.0.Final.jar to classpath and the JBoss library path:
NOTE: DO NOT USE hibernate-commons-annotations-3.3.0.ga.jar as it is a release mistake
java.lang.NoClassDefFoundError: org/hibernate/annotations/common/reflection/MetadataProvider
at org.jboss.hibernate.jmx.Hibernate.buildConfiguration(Hibernate.java:194)
at org.jboss.hibernate.jmx.Hibernate.buildSessionFactory(Hibernate.java:228)
at org.jboss.hibernate.jmx.Hibernate.startService(Hibernate.java:155)
at org.jboss.system.ServiceMBeanSupport.jbossInternalStart(ServiceMBeanSupport.java:289)
at org.jboss.system.ServiceMBeanSupport.jbossInternalLifecycle(ServiceMBeanSupport.java:245)
at sun.reflect.GeneratedMethodAccessor3.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)

To resolve the below error, add jboss-logging-3.2.1.Final.jar to classpath and the JBoss library path:
Not resheduling failed loading task, loadTask=org.jboss.mx.loading.ClassLoadingTask@1219665{classname: org.hibernate.internal.CoreMessageLogger, requestingThread: Thread[main,5,jboss], requestingClassLoader: org.jboss.mx.loading.UnifiedClassLoader3@1b06041{ url=null ,addedOrder=2}, loadedClass: nullnull, loadOrder: 2147483647, loadException: java.lang.NoClassDefFoundError: org/jboss/logging/BasicLogger, threadTaskCount: 0, state: 1, #CCE: 1}
java.lang.NoClassDefFoundError: org/jboss/logging/BasicLogger
at java.lang.ClassLoader.defineClass1(Native Method)
at java.lang.ClassLoader.defineClassCond(ClassLoader.java:631)
at java.lang.ClassLoader.defineClass(ClassLoader.java:615)
at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:141)
at java.net.URLClassLoader.defineClass(URLClassLoader.java:283)

Follow the Hibernate Code Migration Guide to make the appropriate changes as required:

  1. Initial move to ServiceRegistry.  For now, see design wikis or sources for more information.  Not all "services" have been migrated to this model yet.  The main ones (JDBC and transaction stuff) as well as lowever level one (classloading and such) have been migrated.  The rest will be moved during Alpha2 development.
  2. In an initial push toward osgi we started splitting up packages a little bit differently in this release. 
    1. The reason is to identify classes which are intended as
      1. public API, which are fully expected to be used in application code.
      2. internal implementation details, which are only intended for Hibernate use.
      3. SPI contracts, whch define
        1. extension contracts
        2. contracts with Hibernate internals exposed to these extensions
    2. This will potentially lead to some  packaging changes needed in user code:
      1. org.hibernate.dialect.resolver.DialectResolver -> org.hibernate.service.jdbc.dialect.spi.DialectResolver
  3. Deprecated methods that have been removed:
    1. References to org.hibernate.type.AbstractSingleColumnStandardBasicType and org.hibernate.type.SingleColumnType methods should be changed as indicated:
      1. nullSafeGet(ResultSet rs, String name) should be changed to 
        nullSafeGet(ResultSet rs, String name, SessionImplementor session)
      2. get(ResultSet rs, String name) should be changed to 
        get(ResultSet rs, String name, SessionImplementor session)
      3. nullSafeSet(PreparedStatement st, T value, int index) should be changed to nullSafeSet(PreparedStatement st, Object value, int index, SessionImplementor session)
      4. set(PreparedStatement st, T value, int index) should be changed to set(PreparedStatement st, T value, int index, SessionImplementor session)
    2. References to org.hibernate.usertype.UserType methods should be changed as indicated:
      1. nullSafeGet(ResultSet rs, String[] names, Object owner) should be changed to   
        nullSafeGet(ResultSet rs, String[] names, SessionImplementor session, Object owner)
      2. nullSafeSet(PreparedStatement st, Object value, int index) should be changed to nullSafeSet(PreparedStatement st, Object value, int index, SessionImplementor session)
    3. Session.reconnect() - manual disconection and reconnection is now only supported for user-supplied-connection scenarios (JDBC Connection passed in while opening the Session)
    4. Session.connection() - use Session.doWork(), Session.doReturningWork() or Session.sessionWithOptions()...openSession() as replacement depending on need
    5. Most of the overloaded SessionFactory.openSession methods.  Use SessionFactory.withOptions()...openSession() instead
  4. Deprecated classes/interfaces that have been removed:
    1. org.hibernate.classic.Session
    2. org.hibernate.classic.Validatable
    3. org.hibernate.classic.ValidationException
  5. org.hibernate.jdbc.BatcherFactory, Batcher, and their implementations have been replaced by org.hibernate.engine.jdbc.batch.spi.BatchBuilder and Batch, with default implementations in org.hibernate.engine.jdbc.batch.internal. You can override the default BatchBuilder by defining the  "hibernate.jdbc.batch.builder" property as the name of a BatchBuilder implementation, or by providing a BatchBuilder in a custom ServiceRegistry.
  6. hibernate.cfg.xml no longer supported as means of specifying listeners.  New approach invloves using an org.hibernate.integrator.spi.Integrator which works based on "service discovery". 




Thursday, May 14, 2015

Upgrade from Spring 2.5.x to Spring 4.1.x - JBoss

After completing the steps mentioned in my previous post for Upgrading Spring 2.5.x to Spring 4.1.x, the project compiles without problems, however, JBoss deployment does not work as it does not get all the required new Spring Jars.

The Spring component jars also need to be added to the JBoss classpath. However, here are a few specific exceptions that point to requiring specific jars in the JBoss classpath as below.

To resolve the below error, add spring-context.jar to JBoss library path:
java.lang.ArrayStoreException: sun.reflect.annotation.TypeNotPresentExceptionProxy
at sun.reflect.annotation.AnnotationParser.parseClassArray(AnnotationParser.java:653)
at sun.reflect.annotation.AnnotationParser.parseArray(AnnotationParser.java:460)
at sun.reflect.annotation.AnnotationParser.parseMemberValue(AnnotationParser.java:286)
at sun.reflect.annotation.AnnotationParser.parseAnnotation(AnnotationParser.java:222)
at sun.reflect.annotation.AnnotationParser.parseAnnotations2(AnnotationParser.java:69)
at sun.reflect.annotation.AnnotationParser.parseAnnotations(AnnotationParser.java:52)
at java.lang.Class.initAnnotationsIfNecessary(Class.java:3079)


To resolve the below error, add spring-beans.jar to JBoss library path
java.lang.NoClassDefFoundError: org/springframework/beans/factory/BeanFactory
at java.lang.Class.getDeclaredMethods0(Native Method)
at java.lang.Class.privateGetDeclaredMethods(Class.java:2436)
at java.lang.Class.getDeclaredMethods(Class.java:1793)
at org.jboss.ejb3.interceptor.InterceptorInfoRepository$AnnotationInitialiser.getInfo(InterceptorInfoRepository.java:704)
at org.jboss.ejb3.interceptor.InterceptorInfoRepository.initialiseFromAnnotations(InterceptorInfoRepository.java:469)
at org.jboss.ejb3.interceptor.InterceptorInfoRepository.getOrInitialiseFromAnnotations(InterceptorInfoRepository.java:451)
at org.jboss.ejb3.interceptor.InterceptorInfoRepository.getInterceptorsFromAnnotation(InterceptorInfoRepository.java:341)
at org.jboss.ejb3.interceptor.InterceptorInfoRepository.getClassInterceptors(InterceptorInfoRepository.java:139)
at org.jboss.ejb3.EJBContainer.initialiseInterceptors(EJBContainer.java:737)
at org.jboss.ejb3.EJBContainer.getClassInterceptors(EJBContainer.java:429)

Hopefully this should resolve all issues for a successful upgrade of Spring 2.5.x to Spring 4.1.x!


LinkWithin

Related Posts Plugin for WordPress, Blogger...