Friday, June 8, 2018

VOIP Traffic Segregation Should Be App Developers' Work, Phone-To-Phone

To achieve highest possible VOIP quality, it seems obvious that phones should generate IP UDP packets with the proper markings to segregate the traffic. The problem is that IP network is a cloud of many competing routing protocols, each with its own forwarding algorithm, each is bent on dominating the market for monetary gains. Civilizations come and go; protocols pop and burst throughout history. How can the Internet work worldwide is a mystery, let alone ensuring the highest quality, right? People's will makes the roads, VOIP is no exception. The competing protocols need to come together to make ways for the greater good. The evidence is in an experiment with this 2-leg setup, . And the netflow collection export shows that, indeed, legitimate hardware developers faithfully copy DSCP field from different vendors into MPLS labels and out onto phones.

I first checked with freeware Kibana Elk collector, which omits MPLS flow exports, but I hold out the hope that the actual packet have faithful replications.

I used the common flow exporting configuration,

, and I see tell-tale signs of MPLS packet markings in the "experimental bits" fields with the VPN label as well as the transport label,

, then I turn to commercial grade Plixer netflow collector, and bang, CS3 marking for SCCP control packets (TCP port 2000) is in the rainbow graphing,

, and further inspection of all the flows between phones and CUCM shows TCP non-SCCP-control packets that have common DSCP 0 in the MPLS labels. 

Sunday, June 3, 2018

Internet As A Community Needs To Be Practiced - Enter Proxy Security

You are looking at my site as if it belongs to and hosted by MPLS-Phone Inc's hardware, but you are also aware that this site looks just like a google blogger's page. So, we assume that google is aware that its server is being used by server IP, or is it? Does google think that is just another browser on the net, not knowing that google's application servers, counter tracker servers, warehouse rental fees, property tax, etc, are diverted to serve MPLS-Phone Inc's interest? This is different from google's authorized custom domain, which allows only 1 custom domain for a particular blog. Here the proxy allows any number of sites with different domain names simultaneously.

From the agriculture revolution of mankind, everything can be traced to its owner, and ownership can be protected. It will be very surprising if the Web is an exception, and laws of economy needs to be changed. The Web can be protected even though it appears counter intuitive. Most people think that no one is in charge of the Internet, no regulation, no borders, no laws. But, all the routers, servers, modems are business properties of different commercial entities or states. If the hardware's ownership is traceable, so is the content of the Internet, right? We need to dig a little deeper.

So, lets first look at the hardware setup,

And look at the software uses Amazon's AMI IDamzn-ami-hvm-2017.03.0.20170417-x86_64-gp2 (ami-c58c1dd3)
uname -a shows
Linux ip-10-201-1-124 4.9.20-11.31.amzn1.x86_64 #1 SMP Thu Apr 13 01:53:57 UTC 2017 x86_64 x86_64 x86_64 GNU/Linux

The steps to install the proxy is
- yum intall httpd mod24_ssl
- yum install httpd24
- yum install mod_ssl
- yum install mod_proxy
- yum install mod_proxy_html
- vim conf.d/proxy_html.conf , content be as
- vim conf/httpd.conf , content be as
   30  vim conf.d/ssl.conf ,  content be as
- service httpd enable
- service httpd start
- mkdir /var/www/nonexisting/ , content of index.html inside it be one bogus line.

So, the SSL PKI facility does not protect google. What went wrong? Please stay tuned for the update of this post for answer.

Thursday, December 28, 2017

Converged Drone IoT Developer's Platform

I installed the most popular 250 sized racing quadcopter's motor on the most popular hobby helicopter for IOT/MQTT/COAP research, and see what happened.

Nothing dramatic happened. It doesn't fly much differently from other 200-250 size helis sold by stores/vendors. 3S, 11.1 volts lifts the 240-249 gram(including Raspberry Pi Zero) take-off-weight at less than 4/6 throttle. The fuselage is Blade 230 sized heli(Blade BSR) body. Tail motor is the popular 1306 sized 3100kv intended for 130 sized quadcopters, tail prop is bull-nose cut from a 5040 prop , which produces counter torque thrust of 33 grams for cruising. Rotor head and blades are 210 sized helicopter parts from Oxy2 helicopter.

The helicopter fuselage is cheaper, at less than 7 dollars including shipping. The quadcopter motors and props are cheaper. The complexity of the system is about the same as a quadcopter with 4 pairs of folding blades. Either this helicopter, in direct drive configuration, or DJI Mavic Pro has exactly 16 moving parts of the vehicle. They are the main motor, tail motor, 3 CCPM servos, 2 folding blades, 2 grips, 2 halves of the swashplate, 5 linkage rods. And on the DJI Mavic Pro, they are 4 motors, 4 folding arms, 2 folding blades for each motor. So, the math is 2+3+2+2+2+5 = 16 = 4+4+2x4 .

The cost is about 1 dollar per gram, including shipping cost, break downs in the bottom table. Shipping discount for multiple items from a vendor has been applied. No volume discounts are used.

The entire craft can be built without a machineshop. All built in my car while waiting in traffic and in between commutes. Only used light hand tools and light electric tools that can be powered from car battery.

CC3D configuration for LibrePilot 16.09+dirty is at
(for flysky 6x transmitter)
(turnigy 9xrp transmitter)
And the flight videos below,

Sunday, July 16, 2017

C Programming Raspberry Pi MQTT Drone PWM

Drones commonly require real time programming because a split second control delay of a tail rotor can mean 180 degrees difference of a helicopter's heading.  For this reason, flight controller programming is often done with C language on a micro controller, where control logic can be optimized on a per-CPU-instruction basis.

However, a new trend has emerged to use Raspberry Pi Zero as a robotic controller to take advantage of the ubiquitous Linux programming, which the OS hides the underlying custom circuitry of micro controllers and presents the abstract programming interface to the programmers so that a program can be portable between different hardware systems. Adafruit has many tutorials focus on the Python library for the I2C devices. But, again, few resources provide the comprehensive view of the requirement of real time C programming. So, as soon as I found a hint of a C library controlling I2C servos, I have to jump in and test drive its performance.

The solution is . Steps I took:
  1. "Burn" SD Card with 2017-06-21-raspbian-jessie-lite.img , which is public downloadable from raspberrypi official site. After first powering on with the "burned" SD, wait for the disk expansion to finish in a few minutes while green LED light busy flashes.
  2. Wire up as the following diagram, 
  3. The usual IP connectivity chores. First thing is to get UART access through USB-FTDI adapter. Raspberry Pi Kernel side needs "enable_uart=1" in /boot/config.txt . To do so, insert the SD in to my PC to mount it .  
  4.  Then try to get IP access. Comment out the wlan entries in /etc/network/interfaces , and replaces it with my AP access credential,
    auto wlan0
    iface wlan0 inet static
    wpa-ssid "pc36000"
    wpa-psk "A...."
    Then, systemctl enable ssh , and reboot. Once IP SSH access is successful, apt install vim , and comment out the "enable_uart=1" .
  5. apt-get install git-core
    git clone git://
    cd wiringPi/
  6. git clone
    cd pca9685/src/
    sudo make install
  7. cd; mkdir mqtt-pizero
    cd mqtt-pizero
  8. vim servo-check.c ; The content follows,
    #include <pca9685.h>
    #include <stdio.h>

    int calcTicks(float impulseMs, int hertz)
    float cycleMs = 1000.0f / hertz;
    return (int)(4096 * impulseMs / cycleMs + 0.5f);

    int main()
    int fd = pca9685Setup(300, 0x40, 50);

    float millis = 1.5;
    int tick = calcTicks(millis, 50);
    pwmWrite(300, tick);

    while (1)
    millis = 1.8;
    tick = calcTicks(millis, 50);
    pwmWrite(300, tick);

    millis = 1.2;
    tick = calcTicks(millis, 50);
    pwmWrite(300, tick);
  9. gcc servo-check.c -o servo-check -l wiringPiPca9685 -l wiringPi
  10. apt install i2c-tools
  11. sudo vim /boot/config.txt ;  uncomment the following line,
  12. sudo vim /etc/modules; content follows,
  13. sudo vim /etc/modules-load.d/modules.conf; content follows,
  14. sudo sync ; sudo reboot
  15. Once rebooted, check i2c device is at 0x40 by gpio readall ; then cd mqtt-pizero/ ; ./servo-check

Friday, May 19, 2017

Inbound And Outbound Dialings Are "Institutional"

Why are there inbound and outbound boundaries with phones but not with Facebook/Google/Apple voice chats? Can we answer that question by looking at the smallest bits and pieces ourselves? I think so. But, what is the implication behind all these?

OK. In my diagram above, when lines, connections touch, it means they are associated. The purple inbound dialings do not touch any trunk lines, which means the inbound dialings are not associated with any particular trunk line. The orange PBX outbound dialing does not touch any phone line and is not associated with any phone protocol. The PBX outbound dialing, however, does touch SIP trunk line, which means it only goes out on the SIP trunk and not H323 protocol. So, all that means is that an inbound dialing does not care what the outbound trunk or protocol will be; an outbound dialing does not care what the inbound phone or protocol is. This is the essence of the PSTN call leg and the essence of VOIP.
For the green VOIP signal dash lines, the corresponding configs are in pjsip.aor.conf ,



, and in ooh323.conf ,
port = 1720
. The purple inbound dialings are in extensions_additional.conf ,
exten => 18001231101,1,Set(__DIRECTION=INBOUND)
exten => 18001231101,n(dest-ext),Goto(from-did-direct,101,1)

exten => 18001231102,1,Set(__DIRECTION=INBOUND)
exten => 18001231102,n(dest-ext),Goto(from-did-direct,102,1)

exten => 18004561203,1,Set(__DIRECTION=INBOUND)
exten => 18004561203,n(dest-ext),Goto(from-did-direct,203,1)
, and outbound dialings are also in extensions_additional.conf
[outrt-1] ; siptrunk
exten => _1800321XXXX,1,Macro(user-callerid,LIMIT,EXTERNAL,)
exten => _1800321XXXX,n,Macro(dialout-trunk,2,${EXTEN:7},,off)

[outrt-2] ; h323trunk
exten => _1800654XXXX,1,Macro(user-callerid,LIMIT,EXTERNAL,)
exten => _1800654XXXX,n,Macro(dialout-trunk,1,${EXTEN:7},,off)

. The FreePBX GUI generates the entire extensions_additional.conf and pjsip_aor.conf . ooh323.conf is entirely manually created. All configurations are downloadable here, .
The GUI dialogs are

The voice-vlan enabled router configuration is as .
The CUCM GUI screenshots are 

So, a call leg becomes a proxy in the TCP/IP/HTTP world so that the destination and source phones do not know the IP address of each other. The very definition of protocol proxy. It provides some isolation("does not care") of parts of the network while requiring the border routers to have the insights into the protocol. Speaking of proxy, do you know that this very page you are viewing is a proxy'ed page when you are at, which is . The true IP address of the web server is google's blogger web server IP address. That will be yet another posting about the Apache configuration that made the proxy.

Sunday, May 7, 2017

Watching The Branch Office Traffic

The branch office is on the far side of the WAN, and predictably the SCCP phones are on the branch router's EtherSwitch ports. So, how to find the actual voice packets that we want to know how much network bandwidth is utilized?

  1. Easy, just browse the flow exports pcap. But the number of voice flows is actually a very small fraction of the number of signaling flows. Just look at this screenshot of pcap search, 
    , the first actual voice flow is at packet 280. The IP source/destination is indistinguishable between small, frequent signaling flows and actual voice flow. It turns out, among the thousands of packets, only 3 are actual voice traffic flow exports. Browsing is out of the question. The real C1900's flow pcap is at . You can try it yourself. 
  2. Easy, just search the TOS on the flow exports pcap, right? The problem is that the hardware phone is subject to change without notice, so the TOS number is unknow. 
  3. Why not search for flow packet size? The size is actually unknown as well. In above screenshot, there is a roughly 36MB sized packet every half an hour of 1800 seconds. The string "Octets: 360" seems very unique. However,  how do you get this number? Intranet voice runs at the common 64kbps for u/alaw 8kps sample,  8 bits quantization. (64+16overhead)kbps * 1800 seconds / 8bit/Byte . It should be 18MB. It turns out, the counting is done twice for each packet while ingress to the router and at the egress interface. There is no certain way to foresee the search string "Octets: 360".
It turns out, ELK search is necessary to figure out what search strings we want! And that search is performed by ranking all flow size(bytes), and the 36MB stands out in the crowd of 1KB short signaling flows.

The ELK graphing is as below picture after taking out all signaling flows,
. Notice, that straight ELK can't handle niche fields like VLAN ID. When VLAN ID is present, ELK may simply discard the whole flow. That is why we need to alter the flow content in an editor in the terminal.

Now, after going through so much, are we sure that modern phone voice indeed is with 8kps sampling rate? According to Math, 8 kHz sampling rate can only transmit 4kHz sound, and that seems too low for high human hearing. The answer is that modern SD phone speech is defined as from 300 to 3400 Hz. We can hear a lot wider range of sounds than we can make. And the speech encoding is not meant to transmit Hi-Fi music, waves, etc.

Saturday, May 6, 2017

Mind In The Data Center Zone

Zoning out on a compact setup that has everything.

The MQTT logs come from the Internet, sourced from a ARM mosquitto program. And the Kibana display of the MQTT traffic flow is this,

, notice TOS is marked down to precedence 1 (TOS 32 decimal), by T-Mobile. And a hundred of these IoT sensors looks like the picture at the top.

Sunday, November 8, 2015

Maple Park Next to Grandparents' Home

    The scenery around my grandparents' home was beautiful. My grandparents owned a hotel across the street from Solpei County's Maple Park in Chanti. Two wide gray, limestone walkways ran across the rectangular park. There was a pond at the center of the park from which the Fujitai River flowed upstream. A five story tall cotton tree stood at the corner. In the summer, the cotton tree flowered and cotton flakes fell like drifts of snow. My older brother, Francis, and I stayed with my grandparents, Aunt Jen and her daughter, Ana, for two weeks when I was ten while my parents went on a tour abroad. Aunt Jen was a professional nurse, but she helped at the hotel for a while. This visit was the only time in a year when my brother and I got away from our piano and violin lessons.

    It was a Saturday or Sunday late afternoon when my parents dropped us off there. I learned it was not the first time we had visited the park. They later showed me a photo of myself stuffing my cheeks with candy while sitting next to the pond, but I was too young to remember the other times we had visited. Aunt Jen and Grandmother took us to the park which was packed with people. At the entrance, beverages, cotton candies, china dolls, and alike were sold to tourists. Francis and I tried not to talk to any strangers. Some girls, who looked classy and flawless and sophisticated, stared at us when I watched them passing by. We thought all the other families were strange and poor even if they sometimes had newer shoes. I wondered where they bought their bamboo picnic baskets. We approached the cotton candy stand and Aunt Jen said, "Two, please," to the vendor, and we each got our cotton candy. Aunt Jen also bought us orange soda, which my mother prohibited. Bursting in my throat, the cold sweet bubbles were phenomenal. I learned my brother liked the orange soda a few years later.

    We walked along a walkway to the pond while I watched the limestone pattern change to different contemporary abstract patterns. An artist connected leg and arm patterns interlocked and I tried to step on the leg patterned stones. My grandmother liked to pick up flower seeds. "I've never seen such an enormous seed, maybe it's not for a flower", she said to Aunt Jen as she put it in her pocket. The pond was full of pink Lotus flowers. Francis thought there must be fish in the pond and tossed a cookie morsel into the water. Some black and red Koi approached and swallowed the morsel. The ripple of the water diffused from its mouth. I took another piece of cookie to feed the fish and tried to grab it when it approached, but the Koi was slippery and I only touched it. The Lotus leaves were all waxed on the top. In the sun, water drops shined from the wax contact. My hand smelled like soil mixed with algae, much like the smell when we helped my mother garden at home.

    Ana was in second grade and I knew we, the more advanced ones, must be very appealing to her. We invented a "Taekwan-Wrestling" game and showed Ana we have to step our feet on the maple trunk and jump to boost our "Energy". She couldn't help but join us in the new game. Francis helped her every time she was about to lose a round of a jump. Aunt Jen and Grandmother rested in the gazebo next to the pond to watch us play. Swallows started to fly in large flocks, and sparrows started to whistle really loudly when the sun was about to set. We continued our wrestling match in Grandparents' home with a dozen different styles of "energy boosting." The pseudo south pacific residences did not have bed frames; mattresses were all laid on the wood floor making them perfect for wrestling. The adults were overwhelmed with us in the house. My grandmother wanted us to watch "Weekend 2100" TV variety show with Grandfather and we finally calmed down.

    Francis spend the whole two weeks reading three Sherlock Holmes books; and I dug out pieces of cardboard and styrofoam from the hotel's dumpster to build gliders. I struggled to build a glider that flew in a zig-zag pattern. Aunt Jen asked me why I made the glider fly that way. I explained confidently to her "The center of gravity is supposed to be located here for a stable flight," as I pointed at the fuselage. "If I control  the wing's movement toward the head of the plane, it will lose lift and I have a silicon integrated circuit, which can form a periodic movement of the wing in the wind, which can dramatically change the flight pattern of different concepts." It was over my head, and I lost my point, but she asked me "Is that how they make micro capsule controllers and all the decoding in James Bond?" I lowered my voice and nodded "Y-e-a-h". I went to the park almost every day, though avoiding the weekend crowd, to test my glider. Some really green trees were trimmed to form a neat fence around the park. I swept my right hand along the top of the trees and felt the smooth needles after being trimmed by the gardener every time I walked along the side of the park.

    My mother's other younger sister, Aunt Edna, was only eleven years older than me. She went to college and wasn't with my grandparents in the summer. We used her room and slept there. I browsed through her books and read two pages of her college psychology book and learned that most people have auditory hallucination, hearing a voice that does not exist, right before they fall asleep. The book also said that most people don't realize that it is happening and ignore it. One night, we turned on her radio next to the bed. The radio was last tuned to a classical music station when Aunt Edna left for college. One of the pieces they played was a piano solo, and the music was as soothing as Johann Sebastian Bach's "Man's Desiring." There were visitors leaving the park late at night. Some cars passed by projecting their head lights through the windows forming triangles flying across the ceiling. I wondered if the people in the cars felt the same kind of peace I did. Then I heard some classmate call my name , "John." I though it must be the girl who I liked in school. It wasn't. But, the college psychology text book was right, and I fell asleep shortly after.

Friday, December 26, 2014

Wildfly EJB With JPA On A Phone

Seconds to the count down:
9 enter Fedora21
8 start Wildfly
7 add database browser
6 Wildfly up
4 database empty
2 run application
0 object in database

My server(my phone) runs the precidio-jndi-calc.tar.gz software, which calculates resonator designs for buyers with their JPA Buyer accounts like this,

. When a visitor does not have an account, the stateful bean creates a temporary account, which can be viewed in the video's H2 console.

The wildfly web interface is ; database web interface url is . JDBC url and password are in /etc/wildfly/standalone/standalone-full.xmljdbc:h2:mem:test and sa respectively.

The precidio-calc.jar's structure is this,
├── Buyer.class
│   ├── create-script.sql
│   ├── drop-script.sql
│   ├── ejb-jar.xml
│   └── persistence.xml
├── PackagerBean.class
├── PackagerCommonBusiness.class
├── RemoteResonatorCalculator.class
├── RemoteSiliconResonatorCalculator.class
├── ResonatorCalculatorBean.class
└── SiliconResonatorCalculatorBean.class
, which is a standard standalone jar layout, a subset of an EAR. The client layout is this,
├── RemoteCalculatorClient.class
├── RemoteResonatorCalculator.class
└── RemoteSiliconResonatorCalculator.class
, which means that the client does not need to know the bean implementation, just the shell of the different Calculators . The has username and password, which the server side needs to catch up with the client.

The Fedora 21 Wildfly's jar files are split into 2 directories which fails the EJB server startup. To fix it, shell command lines were these, (all these are already done in my Fedora...arm...21-6.tar.gz)
   91  mv /usr/lib/java/hawtjni/* /usr/share/java/hawtjni/
   92  mv /usr/lib/java/hornetq/* /usr/share/java/hornetq/
   93  mv /usr/lib/java/jansi-native/ /usr/share/java/
   94  rmdir /usr/lib/java/hawtjni/
   95  rmdir /usr/lib/java/hornetq/
   96  mv /usr/lib/java/jffi.jar /usr/share/java/
   97  mv /usr/lib/java/jss4.jar /usr/share/java/
   98  mv /usr/lib/java/netty/netty-* /usr/share/java/netty/
   99  rmdir /usr/lib/java/netty/
  100  mv /usr/lib/java/snappy-java/ /usr/share/java/
  101  mv /usr/lib/java/weld-core/* /usr/share/java/weld-core/
  102  rmdir /usr/lib/java/weld-core/
  103  mv /usr/lib/java/wildfly/wildfly-client-all.jar /usr/share/java/wildfly/
  104  cd /usr/lib/java
  106  rmdir wildfly/
  107  cd ../
  108  rmdir java
  109  ln -s /usr/share/java
  129  ln -s /usr/share/java/resteasy/resteasy-json-p-provider-jandex.jar /usr/share/wildfly/modules/system/layers/base/org/jboss/resteasy/resteasy-json-p-provider/main/resteasy-json-p-provider-jandex.jar

I studied the EJB exam and researched on EJB to obtain certification entirely on this phone/tablet/wildfly setting. 

Tuesday, December 9, 2014

An Amazing Dream - typed on the PC phone before getting up

I met my mother in the Starbucks. She got a tan, a toned body, on high heels, approaching my height of 5'11. I walked some yards in my basketball shoes from the plaza of the Home Depot to the Barnes Noble store to meet her and my brother. I asked her about gardening with a species of flower because I didn't know the name of that flower that she used to plant. But she could not recall the name either. I asked my brother , "what is that called in English?" He didn't answer. I said to them that it was time to go back to reading as many books for the afternoon, and maybe one book will reveal the name of the species.

My mother and I embraced and said goodbye, that's how I noticed how tall she was on high heels that day. She tied her hair a pony tail. Her age spot somehow faded blended in with the tanned face. I walked out of the BN store instead of reading the books. The scene was so far all american.

Now it got less american themed, and as I walked back to the plaza of Home Depot back to my car, I tried crossing 2 low fences to shortcut to my car, I got lost in between the parking lots. I started to bump into tall fences and buildings like government facilities. I realized that I ended up in a prison facility. I thought many people must have entered this facility unkowningly or by accident or by a better word here not to be mocked with committing a crime unintentionally. I walked into a house and asked to be pointed to the exit. The prison was in their daily gathering routine. The clerk was a young lady in a blue uniform. She talked to her colleagues saying they have never heard that a person walked in their facility by accident. They started raising suspicion about my identity. She asked me to show my ID. I gave my driver's license, still with my document brief in my underarm, which assured that I was a citizen lay back guy walking down the street.

That was not assuring enough. In side the house, it had partitions made of steel and mesh fences. She told me that she could let me go, but I needed to "reconsider" my action, and "think" clearly. I was confused about the word "think". What did I need to think when I was just walking to my car unless she meant that I was committing a jailbreak? I pulled out my phone with GPS map to figure out how I wound up here. There must be a way to clear the misunderstanding.

Friday, November 28, 2014

Interceptors dependency code path and inherited interceptors

They are 
import javax.interceptor.AroundInvoke;
import javax.interceptor.InvocationContext;
and inside
jboss-interceptors-api_1.1_spec-1.0.0.Final.jar .

For wildfly, the remoting has changed again, port 4447 obsoleted, 8080 now, so the precidio-jndi-calc.tar.gz package is this,
, and I have 2 classes, one extends another. My experiment shows that the base object's interceptor is invoked first the the more specific object's interceptor is invoked, like this,
20:58:39,027 INFO  [stdout] (EJB default - 7) *** Intercepting call to baseInterceptor()
20:58:39,029 INFO  [stdout] (EJB default - 7) *** Intercepting call to siliconInterceptor()

Calling Stateless Application EJB JARs From Plain Java Code

The stateless application jar is compiled with ejb api. But the invoker should not need the ejb api jars if it can avoid triggering ejb related code, or can it? We have a application for intensive computing farm for intra-red-EM-wave photoresonator calculation of quartz business Precidio Inc. ,

The precidio-jndi-calc.jar has this,
import javax.ejb.Remote;
import javax.ejb.Stateless;

public class ResonatorCalculatorBean implements RemoteResonatorCalculator {

    public int add(int a, int b) {
        return a + b + 111;

    public int subtract(int a, int b) {
        return Math.abs(a - b) - 11;
, and we should be able to -cp precidio-calc.jar , instantiate ResonatorCalculatorBean, and run the add command. This is the essence of EJB.

What is the problem, then, when -cp precidio-calc.jar ? 

[root@android01 ~]# cat 

import CalculatorBean;

public class UseEjb {

public static void main (String [] args) {


CalculatorBean cb = new CalculatorBean();

System.out.println(cb.add ( 1, 2));


[root@android01 ~]# javac -cp precidio-jndi-calc/build/precidio-calc.jar error: '.' expected
import CalculatorBean;
                     ^ error: ';' expected
import CalculatorBean;
2 errors
[root@android01 ~]#
Why? Non-packaged classes can not be imported. Instead, use it without importing it,
[root@android01 ~]# cat 
public class UseEjb {
public static void main (String [] args) {
CalculatorBean cb = new CalculatorBean();
System.out.println(cb.add ( 1, 2));
[root@android01 ~]# javac -cp precidio-jndi-calc/build/precidio-calc.jar warning: Cannot find annotation method 'value()' in type 'Remote': class file for javax.ejb.Remote not found
1 warning
[root@android01 ~]# java -cp precidio-jndi-calc/build/precidio-calc.jar:. UseEjb
[root@android01 ~]#java -cp precidio-jndi-calc/build/precidio-calc.jar UseEjb
Error: Could not find or load main class UseEjb
[root@android01 ~]# 

As predicted, as long as the invoker don't touch EJB specific workings, the regular java interpreter can invoke ejb jar without incident. It has a warning at compile time.

This exercise actually exposes the defect of java cp. The cp actually disturbs the java interpreter's original work path. Original java interpreter looks at current working directory in search for a class file, UseEjb in this case. So, simple java UseEjb does not have error of "Cloud not find" UseEjb. When -cp argument is in, it erases the default looking at current working directory.