Use Maven to configure active environment profile (with spring profile)

Environment profiles are templates that are used to derive concrete environments based on pre-defined templates. Essentially, they are abstract environment definitions that allow environments to be categorized or classified by associating a given environment with an underlying environment profile. Typical examples of profiles are dev, prod, QA, Test, etc.

In this post, we are only focusing on using maven to configure active environment profile with spring profiles in a web application. Certainly, there are different ways to allow us to configure environment profiles even within spring profiles explained in this article :

The idea is basically from 4.6 from the above posts with more details to elaborate further on this approach within the web application scope.

Step 1 Configure different environment profiles in pom.xml

For eg, to simplify the problem, I only have two environments for configuration respectively defined as dev and prod. Adding the code below into pom.xml. You will have dev as the default environment when maven build your project.


Step 2 Enable resource filtering in pom.xml

Note: Spring provides environment property to specify which profile is active. The question here is: how to populate the value from our configuration property defined as activeProfile in the pom file to this spring environment property. The answer is that you could include it in your application.propertie(dir: src/main/resources ).

Before proceeding below, you have to answer one simple question: Are you using Spring Boot?

If yes, this file is already ready for you under “src/main/resources” directory, and it will be auto-detected. We can then inject any loaded properties from it as normal. However, if you are not using Spring Boot, create the under “src/main/resources” directory. Add the following line into your file. (Here we use the placeholder activeProfile to get value populated to when maven build the project).

Still, in order to populate the value defined in activeProfile from the pom.xml to the @activeProfile@ placeholder. You have to enable source filtering in pom.xml.

Here is how to do that:



What is happening under the hood:

By turning on the filter( <filtering>true</filtering>), the code above works as charm when you use the command line mvn clean package. Since you didn’t specify the active profile. Maven will use dev as the default active profile as described by activeByDefault property. And then the activeProfile property will have dev as value and then in, the line above becomes

By setting the targetPath to WEB-INF( <targetPath>WEB-INF</targetPath> ). After the build, you will see your get deployed under WEB-INF.

Learn more about the resource filtering over here:

Step 3 Use value in Java config class

In your java config file, you might want to introduce different logic based on different profiles. One practical example is if you would want to set the static content like html, js, css to not cache in dev environment whereas get cached well in prod environment. Then you have to use the value from property from file. You might skip this session if you are very familiar with how spring wire in the property variables.

Now if you answer Yes that if you are using Spring boot in step 2, You can skip the line below, because spring boot will auto detect However, if you are not using spring boot, in your Java config file, specify the property file as this:

@PropertySource(value = {“/WEB-INF/” })

Now let’s talk about how to get the value from the property variable, I will introduce two intuitive ways to do it:

  1. Use environment variable


private Environment env;

In the actual logic, simply use like this:

if( env.getProperty(“”).equals(“dev”) ) …

2. Use @Value notation.

private String activeProfile;

In the actual logic, simply use like this:

if(activeProfile.equals(“dev”)) …

Note: in order to use @Value annotation to resolve ${} in Spring,  you need to declare a STATIC PropertySourcesPlaceholderConfigurer bean manually. Otherwise if it will show as ${} instead of a resolved value like “dev” or “prod”.

Add the following code in the Java config file if you have not declared the bean:

public static PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer() {
return new PropertySourcesPlaceholderConfigurer();

There are certainly more ways to manipulate the properties, read more on properties with spring with this link:

Step 4 Switch to prod profile

Now, if you want to switch to prod environment. You could do like this:Append a -P parameter to switch which Maven profile will be applied:

mvn clean package -Pprod

This command will package the application for prod profile. It also applies the value ‘prod’ for this application when it is running.

You can find the corresponding xml configuration if you are not using Java configuration. I won’t cover this part in the post since it is already too long 🙂


Batch convert word docs to HTML/PDF with PowerShell.

There are a bunch of static web contents in my project that initially get drafted from word documents from various sources. These word documents need to get published to the web application eventually in either HTML or PDF formats. Obviously, our BA Julio is super tired of converting them one by one. With hundreds of documents, it could be a nightmare to do it by hand. So he came to me for help. It ended up to be a simple task with a few lines of script using PowerShell. Salute to the power of programming!!

Let’s get started. Copy the code below and save it to converter.ps1 for eg.


$targetPdfPath = "${documents_path}\pdf"

if (!(Test-Path $targetPdfPath -PathType Container)) {
    New-Item -ItemType Directory -Force -Path $targetPdfPath

$word_app = New-Object -ComObject Word.Application

# This filter will find .doc as well as .docx documents

$count = 0
Get-ChildItem -Path $documents_path -Filter *.doc? | ForEach-Object {

    $document = $word_app.Documents.Open($_.FullName)

    $pdf_filename = "${targetPdfPath}\$($_.BaseName).pdf"
    Write-Host "Converting ${pdf_filename} ..." 

    $document.SaveAs([ref] $pdf_filename, [ref] 17)



Write-Host "Complete converting ${count} word documents to pdf under ${targetPdfPath}" -BackgroundColor "Green" -ForegroundColor "Black";

$targetHtmlPath = "${documents_path}\html"

if (!(Test-Path $targetHtmlPath -PathType Container)) {
    New-Item -ItemType Directory -Force -Path $targetHtmlPath

$word_app = New-Object -ComObject Word.Application

# This filter will find .doc as well as .docx documents

$count1 = 0
Get-ChildItem -Path $documents_path -Filter *.doc? | ForEach-Object {

    $document = $word_app.Documents.Open($_.FullName)

    $html_filename = "${targetHtmlPath}\$($_.BaseName).html"
    Write-Host "Converting ${html_filename} ..." 
    $saveFormat = [Enum]::Parse([Microsoft.Office.Interop.Word.WdSaveFormat], "wdFormatFilteredHTML");

    $document.SaveAs([ref] $html_filename, [ref] $saveFormat)



Write-Host "Complete converting ${count1} word documents to html under ${targetHtmlPath}" -BackgroundColor "Green" -ForegroundColor "Black";


Now copy the docs you would like to convert to a temporary folder for eg:


Follow the following steps to convert the documents to htmls and pdfs. Assume you are on windows system.

Step 1: Click on window icon at the left bottom corner and search powershell.

Step 2: Run as administrator to open powershell

Step 3: At prompt, run the following command

Set-ExecutionPolicy Restricted

If the above command didn’t work, try this command

 Set-ExecutionPolicy RemoteSigned

Step 4: Input “Y” when prompted

Step 5: Navigate to script folder => cd

is where your put your converter.ps1.

Step 6: Run the following command

./converter.ps1 “”

refers to C:\temp\msdocs if you follow the example to move your documents to this example folder.

Step 7: It will create a pdf & html folder respectively under the current directory. Please watch the console output in case there is some unusual hanging behavior on the screen. It could indicate that there is some popup interaction from word application. Once you interact with the word application, script will continue the process until finished.

Step 8: Go to msdocs folder and check to make sure you don’t have any missing files.

Note the console would output the number of pdfs that have been converted from word documents. You should compare the two counts to prevent from any potential missing conversion.




[DBA Daily Notes] ORA-00054 Resource busy when dropping table

Here are a few things you can do

  • Kill session from GUI

Go to toad and log on as system administrator. You could also do this sql developer.


Now you would have an overview of the sessions that might involve in locking the tables you would like to drop. So you could simply identify the sessions and kill the corresponding sessions where table locks are withheld.


  • Check v$session and kill session from command.

However sometimes, even we kill the existing sessions, the error would still not go away. I run my drop table script in toad that you could get the details of which table is being locked and the type of the lock. And then go to locks tab to identify the Sid number. You would see a similar window as below.  


For example, on the above screen, my PEGASYS_OBLIGATI table is locked with Lock Type DML. It is because I was doing the data refresh and then it was interrupted in the middle. But Sid 24 didn’t show in any of the sessions in the session window. I could not kill the session to get rid of the locks. Instead I run the following sql statement to find the serial number in order to kill the dead session that holds the lock for my table of object.


> select * from v$session where blocking_session is not null;


After running the sql statement, I find the serial number with the corresponding  sid.


> alter system kill session ‘42,789’;


Now we are all set. Lock is released and drop could be proceeding.


If you want  to know more about v$session, check the link below:


More from the same professor

CS140, 01/13/2012

From a lecture by Professor John Ousterhout.

The greatest performance improvement of all is when a system goes from not-working to working

Programmers tend to worry too much and too soon about performance. Many college-level Computer Science classes focus on fancy algorithms to improve performance, but in real life performance rarely matters. Most real-world programs run plenty fast enough on today’s machines without any particular attention to performance. The real challenges are getting programs completed quickly, ensuring their quality, and
 managing the complexity of large applications. Thus the primary design criterion for software should be simplicity, not speed.

Occasionally there will be parts of a program where performance matters, but you probably won’t be able to predict where the performance issues will occur. If you try to optimize the performance of an application during the initial construction you will add complexity that will impact the timely delivery and quality of the application and probably won’t help performance at all; in fact, it could actually reduce the performance (“faster” algorithms often have larger constant factors, meaning they are slower at small scale and only become more efficient at large scale). I’ve found that in most situations the simplest code is also the fastest. So, don’t worry about performance until the application is running; if it isn’t fast enough, then go in and carefully measure to figure out where the performance bottlenecks are (they are likely to be in places you wouldn’t have guessed). Tune only the places where you have measured that there is an issue.

Use your intuition to ask questions, not to answer them

Intuition is a wonderful thing. Once you have acquired knowledge and experience in an area, you start getting gut-level feelings about the right way to handle certain situations or problems, and these intuitions can save large amounts of time and effort. However, it’s easy to become overconfident and assume that your intuition is infallible, and this can lead to mistakes. So, I try to treat intuition as a hypothesis to be verified, not an edict to be followed blindly.

For example, intuition works great when tracking down bugs; if I get a sense for where I think the problem is I can quickly go to the code and verify whether this really is the problem. For more abstract tasks such as design I find that intuition can also be valuable (I get a vague sense that a particular approach is good or bad), but the intuition needs to be followed up with a lot of additional analysis to expose all the underlying factors and verify whether the intuition was correct. The intuition helps me to focus my analysis, but it doesn’t eliminate the need for analysis.

One area where people frequently misuse their intuition is performance analysis. Developers often jump to conclusions about the source of a performance problem and run off to make changes without making measurements to be sure that the intuition is correct (“Of course it’s the xyz that is slow”). More often than not they are wrong, and the change ends up making the system more complicated without fixing the problem.

Another reason for constantly challenging and validating your intuitions is that over time this will sharpen your intuitions so that they work even better for you. Ironically, people who are most dogmatic about their intuitions often seem to have least well-developed intuitions. If they would challenge their intuitions more, they would find that their intuitions become more accurate.

Facts precede concepts

A fact is a piece of information that can be observed or measured; a concept is a general rule that can be used to predict many facts or a solution to many problems. Concepts are powerful and valuable, and acquiring them is the goal of most learning processes. However, before you can appreciate or develop a concept you need to observe a large number of facts related to the concept. This has implications both for teaching and for working in unfamiliar areas.

In teaching it’s crucial to give lots of examples when introducing a new concept; otherwise the concept won’t make sense to the students. Edward Tufte describes this process as “general-specific-general“: start by explaining the concept, then give several specific examples to show where the concept does and does not apply, then reiterate the concept by showing how all the examples are related.

I also apply this principle when I’m working in a new area and trying to derive the underlying concepts for that area. Initially my goal is just to get experience (facts). Once I have a collection of facts to work from, then I start looking for patterns or themes; eventually these lead to concepts. For example, a few years ago I started working on my first large Web application. My goal was to develop a library of reusable classes on which to base the application, but being new to Web development I had no idea what those classes should be. So, I built the first simple version of the application without any shared code, creating each page separately. Once I had developed a dozen pages I was able to identify areas of functionality that were repeated over and over in different pages, and from this I was able to develop a set of classes that implemented the the shared functionality. These classes represented the key concepts of that particular application.

If you don’t know what the problem was, you haven’t fixed it

Here’s a scenario that I have seen over and over:

  • A developer is tracking down a difficult problem, often one that is not completely reproducible.
  • In a status meeting the developer announces that the problem has been fixed.
  • I ask “what was the cause of the problem?”.
  • The developer responds “I’m not really sure what the problem was, but I changed xyz and the problem went away.”

Nine times out of ten this approach doesn’t really fix the problem; it just submerges it (for example, the system timing might have changed so that the problem doesn’t happen as frequently). In a few weeks or months the problem will reappear. Don’t ever assume that a problem has been fixed until you can identify the exact lines of code that caused it and convince yourself that the particular code really explains the behavior you have seen. Ideally you should create a test case that reliably reproduces the problem, make your fix, and then use that test case to verify that the problem is gone.

If you do end up in a situation where you make a change and the problem mysteriously goes away, don’t stop there. Undo the change and see if the problem recurs. If it doesn’t, then the change is probably unrelated to the problem. If undoing the change causes the problem to recur, then figure out why. For example, try reducing the scope of the change to find the smallest possible modification that causes the problem to come and go. If this doesn’t identify the source of the problem, add additional tracing to the system and compare the “before” and “after” traces to see how the change affected the behavior of the system. In my experience, once I have a code change that makes a problem come and go I can always find the source of the problem fairly quickly.

If it hasn’t been used, it doesn’t work

This is one of the biggest frustrations of software development. You design and implement a new feature or application, you test it carefully, and you think you are done. Unfortunately you aren’t. No matter how carefully you have tested, there will be problems as soon as QA gets their hands on it or someone tries to use the feature or application for real work. Either there will be bugs that you missed, or some of the features will be clumsy, or additional features will be needed. Sometimes the entire architecture turns out to be wrong. Unfortunately, the problems come out at a time when you are ready to move on to the next thing (or perhaps you already have moved on), so it’s frustrating to go back and spend more time on a project that you thought was finished. And, of course, you didn’t budget time for this so the cleanup work causes delays in your next project.

I don’t know any solution to this problem except to realize its inevitability and plan for it. My rule of thumb is that when you think you are finished with a software project (coded, tested, and documented, and ready for QA or production use) you are really only 50-75% done. In other words, if you spent 3 months in initial construction, plan on spending another 4-8 weeks in follow-up work. One way to minimize this problem is to get your new software in use as soon as possible. If you can create a skeletal version that is still useful, get people trying it out so you can find out about problems before you think you’re finished. This is one of the ideas behind Agile Development.

Sometimes people just refuse to do the follow-up work: “It’s not my highest priority” or “I will get to it when I have time”. If you take this approach you’ll produce mediocre software. No software is ever gotten right the first time. The only way to produce high-quality software is to keep improving and improving it. There are 2 kinds of software in the world: software that starts out crappy and eventually becomes great, and software that starts out crappy and stays that way.

The only thing worse than a problem that happens all the time is a problem that doesn’t happen all the time

Not much to say about this one: it’s painful to debug a problem that isn’t reproducible. I have spent as long as 6 months tracking down a single nondeterministic bug. Conversely, in my experience any problem that can be easily reproduced can also be tracked down pretty quickly.

The three most powerful words for building credibility are “I don’t know”

Many people worry that not knowing something is a sign of weakness, and that if a leader seems not to have all the answers they will lose the confidence of their team. Such people try to pretend they have the answer in every situation, making things up if necessary and never admitting mistakes.

However, this approach ultimately backfires. Sooner or later people learn the truth and figure out that the person never admits when they don’t know. When this happens the person loses all credibility: no-one can tell whether the person is speaking from authority or making something up, so it isn’t safe to trust anything they say.

On the other hand, if you admit that you don’t know the answer, or that you made a mistake, you build credibility. People are more likely to trust you when you say that you do have the answer, because they have seen that you don’t make things up.

Coherent systems are inherently unstable

A coherent system is one where everything is the same in some respect; the more things that are uniform or shared, the more coherent the system is. For example, a typical cornfield in Iowa is highly coherent: every corn stalk is from the same strain; they’re all planted at the same time, fertilized at the same time, and harvested at the same time. The world of computing is also fairly coherent: most of the world’s computers run one of a few versions of Windows, and almost any computer in the world can be reached using the IP/TCP protocol. Human-engineered systems tend to be coherent.

Natural systems tend not to be coherent. For example, consider the ecosystem of a wetland: there are numerous different species of plant and animal sharing the same area, but behaving very differently with complex interrelationships. The behavior of the overall system is hard to predict from the behavior of any individual in it.

Coherent systems often have advantages of efficiency, which is why humans gravitate towards them. For example, it’s easier to plant the same seed everywhere in a cornfield, and given that some seeds are better than others, it’s more efficient to use the best seed everywhere. It’s also easier to harvest if all of the corn ripens at the same time. It’s more efficient to have a single operating system running most of the world’s computers: once a new facility is implemented for that system, everyone in the world can benefit from it. If there were dozens of different operating systems, then new applications would have to be reimplemented for each of them.

Unfortunately, coherent systems are unstable: if a problem arises it can wipe out the whole system very quickly. For example, a new plant disease could quickly take out a large fraction of U.S. grain production. Computer viruses are another example: a virus that takes advantage of a bug in Windows can potentially impact most of the world’s computers. The U.S. stock market exhibits a certain degree of coherency in the way people think and trade, which results in huge swings up and down as investors move en masse to buy the latest fad or sell when a recession looms.

The incoherence of natural systems give them greater stability. For example, a particular plant disease could probably only affect a small fraction of the species in a wetland.

SSO Integration with J2EE application deployed on 11g WebLogic Server(Part 2)

In the previous post, we went through the structure of the integration and the procedure of installing oracle web tier. Now we are going to review the configuration of SSO Integration with J2EE application.


       I assume you have deployed your J2EE applicaiton onto webLogic server and it could be reached by the link:

       (Suppose your J2EE application is deployed on to Admin Server, by default the port number is 7001.)


       Note: Port number would be vary if you deploy J2EE application on to managed server. For more information about this, you should check the following posts:

        Deploy application to Managed Server on 11g WebLogic Server (Part 1)

        Deploy application to Managed Server on 11g WebLogic Server (Part 2)


     The following solution is basically a summary from oracle document: (If you would like a more detailed explanation of what and why)

     For how to install oracle web tier, check previous post:

     SSO Integration with J2EE application deployed on 11g WebLogic Server(Part 1)


        J2EE Application Code Change

          The idea is to enable the fuctionality of enabling OID users login into your J2EE application directly.

        Set up mod_osso

          Find the mod_wl_ohs.conf. This file should reside under the following directory:


          The following code snippet comes from mod_wl_ohs.conf file.


          Modify the line marked in red. Uncomment the line starting with “MatchExpression…” to below 


Restart ohs1 after editing:

cd /Oracle_WT1/opmn/bin

opmnctl stopall

opmnctl startall

       Registering Oracle HTTP Server mod_osso with OSSO Server 10.1.4      

The mod_osso module is an Oracle HTTP Server module that provides authentication to OracleAS applications. This module resides on the Oracle HTTP Server that enables applications protected by OracleAS Single Sign-On to accept HTTP headers in lieu of a user name and password once the user has logged into the OracleAS Single Sign-On server. The values for these headers are stored in a mod_osso cookie. The mod_osso module enables single sign-on for Oracle HTTP Server by examining incoming requests and determining whether the requested resource is protected. If it is, then it retrieves the Oracle HTTP Server cookie. Under certain circumstances, you must register Oracle HTTP Server mod_osso using the 10.1.4 Oracle Identity Manager single sign-on registration tool .

To register mod_osso:

   Go to the following 10.1.4 Oracle Identity Manager directory path: (This could be your OSSO server)


  Run ssoreg with the following parameters and values for your environment:

             ./ -oracle_home_path $ORACLE_HOME -config_mod_osso TRUE -site_name <host_name>:7777 -remote_midtier -config_file $ORACLE_HOME/osso.conf -mod_osso_url http://<host_name>:7777

      (Note: the osso.conf would be generated under specified directory: $ORACLE_HOME/osso.conf)

  Ftp osso.conf file from the directory above to the application server where web tier is installed.

              Put osso.conf under directory: (Note: create directory osso if it does not exist)


 Copy mod_osso.conf from disabled directory to the moduleconf directory for editing.

              From directory:


             To directory:


      The orignial mod_osso.conf file should look like :


      Modify the red line and add the corresponding code into this file. It should look like :


Note: Httpd.conf for Oracle http server 11g is not in need for further modification, for it has already included the following:


Restart ohs1 after editing:

cd /Oracle_WT1/opmn/bin

opmnctl stopall

opmnctl startall

         To be Continued with:

                SSO Integration with J2EE application deployed on 11g WebLogic Server(Part 3)

SSO Integration with J2EE application deployed on 11g WebLogic Server(Part 1)

Previously, we talked about how to deploy our J2EE web application on to oracle 11g weblogic server. With the upcoming need of SSO integration, our goal becomes to enable SSO functionality on weblogic server and secure our application access by going through portal page and then getting user authentication through LDAP server with the OID repository.

I have successfully implemented the solution on SSO integration within Oracle 10g Applicaiton Server(OAS). The idea is quite simliar since we are still using 10g portal page. However, oracle 11g enterprise edition has replaced the OAS with weblogic server which introduces quite a few changes for the SSO integration on weblogic server. I would break into a few posts on elaborating this idea. If you are not familar with SSO(Single Sign On) with oracle 10g OAS, please refer to the following link to get a basic understanding of what and why: (The following link shows a basic work-though of 10g SSO. Our new approach would inherit a lot of similar ideas from the old approach.It would be easier to understand this current post if you have the history knowledge)

Now I assume if you have already knew a few concepts of mod_osso, OID registration,httpd.conf file. Then let us firstly start with reviewing application architecture with the SSO integration. 

The architure of the whole process looks like below.


Now our application is deployed on weblogic server. So right now besides the installation of Business Intelligence SUITE, we also need to install Oracle Web Tier.


  •       Oracle Buisiness intelligence 11g is installed
  •       OR Oracle Web Logic Server is installed

Note: If you have only installed oracle web logic server, be sure to enable JRF manually as below. Oracle Web Tier installation requires Oracle WSM Policy Manager and JRF(Java Required Files) and they do not display by default in the Oracle Fusion  Middleware Configuration Wizard. You must enable the display of these products. To accomplish this, pass the following JVM property to the script:


To pass this property to the script, set the CONFIG_JVM_ARGS environment variable to -DTemplateCatalog.enable.selectable.all=true. The script takes this property when you start the Oracle Fusion Middleware Configuration Wizard using./ .

cd /wlserver_10.3/common/bin

 ./ -DTemplateCatalog.enable.selectable.all=true


Download oracle web tier package and unzip the file. You should find Disk1 within the unziped file folder. Go under Disk1 and run ./runInstaller

Click and Next and then skip the software updates and then continue to check the prerequisite(Keep the default options)

Oracle web tier would be installed under fushion middleware home. So you should make sure you enter the correct FM home.

Uncheck the box to proceed.

It is not neccessary to install web cache if you don’t need to do performance tuning. That is optional.

Enter your domain settings as below:

It will dynamically load the instance home and you just proceed.

Skip the below step if you didn’t install web cache.

Choose Auto Port Configuration.

Check if everything looks right and then install the software.

Wait until it gets successfully finished.

Once web tier has been installed. You could check the status on em to see if it keeps up and running.

 To be continued to :

SSO Integration with J2EE application deployed on 11g WebLogic Server(Part 2)

Scar Tissues Make Relationships Wear Out

CS140, 04/26/2012
From a lecture by Professor John Ousterhout.

This is my most touchy-feely thought for the weekend. Here’s the basic idea: It’s really hard to build relationships that last for a long time. If you haven’t discovered this, you will discover this sooner or later. And it’s hard both for personal relationships and for business relationships. And to me, it’s pretty amazing that two people can stay married for 25 years without killing each other.

But honestly, most professional relationships don’t last anywhere near that long. The best bands always seem to break up after 2 or 3 years. And business partnerships fall apart, and there’s all these problems in these relationships that just don’t last. So, why is that? Well, in my view, it’s relationships don’t fail because there some single catastrophic event to destroy them, although often there is a single catastrophic event around the the end of the relationship, but that’s typically a symptom rather than a cause. What typically happens is it accumulates in the little things that just build up over time, and I call those scar tissues. And the reason I use the phrase “scar tissues” is because scar tissue is when you have a wound that doesn’t heal quite properly and you get this other tissue that just sort of fills the gap, which is called scar tissue, and that tissue is not as strong as the original tissue that was there. So, scar tissue is weak. So, what happens in relationships is that sooner or later, there’s a conflict. It happens in all relationships and not all of them get resolved perfectly. So, now somebody’s left feeling just a little bit unhappy about the result, mostly okay but just a little bit unhappy. But then it happens again… and it happens again in a different situation and no one of these is enough to kill the relationship, but over time that annoyance just builds up more and more and more and more, and then people start seeing patterns in behavior. You know if you ever hear the phrase “You always X”: scar tissue.

So people start becoming sensitive and then they expect the bad behavior and there’s nothing more guaranteed to create bad behavior than expectation. You will find it if you see it. And so eventually it just gets worse and worse and worse and worse, and then somebody decides they just don’t care anymore and typically that’s the point where something spectacular happens and the relationship collapses. And people often think it was the spectacular thing that wrecked the relationship, but really it was all those little bits of scar tissue building up over months or years. And my opinion is that in most of these situations the people aren’t fundamentally bad, though they often appear bad, typically at the spectacular end phase of the relationship. It’s just that the relationship wore off. Just wore off: too much scar tissue.

So, I’ll give you an example of a relationship of mine that wore off. So, we had our house remodeled a couple years ago. Major remodeling of our kitchen and family room, and the foreman for the contractor, Jim, was in our house for every day for about 4 months during the work on the job. And it started off and things were fine, but then there were just little things that started happening. Like he wouldn’t seal up the plastic around the kitchen, and so, dust would get in to the rest of the house. And most of the work he did was really great, but if he ever made a mistake he wouldn’t want to admit it; he would kinda make excuses to try to avoid fixing his mistake, and this just got more and more annoying for me. And I’m sure I did my share in return because I’m sort of a perfectionist, and I probably noticed every little thing he did that wasn’t absolutely perfect, and it probably drove him crazy that every morning when he came in, I was there standing in the kitchen ready to tell him about all the mistakes he made yesterday [Laughter], and so it just got worse and worse and worse to the point where we were barely on speaking terms at the end of the project, and one day our daughter came in, and she was like, “Dad I think your relationship with Jim is wearing out,” [Laughter] which was when I realized I shouldn’t be telling her my theories about relationships.

Now, I could have sat down with Jim to try to work it out, but I decided since it was only a 4 month contracting job, I’ll just put up with it, and you know, it’ll be done in a while. He would have been pretty worried if we sat down and I was like, “Jim, can we talk [Laughter] about my feelings? I mean you left the plastic open and dust got into the house, and sometimes I feel like you don’t respect me as a person.”

Now maybe if I tried that he would instantly change his behavior just to make sure we never, ever had to have a conversation again. [Laughter] So, the solution is if you want a relationship to last a long time, somehow you have to keep the scar tissue from building up. And that’s really hard. So, when there’s an issue, you somehow have to resolve it where there is zero lingering animosity. Nobody is even a little bit upset. Because even a little upset, that scar tissue that accumulates, that never goes away. And that’s really hard to do; I don’t have any perfect answers for that; it’s communication and compromise. Both people need to be willing to listen to understand the other person’s view and then you have to find some compromise where everybody agrees that’s a fair trade off so nobody’s upset. So, that’s really hard, and if either person can’t listen or can’t compromise, the odds are not good long term for that relationship. But there are classic mistakes people make. Like, some people are just too nice, and they wreck the relationships. They think, “Oh, it’s not a big deal, it’s just one little thing, not worth having a big argument about it. I’ll just give in.” Well, that seems generous, but it’s a really bad idea. You have to ask yourself, “Are you really, completely, 100% over this? You’re giving in? No animosity? You’re not secretly hoping that maybe they’ll do something for you in return or a little behavior change here or there?”

Because if there’s anything at all when you’re giving in that you can feel bad about later, you’re nuking the relationship – you’re creating scar tissue with yourself, and that will build up to the point where you wreck the relationship. And the flipside is also bad. You may think, “I’m such a good arguer, I can just argue this person to death, and whatever they want I can just outargue them: I’ll yell louder with more words, and I’ll get my way. Whew! That was a great, great resolution, I got my way.” Well, you’re nuking the relationship, sorry. So, somehow both people have to be completely satisfied with the outcome. So, the irony of this is, I think it’s not the big things that nuke relationships it’s all those little things. Even if there’s a big thing, the relationship was going to die really soon anyway. So, just think about your relationship experience and the people around you. How many of you have either had a relationship that wore out like this or you’ve seen somebody around you and you could see their relationship wearing out?

Yeah, it happens to everybody and we’ve all been there. And the trick is, again, you just have to avoid the creation of scar tissue. Not easy, but it’s the only solution. Okay, that’s my thought for the weekend