I sometimes need to set a custom JVM Property for one or more Application Servers and dislike the tedium of setting them one-at-a-time through the console.
Here's a Jyth
wsadmin -f addJvmProperty.
Server version: IBM_
At this version of WebSphere, JAX-RS 1.1 is supported, but that doesn't include any REST Client support. JAX-RS 2.0 apparently does, but that's not yet available here on WAS 8.5.5 Full Profile. It i
Those steps are actually pretty clear and comprehensive. I'll give quick examples of the mostly-default code I used. (Showing full class packages inline, just once, for simplicity.)
Another form of each operation does not throw that Exception, but allows you to manually check the ClientResponse yourself. This is how the example in the above WAS documentation does things. (Note that even those methods do seem to throw Clie
Speaking of POST, here's what that looks like. With a JSON payload as well.
Adding HTTP Basic Authentication
From another WebSphere Knowledge Center article, Secu
JSON Beans and Seri
I'm sure this information is in hundreds or thousands of other places, but as I had written it up for an internal team Wiki, I thought I'd repost here as well.
Perl is included by default in AIX, but most of the Modules are not, so the rest of this article deals with installing those.
Some Perl scripts make use of additional Modules, and there are Modules with many different capabilities, so be sure to look for existing Modules if you need to do anything that someone else might have had to do already.
Obtaining a Module
For instance, a script we created uses the Date::Simple module. After finding its page, you click the Download link on the right side to obtain what is actually a source package in .tar.gz format.
Module Installation from Source
These instructions are summarized from somewhere, I thought an earlier version of the generic installation instructions on the CPAN site. However, that site now describes a simpler approach using a cpanminus installation module. I'll have to try that out.
Decompress the file
This can be done as any user.
gunzip -c Date
Build the module
These steps can also be performed as any user.
By default, the Makefile will attempt to create an "XS" version of the Module, which means a version that uses native C code to improve performance. This means the "make" command will require access to a local C compiler.
If you don't have a C compiler or want to create a "pure-Perl" Module to copy around to various systems, you use the "noxs" option. The output of "perl Makefile.PL" will actually tell you to use this option if you see errors during the "make" step. If that occurs, the error will look something like:
cc_r -c -D_ALL_SOURCE -D_ANSI_C_SOURCE -D_POSIX_SOURCE -qmaxmem=-1 -qnoansialias
Install the module
This step needs to be performed as a user that can write to the Perl installation direction. Most likely "root".
Also watch for file permissions. By default this could make the module directory, subdirectories, and files be only readable by root.
Update: the above only obtains the heap size if a custom value has been explicitly configured. From this other post, here's a mechanism which will obtain the maximum heap size otherwise (note there doesn't appear to be an attribute to obtain the minimum heap size):
Web Application Configuration
This is the basic annotation-based JAX-RS coding. See the below "Getting Started" article, Part 1 of the "RESTful Web services" article, and the Developing JAX-RS Web applications section of the WebSphere Feature Pack documentation.
It's a straightforward, portable way to define the URI Paths of your Resources, the HTTP Methods supported by them, the Parameters passed to them, the Content Types supplied by them, and more.
I'm normally a PuTTY user, but I'm temporarily on a *IX (MacOS) system, and learning a few simple techniques for doing some
First, I'm using SSH keys for much of my authentication. I may add details here later on how to create those, but it's pretty straightforward to find all over the web.
Next, ssh-add to add SSH keys to your system's authentication agent (what PuTTY pageant does). e.g.
ssh-add -K /Use
Proxy a hop
To proxy/hop through one host that can reach the other hosts you want to reach, use the ProxyCommand option. (Source of this one was fellow IBMer, @Harley Stenzel0600022V4M.)
ssh -o ProxyCommand="ssh -W %h:%p my-proxy-server" my-d
Further, I can tunnel ports, like the WebSphere administrator port, through that as well:
ssh -o ProxyCommand="ssh -W %h:%p my-proxy-server" -L90
Where my-destination and my-websphere-server might or might not be the same server, as long as my-destination can reach my-websphere-server on the port being tunneled.
I'll get a login shell to my-destination, and a tunneled port 9043 to my-w
Thanks, again, to Harley, this tip actually obviates some of the need for port tunneling. The -D option will dynamically forward connections through a local port, as a SOCKS server. Which... a browser can be configured to use, thus reaching any http URLs on the "other side" of that tunnel.
ssh -D localhost:8888 my-destination
Firefox proxy settings
I'm also currently trying out the SwitchyOmega add-on to automatically switch to this proxy configuration when hitting hosts in our private domain. Thus far, it seems to be working exactly as I'd like.
Saving SSH options
Finally, .ssh/config file in your home directory can contain saved configurations. Here's what mine looks like (again, largely thanks to Harley):
The first item is just to prevent our firewall from dropping my connection regularly. It sends a "keepalive" request every 60 seconds.
The second allows me to just type:
and have that automatically use the configured proxy server via the ProxyCommand to connect to host
You can also add Dynamic Forwarding to this file, with a line like this:
We've recently had a need to accept files submitted by a partner and perform some processing on them, with the partner returning later to retrieve the results. Rather than the "old", standard approach of using something like sftp and regularly kicking off a cron job to look for input files, this seemed like a good case for a Web Service.
And IMO REST style services are simpler to produce (particularly with standard APIs like JAX-RS), consume, and test, and further are a good fit for this particular scenario. (See the excellent book REST
I decided to support the URL "/batch", as an HTTP POST of standard "mul
I should say, I decided to propose this approach and then go see if I could make it happen in a straightforward way. I wasn't sure if submitting files this way was normal enough to be easily supported by JAX-RS and/or WebSphere.
It turns out this is supported by JAX-RS in WebSphere, with a few different mechanisms. Right there in the official IBM Knowledge Center documentation, (almost) everything I needed to know:
So go read that, I'm done :-)
... well, ok, I'll summarize and note a few things, while I'm here.
Generic JAX-RS approach
I generally prefer to stick to the specs, not using any server-specific or impl
With WebSphere, this uploads the file to a temporary location, and gives it a generated file name. (On my Windows development system, the location seems to be my Windows %TEMP% directory.)
However, I'd prefer to prescriptively set the upload directory (so I don't have to later copy it to a more "permanent" location), and I really want the original file's name (among other things, so I can detect when the same file is inadvertently submitted again).
Because of these requirements, I needed to look for another approach.
WebSphere-specific (Apache Wink) approach
It turns out the last example on that
This approach looks more like:
And involves looping through the parts and parsing the HTTP Headers to get the Cont
In addition to the above WebSphere link, also see Apac
I'll note a few problematic behaviors we discovered during the implementation and testing.
Internet Explorer and file input elements
Further, the java
Granted, this service won't normally be called from a browser and HTML page, but during testing, it sometimes is. And even there, using a different browser is acceptable. But still, if it wasn't too much work, I'd prefer to handle this more robustly "just in case".
.NET client error on the GET request
Our partner appears to be using a C# .NET client, and even after he had success submitting a file to our POST URL, he was getting this error upon calling our GET URL from Http
“The server committed a protocol violation. Sect
However, with object lifecycles now managed by JEE containers, like for JAX-WS or JAX-RS services, sometimes using Spring-managed beans is not as direct as I'd like. JEE 6's Cont
Most of my projects use Spring for other things as well, so I hadn't been willing to look down the CDI path just yet. However, I'm now working on some SOAP Web Service projects that don't yet use Spring, so I thought I'd give CDI a look.
What follows is the basics of configuring a "web" application that is both a JAX-WS service and a JAX-WS client to one or more other services. I need to inject both some interface implementation classes and some JEE Resource References into my service. In case documenting this particular example helps anyone else. Or just helps me clarify what I did and remember it in the future :-)
In my @WebService JAX-WS implementation class (or any other "service" / "servlet" class managed by the JEE container), I need to make use of a "business facade" interface implementation singleton. JEE 6 annotation @Inject enables this.
If I only have one such BusinessFacade implementation class defined in the application, this is sufficient to locate it. (Classes don't have to be annotated in order to have their instance(s) injectable as "Producers". They just have to meet some conventions: see Abou
If you have multiple implementation classes, you'll need to qualify the @Inject like with @Named.
By default, the "sco
Since I want this BusinessFacade instance to be a singleton, only initialized once for the whole application, I need to tell my implementation class that I want instances of it to have "Application" scope. I do that by annotating that class with @ApplicationScoped.
(@Singleton is from the EJB spec and is somewhat different from CDI's @App
Now, somewhere down my object chain, I have another object that calls another Web Service, via a JAX-WS client wrapper, and I need to inject the endpoint URL into that wrapper.
I manage that URL through a web.xml <resource-ref> that I can map to server Resource at deploy time:
To get that injected into my hand-written caller class, I use @Resource, specifying the same name used in <res-ref-name>:
Now, specific to JAX-WS client wrappers, I want to override the endpoint URL that was specified in the WSDL used to create the client code. The approach that seems cleanest to me is usin
The @PostConstruct annotation indicates a method (named whatever you want) to be called after a class instance is created. I'll use this to bind a (singleton) JAX-WS client wrapper (ServicePortType in the example) to the endpoint URL specified in the above injected @Resource:
private ServicePortType serviceEndpoint = null;
(Where Service and ServicePortType match whatever was generated from your WSDL.)
Note that I've annotated this particular class with @ApplicationScoped, so this @PostConstruct will only be called once. Another potential pattern would be to have this class not be a singleton but have the @PostConstruct method lazy-initialize and reuse a static ServicePortType instance.
Finally, logistically, your application must contain a beans.xml file in its WEB-INF directory in order for WebSphere to know to scan it for CDI annotations. This file can be completely empty.
While attempting to answer a question on StackOverflow, I experimented a little with some wsadmin commands, so I thought I'd record what I discovered. (I work with the Jython, rather than JACL, versions of the commands mostly because I like the idea of picking up a little of a new programming language which has other uses.)
In this particular case, I wanted to discover runtime System.properties values for a running JVM, of which many are not items you configure explicitly with WebSphere. Thus, after looking at the AdminConfig object and determining that it only had visibility into what you've configured, I determined that the AdminControl object was needed.
Still, here are some AdminConfig commands that I've used and will likely have reason to use again:
You can see where I previously used this approach to create JVM Custom Properties for Application Servers and to determine the (configured) maximum heap for a particular Application Server. (I'll return to that latter case later.)
The AdminControl scripting object is used for operational control. It communicates with MBeans that represent live objects running a WebSphere® server process.
These commands allowed me to locate and query runtime WebSphere objects:
Or skip straight to the JVM:
Or, returning to the maximum heap case from before, now I can see the maximum heap of a JVM even if I haven't explicitly configured one. Either of these variations, invoking a getter method, or getting an attribute, does the same thing:
Finally, here's a way to see which attributes and operations are available for a particular object:
Since I can tell that I don't fully understand this myself, I'll start by pointing to these articles which more fully & authoritatively describe SPF's purpose, behavior, and effects:
The first concept to understand is that SMTP email contains an "envelope" with an "envelope sender address" (sometimes called the "return-path" and technically the SMTP MAIL FROM command) that is separate from the "From" header in the message itself (a.k.a. the "header sender address").
The envelope sender address is what actually receives bounces, BTW. It's sent, and potentially checked, before the email message itself (including the header) is even delivered. The header sender address is what a user's email client typically displays, and it obviously doesn't always match the domain of the SMTP server which actually originated the message.
Sender Policy Framework
SPF, then, is an attempt to prevent forging of the envelope sender, not the header sender.
SPF is a combination of "sender" and "receiver" actions. The domain owner publishes a special kind of DNS record indicating which servers are authorized to send emails from its users. The receivers then verify that the IP address from which the email originated is in that authorized list for the domain.
So the purpose of SPF isn't to allow anotherdomain.com servers to send email on behalf of somedomain.com, the original requirement I was investigating; that can be done without SPF. Its purpose is the opposite: to tell receivers (who check) not to accept email which claims to come from somedomain.com (that is, with an envelope sender address of somedomain.com) unless the actual originating server's IP address is one listed as authorized to do so.
The primary goal seems to be reducing the amount of SPAM claiming to originate at somedomain.com.
Sender Addresses in JavaMail
Note that JavaMail by default uses the header sender ("From" address) also as the envelope sender address, but this doesn't have to be the case.
Potential Problems with SPF
The main potential problem I see is that email forwarding services typically don't work with SPF. That is, if a domain publishes a restrictive SPF record, an individual receiving emails from that sender provides an email address that is actually a forwarding address, and the eventual destination of that forwarding address checks SPF records, the email will be rejected.
Since the sending server typically cannot control what kind of email addresses its customers provide, this seems like an unacceptable situation to me. Undoubtedly some end-users will provide email addresses which will be unable to receive email from a domain with strict SPF settings, and they'd never know they had done so. (Although the sending server should receive bounce emails indicating SPF failure in those cases.)
For those curious but not curious enough to work through the linked articles.
SPF is implemented by a domain adding a special kind of DNS record to its DNS server. (Apparently this can be either a TXT record or a SPF record, with the same content/format either way.) I won't go into the details documented elsewhere, but a simple example would be:
somedomain.com. IN TXT "v=spf1 a mx -all"
Meaning, for email with an envelope sender address in somedomain.com, only accept the email if the sending IP is either one of the domain's DNS "A" servers (the main DNS record for a domain) or one of its DNS "MX" (mail) servers. Consider "all" other IP addresses a "hard FAIL" (i.e. reject them if you care about such things).
I looked up ibm.com and saw that it actually has an SPF record that says no servers at all should be sending email for @ibm.com:
ibm.com. IN TXT "v=spf1 -all"
I had to ponder for a bit before I thought to check us.ibm.com. It has several valid senders listed, including some IP ranges:
us.ibm.com. IN TXT "v=spf1 ip4:188.8.131.52/24 ip4:184.108.40.206/24 a:d2
Hard and Soft Fail
Note the difference in the "all" clauses in the previous two examples. "-all" (hyphen) means to treat emails from all (other) senders as a "hard FAIL". "~all" (tilde) means to treat them as a "SOFTFAIL". Note that Google.com's SPF record and Microsoft.com's SPF record also use the SOFTFAIL default.
SOFTFAIL is theoretically intended as a transitional setting while you're testing out the implications of your SPF record/policy, with the recommendation that recipients accept the email but "mark" them in some way. But based on the noted use of that SOFTFAIL indicator by those large, savvy domains, I'd say that Hard FAILS probably reject too many real-world uses today. (I suspect the forwarding scenario described above as one of the main such problematic uses.)
It seems that in our current configuration the WebSphere plugin does not reliably stop sending requests to a Cluster member when it's been taken down. Or sometimes it seems to take an inordinate amount of time for it to do so, or sometimes it starts sending requests before a restarting member is fully operational.
A quick workaround is to manually edit the plugin's configuration file on each web server to comment-out the unwanted servers. The plugin will automatically detect and apply the changes within a minute or so and stop routing requests to those servers until you manually uncomment them.
Plugin Configuration File Location
On our AIX systems, the plugin configuration file is in a location like:
(If you're ever uncertain you're looking in the correct location, look for the WebS
Plugin Configuration File Contents
Within that file are many configuration items, most should never be manually edited, but the ones we care about for this purpose are the <PrimaryServers> elements within each <ServerCluster> element.
The ServerCluster's "Name" attribute will tell you which element to edit.
Then the PrimaryServers element in that ServerCluster will list each of the individual <Server> Cluster members which are also defined within ServerCluster.
Removing a specific server from Plugin dispatching
The only change we have to make is to comment-out the specific Server which we want to cease receiving requests. So to disable the TestApp-B server on serverB:
Following up on Part 1, here's an additional tip which I use frequently. That is, when I need to tunnel SSH through one machine to reach others, using a background proxy with SSH key authentication for the initial connection simplifies this 2-hop process.
Automatic proxying with Plink
The PuTTY installation also includes a command-line SSH program called Plink which can be used in a "background" mode. The PuTTY help describes how to use Plink as a local proxy program, creating a background tunnel for the main PuTTY window. This configuration is performed in the Window > Proxy tab:
Specify a Proxy type of local, and the standard SSH Port, 22.
In the Proxy hostname field, you enter a host to which you have direct access and on which you've configured key authentication, then you refer to that host via the %proxyhost variable in the plink command you provide as the local proxy:
\path\to\plink -l %user %proxyhost -nc %host:%port
The %host and %port variables represent the ultimate destination Host Name and Port fields from the main PuTTY Session tab (which, as usual, you can enter as needed or save under separate Sessions for each server).
%user and %proxyhost are from this configuration page.
Note: If your Default Settings PuTTY profile has a username (on the Connection > Data tab) or hostname configured in it, plink will use those automatically. Discovering that wasted a couple of hours for myself and a colleague. On the other hand, if the configured default username matches your username on the proxy server, you can completely omit the -l parameter from the plink command.
Tunneling additional Ports
Furthermore, this technique can be used in conjunction with "normal" SSH tunneling (Connection > SSH > Tunnels) in order to tunnel a localhost port through both hops. For instance, to tunnel the default WebSphere Application Server administration console port:
Then you connect your browser to http
You can similarly 2-hop tunnel X-Windows by enabling X11 Forwarding on PuTTY's Connection > SSH > X11 tab. (You'll need Windows X server like XMing.)
Any additional tips you've found useful? Better ways to accomplish these same tasks? I welcome your comments and suggestions.
Have you ever discovered that you no longer have the EAR file for the specific version of an Enterprise Application which is deployed on one of your systems?
It turns out WebSphere keeps a copy around that can be retrieved and re-deployed elsewhere. For the Network Deployment edition of WAS v6.1, you can find a deployed EAR file in:
(Note the ear name twice, first as a directory, then as a file.)