DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Please enter at least three characters to search
Refcards Trend Reports
Events Video Library
Refcards
Trend Reports

Events

View Events Video Library

Zones

Culture and Methodologies Agile Career Development Methodologies Team Management
Data Engineering AI/ML Big Data Data Databases IoT
Software Design and Architecture Cloud Architecture Containers Integration Microservices Performance Security
Coding Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Culture and Methodologies
Agile Career Development Methodologies Team Management
Data Engineering
AI/ML Big Data Data Databases IoT
Software Design and Architecture
Cloud Architecture Containers Integration Microservices Performance Security
Coding
Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance
Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks

Because the DevOps movement has redefined engineering responsibilities, SREs now have to become stewards of observability strategy.

Apache Cassandra combines the benefits of major NoSQL databases to support data management needs not covered by traditional RDBMS vendors.

The software you build is only as secure as the code that powers it. Learn how malicious code creeps into your software supply chain.

Generative AI has transformed nearly every industry. How can you leverage GenAI to improve your productivity and efficiency?

Related

  • Using SQS With JMS for Legacy Applications
  • Javac and Java Katas, Part 2: Module Path
  • Javac and Java Katas, Part 1: Class Path
  • Multiplatform Directory Bookmarks on the Command Line

Trending

  • Prioritizing Cloud Security Risks: A Developer's Guide to Tackling Security Debt
  • Developers Beware: Slopsquatting and Vibe Coding Can Increase Risk of AI-Powered Attacks
  • Infrastructure as Code (IaC) Beyond the Basics
  • Operational Principles, Architecture, Benefits, and Limitations of Artificial Intelligence Large Language Models
  1. DZone
  2. Coding
  3. Languages
  4. Generating a JAX-WS Client JAR From WSDL URL Using PowerShell

Generating a JAX-WS Client JAR From WSDL URL Using PowerShell

Don't underestimate the power of PowerShell.

By 
Artun Kutluk user avatar
Artun Kutluk
·
Oct. 17, 19 · Tutorial
Likes (4)
Comment
Save
Tweet
Share
11.6K Views

Join the DZone community and get the full member experience.

Join For Free

PowerShell

Don't underestimate the power of PowerShell.

Sometimes, I like to get to the point directly rather than read an entire article. So if you are short on time, you may want to skip to the final step where you just have to copy the code, save it as a PowerShell script file, and run it with PowerShell.

However, if you are in the mood to do a little reading, then let's begin.

You may also like: [DZone Refcard] Windows PowerShell

1) Removing Unnecessary Files and Folders for a Clean Start

We will be dealing with WSDL, XSD, Jar, and XML files as well as some folders. To prevent any mistakes, let's first get rid of all the files with these extensions and the folders we will be working with.

Get-ChildItem returns the child items in the path specified. To get all the child items in subfolders, we use the Recurse parameter. The returned items can then be deleted with the Remove-Item command.

Get-ChildItem -Path "./*.wsdl" -Recurse | Remove-Item -force -recurse
Get-ChildItem -Path "./*.xsd" -Recurse | Remove-Item -force -recurse
Get-ChildItem -Path "./*.jar" -Recurse | Remove-Item -force -recurse

Remove-Item -LiteralPath "./files" -Force -Recurse -ErrorAction SilentlyContinue


2) Creating Necessary Folders

We need our target and META-INF  folders under the files folder. We can then create them with a new-item command.

new-item -Name "./files" -ItemType directory
new-item -Name "./files/target" -ItemType directory
new-item -Name "./files/META-INF" -ItemType directory


3) Creating Necessary Files

We will be using JAXB for generating Java classes from XML. Let's now create a jaxWs catalog and jaxbBindings files with their content embedded in the script.

$jaxWsCatalog = '<catalog xmlns="urn:oasis:names:tc:entity:xmlns:xml:catalog" prefer="system"><system systemId="http://localhost/wsdl/service.wsdl"uri="service.wsdl"/></catalog>'
$jaxbBindings = '<?xml version="1.0" encoding="UTF-8"?><jaxb:bindings xmlns:jaxb="http://java.sun.com/xml/ns/jaxb" xmlns:xjc="http://java.sun.com/xml/ns/jaxb/xjc" jaxb:version="2.1"><jaxb:globalBindings><xjc:serializable uid="1"/></jaxb:globalBindings></jaxb:bindings>'

$jaxWsCatalog | Set-Content "files/jax-ws-catalog.xml"
$jaxbBindings | Set-Content "files/Jaxb-bindings.xml"


4) Requesting the WSDL URL From the User and Retrieving Wsdl Content

All of the files and folders are ready. We now need to ask the user for the WSDL URL. In PowerShell, you can get an input from the user with  Read-Host. Once we get the URL, we can get the content of the wsdl with the Invoke-WebRequestcommand.

$wsdlUrl = Read-Host 'Please enter wsdl url'
$WsdlOriginal = (Invoke-WebRequest $wsdlUrl).Content


5) Checking for XSD Existence

The WSDL content may contain all xsd file information. We will check its existence by checking if the content contains schemaLocation or not using the IndexOf command.

$startIndex = [int]$WsdlOriginal.IndexOf("schemaLocation")+16

if( $startIndex -ge 16)


If XSD does not exist (the index is less then 16), we must skip to step 8. If it exists, then we have to retrieve the xsd file and modify the WSDL content retrieved in step 4.

6) Retrieving the XSD Content and Writing it to a File

By using the OutFile parameter, we can write the content retrieved with Invoke-WebRequest to a file with a name that we will give. In our example, it is  service.xsd:

Invoke-WebRequest -OutFile service.xsd $xsdUrl


7) Modifying WSDL Content

We retrieved the XSD file defined in the WSDL content. We need to change the reference of the XSD file from our URL to the local file. The start index of the string to be replaced was found in step 5. The end index is the position of the first quote symbol after the start index. This index can be found with:

$endIndex = [int]$WsdlOriginal.IndexOf('"',$startIndex)


The string between the start and end index must be replaced with the name of the XSD file ( service.xsd). This can ben achieved with the join command.

$WsdlModified = -join($WsdlOriginal.Substring(0,$startIndex),"service.xsd",$WsdlOriginal.Substring($endIndex))


The second modification we need to make is to replace the IP of the service-port-address-location with localhost. 

$startIndex = [int]$WsdlModified.IndexOf('address location="http://')+25
$endIndex = [int]$WsdlModified.IndexOf(':',$startIndex)
$WsdlModified = -join($WsdlModified.Substring(0,$startIndex),"localhost",$WsdlModified.Substring($endIndex))


8) Writing WSDL content to a File

Our WSDL content ( $WsdlOriginal if we skipped steps 6 and 7,  $WsdlModified otherwise) is ready. Let's now write it to a file with the Set-Content command.

$WsdlModified | Set-Content "service.wsdl"


9) Retrieving a Package Name From the User

Let's get the full package name of the classes to be generated from the user.

 $packageName = Read-Host 'Please enter package name'


10) Copying the Necessary Files

The files we generated in earlier steps must be in the folders we created in step 2. Let's copy the files to the folders:

copy service.wsdl files\
copy *.xsd files\
cd files
copy service.wsdl META-INF\
copy *.xsd META-INF\
copy jax-ws-catalog.xml META-INF\


11) Generating the Client

The preparation is complete. Let's create our client into the target folder with the package name $packageName using the Jaxb-bindings.xml file and XautoNameResolution parameter to prevent a problem with the class name already in use.

wsimport -d target -keep -p $packageName -b Jaxb-bindings.xml -B-XautoNameResolution -wsdllocation http://localhost/wsdl/service.wsdl -catalog jax-ws-catalog.xml service.wsdl


12) Removing Java Files

Our client has been generated. We have got the Java files and the class files. To decrease the size of the final JAR, let's get rid of the Java files. You may skip this step if you want to keep the Java files.

$packageName = [string]$packageName -replace "\.", "/"
Get-ChildItem -Path $packageName *.java | foreach { Remove-Item -Path $_.FullName }


13) Creating a JAR File and Moving it to the Root Folder

Now, let's create the JAR file and move it to the root folder.

jar cvf service.jar .
cd ..
cd ..
Move-Item files/target/service.jar ./


14) Final Code

If we combine all the steps above and add some controls and comments, we will get the result below. Once you save the following code in the PowerShell script file and run it, all you have to do to generate a JAX-WS client JAR and enter a valid WSDL URL and enter the package name for the generated classes.

#Removal of unnecessary files and folders for a clean start
Get-ChildItem -Path "./*.wsdl" -Recurse | Remove-Item -force -recurse
Get-ChildItem -Path "./*.xsd" -Recurse | Remove-Item -force -recurse
Get-ChildItem -Path "./*.jar" -Recurse | Remove-Item -force -recurse

Remove-Item -LiteralPath "./files" -Force -Recurse -ErrorAction SilentlyContinue

#Creation of necessary folders
new-item -Name "./files" -ItemType directory
new-item -Name "./files/target" -ItemType directory
new-item -Name "./files/META-INF" -ItemType directory

#Creation of necessary files
$jaxWsCatalog = '<catalog xmlns="urn:oasis:names:tc:entity:xmlns:xml:catalog" prefer="system"><system systemId="http://localhost/wsdl/service.wsdl"uri="service.wsdl"/></catalog>'
$jaxbBindings = '<?xml version="1.0" encoding="UTF-8"?><jaxb:bindings xmlns:jaxb="http://java.sun.com/xml/ns/jaxb" xmlns:xjc="http://java.sun.com/xml/ns/jaxb/xjc" jaxb:version="2.1"><jaxb:globalBindings><xjc:serializable uid="1"/></jaxb:globalBindings></jaxb:bindings>'

$jaxWsCatalog | Set-Content "files/jax-ws-catalog.xml"
$jaxbBindings | Set-Content "files/Jaxb-bindings.xml"

Write-Output ''
Write-Output 'Deleted unnecessary files/folders'
Write-Output 'Created necessary files/folders'
Write-Output ''

#Request wsdl url from user and retrieve wsdl content
$wsdlUrl = Read-Host 'Please enter wsdl url'
$WsdlOriginal = (Invoke-WebRequest $wsdlUrl).Content

Try
{ 
#Check if the wsdl contains xsd file definition by looking for schemaLocation tag name
$startIndex = [int]$WsdlOriginal.IndexOf("schemaLocation")+16

#if xsd exists 
if( $startIndex -ge 16)
{
$endIndex = [int]$WsdlOriginal.IndexOf('"',$startIndex)

Try{
#retrieve the xsd url from wsdl
$xsdUrl = [string]$WsdlOriginal.Substring($startIndex,$endIndex-$startIndex)

#if the xsd url is not a full path url, append the prefix of the wsdl url to the begining of xsd url
if( ([int]$xsdUrl.IndexOf("http")) -lt 0 )
{
$xsdUrl = -join($wsdlUrl.Substring(0,($wsdlUrl.LastIndexOf('/')+1)),$xsdUrl) 
}

#retrieve the xsd file from the xsd url and then write its content to service.xsd file
Invoke-WebRequest -OutFile service.xsd $xsdUrl
}Catch
{
#if something goes wrong, ask the user for the valid xsd url and then retriev and write its content to service.xsd file
$xsdUrl = Read-Host 'Please enter valid xsd url'
Invoke-WebRequest -OutFile service.xsd $xsdUrl
}

#replace the xsd schemaLocation value with the file name of the xsd
$WsdlModified = -join($WsdlOriginal.Substring(0,$startIndex),"service.xsd",$WsdlOriginal.Substring($endIndex))

#replace the ip of the service-port-address-location with localhost
$startIndex = [int]$WsdlModified.IndexOf('address location="http://')+25

if( $startIndex -ge 0 )
{
$endIndex = [int]$WsdlModified.IndexOf(':',$startIndex)
$WsdlModified = -join($WsdlModified.Substring(0,$startIndex),"localhost",$WsdlModified.Substring($endIndex))
}else
{
Write-Output 'ATTENTION! service port address ip could not be replaced with localhost. Change must be made manually!'
}

#write the modified wsdl to service.wsdl file
$WsdlModified | Set-Content "service.wsdl"
}else
{
#There is no xsd. For this reason no need to make changes with wsdl so write it to service.wsdl as it is.
$WsdlOriginal | Set-Content "service.wsdl"
}

Write-Output 'Check input files and make necessary changes if needed'
pause

#ask user for package name
$packageName = Read-Host 'Please enter package name'

#copy necessary files to folders 
copy service.wsdl files\
copy *.xsd files\
cd files
copy service.wsdl META-INF\
copy *.xsd META-INF\
copy jax-ws-catalog.xml META-INF\

#generate client
wsimport -d target -keep -p $packageName -b Jaxb-bindings.xml -B-XautoNameResolution -wsdllocation http://localhost/wsdl/service.wsdl -catalog jax-ws-catalog.xml service.wsdl

#remove .java files to minimize the size of the client jar
cd target
$packageName = [string]$packageName -replace "\.", "/"
Get-ChildItem -Path $packageName *.java | foreach { Remove-Item -Path $_.FullName }

#create the jar file and move it to the same folder with the powershell script file
jar cvf service.jar .
cd ..
cd ..
Move-Item files/target/service.jar ./

pause

}Catch
{
Write-Output "An error occured. Open the powershell script file and check each step"
}


That's it! Happy coding!

Further Reading

[DZone Refcard] Windows PowerShell

PowerShell JAR (file format)

Opinions expressed by DZone contributors are their own.

Related

  • Using SQS With JMS for Legacy Applications
  • Javac and Java Katas, Part 2: Module Path
  • Javac and Java Katas, Part 1: Class Path
  • Multiplatform Directory Bookmarks on the Command Line

Partner Resources

×

Comments
Oops! Something Went Wrong

The likes didn't load as expected. Please refresh the page and try again.

ABOUT US

  • About DZone
  • Support and feedback
  • Community research
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Core Program
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 3343 Perimeter Hill Drive
  • Suite 100
  • Nashville, TN 37211
  • support@dzone.com

Let's be friends:

Likes
There are no likes...yet! 👀
Be the first to like this post!
It looks like you're not logged in.
Sign in to see who liked this post!