Is there a library for reading maven2/3 pom xml files? - java

I would like to read a pom.xml in Java code. I wonder if there is a library for that, so I can have an iterator for different sections, e.g., dependenes, plugins, etc. I want to avoid to build a parser by hand.

You can try MavenXpp3Reader which is part of maven-model. Sample code:
MavenXpp3Reader reader = new MavenXpp3Reader();
Model model = reader.read(new FileReader(mypom));

Firstly, I'm assuming you are not already running inside a Maven plugin, as there are easier ways to achieve that with the available APIs there.
The MavenXpp3Reader solution posted earlier will allow you to read the POM easily, however does not take into account inheritance of the parent and interpolation of expressions.
For that, you would need to use the ModelBuilder class.
Use of this is quite simple, for example from Archiva is this code fragment:
ModelBuildingRequest req = new DefaultModelBuildingRequest();
req.setProcessPlugins( false );
req.setPomFile( file );
req.setModelResolver( new RepositoryModelResolver( basedir, pathTranslator ) );
req.setValidationLevel( ModelBuildingRequest.VALIDATION_LEVEL_MINIMAL );
Model model;
try
{
model = builder.build( req ).getEffectiveModel();
}
catch ( ModelBuildingException e )
{
...
}
You must do two things to run this though:
instantiate and wire an instance of ModelBuilder including its private fields
use one of Maven's resolvers for finding the parent POMs, or write your own (as is the case in the above snippet)
How best to do that depends on the DI framework you are already using, or whether you want to just embed Maven's default container.

This depends on what you're trying to achieve. If you just want to treat it as an XML with embedded XML files, go with suggestions already offered.
If you are looking to implement some form of Maven functionality into your app, you could try the new aether library. I haven't used it, but it looks simple enough to integrate and should offer Maven functionality with little effort on your part.
BTW, this library is a Maven 3 lib, not Maven 2 (as specified in your tag). Don't know if that makes much difference to you

Related

ServiceLoader cannot find service loaded from path

I have been trying to do a kind of plugin-system using the ServiceLoader. There are 2 modules, the first provides the abstract class LoadedRealmPlugin. The second one extends this class. I have added the file corresponding to the full name of the ServiceProvider and added the service-class to it. IntelliJ does not find any errors (but when changing the filename or classname it does). Here is the structure:
MainModule
src
main
java
com.interestingcompany.mainmodule
LoadedRealmPlugin
MainModule.iml
Plugin
META-INF
services
com.interestingcompany.mainmodule (-> Content: "PluginExtension")
src
PluginExtension
Plugin.iml
(This is simplified, I left out classes that (I think) are not important to the ServiceLoader. I can post a screenshot of the actual structure if anyone needs it)
Here is the code I use to load the Service:
File file = new File("Plugins/Plugin.jar");
URLClassLoader c = new URLClassLoader(new URL[]{file.getAbsoluteFile().toURI().toURL()});
ServiceLoader<LoadedRealmPlugin> loader = ServiceLoader.load(LoadedRealmPlugin.class, c);
LoadedRealmPlugin p = loader.iterator().next(); // Throws a java.util.NoSuchElementException
p.Initialize(RealmPath); // Abstract method implemented in the service
return p;
When trying to run it, I always get an empty ServiceLoader. I looked at this post, but I was not quite sure about how to apply that answer since I am trying to load my plugin from a file. In addition, I found this post. Yet, there was no answer, just some comments that did not seem to have answered the question.
As you might have been able to tell, this is my first time working with classloaders. If there is any additional information needed, just ask me. Thank you for reading through my beginner troubles.
package-less classes are in the unnamed package, which is inaccessible to rather a lot of code, notably including here.
Put PluginExtension.java in a package, make sure the content of your META-INF/services/com.ic.mainmodule file reflects this (content should be pkg.PluginExtension), and it'll work fine.

How to create a tensorflow serving client for the 'wide and deep' model?

I've created a model based on the 'wide and deep' example (https://github.com/tensorflow/tensorflow/blob/master/tensorflow/examples/learn/wide_n_deep_tutorial.py).
I've exported the model as follows:
m = build_estimator(model_dir)
m.fit(input_fn=lambda: input_fn(df_train, True), steps=FLAGS.train_steps)
results = m.evaluate(input_fn=lambda: input_fn(df_test, True), steps=1)
print('Model statistics:')
for key in sorted(results):
print("%s: %s" % (key, results[key]))
print('Done training!!!')
# Export model
export_path = sys.argv[-1]
print('Exporting trained model to %s' % export_path)
m.export(
export_path,
input_fn=serving_input_fn,
use_deprecated_input_fn=False,
input_feature_key=INPUT_FEATURE_KEY
My question is, how do I create a client to make predictions from this exported model? Also, have I exported the model correctly?
Ultimately I need to be able do this in Java too. I suspect I can do this by creating Java classes from proto files using gRPC.
Documentation is very sketchy, hence why I am asking on here.
Many thanks!
I wrote a simple tutorial Exporting and Serving a TensorFlow Wide & Deep Model.
TL;DR
To export an estimator there are four steps:
Define features for export as a list of all features used during estimator initialization.
Create a feature config using create_feature_spec_for_parsing.
Build a serving_input_fn suitable for use in serving using input_fn_utils.build_parsing_serving_input_fn.
Export the model using export_savedmodel().
To run a client script properly you need to do three following steps:
Create and place your script somewhere in the /serving/ folder, e.g. /serving/tensorflow_serving/example/
Create or modify corresponding BUILD file by adding a py_binary.
Build and run a model server, e.g. tensorflow_model_server.
Create, build and run a client that sends a tf.Example to our tensorflow_model_server for the inference.
For more details look at the tutorial itself.
Just spent a solid week figuring this out. First off, m.export is going to deprecated in a couple weeks, so instead of that block, use: m.export_savedmodel(export_path, input_fn=serving_input_fn).
Which means you then have to define serving_input_fn(), which of course is supposed to have a different signature than the input_fn() defined in the wide and deep tutorial. Namely, moving forward, I guess it's recommended that input_fn()-type things are supposed to return an InputFnOps object, defined here.
Here's how I figured out how to make that work:
from tensorflow.contrib.learn.python.learn.utils import input_fn_utils
from tensorflow.python.ops import array_ops
from tensorflow.python.framework import dtypes
def serving_input_fn():
features, labels = input_fn()
features["examples"] = tf.placeholder(tf.string)
serialized_tf_example = array_ops.placeholder(dtype=dtypes.string,
shape=[None],
name='input_example_tensor')
inputs = {'examples': serialized_tf_example}
labels = None # these are not known in serving!
return input_fn_utils.InputFnOps(features, labels, inputs)
This is probably not 100% idiomatic, but I'm pretty sure it works. For now.

Extracting Geometry from IFC File

I have to extract the geometry of a ifc file in JAVA. My problem is, that i don't know how to do it.
I tried to use openifctools but the documentation is really bad. For now i have the ifc file loaded, but i cannot get the geometry out of the model.
Does anyone have experience with ifc model loading?
Thanks in advance.
EDIT: This is what I've done so far
try {
IfcModel ifcModel = new IfcModel();
ifcModel.readStepFile(new File("my-project.ifc"));
Collection<IfcClass> ifcObjects = ifcModel.getIfcObjects();
System.out.println(ifcObjects.iterator().next());
} catch (Exception e) {
e.printStackTrace();
}
This correctly loads the ifc file. But I don't know what to do with this information.
I also tried to use IfcOpenShell but the provided jar container hadn't worked either. At the moment I try to build IfcOpenShell by myself.
I'm kinda desperate because everything is very undocumented and I really need to load and parse the ifc geometry.
Depending on what you want to do with the geometry, how deep you want to delve into the IFC standard and what performance you need for your solution you have two different options:
Extract the implicit geometry on your own
Use an external geometry engine
If you go for the first option, you'd have to study the IFC schema intensively. You would only be interested in IFCProducts, because only those can have geometry. Using OpenIfcTools you could do something like:
Collection<IfcProduct> products = model.getCollection(IfcProduct.class);
for(IfcProduct product: products){
List<IfcRepresentation> representations = product.getRepresentation().getRepresentations();
assert ! representations.isEmpty();
assert representations.get(0) instanceof IfcShapeRepresentation:
Collection<IfcRepresentationItem> repr = representations.get(0).getItems();
assert !repr.isEmpty();
IfcRepresentationItem representationItem = repr.iterator().next();
assert representationItem instanceof IfcFacetedBrep;
for(IfcFace face: ((IfcFacetedBrep)representationItem).getOuter().getCfsFaces()){
for(IfcFaceBound faceBound: face.getBounds()){
IfcLoop loop = faceBound.getBound();
assert loop instanceof IfcPolyLoop;
for(IfcCartesianPoint point: ((IfcPolyLoop) loop).getPolygon()){
point.getCoordinates();
}
}
}
}
However, there are a lot of different GeometryRepresentations, which you'd have to cover, probably doing triangulation and stuff on your own. I've shown one special case and made a lot of assertions. And you'd have to fiddle with coordinate transformations, because these may be nested recursively.
If you go for the second option the geometry engines I know are all written in C/C++ (Ifcopenshell, RDF IfcEngine), so you'd have to cope with native library integration. The jar package provided with IFCOpenshell is intended to be used as a Bimserver plugin. Those you can't use it without the respective dependencies. However you can grab the native binaries from this package. In order to use the engine you can draw some inspiration from the Bimserver plugin source. The key native methods you're gonna use are
boolean setIfcData(byte[] ifc) to parse the ifc data
IfcGeomObject getGeometry() to access the extracted geometry successively.

Consuming SOAP Webservice - Java VS PHP

a general question:
We are launching a new ITSM Toolsuite in our company called ServiceNow.
ServiceNow offers a lot of nice out-of-the-box Webservices.
Currenty we are implementing some interfaces to other interal systems and we use these Webservices to consume data of Servicenow.
How we did it in PHP:
<?php
$credentials = array('login'=>'user', 'password'=>'pass');
$client = new SoapClient("https://blah.com/incident.do?WSDL", $credentials);
$params = array('param1' => 'value1', 'param1' => 'value1');
$result = $client->__soapCall('getRecords', array('parameters' => $params));
// result array stored in $result->getRecordsResult
?>
And thats it! 5 minutes of work, Beautiful and simple - from my point of view.
Ok and now the same in Java:
I did some research and it seems everbody is using Apache Axis2 for consuming Webservices in Java. So I decided to go down that road.
Install Apache Axis
open cygwin or cmd and generate Classes from WSDL.. WTF? what for?
$ ./wsdl2java.sh -uri https://blah.com/incident.do?WSDL
copy generated classes to Java Project in Eclipse.
Use this classes:
ServiceNow_incidentStub proxy = new ServiceNow_incidentStub();
proxy._getServiceClient().getOptions().setProperty(org.apache.axis2.transport.http.HTTPConstants.CHUNKED, Boolean.FALSE);
ServiceNow_incidentStub.GetRecords defectsGetRecords = new ServiceNow_incidentStub.GetRecords();
ServiceNow_incidentStub.GetRecordsResponse defectsResult = new ServiceNow_incidentStub.GetRecordsResponse();
proxy._getServiceClient().getOptions().setManageSession(true);
HttpTransportProperties.Authenticator basicAuthentication = new HttpTransportProperties.Authenticator();
basicAuthentication.setUsername("user");
basicAuthentication.setPassword("pass");
proxy._getServiceClient().getOptions().setProperty(org.apache.axis2.transport.http.HTTPConstants.AUTHENTICATE, basicAuthentication);
defectsResult = proxy.getRecords(defectsGetRecords);
com.service_now.www.ServiceNow_incidentStub.GetRecordsResult_type0[] defects = defectsResult.getGetRecordsResult();
for (int j=0; j < defects.length; j++) {
// do something
}
Its working but I think this way is very complicated..
everytime something in the wsdl changes - i must recompile them with axis.
There is no way to configure something globally like Soap-endpoint or something like that.
Is there an easier way in Java to consume SOAP with a WSDL??
First off: I completely agree. I do quite a bit of work with Web Services and ServiceNow, and using Java and/Or .Net is quite different than using a scripted language (I usually use Perl for scripts). The inherent issue comes into the fact that a WSDL should not be changing that often, especially in production. The idea in Java and .Net is that you get these stub classes to get compile time error checking.
If your currently in a Ph1 and haven't deployed Prod yet, then you should really look into how often that WSDL will be changing. Then make your decision from there on which technology to use. The nice thing is that even if the WSDL changes, posting data to the instance - almost all of the fields are optional. So if a new field is added it's not a big deal. The issue comes in when data is returned (most of the time) because many times java and .net will throw an exception if the returned XML is not in the structure it is expecting.
One thing that many people do is setup Modules as CI's in the CMDB and maintain their ServiceNow instance through the Change Request module. That way your java application will be a downstream CI to whatever module/table you are querying, and when a CR is put in to modify that table, it will be known immediately that there will be an impact on your internal application as well.
Unfortunately you are right though, that is a trade off with the different languages and from my experience there is very little we can do to change that.
One thing I forgot to add, another option for you is to use the JSON service instead. That will allow you to make raw requests to the SNC instance then use a JSON parser to parse that data for you "on the fly" so to speak. It takes away the compile time checking but also takes away many of the flaws of the SOAP system.
IF you are using maven, try using this plugin.
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>axistools-maven-plugin</artifactId>
<version>1.4</version>
<configuration>
<urls>
<url>https://blah.com/incident.do?WSDL</url>
</urls>
<packageSpace>your.destination.package</packageSpace>
<serverSide>true</serverSide>
<outputDirectory>src/main/java</outputDirectory>
</configuration>
<executions>
<execution>
<goals><goal>wsdl2java</goal></goals>
</execution>
</executions>
</plugin>
I was also trying to access ServiceNow from Java using Eclipse, and it seemed to me that the Axis2 approach was overly restrictive given how ServiceNow designed their API, so I wrote my own package to generate SOAP calls dynamically using JDOM. Here is an example of what the code looks like:
Instance instance = new Instance("https://blah.service-now.com", "username", "password");
GlideFilter filter = new GlideFilter("category=network^active=true");
GlideRecordIterator iter = instance.table("incident").
bulkFetcher().setFilter(filter).getAllRecords().iterator();
while (iter.hasNext()) {
GlideRecord rec = iter.next();
System.out.println(
rec.getField("number") + " " + rec.getField("short_description"));
}
A couple of things about this code:
I use run-time validation rather than build-time validation. If you mistakenly type getField("shortdescription") the code throws an InvalidFieldNameException.
Queries are not bound by ServiceNow's normal 250 record limit because the BulkFetcher loops internally making as many Web Service calls as necessary to retrieve all the data.
The package source code is at https://sourceforge.net/projects/servicenowpump/
I consume lots of Soap services with PHP in the company I work for, and I would always suggest generating classes for the request and response data structure. Otherwise you will easily get lost - PHP does not preserve any remains of the original XML structure, it will all be converted to arrays and stdClass objects.
Getting classes created from the WSDL description is not that easy in PHP, as there are only a few scripts that do this - and they all have their shortcomings when it comes to WSDL files that make use of the more obscure parts of the SOAP standard. After that, you somehow have to make these classes available to your PHP script. If this is hard for you, it is a sign of a not too well organized code base. With the autoloading feature it works like a charm.
But yes, this step is entirely optional for PHP. If using only one Soap service, it'll probably make no difference.

Programmatically multi language content in Alfresco

The requirement I receive is to model some existing content available on a SQL Server database using Alfresco content managment so, I create my new content model and it seems to working fine. But I've a problem with multi language: I know in Alfresco is possible for one node add multiple language (how can I do that using Java for a massive load?) but, I used also some aspects that need to be translated.
What do you usually do in that case? I thoug to follow this steps:
Create Eng content and add aspects
Create new child translted and add aspects
Is it correct? How can I make a node Multilingual programmatically (Java) and how can I add the new translate content with aspects? I took a look to Alfresco documentation but, I didn't find it, could you help me to find some documentation or tutorial about that?
UPDATE:
I'm trying to make a content multilangue:
void makeTranslation(Reference contentNodeRef, Locale locale) throws AlfrescoRuntimeException, Exception
{
try {
NodeRef nodeRef = new NodeRef("workspace://SpacesStore/" + contentNodeRef.getUuid());
MultilingualContentServiceImpl multilingualContentServiceImpl = new MultilingualContentServiceImpl();
multilingualContentServiceImpl.makeTranslation(nodeRef, locale);
}
catch (org.alfresco.error.AlfrescoRuntimeException ex) {
throw new AlfrescoRuntimeException(ex.getMessage());
}
catch (Exception ex) {
throw new Exception(ex.getMessage());
}
}
but, makeTranslation raise an nullPoint exception because MultilingualContentServiceImpl it's not initialized correctly. Any suggestion how to initialize it? I've to use spring but, how?
Any suggerstion or reply will be very helpful!
Thanks,
Andrea
You can use MultilingualContentService to add translations. But! I guess your properties should be of type d:mltext (like cm:title and cm:description are) to support multilingual content.
This means if you access alfresco using browser with english language you will see a different description as someone using german language settings in browser. This can be a little confusing because in Share there is (was?) no identifier that the property is multilingual.
If you want your translations to appear everywhere, no matter what kind of language in browser people are using, then the better approach is to define some aspect (for example ex:translatable) with as many properties as you need translations. Then you can programatically (using Java or JavaScript) use search service to find nodes you want and add the aspect to them. Finally you then add properties (translations) of that aspect to the node.
I hope this helps to clear things a bit... :)

Categories