Proper usage of Apache Commons Configuration - java

My code is the following:
package org.minuteware.jgun;
import org.apache.commons.configuration.*;
class ConfigReader {
public void getconfig() {
Configuration config;
try {
config = new PropertiesConfiguration("gun.conf");
} catch (ConfigurationException e) {
e.printStackTrace();
}
String day = config.getString("sync_overlays");
System.out.println(day);
}
}
Eclipse has two problems with this code:
For the package org.minuteware.jgun; line it says The type org.apache.commons.lang.exception.NestableException cannot be resolved. It is indirectly referenced from required .class files
For the line } catch (ConfigurationException e) { it says No exception of type ConfigurationException can be thrown; an exception type must be a subclass of Throwable
I've found ConfigurationException in Java?, but the solution provided there does not help.

The core of Apache Commons Configuration has the following runtime dependencies:
Apache Commons Lang (version 2.2, 2.3, 2.4, 2.5 or 2.6)
Apache Commons Collections (version 3.1, 3.2 or 3.2.1)
Apache Commons Logging (version 1.0.4, 1.1 or 1.1.1)
Put them in your classpath as well. Your particular problem is caused by a missing Lang dependency.

This library issue plagued me for a few days until I figure out why Apache was wanting me to use old libraries.
If you are being requested to use older Lang libraries by the compiler, ensure you are making your Apache properties file the NEW way, not the old way (which utilizes the older lang libraries).
https://commons.apache.org/proper/commons-configuration/userguide/howto_filebased.html
is the Apache site I derived my following code from, which does a basic SET operation against a file on my Windows machine.
import org.apache.commons.configuration2.Configuration;
import org.apache.commons.configuration2.FileBasedConfiguration;
import org.apache.commons.configuration2.PropertiesConfiguration;
import org.apache.commons.configuration2.builder.FileBasedConfigurationBuilder;
import org.apache.commons.configuration2.builder.fluent.Parameters;
public final class Settings implements Serializable {
private Configuration config;
private String propertiesFilePath;
private FileBasedConfigurationBuilder<FileBasedConfiguration> builder;
public Settings(String propertiesFilePath) {
Parameters params = new Parameters();
File propFile = new File(propertiesFilePath);
builder = new FileBasedConfigurationBuilder<FileBasedConfiguration>(PropertiesConfiguration.class)
.configure(params.fileBased()
.setFile(propFile));
try {
config = builder.getConfiguration();
} catch (Exception e) {
System.out.println("Exception - Settings constructor: " + e.toString());
}
}//end constructor
public void setValue(String key, String value) throws Exception {
config.setProperty(key, value);
builder.save();
}// end setter method
}//end class

Related

How to install or register a Saxon HE 10.3 Configuration? Configuration is not being used

I'm trying to use a custom Configuration for saxon HE 10.3.
The Configuration is not being used. Presumably the config needs to be registered or installed? But how?
Here's my code:
final Configuration config = new net.sf.saxon.Configuration();
/**/ config.setLocalizerFactory(new LocalizerFactory() {
public Numberer getNumberer(final String language, final String country) {
if (language.equals("de")) {
return Numberer_de.getInstance();
} else {
return null;
}
}
});
net.sf.saxon.Transform.main(new String[] {
"-s:source.xml",
"-xsl:stylesheet.xslt",
"-o:result.txt"
});
You really don't want to be running net.sf.saxon.Transform.main from a Java application: use either the s9api or JAXP transformation APIs. The net.sf.saxon.Transform.main interface is designed for use from the command line, and it can therefore only modify the configuration through command line switches. It also has drawbacks like shutting down the Java VM if the transformation fails.
There is a workaround, which is to use the -init option on the command line to trigger user-supplied initialisation code (which has access to the Configuration object), but that's only really digging yourself deeper into your hole. I'd recommend switching to the s9api API.
Documentation: https://saxonica.com/documentation/index.html#!using-xsl/embedding
If you want to change the configuration when running Saxon from the command line, as Michael said, there is the -init option to pass in the name of a class implementing the Initializer interface https://saxonica.com/documentation/index.html#!javadoc/net.sf.saxon.lib/Initializer so you would use roughly e.g.
package com.example;
import net.sf.saxon.option.local.Numberer_de;
import net.sf.saxon.lib.Initializer;
import net.sf.saxon.Configuration;
import net.sf.saxon.lib.LocalizerFactory;
import net.sf.saxon.lib.Numberer;
import javax.xml.transform.TransformerException;
public class MyInitializer implements Initializer {
public override void initialize(Configuration config) throws TransformerException {
config.setLocalizerFactory(new LocalizerFactory() {
public Numberer getNumberer(final String language, final String country) {
if (language.equals("de")) {
return Numberer_de.getInstance();
} else {
return null;
}
}
});
}
}
compile that, put it on the classpath and then run e.g. java -cp saxon-he-10.3.jar;com/example/MyInitializer;net/sf/saxon/option/local/Numberer_de net.sf.saxon.Transform -init:com.example.MyInitializer -s:source.xml -xsl:stylesheet.xslt -o:result.txt.
Or you can subclass net.sf.saxon.Transform.
On the other hand, if you don't want to run Saxon from the command line but from the JAXP API then I think one approach is to create the Configuration e.g.
Configuration config = new Configuration();
config.setLocalizerFactory(new LocalizerFactory() {
public Numberer getNumberer(final String language, final String country) {
if (language.equals("de")) {
return Numberer_de.getInstance();
} else {
return null;
}
}
});
TransformerFactory transformerFactory = new TransformerFactoryImpl(config);
Templates templates = transformerFactory.newTemplates(xsltSource);
What was missing, was how to inject the Config. This worked for me:
import net.sf.saxon.Configuration;
import net.sf.saxon.TransformerFactoryImpl;
import net.sf.saxon.lib.Feature;
final TransformerFactoryImpl factory = (TransformerFactoryImpl) TransformerFactory.newInstance();
factory.getProcessor().setConfigurationProperty(Feature.CONFIGURATION, config);

java FileUtils.delete() not deleting folder

Whats wrong with my code ? with reference with this question
the folder is not being deleted.
File f = new File(directory+"\\OOO");
if (f.exists())
{
System.out.println(f);
FileUtils.delete(f);
f.delete();
// f.mkdir();
}
else
{
System.out.println("created");
//f.mkdir();
}
FileUtils does not contain any method named delete();
You should use deleteDirectory() to recursively delete directory.
Or you can also use deleteQuitely() to suppress any exceptions while deletion.
FileUtils does not contain any method named delete(), so you should use deleteDirectory() instead. Also, please ensure you have imported the correct Java file utility class from Apache Commons IO. If it is not the case, your need to
Download Apache Commons IO as a JAR file, link it to the classpath
Or declare a dependency the Apache Commons IO in your Maven, or other dependency management system.
Here's the code:
import org.apache.commons.io.FileUtils;
public class YourClass
{
public void yourMethod() throws IOException
{
File f = new File(directory+"\\OOO");
if (f.exists())
{
FileUtils.deleteDirectory(f);
}
...
}
}
This may help
try {
FileUtils.deleteDirectory(new File("path");
//path Example - C:\\myfolder\\foldertodelete
} catch (IOException e) {
}

how to migrate from opensaml 2.6 to 3.1.1

I have to migrate a class from opensaml 2.6 to opensaml 3.1.1
Compiling I obtain some errors
1)
Element plaintextElement = getElementAssertion(inputBean);
String xml = XMLHelper.prettyPrintXML(plaintextElement);
I can't find the class XMLHelper in the new version.
2)
DefaultBootstrap.bootstrap();
builderFactory = Configuration.getBuilderFactory();
Configuration.getMarshallerFactory().getMarshaller(assertion).marshall(assertion);
I can'f find class DefaultBootstrap and I can't find a class Configuration with the methods getBuilderFactory(), getMarshallerFactory()
3)
BasicCredential credential = new BasicCredential();
Now the contructor new BasicCredential() is not visible.
I haven't found documentation with deprecation indication.
What must I do to port this class to the opensaml 3.1.1 version?
Not sure if you managed to upgrade to opensaml 3 already but since I came across this while attempting the upgrade myself I thought I'm gonna document what I found.
There's very little documentation as apparently it's not a priority for them at the moment (also mentioned here: OpenSaml3 Documentation), the most useful (even if by far not complete) page I found is this one: https://wiki.shibboleth.net/confluence/display/OS30/Initialization+and+Configuration
1) There's a class SerializeSupport with a method prettyPrintXML in lib net.shibboleth.utilities:java-support
2) Initialization is now done via InitializationService
e.g.
InitializationService.initialize();
You can retrieve the builder/marshallers via XMLObjectProviderRegistrySupport e.g.:
XMLObjectProviderRegistrySupport.getMarshallerFactory()
XMLObjectProviderRegistrySupport.getBuilderFactory()
XMLObjectProviderRegistrySupport.getUnmarshallerFactory()
Mind that opensaml is using the Java Service Provider API. In my case (using OSGi bundle org.apache.servicemix.bundles:org.apache.servicemix.bundles.opensaml) for parsing a SAML assertion I added the SPI config META-INF/services/org.opensaml.core.config.Initializer containing the following entries:
org.opensaml.core.xml.config.XMLObjectProviderInitializer
org.opensaml.core.xml.config.GlobalParserPoolInitializer
org.opensaml.saml.config.XMLObjectProviderInitializer
org.opensaml.saml.config.SAMLConfigurationInitializer
org.opensaml.xmlsec.config.XMLObjectProviderInitializer
EDIT: The above worked in a test but did not run in the OSGi container. Workaround for OSGi: OpenSAML3 resource not found 'default-config.xml' in OSGi container
If you use the standard libraries (org.opensaml:opensaml-core, org.opensaml:opensaml-saml-api, org.opensaml:opensaml-saml-impl, ...) you may not need to add any SPI config as the jars already contain SPI configs with a standard configuration for initialization.
3) There's a class BasicCredential in lib org.opensaml:opensaml-security-api. I don' see an alternative to providing a key during initalization.
I am learning how to use the OS3 for development. This is one example to convert base 64 saml request to SAMLObject in V3 version. Hope it can help you.
The project see the github repository
public class SAMLToolkit {
public static SAMLObject convertBase64ToSaml(String base64Str) {
byte[] decodedBytes = new byte[0];
try {
decodedBytes = Base64.decode(base64Str);
} catch (Base64DecodingException e) {
e.printStackTrace();
return null;
}
InputStream is = new ByteArrayInputStream(decodedBytes);
//is = new InflaterInputStream(is, new Inflater(true));
try {
InitializationService.initialize();
Document messageDoc;
BasicParserPool basicParserPool = new BasicParserPool();
basicParserPool.initialize();
messageDoc = basicParserPool.parse(is);
Element messageElem = messageDoc.getDocumentElement();
Unmarshaller unmarshaller = XMLObjectProviderRegistrySupport.getUnmarshallerFactory().getUnmarshaller(messageElem);
assert unmarshaller != null;
return(SAMLObject) unmarshaller.unmarshall(messageElem);
} catch (InitializationException e) {
e.printStackTrace();
return null;
} catch (XMLParserException e) {
e.printStackTrace();
return null;
} catch (UnmarshallingException e) {
e.printStackTrace();
return null;
} catch (ComponentInitializationException e) {
e.printStackTrace();
return null;
}
}
}

loading jar at runtime and using its class

i have one problem in which i need some help.
Problem statement:
I'm using one jar to generate reports in excel sheet format. This jar is required only if the user wants to generate report in excel format. Other formats of report available are html and txt which don't require this jar.
The current user generates the reports in html format so he says, why should I download this jar and export it in the classpath when I don't need report in the excel format.
Now the problem is if this jar is removed, this build will fail/as all the imports to the classes which are being used will give error. Class.forName can load the class at run-time and doesn't give me error but with this I will not be able to use the method of that class since I cannot have the reference of the class.
Is there any way out or this is not possible?
Did you try to compile it with the jar as a dependency for the compile.
Then at runtime, you will have a part where you check if the jar is needed and if so you can dynamically get the jar and load it like so (Code does not work like this of course ;) ):
import java.lang.reflect.Method;
import java.net.URLClassLoader;
Method addURL = null;
try {
addURL = URLClassLoader.class.getDeclaredMethod("addURL",
new Class[]{URL.class});
} catch (Exception e1) {
//Log error
}
addURL.setAccessible(true);
//Maybe download the file or check if file exist else give out error and end processing
File yourJar = new File(filePath+"/"+fileName+".jar");
//Replace Your.Main.Class with your main class
addURL.invoke(Your.Main.Class.class
.getClassLoader(), yourJar.toURI().toURL());
// Your class should now be loaded and no more ClassNotFound exception should occur when it is accessed, but not if it is accessed before!
The problem is that you are hard wiring your dependencies. So your code needs to do some imports for the third party libs. What you need is to loosely couple the third party libs so that the core of you application does not need to import anything related to 3rd party libs. Use an interface which defines a method or the set of methods needed to generate reports in any format. Make this interface part of your core application. Format specific implementation goes then in separate modules which are dependent on your core application and on the 3rd party libs. Use a factory in the core application to load the specific implementation at runtime using refelction. If a format is requested from which the relevant module jars are not present in the classpath, a ClassNotFoundException will be thrown, catch it and handle accordingly.
Here a sample structure for your application
Core application
class ReportData {
}
interface ReportGenerator {
byte[] generate(ReportData data);
}
class ReportGeneratorFactory {
public ReportGenerator getInstance(String format)
throws InstantiationException, IllegalAccessException, ClassNotFoundException {
ReportGenerator reportGenerator = null;
if("txt".equals(format)) {
reportGenerator = (ReportGenerator)
Class.forName("com.foo.TxtReportGenerator").newInstance();
} else if("html".equals(format)) {
reportGenerator = (ReportGenerator)
Class.forName("com.foo.HtmlReportGenerator").newInstance();
} else if("xl".equals(format)) {
reportGenerator = (ReportGenerator)
Class.forName("com.foo.XlReportGenerator").newInstance();
} else {
throw new UnsupportedOperationException(
String.format("Unsupport format %s", format));
}
return reportGenerator;
}
}
Txt / Html Export (Could be part of the core application if no 3rd party lib are needed)
class TxtReportGenerator implements ReportGenerator {
public byte[] generate(ReportData data) {
// TODO Auto-generated method stub
return null;
}
}
class HtmlReportGenerator implements ReportGenerator {
public byte[] generate(ReportData data) {
// TODO Auto-generated method stub
return null;
}
}
Module (own jar) for XL report (depends on your core application and on the 3rd party lib)
class XlReportGenerator implements ReportGenerator {
public byte[] generate(ReportData data) {
// TODO Auto-generated method stub
return null;
}
}
Usage:
public static void main(String[] args)
throws InstantiationException, IllegalAccessException, ClassNotFoundException {
byte[] report = new ReportGeneratorFactory()
.getInstance("xl")
.generate(new ReportData());
}

JAX-WS = When Apache CXF is installed it "steals" default JDK JAX-WS implementation, how to solve?

I have a strange problem.
Using wsimport I generated als JAX-WS Code from a WSDL (in a dedicated eclipse java project). This works fine in JDK6 without any external dependencies (running in Eclipse)
I have second project where I once used Apache CXF. If I copy the Code described in 1.) into this project, suddenly not the JDK executes the JAX-WS stuff (files I generated), but rather Apache CXF.
How can I prevent Apache CXF "running" the JAX-WS stuff. (Problem is, CXF Fails to run the code...). I also completely do not understand how Apache CXF discovers these classes. I did not register them anywere?
Thank you very much!
Markus
Apache CXF (cxf-rt-frontend-jaxws-*.jar to be precise) registers itself as a JAX-WS provider in the JVM. Inside the aforementioned JAR there is a file named: /META-INF/services/javax.xml.ws.spi.Provider with the following contents:
org.apache.cxf.jaxws.spi.ProviderImpl
If you now look at javax.xml.ws.spi.FactoryFinder#find method you will discover that JDK searches the CLASSPATH for the presence of javax.xml.ws.spi.Provider file and falls back to default Sun implementation if not available. So you have two options to force fallback:
either remove cxf-rt-frontend-jaxws-*.jar from CLASSPATH
or override javax.xml.ws.spi.Provider file provided by CXF to point to fallback location
The second option is actually a bit easier. Simply create:
/src/main/resources/META-INF/services/javax.xml.ws.spi.Provider
file (assuming you are using Maven) with the following contents:
org.apache.cxf.jaxws.spi.ProviderImpl
That's it, tested with javax.xml.ws.Endpoint#publish.
For the default implementation put:
com.sun.xml.internal.ws.spi.ProviderImpl
inside /src/main/resources/META-INF/services/javax.xml.ws.spi.Provider
I tried the other and I just couldn't make it work at all, so to set CXF if it was not set to CXF, I just override the delegate inside the service.
try {
loc = this.getClass().getResource(wsdlResource);
QName qName = new QName( wsTargetNamespace, wsName );
service = new YourWS(loc, qName);
Field delegateField = Service.class.getDeclaredField("delegate"); //ALLOW CXF SPECIFIC SERVICE DELEGATE ONLY!
delegateField.setAccessible(true);
ServiceDelegate previousDelegate = (ServiceDelegate) delegateField.get(service);
if (!previousDelegate.getClass().getName().contains("cxf")) {
ServiceDelegate serviceDelegate = ((Provider) Class.forName("org.apache.cxf.jaxws.spi.ProviderImpl").newInstance())
.createServiceDelegate(loc, qName, service.getClass());
log.info("The " + getClass().getSimpleName() + " delegate is changed from " + "[" + previousDelegate + "] to [" +
serviceDelegate +
"]");
delegateField.set(service, serviceDelegate);
}
port = service.getYourWSSoap();
The standard finding mechanisms don't seem to work nicely in OSGi (*).
There are two ways I've gotten to work forcing the service to pick up the CXF implementation of javax.xml.ws.spi.Provider:
the approach of setting delegate by reflection given in EpicPandaForce's answer to this question (https://stackoverflow.com/a/31892305/109079)
calling the lower-level JaxWsProxyFactoryBean; this seems to avoid all calls to the javax.xml.ws.spi.FactoryFinder included with Java which is the root of the problem
Here is an example of the latter, for less intrepid coders who prefer not reflectively changing private fields:
JaxWsProxyFactoryBean factory = new JaxWsProxyFactoryBean();
factory.getClientFactoryBean().getServiceFactory().setWsdlURL(WinRmService.WSDL_LOCATION);
factory.setServiceName(WinRmService.SERVICE);
factory.setEndpointName(WinRmService.WinRmPort);
// factory.setFeatures(...); // if required
Service winrm = factory.create(WinRm.class);
Client client = ClientProxy.getClient(winrm);
A couple of notes:
Passing a URL as above, rather than the simpler factory.setWsdlURL(String) may be needed if the WSDL is a resource on the classpath (avoid unresolvable bundle://... URLs for classpath items)
You may need additional bundles for features (such as addressing)
(*) As for why the finding mechanisms don't work in most OSGi containers, check out this little bit of nasty in Oracle Java's FactoryFinder:
private static final String OSGI_SERVICE_LOADER_CLASS_NAME = "com.sun.org.glassfish.hk2.osgiresourcelocator.ServiceLoader";
private static boolean isOsgi() {
try {
Class.forName(OSGI_SERVICE_LOADER_CLASS_NAME);
return true;
} catch (ClassNotFoundException ignored) {
}
return false;
}
OSGi = Glassfish? Fishy indeed!
I had a similar problem. In my case I had to use org.apache.cxf.jaxws.spi.ProviderImpl for JAX-WS stuff (creating webservice endpoints etc.) and com.sun.xml.internal.ws.spi.ProviderImpl for publishing endpoints on com.sun.net.httpserver.HttpsServer.
I managed to solve this by creating my own provider which extends javax.xml.ws.spi.Provider and using it instead of the default one.
package provider;
import java.net.URL;
import java.util.List;
import javax.xml.namespace.QName;
import javax.xml.transform.Source;
import javax.xml.ws.Endpoint;
import javax.xml.ws.EndpointReference;
import javax.xml.ws.WebServiceFeature;
import javax.xml.ws.spi.Provider;
import javax.xml.ws.spi.ServiceDelegate;
import javax.xml.ws.wsaddressing.W3CEndpointReference;
import org.w3c.dom.Element;
public class MyProvider extends Provider
{
#SuppressWarnings({ "rawtypes", "unchecked" })
#Override
public ServiceDelegate createServiceDelegate(URL wsdlDocumentLocation, QName serviceName, Class serviceClass)
{
try {
return ((Provider) Class.forName("org.apache.cxf.jaxws.spi.ProviderImpl").newInstance()).createServiceDelegate(wsdlDocumentLocation, serviceName, serviceClass.getClass());
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
#Override
public Endpoint createEndpoint(String bindingId, Object implementor)
{
try {
return ((Provider) Class.forName("com.sun.xml.internal.ws.spi.ProviderImpl").newInstance()).createEndpoint(bindingId, implementor);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
#Override
public Endpoint createAndPublishEndpoint(String address, Object implementor)
{
try {
return ((Provider) Class.forName("com.sun.xml.internal.ws.spi.ProviderImpl").newInstance()).createAndPublishEndpoint(address, implementor);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
#Override
public EndpointReference readEndpointReference(Source eprInfoset)
{
try {
return ((Provider) Class.forName("org.apache.cxf.jaxws.spi.ProviderImpl").newInstance()).readEndpointReference(eprInfoset);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
#Override
public <T> T getPort(EndpointReference endpointReference, Class<T> serviceEndpointInterface, WebServiceFeature... features)
{
try {
return ((Provider) Class.forName("org.apache.cxf.jaxws.spi.ProviderImpl").newInstance()).getPort(endpointReference, serviceEndpointInterface, features);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
#Override
public W3CEndpointReference createW3CEndpointReference(String address, QName serviceName, QName portName, List<Element> metadata, String wsdlDocumentLocation, List<Element> referenceParameters)
{
try {
return ((Provider) Class.forName("org.apache.cxf.jaxws.spi.ProviderImpl").newInstance()).createW3CEndpointReference(address, serviceName, portName, metadata, wsdlDocumentLocation,
referenceParameters);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
}
Then simply create:
/src/main/resources/META-INF/services/javax.xml.ws.spi.Provider
file (assuming you are using Maven) with the following contents:
package.MyProvider

Categories

Resources