Granny's Programming Pearls
"inside of every large program is a small program struggling to get out"
JavaRanch.com/granny.jsp

Xolani Nkosi

Ranch Hand
+ Follow
since Apr 29, 2009
Cows and Likes
Cows
Total received
0
In last 30 days
0
Total given
0
Likes
Total received
1
Received in last 30 days
0
Total given
0
Given in last 30 days
0
Forums and Threads
Scavenger Hunt
expand Ranch Hand Scavenger Hunt
expand Greenhorn Scavenger Hunt

Recent posts by Xolani Nkosi

cat MyService.wsdl | sed 's/minOccurs="0"/minOccurs="1"/g' | sed 's/nillable="true"/nillable="false"/g' >MyServiceFixed.wsdl

In other words, no, as it was wasting more time trying to work out why Axis2 doesn't work that it was to just fix the wsdl with a find/replace. I did notice that Eclipse only offers ADB or XMLBEANS databindings, whereas @XmlElement is a JAXB annotation, but then the (virtually nonexistant and unhelpful) documentation on ADB says it's supposed to support JSR222 annotations, which it clearly doesn't, at which point I lost the will to keep digging. Why nothing in Java enterprise is ever simple or easy god only knows.
7 years ago
I'm generating a bottom-up Axis2 webservice in Eclipse. However, once deployed, every element in my WSDL looks like:

for the corresponding javabean:

I thought applying an @XmlElement annotation was the way to go to change this in the emitted xsd, but evidently not.

So how to make Axis2 generate an XSD with anything other than minOccurs="0" nillable="true"? Please don't suggest I change the Integer to an int, as this is obviously not going to work for Strings, which I also need to mark as minOccurs="1" nillable="false"
7 years ago
Hi,

All the tutorials I've found on how to create an Axis web service seem to include a step of 'deploying' it, which requires running a java app with a deploy.wsdd file (java org.apache.axis.client.AdminClient deploy.wsdd). This seems to talk to the admin servlet, which then 'enables' the web service. This all seems unnecessarily complicated, not to mention something I don't want to have to do every single time I start the EAR.

So my question is how do I structure and configure my web app so that when it starts, it starts my web service automatically without requiring me manually running the deploy.wsdd stage.

For reference, the current structure of my EAR is:

services.ear
- META-INF/application.xml
- services.war


services.war
- wsdl/MyService.wsdl
- WEB-INF
- - classes (contains MyService.class and beans it uses)
- - lib
- - - axis.jar
- - - commons*.jar
- - - jaxrpc.jar
- - - log4j
- - - saaj.jar
- - - wsdl4.jar
- - MyServiceService
- - - /big/long/package/list/deploy.wsdd
- - - /big/long/package/list/undeploy.wsdd
- - web.xml


Contents of web.xml look pretty standard:

7 years ago

I'm currently converting an app that we'd developed using Oracle onto DB/2, and noticed something very strange related to the above bit of code. For some reason, the DB/2 driver ignored the incorrect (Oracle specific) SQL in my prepared statement, and went on to attempt to execute the query, which then threw this error:

com.ibm.websphere.ce.cm.ObjectClosedException: DSRA9110E: Statement is closed.
at com.ibm.ws.rsadapter.jdbc.WSJdbcWrapper.createClosedException(WSJdbcWrapper.java:110)
at com.ibm.ws.rsadapter.jdbc.WSJdbcStatement.runtimeXIfNotClosed(WSJdbcStatement.java:1747)
at com.ibm.ws.rsadapter.jdbc.WSJdbcPreparedStatement.executeQuery(WSJdbcPreparedStatement.java:727)
at uk.co.liss.base.common.DatabaseSupport.getNextIdentifier(DatabaseSupport.java:156)


So my question is, why does the DB/2 driver not throw SQLException when you attempt to prepare completely wrong SQL? In the above example, the sys.dual table doesn't exist - if I try this via a SQL worksheet I get:

------------------------------ Commands Entered ------------------------------
select seq_uw_dictionary.nextval from sys.dual;
------------------------------------------------------------------------------
select seq_uw_dictionary.nextval from sys.dual
SQL0204N "SYS.DUAL" is an undefined name. SQLSTATE=42704

SQL0204N "SYS.DUAL " is an undefined name.
Thanks, but that's not that way I want to do things, as it would mean redeploying the EAR every time I want to make a config change to a properties file. Anyone know how to configure a shared library folder in AS7?
7 years ago
How do you configure a shared library directory in AS7? So that any EAR I deploy will find the contents of that directory on its classpath, if it looks up a properties file or wants to use a class in a jar in the folder? In websphere, it's dead simple, and I was hoping that the contents of $JBOSS_HOME/standalone/lib or $JBOSS_HOME/standalone/lib/ext would automatically be on the classpath, with no joy.

So how's it done? Preferably with as little changes to the EAR as possible, as I'm trying to make an EAR that'll deploy to other app servers too (the question of why so much vendor-specific configuration is needed for what should a standard platform is a question for another day...)

Thanks
7 years ago
Is there a standard way to tell an application server that, once it's installed an EAR, it should run a class contained therein? I'd like to be able to drop a configuration class into an EAR such that, once it's installed somewhere, it runs and sets up some local configuration.

If not a standard way, is there a Websphere specific way of doing this?

Or am I going to be limited to creating something that runs every time on startup, but does this configuration the first time only?
I appear to have answered my own question. As a note to framework authors, one problem with using convention over configuration, is if no-one explains the convention in the documentation, it can be hard to work out exactly what you need to do.

Anyway, it appears Tapestry looks for your module using the name you specified in your web.xml for the Tapestry filter. Yeah, wasn't expecting that...

So in my example, if I had:

Then the module appears to be needed to be called:
org.foo.services.TestAppModule

Do that and it'll pick it up and load it
I've written a module definition:

When I start my web app up, I get this in the output from tapestry:

- Adding module definition for class org.apache.tapestry5.ioc.services.TapestryIOCModule
- Adding module definition for class org.apache.tapestry5.hibernate.HibernateModule
- Adding module definition for class org.apache.tapestry5.hibernate.HibernateCoreModule
- Adding module definition for class org.apache.tapestry5.upload.services.UploadModule
- Adding module definition for class org.apache.tapestry5.services.TapestryModule
- Adding module definition for class org.apache.tapestry5.internal.services.InternalModule


It hasn't found my ServicesModule - so where do I add this to get Tapestry to pick it up?
I have some serialised objects from a class that looks like:

I have since decided that number needs to be a Long. I know that I can't just change it, as that will break deserialisation for my existing objects. So I do the following:

So now, newly made objects will exclusively use newNumber to store the value, and leave number null, and existing classes that I deserialise, get/set from, and then serialise again, will have their value copied over to newNumber.

My question is... is it safe to remove the Integer number field, once I know that all my stored objects have been migrated over to use the new field? e.g. does deserialision break even if the value it's attempting to set is null?
8 years ago

Richard Golebiowski wrote:While you could modify the converter or implement your own converter to deal with this, a better solution would be to filter the input client side so that only numbers could be input. My personal favorite is a script library called fiterinput.js that you can download off the web.


Mm, but I can't rely on the browser having javascript enabled. And the most frequent place spaces arise is when copy/pasting a value - that loves to tack an extra space on the end fnar. So making the converter robust enough to try a trim before rejecting input as not a number would be ideal. If I'm on the right track with modifying that class, I'll give that go.
8 years ago
I'm using an s:textfield to populate a field on an action when the user submits a form. Currently, the user typing a number followed by a space into a field backed by a numeric object produces a conversion error. It'd be nice if for numeric fields, the attempt would be made with the trimmed input, so '51 ' is converted to 51 and not rejected.

Looks like the magic for converting user input to the standard java types is going on in XWorkBasicConverter. So has anyone attempted a patch to the XWorkBasicConverter class to trim strings when attempting to convert the user input for numeric fields? Or do I need to grab the source and give it a stab?
8 years ago
Wrapping i1++ and i2++ in a synchronised block does not make it atomic. The other thread is able to examine the state of i1 and i2 while the first thread is in that synchronised block between statements (as the if i1 != i2 isn't synchronised on the same object), therefore making it possible your JVM would print some i's and k's too.

Additionally, I asked a question a while ago about the purpose of 'volatile' when applied to mutable static members, as it would seem any multithreaded program would require them to guarantee to function correctly. Perhaps most JVM's imply volatile with static, as the performance overhead isn't considered excessive, and lots of coders forget about it?
I'm using Selenium to kick off some tests against a web app, via:

java -jar selenium-server.jar -multiwindow -htmlsuite "*firefox" "http://www.google.com" "testsuite.html" "testsuite-results.html"

This works fine, and I end up with a nicely formatted human-readable test report in testsuite-results.html

Has anyone attempted to turn this report into something more machine readable, that I could use as part of a nightly ant build for instance, to pick out and report on failing test cases? Or perhaps (for example, via an xslt transform) found a way to turn it into a JUnit TEST-blah.xml style report? Or found a way to get Selenium to produce reports in a more useful (for automated testing purposes) format?
8 years ago

David Newton wrote:It won't do that unless you enhance the completion code to guess that you're putting in a variable name instead of a type. Just because *you're* expecting it to be able to guess that the variable name isn't actually a type name and you've entered the thing that comes *next* in the token stream... well, I dunno. Why not just just the feature it *does* has, which involves a lot less typing anyway?


Because the principle of least surprise and good interface design means it should behave in the most expected way. Which is as I described. Like if I write:

and CTRL-1 on it, it correctly assumes I want to make a local called a, and offers to fill in the type returned from someMethod(). It doesn't assume that a is a class. So my point is, why is the enhanced for loop not the same? Seems broken.