I've been doing static analysis on Java projects, which usually boils down to running javac2 #a_list_of_all_the_java_files_in_the_project, where javac2 is my modified compiler. Except, finding the right libraries to make everything compile is difficult.
I'm working with a project now (incidentally, eclipse SDK 3.7.1) that has a file artifacts.xml in the root folder. This file looks useful. My understanding so far is that it tells eclipse which libraries to use when opening the folder as an eclipse project. If so, I'd like to download these libraries locally and reference them in my custom compilation command.
Can someone explain the purpose of artifacts.xml, and optionally offer feedback on my approach? Ultimately all I want is to be able to compile the project on the command line using a nonstandard compiler.
First few lines or artifacts.xml
<?xml version='1.0' encoding='UTF-8'?>
<?artifactRepository version='1.1.0'?>
<repository name='Bundle pool' type='org.eclipse.equinox.p2.artifact.repository.simpleRepository' version='1'>
<properties size='2'>
<property name='p2.system' value='true'/>
<property name='p2.timestamp' value='1315600353875'/>
</properties>
<mappings size='3'>
<rule filter='(& (classifier=osgi.bundle))' output='${repoUrl}/plugins/${id}_${version}.jar'/>
<rule filter='(& (classifier=binary))' output='${repoUrl}/binary/${id}_${version}'/>
<rule filter='(& (classifier=org.eclipse.update.feature))' output='${repoUrl}/features/${id}_${version}.jar'/>
</mappings>
<artifacts size='405'>
<artifact classifier='osgi.bundle' id='org.eclipse.ecf.provider.filetransfer.ssl' version='1.0.0.v20110531-2218'>
<properties size='1'>
<property name='download.size' value='8460'/>
</properties>
</artifact>
This is the file that the Eclipse 'p2' install system uses to describe a repository of installable artifacts. The file is sometimes compressed in to an artifacts.jar file.
Eclipse p2 is described here: http://wiki.eclipse.org/Equinox/p2
A maven artifact, in general, is a file that gets deployed to a maven repo.
artifacts.xml is the canonical way of listing everything that needs to be sent to said repository.
Check this previous post for more information:
What is a Maven artifact?
Related
What is the best (easiest) way to reverse-engineer POJOs from a database? I would like to generate probably 40 entity classes from tables, just to save a bunch of typing. I would like to use the Hibernate Tools toolset but all examples seem incomplete or contradictory - some reference using Ant tasks, some reference Maven plugins, and the Jboss site itself indicates that Hibernate Tools 4.x now seems to be an Eclipse plugin!
What is the "correct" way to do this, starting from scratch?
I actually wound up using an Ant task. If you have a situation where you need to reverse-engineer POJOs from a database, and you have no existing infrastructure in place, I believe the Ant method is best. I started with this excellent blog post and was able to cut and paste most of the code I needed. I found through experimentation that some additional JARs were needed and after some tweaking was able to generate the POJOs I needed in fairly short order.
This assumes that you know basic Java terminology and a little about Ant, and have both installed. Here are the steps.
You'll need to create two files (build.xml and hibernate.cfg.xml) and download some JARs. You may also need to download the Hibernate DTD files if you are behind a proxy or firewall (since Hibernate will try to go out and read the DTDs). That's it.
Create the following directories:
/myantproject
/lib
/src
In your "myantproject" directory create your build.xml file as follows:
<project name="antbuild" basedir="." default="gen_hibernate">
<taskdef name="hibernatetool"
classname="org.hibernate.tool.ant.HibernateToolTask">
<classpath>
<fileset dir="lib">
<include name="**/*.jar"/>
</fileset>
</classpath>
</taskdef>
<target name="gen_hibernate"
description="generate hibernate classes">
<hibernatetool>
<jdbcconfiguration
configurationfile="hibernate.cfg.xml"
packagename="com.mycompany.model"
detectmanytomany="true"
/>
<hbm2hbmxml destdir="src" />
<hbm2java destdir="src" />
</hibernatetool>
</target>
</project>
Also in the "myantproject" directory create your hibernate.cfg.xml file as follows:
<?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>
<property name="hibernate.connection.driver_class">com.ibm.as400.access.AS400JDBCDriver</property>
<property name="hibernate.connection.url">jdbc:as400://myserver;libraries=MYLIB;dateformat=iso;timeformat=iso;prompt=false;naming=system;transaction isolation=none</property>
<property name="hibernate.connection.username">myuser</property>
<property name="hibernate.connection.password">mypassword</property>
<property name="hibernate.dialect">org.hibernate.dialect.DB2400Dialect</property>
</session-factory>
</hibernate-configuration>
If you are behind a firewall/proxy, you can download the DTD change the DTD reference in the file to this (make sure you edit it to point to your actual file location):
"file:///mypath/myantproject/lib/hibernate-configuration-3.0.dtd"
You can then download the DTD from the original URL and stick it in your "lib" directory.
Here are the JARs I wound up with. With these JARs, you should be able to run this Ant task and it will reverse-engineer all the tables in the database you have pointed to in "hibernate.cfg.xml".
cglib-nodep-2.2.3.jar
commons-collections-3.2.1.jar
commons-logging-1.1.1.jar
dom4j-1.6.1.jar
freemarker-2.3.8.jar
hibernate-annotations-3.5.0-Final.jar
hibernate-commons-annotations-4.0.1.Final.jar
hibernate-configuration-3.0.dtd
hibernate-core-3.3.1.GA.jar
hibernate-entitymanager-4.2.0.Final.jar
hibernate-tools-3.2.3.GA.jar
jt400-6.6.jar
jtidy-r938.jar
log4j-1.2.16.jar
slf4j-api-1.7.5.jar
These come from various sources - most either from apache.org or hibernate.org. You will need your database JDBC JAR from your database vendor (in this case an AS400 connector jar from IBM) to connect to the database. I also needed to download these DTDs since I was behind a firewall:
hibernate-mapping-3.0.dtd
hibernate-reverse-engineering-3.0.dtd
Good luck!
I have tried setting different properties and attributes (debug="true"), but it didn't work.
This is from our build.xml (just showing the parts relating to the build step):
<!-- Environment holen -->
<property environment="env" />
<!-- Target: all -->
<target name="all" depends="build, test, export">
</target>
<!-- Target: build -->
<target name="build">
<ant4eclipse:executeProjectSet workspaceDirectory="${env.WORKSPACE}" teamprojectset="${env.WORKSPACE}\${env.JOB_NAME}\projectSet.psf">
<ant4eclipse:forEachProject filter="(executeProjectSet.org.eclipse.jdt.core.javanature=*)">
<buildJdtProject workspaceDirectory="${env.WORKSPACE}" projectName="${executeProjectSet.project.name}" targetLevel="1.6" />
</ant4eclipse:forEachProject>
</ant4eclipse:executeProjectSet>
</target>
Detailed description:
An internal project consists of a large number of classes and some applications, all written in Java.Everything runs just fine when started from within Eclipse.
After each commit to our SVN repository, the project is built using ant4eclipse on our Hudson installation and if tests pass, a zip is automatically created and copied to a file server to be used by simply unpacking and starting the supplied startup batch script.
Now last week a colleague informed me that the version from the file server doesn't work for him. I checked and am able to reproduce the problem - loading data from a database doesn't work. No exception is shown in the log/console and I have no idea what goes wrong. Everything works when started from within eclipse (same vmargs, same JVM etc.).
When trying to connect the debugger, it seems like no debug info is present ("line numbers missing" etc.). So I now need to find out how to convince ant4eclipse to include debug infos.
In the meantime, I found out how to do this myself: I added a default compiler options file like this (attribute defaultCompilerOptionsFile):
<!-- Target: build -->
<target name="build">
<ant4eclipse:executeProjectSet workspaceDirectory="${env.WORKSPACE}" teamprojectset="${env.WORKSPACE}\${env.JOB_NAME}\projectSet.psf">
<ant4eclipse:forEachProject filter="(executeProjectSet.org.eclipse.jdt.core.javanature=*)">
<buildJdtProject
workspaceDirectory="${env.WORKSPACE}"
projectName="${executeProjectSet.project.name}"
targetLevel="1.6"
defaultCompilerOptionsFile="compilerOptions.prefs"/>
</ant4eclipse:forEachProject>
</ant4eclipse:executeProjectSet>
</target>
compiler options file is just a copy of .metadata\.plugins\org.eclipse.core.runtime\.settings\org.eclipse.jdt.core.prefs inside the workspace. Make sure to set the desired options inside the file:
org.eclipse.jdt.core.compiler.debug.lineNumber=generate
org.eclipse.jdt.core.compiler.debug.localVariable=generate
org.eclipse.jdt.core.compiler.debug.sourceFile=generate
I haven't tested if it works if you create a compiler options file that just contains the 3 lines above.
I'm trying to configure Ivy to play nicely with Artifactory (a popular repository manager) and need confirmation that I'm heading down the right path here.
I assume that once I have Artifactory configured correctly on my repository server, that I can just point Ivy to some directory under ARTIFACTORY_HOME and pass it the same information as I would an ordinary URL resolver. This way, Artifactory gets passed the info (what command to process, username & password, etc.) and takes over on the actual repositories behalf. (Thus, if credentials are wrong or if the user doesn't have permission to honor the request, Artifactory sends back a 404/etc.)
So to start with, if this is wrong, please correct me!
So here is what I'm thinking. In the Ant build for my project:
<ivy:settings url="http://my-repo-server.com/ivy/settings/ivy-settings.xml"/>
<target name="ivy-resolve">
<ivy:configure host="http://my-repo-server.com/ivy"
realm="ivy"
username="developer" <!-- "developer" is read-only user configured in Artifactory -->
passwd="38ur84u83j38y83u" <!-- encrypted password provided by Artifactory -->
override="false"/>
<ivy:resolve file="ivy.xml" conf="compile"/>
</target>
And then, in the (server-side) ivy-settings.xml:
<resolvers>
<url name="repo-server">
<ivy pattern="http://my-repo-server.com/ivy/???"/>
<artifact pattern="http://my-repo-server.com/ivy/???"/>
</url>
</resolvers>
So when a developer's Ant build runs the ivy-resolve target, the Ivy client knows where to go to find the ivy-settings.xml file, and configures itself using the developer user and encrypted password that I set up in Artifactory.
The only problem is, I'm not sure what to specify for Ivy & Artifact patterns in the settings file? I assume I have to set them to some directory that is controlled by Artifactory, but I'm not sure what (in Artifactory my repo uses the default Ivy repo layout).
Also, am I violating Artifactory "best practices" by placing the settings file on the repo server like I did? Should I place it inside some Artifactory-managed (hidden) directory? If so, where and why?
Ultimately, code samples help me learn fastest & easiest (I'm a graphical learner), so any programmatic nudges in the right direction are enormously appreciated!
Thanks in advance!
i have a project that uses ivy to manage its dependencies. i'm implementing a feature to the project that requires me to include tools.jar. however, because tools.jar is platform dependent, i'm trying to use ivy to resolve to a local file for the artifact. i'm doing the following:
<dependency org="com.sun" names="tools" rev="1.6.0">
<artifact name="tools" type="jar" url="file:///${java.home}/../lib/tools.jar"/>
</dependency>
that should retrieve the file from the local ${java.home}/../lib/tools.jar. (note: java.home points to the JRE installation).
however, there are problems resolving the location. on my windows machine, it seems to think "c" is the protocol (c is coming from ${java.home}. and i'm sure that my url is defined correctly because "file:///C:/foo" is the correct way to specify a url to a file (3 slashes). the problem i see is that it strips off 2 slashes and tries "file:/C:..." instead of "file:///C:.." as i specify above. i also tried specifying the path to the file directly w/o the ${java.home}
i would like to keep this approach retrieving through ivy, but i can't get it to work. any ideas?
JAVA_HOME needs to point at the location of your JDK, not your JRE. Once you change this, ANT will stop complaining about a missing tools jar.
Looking at the path you provide above, I suspect that you already have a JDK installed....
Analysis
On my system the tools jar is located here:
$ find $JAVA_HOME -name tools.jar
/usr/lib/jvm/java-6-openjdk/lib/tools.jar
Oddly, and confusing, the Java JDK ships with a JRE inside
$ find $JAVA_HOME -name java
/usr/lib/jvm/java-6-openjdk/bin/java
/usr/lib/jvm/java-6-openjdk/jre/bin/java
I was able to get this to work using a dedicated resolver
ivysettings.xml
<resolvers>
<!-- your other resolvers here -->
<filesystem name="JDK" local="true">
<artifact pattern="${java.home}/lib/[artifact].[type]" />
<artifact pattern="${java.home}/../lib/[artifact].[type]" />
<!-- You can add more patterns to fit your needs for MacOSX etc -->
</filesystem>
</resolvers>
<modules>
<module organisation="com.sun" name="tools" resolver="JDK"/>
</modules>
ivy.xml
<dependency org="com.sun" name="tools"/>
Works for me...
I can't find any thorough explanation of the Ivy dependency tag's conf attribute:
<dependency org="hibernate" name="hibernate" rev="3.1.3" conf="runtime, standalone -> runtime(*)"/>
See that conf attribute? I can't find any explanation (that I can understand) about the right hand side of the -> symbol. PLEASE keep in mind I don't know the first thing about Maven so please explain this attribute with that consideration.
Yes, I've already looked at this: http://ant.apache.org/ivy/history/latest-milestone/ivyfile/dependency.html
Thanks,
Dan
First of all, Ivy is not Maven ;)
Maven2 is a software project management and comprehension tool, whereas Ivy is only a dependency management tool.
Ivy heavily relies on a unique concept called configuration.
In Ivy, a module configuration is a way to use or to see the module.
For instance, you can have a test and runtime configuration in your module. But you can also have a MySQL and an Oracle configuration. Or an Hibernate and a JDBC configuration.
In each configuration, you can declare:
what artifacts (jar, war, ...) are required.
your dependencies on other modules, and describe which configuration of the dependency you need. This is called configuration mapping.
So the conf attribute does precisely that: Describes a configuration mapping for a dependency.
The mapped child element is your "right hand side of the -> symbol" and represents the name of the dependency configuration mapped. '*' wildcard can be used to designate all configurations of this module.
See more at "Simplest Explanation of Ivy Configuration" from Charlie Hubbard
The important part of that is Ivy downloads dependencies and organizes them.
An ivy-module (ie ivy.xml file) has two main parts:
What dependencies do you need?
How do you want them organized?
The first part is configured under the <dependencies> element.
The 2nd is controlled by the <configurations> element
When Ivy is downloading these dependencies it needs to know what scopes to use when pulling these transitive dependencies (are we pulling this for testing, runtime, compilation, etc?). We have to tell Ivy how to map our configurations to Maven scopes so it knows what to pull.
Maven2 on its side has something called the scope.
You can declare a dependency as being part of the test scope, or the buildtime scope.
Then depending on this scope you will get the dependency artifact (only one artifact per module in maven2) with its dependencies depending on their scope. Scopes are predefined in maven2 and you can't change that.
That means :
There are a lot of unnecessary dependencies downloaded for many libraries.
For example, Hibernate downloads a bunch of JBoss JARs and the Display Tag downloads all the various web framework JARs. I found myself excluding almost as many dependencies as I added.
The problem is that hibernate can be used with several cache implementations, several connection pool implementation, ... And this can't be managed with scopes, wheres Ivy configurations offers an elegant solution to this kind of problem.
For instance, in Ivy, assuming hibernate has an Ivy file like this one, then you can declare a dependency like that:
<dependency org="hibernate" name="hibernate" rev="2.1.8" conf="default->proxool,oscache"/>
to get hibernate with its proxool and oscache implementations, and like that:
<dependency org="hibernate" name="hibernate" rev="2.1.8" conf="default->dbcp,swarmcache"/>
to get hibernate with dbcp and swarmcache.
By mapping your default master configuration to "proxool,oscache" or to "dbcp,swarmcache", you specify what you need exactly from the module "hibernate".
You can find those "proxool,..." arguments by listing the Ivy configuration defined for each modules associate with the library. For instance:
<ivy-module version="2.0">
<info organisation="ssn-src" module="pc"/>
<configurations defaultconfmapping="default->default">
<conf name="default" />
<conf name="provided" description="they are provided by the env." />
<conf name="compile" extends="default,provided" />
<conf name="war" extends="default"/>
</configurations>
<dependencies>
Example:
let's suppose modA has two configurations, default and test.
As a practical matter, it's going to be highly unusual to want to leave out the conf attribute of the dependency element.
The ivy.xml for modA might have a dependency:
<dependency org="theteam" name="modB" rev="1.0" conf="default->*" />
You're starting from default, rather than from both default and test.
The above example makes modA's default depend on modB's conf1, conf2, and conf3.
Or you might want to say that modA's default only depends on modB's conf1:
<dependency org="theteam" name="modB" rev="1.0" conf="default->*conf1*" />
I've read these answers and quite frankly I don't find them very helpful. I think they could be improved so I wrote down how I use and understand configurations by showing a practical example:
http://wrongnotes.blogspot.com/2014/02/simplest-explanation-of-ivy.html
Unfortunately, you have to understand a little about maven, and its dependencies because Ivy is using Maven repositories to download those jar files. Therefore, Ivy has to understand Maven and it passes that back to you. But, I think I kept it real simple without going into too much detail about maven.
Thanks VonC!
It helped me alot further.
When it comes to options (configurations) tieTYT, you can find them in the ivy-[revision number].xml file in your Ivy repository under: organization name --> module name.
An example configurations element from the JUnit 4.6 revision downloaded from http://www.springsource.com/repository/app/.
<configurations>
<conf name="compile" visibility="public" description="Compile dependencies"/>
<conf name="optional" visibility="public" extends="compile" description="Optional dependencies"/>
<conf name="provided" visibility="public" description="Provided dependencies"/>
<conf name="runtime" visibility="public" extends="compile" description="Runtime dependencies"/>
</configurations>
In my project's ivy.xml file, I have a configuration compile-test. In the dependencies element I have the following dependency:
<dependency org="org.junit" name="com.springsource.org.junit"
rev="4.6.0" conf="compile-test->compile" />
As you can see, my compile-test configuration depends on the compile configuration in the JUnit's ivy.xml file.
It helped me once to understand things this way:
An ivy configuration is simply a name for some subset of the module's artifacts.
Dependencies between modules are specified in terms of configuration names.