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 : https://www.baeldung.com/spring-profiles

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.

<profiles>
<profile>
<id>dev</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<properties>
<activeProfile>dev</activeProfile>
</properties>
<build>
<directory>target/dev</directory>
</build>
</profile>
<profile>
<id>prod</id>
<properties>
<activeProfile>prod</activeProfile>
</properties>
<build>
<directory>target/prod</directory>
</build>
</profile>
</profiles>

Step 2 Enable resource filtering in pom.xml

Note: Spring provides spring.profiles.active 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 application.properties 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 application.properties under “src/main/resources” directory. Add the following line into your application.properties file. (Here we use the placeholder activeProfile to get value populated to spring.profiles.active when maven build the project).

spring.profiles.active=@activeProfile@

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:

<build>
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
<targetPath>WEB-INF</targetPath>
</resource>
</resources>

</build>

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 application.properties, the line above becomes

spring.profiles.active=dev

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

Learn more about the resource filtering over here:https://maven.apache.org/plugins/maven-resources-plugin/examples/filter.html

Step 3 Use spring.profiles.active 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 spring.profiles.active property from application.properties 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 application.properties. However, if you are not using spring boot, in your Java config file, specify the property file as this:

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

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

  1. Use environment variable

@Autowired

private Environment env;

In the actual logic, simply use like this:

if( env.getProperty(“spring.profiles.active”).equals(“dev”) ) …

2. Use @Value notation.

@Value(“${spring.profiles.active}”)
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 ${spring.profiles.active} 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:

@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: https://www.baeldung.com/properties-with-spring

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 spring.profiles.active 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 🙂

Advertisements

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

If you have finished setting up the managed server in the last blog post, you might run into a sip server error while starting the server as below:

Refer to Deploy application to Managed Server on 11g WebLogic Server (Part 1) if you need to catch up on the topic.

Error Code:”Parsing Failure in config.xml: java.lang.AssertionError: java.lang.ClassNotFoundException: com.bea.wcp.sip.management.descriptor.beans.SipServerBean

The reason why you can not start the managed server Server-1 is that the com.bea.wcp.sip.management.descriptor.beans.SipServerBean is not in classpath yet. Go to $WL_HOME/common/nodemanger and edit the file nodemanager.properties and set the variable StartScriptEnabled=true instead of the default false. Restart nodemanger and weblogic server. After that, you could successfully start the new mangerd server.

Deploy an application on to the managed server.

Click on Deployments under base_domain and then click Install under the Deployments table.

Specify the path where your deployment file would locate and then click next.

On the next page choose: Install this deployment as an application and then click next.

Now it comes to the page where we can choose our target server to deploy on. Here we choose Server-1.

I will go by defaults on the next two pages and then click Finish. You could adjust a bit according to different environments. 

After the new application is deployed, we could go back to Deployments table and check the state of the new application. If it were a successful deployment, the state should turn to be Active. Now it shows Failed meaning something is wrong during the deployment.

By looking at the log files, either nohup.out or Server-1.out,you might find similar errors like this:

Error Code:”Invocation of init method failed; nested exception is javax.persistence.PersistenceException: [PersistenceUnit: btm] Unable to build EntityManagerFactory

This is caused by NOTenabling JPA 2.0. My newapp needs to be running on top of three extra library files:hibernate-jpa-2.0-api-1.0.0.Final.jar,antlr-2.7.6.jar,commons-lang-2.4.jar. I will firstly copy these three jar files to $WL_HOME/common/lib/.In order to include them on to my managed Server Server-1, there are two ways to do that.

 Method 1

   Set the PRE_CLASSPATH to load extra jar files

   There are two places to set the PRE_CLASSPATH, which you have to take into consideration. If you only want to enable those library files on to your managed server, in my case Server-1, then just set the PRE_CLASSPATH in commEnv.sh which is under the directory:

$WL_HOME/common/bin

Insert the following statements into your commEnv.sh.

PRE_CLASSPATH=$WL_HOME/common/lib/hibernate-jpa-2.0-api-1.0.0.Final.jar: $WL_HOME /raid/middleware/wlserver_10.3/common/lib/antlr-2.7.6.jar: $WL_HOME /raid/middleware/wlserver_10.3/common/lib/commons-lang-2.4.jar

Export PRE_CLASSPATH

Note: If you also want to deploy your application on to AdminServer. You also need to set the same PRE_CLASSPATH in startWebLogic.sh under:

$DOMAIN_HOME/startWebLogic.sh

   Set your managed server staging mode to be nostage

After you restert the managed server, you would see the status of the newly deployed application should automatically change to Active.

 Method 2

By setting up the PRE_CLASSPATH in commEnv.sh, that could include all the library files in it for any managed server you created. Suppose you need a more flexible and server-oriented method that for different managed server, you could include different library files. Instead of throwing all necessary library files in to PRE_CLASSPATH, you could also set the boot path. Let us talk about how to do that from frontend.

Go to the servers table and click on the managed server you just created.

It will take you to the settings for your newly created managed server, in this case “Server-1”. Go to Configuration->Server Start. Scroll down to the field of arguments. That is where you will put your path of your library files.

The arguments should look like below:

-Xbootclasspath/p:$WL_HOME/common/lib/hibernate-jpa-2.0-api-1.0.0.Final.jar: $WL_HOME /common/lib/antlr-2.7.6.jar: $WL_HOME /common/lib/commons-lang-2.4.jar

By adding bootclasspath, JVM would load these files with a bootstrap classloader, which is separate from the system class loader. In this case before JVM even looks at the user defined CLASSPATH, those jar files mentioned in the bootclasspath would have already been loaded.

This method also requires the server staging mode being specified as nostage.

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

This post is about the experiments I have done with 11g WebLogic Server recently. I was trying to deploy an web application on to a managed server instead of the default AdminServer. The main purpose is to have my web application deployed on to multiple servers that could be managed separately. I would break this topic into several blog posts in order to document as many pitfalls I have fell into for a better knowledge share. During the experiment, I ‘ve encountered with different types of failures that contained a lot clues which finally led me to the right path to a successfull deployment. Let us firstly start with some basic concepts of the terminologies involved and after that we would talk about more hands-on experience with it.

Kumar has this great post below to discuss the concepts briefly and clearly enough. Take a look at this post firstly if you want to kind of understand why we would configure the way as below:

  http://onlineappsdba.com/index.php/2008/07/24/domain-administration-managed-server-cluster-in-oracle-weblogic/

Create a new Managed Server on 11g WebLogic Server.

Firstly, log on to Administration Console. And then go to Servers under base_domain->Environments. Click on New at the servers table to create a new managed server.

Since AdminServer is taking the port 7001. I now switch to 7002

Then click Finish!! So now I have built one managed Server called Server-1 and I am trying to start the server. You might run into warning messages like below:

This message literally says you should associate the newly created managed server Server-1 with a physical machine and also reminds you that you have to start your Node Manager as well. So let us start with creating a physical machine and then associate the server with it.

Create a new physical Machine on 11g WebLogic Server.

Navigate back from the left panel which is under base_domain, click Machines.

Click New to add a new physical machine.

Fill in the information according to your platform. I call it Machine-1 for an example.

Enter the Listen Address.Mine is just the localhost. And then click Finish.

 

Now we have a physical machine ready to use.

Since Machine-1 is created successfully. And we are going to associate this physical machine to Server-1. Go back to Servers and click on the name Server-1 under servers table.

Now you would see Machine-1 in the drop down list and click on it to apply the machine. Navigate down to the bottom and click Save.

Go back to servers table and you would see the machine applied to the newly created managed server in the table.

Now we need to start Node Manager. Go to the terminal and access the path below:

$WL_HOME/server/bin

nohup ./startNodeManager &

Once the node manger is started and we could go back to frontend and start Server-1

 To be continued with problems starting Server-1 caused by sip server errors

[java.daily.notes]Use Firebug to debug Javascript on the fly

Step 1. You should have firefox browser handy. If not, you could download one from :

        http://www.mozilla.org/products/download.html?product=firefox-11.0&os=win&lang=en-US

Step 2. Once you get your firefox browser, you could then download firebug within the browser.

       Open Firefox browser and go to Tools-> Options

      

 

       Go to General and then click Manage Add-ons

    

      Look for firebug in the search criteria. And then click Install besides the plugin.

   Step 3.  Now you have firebug installed, you could start using firebug to debug the Javascript. You could find a small icon aside on the right corner of the browser and once you click that button, the firebug is invoked . However you could only debug one Javascript a time for one session.

       

   Normally firebug would show up at the bottom. When you choose Script, you have to click the blue link : Enable

 

    Now click Reload

   

 

     Say I navigate to the Javascript for senstive area that I would assume where a problem would be. And put the breakpoints on the left like below: You now see the buttons on the upper right corner are still greyed out because you have not invoke anything on the current web page.

  And when you invoke the corresponding fields on the webpage. It dynamically breaks to the line you set the breakpointes. Now you are ready to debug the Javascript step by step by clicking on the buttons on upper right corner.

      Like most of the debug tools. You could do mouse over to a perticular variable and you could validate from there and on the right panel. You could add or remove breakpoints and  watch the values of different variables. It is super useful for Javascript coders.

     Have fun and this is end of Instructions.Yay!!