how to customize a JAX-WS generated WSDL? - wsdl

I am creating a SOAP service using JAX-WS and JAXB, by annotating the classes. My service implementation looks like this:
#Stateless
#Local(WSApplicationService.class)
#WebService(name = "WSApplicationService", serviceName = "WSApplicationService")
#BindingType(SOAPBinding.SOAP11HTTP_BINDING)
public class WSApplicationServiceImpl implements WSApplicationService {
#Override
#WebMethod
#WebResult(name = "reference")
public long submitApplication(#WebParam(name = "application") ApplicationSubmission application) throws SOAPException {
...
}
}
After asking this question, I learned that there's no way to specify certain restrictions on the input data using JAXB annotations. However, I need to restrict certain String properties to patterns (mainly postcodes and phone numbers). Therefore, I'm looking to customize the WSDL generated by above class. I can't find a way to access the WSDL though. Is there a way to override or customize the JAX-WS generated WSDL?

While you can safely have the WSDL generated automatically, it usually makes sense to hand-code the XSD referenced from the WSDL, which gives you all the richness of expression that a schema generated from JAXB classes can't, and also ensures the schema doesn't change when you don't want it to. (This practice is called contract-first, whereas starting with the classes is called code-first.)
When you do contract-first, you can generate your JAXB classes from the XSD automatically as part of your build process, making sure they're always in sync. You can customize the generated classes using XJB files.
In case you're using Maven, generating the classes could look like this:
<plugin>
<groupId>org.jvnet.jaxb2.maven2</groupId>
<artifactId>maven-jaxb2-plugin</artifactId>
<version>0.7.5</version>
<executions>
<execution>
<goals>
<goal>generate</goal>
</goals>
</execution>
</executions>
<configuration>
<schemaDirectory>src/main/resources/wsdl</schemaDirectory>
<schemaIncludes>
<include>*.xsd</include>
</schemaIncludes>
<verbose>true</verbose>
<extension>true</extension>
</configuration>
</plugin>
Of course you can also use your hand-coded classes with a hand-coded schema definition (by telling the marshaller where to find it). I don't think you can take influence on the WSDL generation by other means.

Related

Vaadin20: Scan Java code from Pom dependency

I want to put a Java class in a Maven artifact that uses the Vaadin #Endpoint annotation (from com.vaadin.flow.server.connect.Endpoint), to use this class in multiple Vaadin projects.
Here is a simple example of such a class:
import com.vaadin.flow.server.connect.Endpoint;
import lombok.RequiredArgsConstructor;
import java.util.Optional;
#Endpoint
#RequiredArgsConstructor
public class SupportInfoEndpoint {
public Optional<String> getSupportInfo(){
return Optional.of("mailto:support#my.corp");
}
}
The Maven artifact includes the source code of the class. What do I have to do so this class is scanned in the using project, by the Vaadin build process, so that
the corresponding TypeScript code for the frontend is generated
the class is included in the Spring-Boot application (so the endpoint is actually available at run time)
Is it possible at all?
Like Erik said, it will be implemented with #9010.
But there is a workaround depending on some restrictions. If you have every class that the endpoint needs in the same jar, you could trigger the typescript generation in same the jar by calling the goal "build-frontend" of vaadin-maven-plugin, then the typescript is generated and it's just a matter of some maven magic to move them to META-INF/resources/frontend (something similar of what is being done here). Then you just can package the endpoints in the jar.
For registering the endpoint in the project, you need to do something similar to what this class is doing, basically a ServiceInitListener that will execute the method registerEndpoint of the EndpointRegistry by using reflection.
Unfortunately it is not currently possible, but it will be once #9010 is implemented.
It is my understanding that it is one of the highest priority features to implement for the Fusion team.

Fake GORM mapping for results of an ad-hoc query

I'd like to use Grails to build application which is a front-end to a complex data search and analysis system written already as a set of stored procedures in a RDBMS (here, oracle).
I'd like to instantiate objects of some class I written as a wrapper against rows of some dataset returned from a stored procedure. For this class I don't need to have any GORM mapping at all, I want to execute the query manually and instantiate these objects from it's rows. Those objects will never be changed and written, as the whole DB should be read-only, only session information can be stored.
Hibernate can do all this, and it has "Immutable" and read-only entities for this, but when I tried to mark this entity as "Immutable" I didn't have much success.
Is it possible to create such a fake mapping and at all, should it be created?
What are other possible ways to do this ?
I don't think you can do that in GORM, but you can use plain Hibernate with Grails.
Add your classes in the src/groovy folder. One example, in src/groovy/example:
package example
import java.io.Serializable;
import javax.persistence.Id
import javax.persistence.Entity
import javax.persistence.Table
import javax.persistence.Column
import org.hibernate.annotations.Immutable
#Entity
#Table(name="first_result")
#Immutable
class FirstResult implements Serializable {
private static final long serialVersionUID = 1L
#Id
Integer id
#Column(name="name")
String resultName
}
(You can also write POJOs in src/java but then you need to write constructors, getters and setters)
And in the grails-app/conf/hibernate/hibernate.cfg.xml add:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN" "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<mapping class="example.FirstResult" />
</session-factory>
</hibernate-configuration>
Then, in your controllers and services you can use:
example.FirstResult.findAllById(1)
or any other method that works on domain classes in Grails.

Is it possible to use Ninject Named Bindings using ninject.extensions.xml

I have a very simple problem of DI, and wanted to know if there is a way to solve it using Ninject (or any other DI helper).
I have a Data Access interface that is implemented by several Data Sources providers, like DB, Sharepoint, CRM, etc.
I want to use Ninject to get a specific instance of the interface, based on a parameter that contains a code representing one of this implementations.
So far I know that I can do that by using named bindings , but I couldn't find a way to do the same by xml config file (Ninject.extensions.xml).
Ninject extensions xml provides a way to solve single mappings:
<module name="SomeModule">
<bind service="Game.IWeapon" to="Game.Sword"/>
<bind service="Game.IWarrior" toProvider="Game.SamuraiProvider"/>
</module>
I'd like to do a config like that, but using multiple mappings for the same interface, using a name, a code or the like.
TIA,
Milton
Just add a name property
<bind service="Game.IWeapon" to="Game.Sword" name="sword"/>
<bind service="Game.IWeapon" to="Game.Dagger" name="dagger"/>

Meaning of bean discovery mode annotated in CDI 1.1

I am migrating an application to Java EE 7 and would like to CDI 1.1. But I don't get the meaning of bean-discovery-mode="annotated". The
CDI 1.1 specification is not very helpful. At least I have not found any useful paragraph. Did I miss it?
This example runs perfectly with bean-discovery-mode="all" and injects an instance of LoggingClass:
public class LoggingClass {
public Logger logger = Logger.getLogger("ALOGGER");
}
#Test
public class MMLoggerProducerIT extends Arquillian {
#Inject private LoggingClass lc;
}
But if I change from bean-discovery-mode="all" to bean-discovery-mode="annotated" the container is not able to inject an instance into the field lc.
How do I have to annotate LoggingClass to use bean-discovery-mode="annotated" correctly?
When using bean-discovery-mode="annotated" only classes with a bean defining annotation are discovered. All other classes are ignored. Any scope type is a bean defining annotation. If a scope type is declared on a bean class, then the bean class is said to have a bean defining annotation [spec]. The 1.1 spec is not completely clear here. Only classes with a #NormalScope scope or #Dependent pseudo scope are discovered, #javax.inject.Singleton and all other #Scope (pseudo) scopes are ignored.
Note that the definition of a "bean defining annotation" changed in CDI 1.2 and is now very well defined:
The set of bean defining annotations contains:
#ApplicationScoped, #SessionScoped, #ConversationScoped and #RequestScoped annotations,
all other normal scope types,
#Interceptor and #Decorator annotations,
all stereotype annotations (i.e. annotations annotated with #Stereotype),
and the #Dependent scope annotation.
As a practical matter, bean-discovery-mode="ALL" turns on scanning of all classes in an archive. This is called an "explicit archive".
Omitting beans.xml, or setting bean-discovery-mode="ANNOTATED", makes the archive an implicit archive. In this case, the container will scan for beans with annotated scope types.
This explains why LoggingClass isn't injected when you set bean-discovery-mode="ANNOTATED". As documented in the Java EE 7 Tutorial:
CDI can only manage and inject beans annotated with a scope type in an implicit archive.
Edit: so just to be absolutely clear, you need to add a scope type to LoggingClass. So something like this:
#SessionScoped
public class LoggingClass {
public Logger logger = Logger.getLogger("ALOGGER");
}
In Java EE 7 and CDI 1.1, we removed the requirement to include the beans.xml deployment descriptor to turn on CDI for an archive, bringing CDI 1.1 in line with most other Java EE APIs where deployment descriptors are optional. It also removed the binary on/off nature of including beans.xml or not. You can control which files are scanned by the container with the settings in bean-discovery-mode.
See the JavaEE tutorial on packaging CDI applications here:
http://docs.oracle.com/javaee/7/tutorial/cdi-adv001.htm#CACDCFDE
I also agree with the answer form #rmuller. But I want to point out that there is still different behavior on application servers Payara and Wildfly.
See the following example with a normal not scoped class but having a #EJB injection:
public class SomeClass {
#EJB
MyService myService;
...
}
If you provide a beans.xml file with:
.... version="1.2" bean-discovery-mode="annotated"....
Payara 4.1 will treat the class SomeClass NOT as a CDI bean and will NOT inject the service EJB.
This is clear to me that it behaves as stated in the specification.
But Wildfly 10 treats the class as an CDI bean and injects the service EJB which is not expected. To get this working the beans.xml file should look like this:
.... version="1.2" bean-discovery-mode="all"....
It's amazing that the two most common application servers are different here in behavior.

Using CDI to inject a Data Access Object

Assuming I have a data access object that I've already written, I'd like to be able to use CDI to inject that into say, a service class. Furthermore, I have two implementations of that DAO.
My understanding of CDI is that I'd have to annotate my DAO implementation class so that CDI would know which implementation to inject.
The problem is, the DAO is in a .jar file. By annotating it with CDI annotations, I'm using JavaEE imports in a non-JavaEE class.
For example, let's say I have the following class
public class BusinessService {
#Inject #SomeMybatisQualifier AccountDAO accountDao;
...
}
The #Inject annotation comes from javax.inject.Inject. Now, this service class is dependent on a JavaEE environment.
Can someone please explain to me what I'm missing? How do I inject a non-annotated class into another non-annotated class? This is fairly simple with Spring.
I agree with LightGuard if there's enough classes. But for a couple, why not just produce them with #Produces?
Here's a decent example of implementing your own producer:
Depedency inject request parameter with CDI and JSF2
You should be able to write return new MyObject(); and you can add whatever qualifiers you want
Not sure what's unclear but here's the gist of things: For CDI to scan a jar for beans it must have a beans.xml. Else it will not be scanned and thus not available for injects.A String is not available either. If you try to inject a String say;
#Inject
String myString;
CDI will have no clue what to give you just like your jar. But I know what String I want (a requestparam) and I can let CDI know as well. How? Well I supply a qualifier #RequestParam to my producer (see example again) and now when I want to use it in client code I do it like this:
#Inject
#RequestParam
String myString;
You can do the same thing. Have a producer and just create a new instance of whatever you need and then return it. Now CDI will know just how to dependency inject that particular bean.
Now say you have 40 classes. Then it gets messy to produce them and you want to make sure it gets scanned instead. Then you write your own little extension, observe when CDI is about to scan and instruct it to scan additional jars. Such extension is probably easy to write but I don't know the details because I have not written any extensions like it
By far, the easiest thing would be to create a CDI extension to add the classes in the jar (because there's no beans.xml in that jar so it won't be picked up by CDI) and add additional qualifiers to the metadata.

Resources