Showing posts with label WSO2. Show all posts
Showing posts with label WSO2. Show all posts

Saturday, August 29, 2015

How to expose SOAP services as SOAP services via WSO2 API Manager?

Exposing SOAP services is well supported by WSO2 ESB. However, if you would like to have features such as design & prototype APIs, publish & govern API use, control access & enforce security, create a store where anyone can come, play around & subscribe to APIs, manage developer community and monitor API usage etc, then WSO2 API Manager is the ideal product. See here for a complete set of features offered by WSO2 API Manager.

In this post, we will see how you can expose a SOAP service as a SOAP service via WSO2 API Manager 1.9.0.

1. If you don't have any SOAP service, find a public SOAP service in http://www.service-repository.com

2. In this post, we will use StockQuote SOAP service from the above public service repository. Below are the details we should have in order to publish a SOAP service via WSO2 API Manager.

StockQuote SOAP WSDL - http://www.webservicex.com/stockquote.asmx?WSDL
StockQuote SOAP Endpoint - http://www.webservicex.com/stockquote.asmx

3. Download WSO2 API Manager 1.9.0 or latest version from here and start it. If you are new to WSO2 API Manager, visit the quick start guide. 

4. Login to API Publisher (https://localhost:9443/publisher)



5. Click on "Add" under "APIs" from the left menu



6. Click on "I have a SOAP Endpoint" option, provide your WSDL URL and click on "Start Creating"



7. In the "Design API" page, fill in the general details and click on "Next: Implement"



8. Click on "Managed API".



9. Fill in "Production Endpoint" and "Sandbox Endpoint" and click on "Next: Manage". If your endpoint is secured, have a look at this to learn how to configure a secured backend endpoint in WSO2 API Manager.



10. Select "Tier Availability" and "Transports" under "Configurations" and click "Save & Publish". You have now successfully published a SOAP service as a SOAP service via WSO2 API Manager.



11. Login to API Store (https://localhost:9443/store)


12. Click on your API and you will see a WSDL is published under "Overview" space of the API. Click "Download WSDL" and save it in your machine. Later we will use SoapUI to load this WSDL and invoke the API.



13.  Subscribe to the API using one of your Application and go to "My Subscriptions" page.



14. Click on "Generate keys" to generate consumer key & secret and access token. You will need this access token to invoke the API unless you have disable security to your API when publishing the API. See here to learn how to do that.



15. Create a new SOAP project in SoapUI using the WSDL you have downloaded in step 12.

16. Send a request and you will get following error. Reason is you haven't sent the access token as a bearer token when invoking the API.



17. Add a header "Authorization" and set the value as "Bearer #access-token". Replace #access-token with the access token you generated step 14.




18. Send the request and you will get the response.



As you can see, it is very straightforward to expose a SOAP service as a SOAP service via API Manager.

Saturday, August 15, 2015

WSO2 ESB - How to check whether a string is encoded or not?

The following sample demonstrate how to encode a string in WSO2 ESB and how to check whether a string is encoded or not.

<property name="string" value="abcd"/>
<property name="encodedString" expression="base64Encode('abcd')"/>
<log level="custom">
  <property name="encodedString" expression="get-property('encodedString')"/>
</log>
<filter source="get-property('encodedString')"
     regex="^([A-Za-z0-9+/]{4})*([A-Za-z0-9+/]{4}|[A-Za-z0-9+/]{3}=|[A-Za-z0-9+/]{2}==)$">
  <then>
     <log level="custom">
        <property name="encoded?" value="yes"/>
     </log>
  </then>
  <else>
     <log level="custom">
        <property name="encoded?" value="no"/>
     </log>
  </else>
</filter>

This is based on the regular expression given here to check whether a string is encoded or not.

Tuesday, July 14, 2015

WSO2 API Manager - Using Custom Handler or Mediation Extensions for Message Transformation?

Custom Handlers and Mediation Extensions are some of the extension points which you can use to extend the functionality of WSO2 API Manager. When it comes to message transformation, it is recommended to use Mediation Extensions over Custom Handlers due to following reasons.

  • If you want to engage a custom handler to all of your APIs, then you need to add it to all the APIs manually unless you modify velocity_template.xml to include the custom handler. If you are changing velocity_template.xml, then already published APIs won't have any impact. You need to republish those APIs to get the effect. On the other hand, if you copy a global mediation extension into AM, it will be engaged with all the APIs immediately.
  • If you decided not to do the transformation, then reverting changes is just a matter of removing mediation extensions from AM. On the other hand, if you are using a custom handler, then you have to remove the custom handler from all the APIs manually. Or else, you need to modify the velocity_template.xml and need to republish all your APIs.
  • If you are using a custom handler, it will be a maintenance overhead when it comes migration and all. If you are migrating, then you need to rebuild your custom handler with correct dependencies.
However, there might be some situations where we can't actually implement our usecase using inbuilt features. Then we should definitely go for a custom handler. For example, DBLookup mediator won't return multiple rows. Hence, while message transformation, if you want to retrieve multiple rows from the database, then you need to go for a custom handler.

As you can see, choice depends on many factors. As a simple rule, we need to use the mediation extensions wherever possible for message transformations within API Manager.

Friday, June 26, 2015

WSO2 ESB - How to print the current thread id in proxy?

You might want to print the current thread id for testing purposes in WSO2 ESB. It might be useful in cases where you want to make sure that the same thread is used for all the operations and no new threads were created. You can add following script mediator in your proxy to print the current thread id.
    <script language="js">java.lang.System.out.println(java.lang.Thread.currentThread().getId());</script>

WSO2 ESB - How to put the current thread into sleep in proxy?

You can add the following script mediator in your proxy to sleep the current thread.
    <script language="js">java.lang.Thread.sleep(10000);</script>

Tuesday, June 23, 2015

WSO2 Carbon Sever Startup Exception - Failed to activate Carbon Application Deployer

You might get the following exception while starting any WSO2 Carbon Server.

TID: [0] [IS] [2015-06-17 16:33:07,706] ERROR
{org.wso2.carbon.application.deployer.internal.AppDeployerServiceComponent} - Failed to activate Carbon Application Deployer {org.wso2.carbon.application.deployer.internal.AppDeployerServiceComponent} java.lang.ExceptionInInitializerError
at org.wso2.carbon.application.deployer.internal.ApplicationManager.findInitialHandlerCount(ApplicationManager.java:765)
at org.wso2.carbon.application.deployer.internal.ApplicationManager.init(ApplicationManager.java:107)
at org.wso2.carbon.application.deployer.internal.AppDeployerServiceComponent.activate(AppDeployerServiceComponent.java:77)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at org.eclipse.equinox.internal.ds.model.ServiceComponent.activate(ServiceComponent.java:260)
at org.eclipse.equinox.internal.ds.model.ServiceComponentProp.activate(ServiceComponentProp.java:146)
at org.eclipse.equinox.internal.ds.model.ServiceComponentProp.build(ServiceComponentProp.java:347)
at org.eclipse.equinox.internal.ds.InstanceProcess.buildComponent(InstanceProcess.java:620)
at org.eclipse.equinox.internal.ds.InstanceProcess.buildComponents(InstanceProcess.java:197)
at org.eclipse.equinox.internal.ds.Resolver.getEligible(Resolver.java:343)
at org.eclipse.equinox.internal.ds.SCRManager.serviceChanged(SCRManager.java:222)
at org.eclipse.osgi.internal.serviceregistry.FilteredServiceListener.serviceChanged(FilteredServiceListener.java:107)
at org.eclipse.osgi.framework.internal.core.BundleContextImpl.dispatchEvent(BundleContextImpl.java:861)
at org.eclipse.osgi.framework.eventmgr.EventManager.dispatchEvent(EventManager.java:230)
at org.eclipse.osgi.framework.eventmgr.ListenerQueue.dispatchEventSynchronous(ListenerQueue.java:148)
at org.eclipse.osgi.internal.serviceregistry.ServiceRegistry.publishServiceEventPrivileged(ServiceRegistry.java:819)
at org.eclipse.osgi.internal.serviceregistry.ServiceRegistry.publishServiceEvent(ServiceRegistry.java:771)
at org.eclipse.osgi.internal.serviceregistry.ServiceRegistrationImpl.register(ServiceRegistrationImpl.java:130)
at org.eclipse.osgi.internal.serviceregistry.ServiceRegistry.registerService(ServiceRegistry.java:214)
at org.eclipse.osgi.framework.internal.core.BundleContextImpl.registerService(BundleContextImpl.java:433)
at org.eclipse.osgi.framework.internal.core.BundleContextImpl.registerService(BundleContextImpl.java:451)
at org.wso2.carbon.core.init.CarbonServerManager.initializeCarbon(CarbonServerManager.java:517)
at org.wso2.carbon.core.init.CarbonServerManager.start(CarbonServerManager.java:219)
at org.wso2.carbon.core.internal.CarbonCoreServiceComponent.activate(CarbonCoreServiceComponent.java:77)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at org.eclipse.equinox.internal.ds.model.ServiceComponent.activate(ServiceComponent.java:260)
at org.eclipse.equinox.internal.ds.model.ServiceComponentProp.activate(ServiceComponentProp.java:146)
at org.eclipse.equinox.internal.ds.model.ServiceComponentProp.build(ServiceComponentProp.java:347)
at org.eclipse.equinox.internal.ds.InstanceProcess.buildComponent(InstanceProcess.java:620)
at org.eclipse.equinox.internal.ds.InstanceProcess.buildComponents(InstanceProcess.java:197)
at org.eclipse.equinox.internal.ds.Resolver.getEligible(Resolver.java:343)
at org.eclipse.equinox.internal.ds.SCRManager.serviceChanged(SCRManager.java:222)
at org.eclipse.osgi.internal.serviceregistry.FilteredServiceListener.serviceChanged(FilteredServiceListener.java:107)
at org.eclipse.osgi.framework.internal.core.BundleContextImpl.dispatchEvent(BundleContextImpl.java:861)
at org.eclipse.osgi.framework.eventmgr.EventManager.dispatchEvent(EventManager.java:230)
at org.eclipse.osgi.framework.eventmgr.ListenerQueue.dispatchEventSynchronous(ListenerQueue.java:148)
at org.eclipse.osgi.internal.serviceregistry.ServiceRegistry.publishServiceEventPrivileged(ServiceRegistry.java:819)
at org.eclipse.osgi.internal.serviceregistry.ServiceRegistry.publishServiceEvent(ServiceRegistry.java:771)
at org.eclipse.osgi.internal.serviceregistry.ServiceRegistrationImpl.register(ServiceRegistrationImpl.java:130)
at org.eclipse.osgi.internal.serviceregistry.ServiceRegistry.registerService(ServiceRegistry.java:214)
at org.eclipse.osgi.framework.internal.core.BundleContextImpl.registerService(BundleContextImpl.java:433)
at org.eclipse.equinox.http.servlet.internal.Activator.registerHttpService(Activator.java:81)
at org.eclipse.equinox.http.servlet.internal.Activator.addProxyServlet(Activator.java:60)
at org.eclipse.equinox.http.servlet.internal.ProxyServlet.init(ProxyServlet.java:40)
at org.wso2.carbon.tomcat.ext.servlet.DelegationServlet.init(DelegationServlet.java:38)
at org.apache.catalina.core.StandardWrapper.initServlet(StandardWrapper.java:1267)
at org.apache.catalina.core.StandardWrapper.loadServlet(StandardWrapper.java:1186)
at org.apache.catalina.core.StandardWrapper.load(StandardWrapper.java:1081)
at org.apache.catalina.core.StandardContext.loadOnStartup(StandardContext.java:5027)
at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5314)
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150)
at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1559)
at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1549)
at java.util.concurrent.FutureTask.run(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)
Caused by: java.lang.NullPointerException
at org.wso2.carbon.application.deployer.AppDeployerUtils.createDir(AppDeployerUtils.java:713)
at org.wso2.carbon.application.deployer.AppDeployerUtils.(AppDeployerUtils.java:77)
... 63 more

Here is the reason why this exception can be thrown and how to solve it.


At the startup of a Carbon Server (ESB, IS, APIM, etc), it creates a directory named "work" under the location "$CARBON_HOME/repository/carbonapps/". We will see the above exception, if it fails to create this particular directory at the startup. There can be several reason for this. Some of them are,
  • It could be a permission issue in the file system. To solve it, change the permission.
  • It could be because the "$CARBON_HOME/repository/carbonapps/" directory does not exist. It can happen with some unzipping tools as they don't extract recursive empty folders. The carbonapps folder is an empty folder which is included in any Carbon Server pack by default. You can either create this directory manually or use a correct unzipping tools to solve this issue.
 Double checking above two things will probably solve this issue.

WSO2 ESB - Dynamic JMS Endpoint

Address endpoint doesn't support dynamic endpoints. Hence if you want to have dynamic endpoint for your JMS queue, you can use default endpoint together with a "To" header which you can set dynamically. Here is a sample JMS proxy.

<proxy xmlns="http://ws.apache.org/ns/synapse"
       name="StockQuoteProxy"
       transports="http"
       statistics="disable"
       trace="disable"
       startOnLoad="true">
   <target>
      <inSequence>
         <property name="OUT_ONLY" value="true"/>
         <property name="sendToThisQueue" value="SimpleStockQuoteService"/>
         <header name="To"
                 expression="fn:concat('jms:/', get-property('sendToThisQueue'), '?transport.jms.ConnectionFactoryJNDIName=QueueConnectionFactory&amp;java.naming.factory.initial=org.apache.activemq.jndi.ActiveMQInitialContextFactory&amp;java.naming.provider.url=tcp://localhost:61616')"/>
         <send>
            <endpoint name="dynamicQueue">
               <default>
                  <timeout>
                     <duration>300000</duration>
                     <responseAction>fault</responseAction>
                  </timeout>
                  <suspendOnFailure>
                     <errorCodes>-1</errorCodes>
                     <initialDuration>0</initialDuration>
                     <progressionFactor>1.0</progressionFactor>
                     <maximumDuration>0</maximumDuration>
                  </suspendOnFailure>
                  <markForSuspension>
                     <errorCodes>-1</errorCodes>
                  </markForSuspension>
               </default>
            </endpoint>
         </send>
      </inSequence>
      <outSequence>
         <send/>
      </outSequence>
   </target>
   <publishWSDL uri="file:repository/samples/resources/proxy/sample_proxy_1.wsdl"/>
   <description/>
</proxy>          


The idea behind is that you can set "To" header dynamically and the default endpoint will send the messages out to the endpoint found in "To" header.

Wednesday, December 10, 2014

Capturing/Decoding messages with JWT using wire logs in WSO2 API Manager 1.7.0

This is intended for the users who have configured WSO2 API Manager 1.7.0 with JWT and wants to see the messages with JWT. If you haven’t configured it, please refer this

1. Enable debug logs for the following loggers in WSO2APIM_HOME/repository/conf/log4j.properties file 

       log4j.category.org.apache.synapse.transport.nhttp.wire=DEBUG

       log4j.category.org.apache.synapse.transport=DEBUG

2. Restart the WSO2 API Manager if already started

3. Access your API and have a look at carbon logs

4. You will get something similar to the following log

[2014-11-30 22:09:22,610] DEBUG - headers http-outgoing-2 >> X-JWT-Assertion: eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsIng1dCI6Ik5tSm1PR1V4TXpabFlqTTJaRFJoTlRabFlUQTF
ZemRoWlRSaU9XRTBOV0kyTTJKbU9UYzFaQT09In0=.eyJpc3MiOiJ3c28yLm9yZy9wcm9kdWN0cy
9hbSIsImV4cCI6MTQxNzM2NjQ2MTk5OCwiaHR0cDovL3dzbzIub3JnL2NsYWltcy9zdWJzY3JpYmV
yIjoicmFqa3VtYXIiLCJodHRwOi8vd3NvMi5vcmcvY2xhaW1zL2FwcGxpY2F0aW9uaWQiOiIxIiwiaHR0
cDovL3dzbzIub3JnL2NsYWltcy9hcHBsaWNhdGlvbm5hbWUiOiJEZWZhdWx0QXBwbGljYXRpb24iLC
JodHRwOi8vd3NvMi5vcmcvY2xhaW1zL2FwcGxpY2F0aW9udGllciI6IlVubGltaXRlZCIsImh0dHA6Ly9
3c28yLm9yZy9jbGFpbXMvYXBpY29udGV4dCI6Ii9waG9uZXZlcmlmeSIsImh0dHA6Ly93c28yLm9yZy
9jbGFpbXMvdmVyc2lvbiI6IjEuMC4wIiwiaHR0cDovL3dzbzIub3JnL2NsYWltcy90aWVyIjoiVW5saW1pd
GVkIiwiaHR0cDovL3dzbzIub3JnL2NsYWltcy9rZXl0eXBlIjoiUFJPRFVDVElPTiIsImh0dHA6Ly93c28yL
m9yZy9jbGFpbXMvdXNlcnR5cGUiOiJBUFBMSUNBVElPTiIsImh0dHA6Ly93c28yLm9yZy9jbGFpbX
MvZW5kdXNlciI6InJhamt1bWFyQGNhcmJvbi5zdXBlciIsImh0dHA6Ly93c28yLm9yZy9jbGFpbXMvZ
W5kdXNlclRlbmFudElkIjoiLTEyMzQiLCAiaHR0cDovL3dzbzIub3JnL2NsYWltcy9lbWFpbGFkZHJlc3Mi
OiJyYWprdW1hcnJAd3NvMi5jb20iLCAiaHR0cDovL3dzbzIub3JnL2NsYWltcy9naXZlbm5hbWUiOiJtb2
1vIiwgImh0dHA6Ly93c28yLm9yZy9jbGFpbXMvbGFzdG5hbWUiOiJtb20iLCAiaHR0cDovL3dzbzIub3J
nL2NsYWltcy9yb2xlIjoiSW50ZXJuYWwvc3Vic2NyaWJlcixJbnRlcm5hbC9ldmVyeW9uZSJ9.eczrlpBg3
+38Y90voBIhei3wXMZqZWV5z4q4nSQoUPPlUYXAo6UGmsiwBkT17BivS16K0I69tGwpxKzju/Tg8slT
06bLVmOwIeFtMH86HLh/VPKqnZ0WKgsZw5fFxccIYDgIfnzo8Gg+x9+tL+R2i71e5EOc7098FXZOXH
nlYm0=

5. As you can see, this is the JWT token in encoded format. The above message contains three parts separated by dots. We can decode this message and see what it represents. You can go https://www.base64decode.org/  and decode this message party by part.

6. If you copy paste the first part of the message (blue) into the decoder, you will get something like below


 And that contains JWT headers.


7. If you copy paste the second part of the message (pink), into the decoder, you will get something like below

 
 And that contains JWT claims set.


 8. That’s it. You have decoded and viewed the end user details that have been sent to the back end.

WSO2 Identity Server - How to add users containing special characters?

You can't create users containing special characters like "raj-kumar", "raj.kumar", "raj_kumar" etc. by default in WSO2 IS.

If you try to create users like above, you will the following error.



However, you can configure WSO2 IS to allow what type of characters a username can contain.

In order to allow usernames with special characters you can do the following.

* Open IS_HOME/repository/conf/user-mgt.xml

* Change the value of the property 'UsernameJavaRegEx' in the user store configuration that is applicable as below.

* Restart the server.

* Now you should be able to add users like "raj-kumar", "raj.kumar" and "raj_kumar"


Limitations - Pipe character

The pipe character is used as a special character in WSO2 code base. Still you will be able to create users like "test|user".


But you will end up with several problems as mentioned below.

* Users will be created and populated in LDAP. But when you list the users from IS management console, you will see only the second part of the username. For example, if you create a user "test|user", then you will see only "user" is listed in management console.
 
* You will not be able to delete this user. It will report "Cannot delete user. Error is: Cannot delete user who is not exist".

 
Hence, avoid creating users with pipe character.

Tuesday, December 9, 2014

WSO2 ESB and RabbitMQ


The Scenario of Interest


1. Client submits an API request with a correlation id and a call back queue to RabbitMQ
2. ESB receives the request from RabbitMQ
3. ESB forwards the request to Endpoint
4. ESB receives the response from Endpoint
5. ESB if receives a response from Endpoint, publishes it at the call back queue specified in the request with the correlation id of the request
6. ESB if doesn't receive a response in timely manner posts an error in the Dead Letter MQ with the correlation id of the request
7. Client receives the response from the call back queue
8. Since request and response have the correlation id, client knows which response is for which request

* Configure the ESB to use rabbitmq transport as explained in https://docs.wso2.com/display/ESB481/RabbitMQ+AMQP+Transport

* Start axis2 server and deploy SimpleStockQuote Service as explained in https://docs.wso2.com/display/ESB481/Setting+Up+the+ESB+Samples

* Go to the management console of ESB and click on 'Source View'

* Copy paste the following synapse configuration into the 'Source View" and click update

* Now you have deployed a rabbitmq proxy service which will,
      consume messages from a queue called "rpc-queue"
      calling the back end simple stock quote service for the symbol found in that request message
      receiving response from back end
      setting the correlation id of the request to the response
      publishes the response to the call back queue found in the request
      if ESB is not getting any response from back end, it will publish an error message, with the correlation id of the request, to a queue called "dead-queue"

* Now run the following RPCClient.java

* Now login to the management console of the rabbitmq server (http://localhost:15672)

* You will see that there is message in your call back queue. This message is the response sent by the ESB.

* Now run the following RPCReceiver.java

* You will get the message in your console. This is the message RPCReceiver pulled from your call back queue. This will have the correlation id of the request too.

* Have a look at in rabbitmq management console, the previous message will not be there, as it is pulled by the RPCReceiver.

* Now shutdown axis2 server

* Run RPCClient.java

* Have a look at rabbitmq management console, you will find that there is a message in a queue called "dead-queue". Since the back end service is unavailable, ESB sends the response to dead queue with the correlation id of the request

I will explain this scenario in detail soon.

Saturday, December 6, 2014

WSO2 API Manager - How to send additional headers in Swagger API Console?

WSO2 API Manager's Swagger API Console allows you to send authorization header by default. If you want to send additional headers, follow these steps.

* Go to the publisher and click on your API.
* Click on Docs.


* Click on Edit Contents of swagger API definition. You will get swagger API definition editor


* Under parameter section of the each HTTP method, you can add what ever parameters you want. It can be headers, body etc.

* For example, if you want to add tenant and enterprise headers to PUT method, you will add the following entries under parameters section of PUT method of your API.

* And then you should add these two headers under Access-Control-Allow-Headers of CORS configuration in api-manager.xml, like below.

* Finally restart the API Manager if already started.

* Go to the API Console in store and click on PUT method


Now you should be able to send additional headers from API Console.

WSO2 API Manager's Swagger API Console does not return any results?

When you click “Try it out!” option, sometimes you will see nothing happens other than some dots are moving.


There can be several reason for this problem.

First you need to verify whether CORS configurations are correct in api-manager.xml
It is clearly explained here. Please make sure your settings are correct according to this guide.

If you are accessing the store via HTTPS, you will not be able to use API Console most of the times.

Reason is swagger base path is set to HTTP production endpoint by default. So swagger client can't connect to it.

You can change the swagger base path as explained here.

* Go to publisher and click on your API.

* Click on Docs


* Click Edit Contents of swagger API definition. You will get swagger API definition editor




* You will see that the base path is set to HTTP production url like http://10.100.5.84:8280/phoneverify/1.0.0

* Change it to HTTPS production url like https://10.100.5.84:8243/phoneverify/1.0.0

* Please note that the ports are different in each url.

* Save and close the swagger API definition editor

* Now click on “Try it out!” option from store, you will get response



There you go! You got the response!

Tuesday, May 13, 2014

Solution for wss4j module compilation failure while building WSO2 Carbon Kernel

Problem - Building WSO2 Carbon often ended up with the following error, if there is a mismatch in the JDK version.

[ERROR] COMPILATION ERROR :
[INFO] -------------------------------------------------------------
[ERROR] /home/rajkumar/workspace/Building-Carbon/kernal/4.2.0/dependencies/wss4j/1.5.11-wso2v6/src/org/apache/ws/security/kerberos/KrbTicketDecoder.java:[10,24] EncryptionKey is internal proprietary API and may be removed in a future release

[ERROR] /home/rajkumar/workspace/Building-Carbon/kernal/4.2.0/dependencies/wss4j/1.5.11-wso2v6/src/org/apache/ws/security/kerberos/KrbTicketDecoder.java:[11,33] EncTicketPart is internal proprietary API and may be removed in a future release

[ERROR] /home/rajkumar/workspace/Building-Carbon/kernal/4.2.0/dependencies/wss4j/1.5.11-wso2v6/src/org/apache/ws/security/kerberos/KrbTicketDecoder.java:[12,33] Ticket is internal proprietary API and may be removed in a future release

[ERROR] /home/rajkumar/workspace/Building-Carbon/kernal/4.2.0/dependencies/wss4j/1.5.11-wso2v6/src/org/apache/ws/security/kerberos/KrbTicketDecoder.java:[13,40] KeyUsage is internal proprietary API and may be removed in a future release

[ERROR] /home/rajkumar/workspace/Building-Carbon/kernal/4.2.0/dependencies/wss4j/1.5.11-wso2v6/src/org/apache/ws/security/kerberos/KrbTicketDecoder.java:[14,24] DerInputStream is internal proprietary API and may be removed in a future release

[ERROR] /home/rajkumar/workspace/Building-Carbon/kernal/4.2.0/dependencies/wss4j/1.5.11-wso2v6/src/org/apache/ws/security/kerberos/KrbTicketDecoder.java:[15,24] DerValue is internal proprietary API and may be removed in a future release

. . . . etc.


Solution - WSO2 Carbon supports Java 1.6, at this point of writing. Hence, if you build using Java 1.7, you will get the above error.
Install Java 1.6, set the environments variables accordingly and try to build.


Solution for java.lang.OutOfMemoryError: PermGen space error while building WSO2 Carbon

Problem - Building WSO2 carbon often ended up with the following error, if you haven't increase memory for Maven.

The system is out of resources.
Consult the following stack trace for details.
java.lang.OutOfMemoryError: PermGen space
    at java.lang.ClassLoader.defineClass1(Native Method)
    at java.lang.ClassLoader.defineClass(ClassLoader.java:800)
    at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:142)
    at java.net.URLClassLoader.defineClass(URLClassLoader.java:449)
    at java.net.URLClassLoader.access$100(URLClassLoader.java:71)
    at java.net.URLClassLoader$1.run(URLClassLoader.java:361)
    at java.net.URLClassLoader$1.run(URLClassLoader.java:355)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.net.URLClassLoader.findClass(URLClassLoader.java:354)
    at org.codehaus.plexus.compiler.javac.IsolatedClassLoader.loadClass(IsolatedClassLoader.java:56)
    at java.lang.ClassLoader.defineClass1(Native Method)
    at java.lang.ClassLoader.defineClass(ClassLoader.java:800)
    at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:142)
    at java.net.URLClassLoader.defineClass(URLClassLoader.java:449)
    at java.net.URLClassLoader.access$100(URLClassLoader.java:71)
    at java.net.URLClassLoader$1.run(URLClassLoader.java:361)
    at java.net.URLClassLoader$1.run(URLClassLoader.java:355)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.net.URLClassLoader.findClass(URLClassLoader.java:354)
    at org.codehaus.plexus.compiler.javac.IsolatedClassLoader.loadClass(IsolatedClassLoader.java:56)
    at com.sun.tools.javac.main.JavaCompiler.(JavaCompiler.java:354)
    at com.sun.tools.javac.main.JavaCompiler.instance(JavaCompiler.java:88)
    at com.sun.tools.javac.main.Main.compile(Main.java:424)
    at com.sun.tools.javac.main.Main.compile(Main.java:353)
    at com.sun.tools.javac.main.Main.compile(Main.java:342)
    at com.sun.tools.javac.main.Main.compile(Main.java:333)
    at com.sun.tools.javac.Main.compile(Main.java:94)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:606)
    at org.codehaus.plexus.compiler.javac.JavacCompiler.compileInProcess(JavacCompiler.java:549)
 

Solution - Building WSO2 Carbon needs additional memory allocated to Maven. You can set it as below.

 

Step 1

Run the following command in your terminal to open .bashrc file, where you can set your environment variables.
 
sudo gedit ~/.bashrc

 

Step 2

Add the following line at the end of .bashrc file.
 
MAVEN_OPTS = "-Xms512m -Xmx1024m -XX:MaxPermSize=1024m"
export MAVEN_OPTS

Close the file.

 

Step 3

Reload/Restart the .bashrc file. Run the following command in terminal.
 
source ~/.bashrc

If you don't do this step, the effect will not be taken immediately . Maven will fail due to out of memory.

If you are still getting the same error, you need to increase the memory even more. Increase -XX:MaxPermSize=1024m parameter (like 2048m, 4096m etc.) in the Maven environment variable.


Thursday, May 1, 2014

Developing Web Application Using Jaggery - Part 2

This is part 2 of a series of Jaggery tutorials. This post explains the syntax of Jaggery and how to develop a simple application using Jaggery. 

Please go through part 1, Developing Web Application Using Jaggery - Part 1, if you don't know about Jaggery, how to install it, run it etc.

 

Jaggery Syntax 

Jaggery file extension is .jag (like Java file extension is .java)

The following is the syntax of Jaggery.



Everything wrapped between <% %> is Jaggery code. It means that everything wrapped by <% %> runs on server.

The print(msg); method outputs a server side variable to the document.

.jag file can contains HTML code. The above code can be written as below, 


Create a directory "myApp" and save the above file as "index.jag" inside "myApp" directory. 

You have successfully created your first Jaggery App.

Let's deploy it. If you don't know how to deploy it, please refer to part 1 of this series.

Copy myApp directory to Jaggery deployment directory which is JAGGERY_HOME/apps. 

Let's start the server. If you don't know how to start the server, please refer to part 1 of this series.

Run sh JAGGERY_HOME/bin/server.sh ( JAGGERY_HOME/bin/server.bat in windows) command to start the server.

Let's access your myApp application. Point the browser URL to http://localhost:9763/myApp/. You will have your myApp up and running.

Let's learn some more built-in functions as we need those functions in our part 3 of this series.

request

This is an object which holds properties and functions regarding the HTTP request that the client made to the server.

For example, 

getRemoteAddr() - returns client's IP
getMethod() - returns type of request

For more information, please refer here


session

This is an object which holds properties and functions regarding the current session of a client.

For example, 
invalidate() - destroy the session

For more information, please refer to here. 

application

This is an object which holds properties which are global to the entire application instance.

For example, 
put('propName', value) - saves the value in the name of probName.

For more information, please refer to here.

I guess these are enough for next part of this series.

Develop a sample e-banking application using Jaggery




Developing Web Application Using Jaggery - Part 1


Introduction

This series of tutorials gives you a basic understanding of Jaggery framework and its capabilities in web application development. This tutorial, part 1, explains a little bit about Jaggery and how we can install it.

Jaggery is a newly designed server side JavaScript framework. You might know about JavaScript that is used at the client side to control the interaction of the user with the browser. It controls the browser, decorate the page, validate fields and do more and more stuff at the client side. At the server side, you normally have your logic in programming languages such as Java or PHP. So JavaScript runs at your computer's browser. Java runs at your server.


Isn't nice if we can write the server side logic using JavaScript? Jaggery is the solution. So you can develop a web application using JavaScript only.

 
Installation


Download the latest Jaggery here
Extract it (jaggery-0.9.0-SNAPSHOT.zip in my case) to a directory you prefer. Lets call it JAGGERY_HOME 


You will get the following folder structure.


├── apps
├── bin
├── carbon
├── etc
├── INSTALL.txt
├── LICENSE.txt
├── modules
├── README.txt
└── release-notes.html



That's it. You have installed it.

 

Running the Server


In your terminal, navigate to JAGGERY_HOME/bin directory which contains all the Jaggery execution scripts.
Run sh JAGGERY_HOME/bin/server.sh ( JAGGERY_HOME/bin/server.bat in windows) command to start the server. It starts the default carbon server bundled with the framework itself.


If your server starts successfully, you will get something like below in your terminal, 

 

Deploy Jaggery Applications

JAGGERY_HOME/apps is the deployment directory. Deploy (copy) your Jaggery application to the deployment directory. You can find some sample application in the deployment directory including the taskmaster application.

 

Accessing Jaggery Applications

Point the browser URL to http://localhost:9763/taskmaster
You will have a web application, taskmaster application, running.

So if you deploy an application $myApp, you can access your application @ http://localhost:9763/$myApp

 

Developing Jaggery Applications

Please refer Developing Web Application Using Jaggery - Part 2