7

The current version of the SAP JCo connector enforces the name of the containing jar at runtime. This will lead to exceptions, if it doesn't match the name (sapjco3.jar).

JCo initialization fails with java.lang.ExceptionInInitializerError: Illegal JCo archive "sap-jco-win-amd-64-3.0.11.jar". It is not allowed to rename or repackage the original archive "sapjco3.jar"

We wrapped these libraries and deployed them with a custom pom in our nexus repository. The standard maven build is unusable atm, as a result of this change/the standard maven way of naming artifacts.

The current workaround uses system scope for this dependency and copies the sapjco maven artifact to a specified folder within the project, as this is the only way to enforce the name of an jar file and also keep it in the build as a dependency. This works within the same module. One of the disadvantages of the system scope is the deactivated/failing resolution of transitive artifacts. We would need that, as the sap connector module is included in an application war module. As system scope dependencies aren't included in the packaged artifacts, we had to copy them to the web-inf/lib folder and add a classpath entry to the manifest.

The build works, when I start it from the parent/root module, but fails when it is started in submodules due to the system scope dependency. We could live with that solution for now, but I'm definitely not happy with it.

Is there a recommended way to use sapjco with maven or a simpler approach to produce platform dependent artifacts, which include the native library and the jar with a specified name? Is SAP reconsidering this check, as the previous versions did not include it?

Edit:

Sandra Rossi
  • 11,934
  • 5
  • 22
  • 48
  • Why is this check even in? Do you violate the license? – Thorbjørn Ravn Andersen Jul 15 '14 at 18:16
  • I don't plan to violate the license. The resulting artifact should contain the file with the specified naming conventions. I'd like to get all dependencies from the maven repository, but sap isn't offering a mavenized version of the connector. As a result we created our own maven artifact and uploaded it to our private repository. I thought this issue is affecting more developers, but haven't found a solution yet. – Alexander Pilch Jul 15 '14 at 18:23
  • We have the same problem. At the moment, we only need standalone applications (which are in fact middleware clients between SAP and an enterprise application). So we are using the maven-assembly-plugin. With that we simply handle this JAR explicit with a renaming in the resulting artifact (a ZIP). Maybe there is also a similar configuration option in the maven-war-plugin? – Seelenvirtuose Jul 15 '14 at 18:33
  • Additionally: We have this problem with version 3.0.11. Prior to that we used 3.0.6, with which we did not have that problem. – Seelenvirtuose Jul 15 '14 at 18:36
  • Suggestions which I have no idea will work: 1) Having the jar file with the correct name in WEB-INF/lib directly instead of having it added as a dependency. 2) Using the outputFilenameMapping feature of maven-war-plugin to rename the jar in the war. – Thorbjørn Ravn Andersen Jul 15 '14 at 19:01
  • The web project also contains some integration tests, which require it to work within the standard execution (surefire, failsafe). The current workaround for the war is more or less: - copy the sap dependency via the dependency plugin to web-inf/lib (as sapjco3.jar) - manually add the manifest entry to the manifest (via war plugin) This will produce a working war, as it totally bypasses maven. I'll have a look at the outputFilenameMapping. Maybe this simplifies the creation of the war. Thanks. – Alexander Pilch Jul 15 '14 at 19:05
  • Just some additions - the native library is also copied over (from target/natives) to web-inf/lib - the standard build uses https://code.google.com/p/mavennatives/ to unpack the native library - the native library path is set at runtime within a servlet context listener – Alexander Pilch Jul 15 '14 at 19:15
  • "Native library is copied over and path is set at runtime"? That sounds brittle (I have no idea whether this functionality is guaranteed to work in Java, or just happens to work). I would suggest moving the library and its native blob from your applications/webapps and into the surrounding environment, so you do not have to bend over backwards to make the SAP and Maven mindset work together. – Thorbjørn Ravn Andersen Jul 15 '14 at 19:44
  • I haven't yet tried to manage the artifact manually within the whole build: - copy the depedency to a subfolder below target in each project, which requires it / copy it one time to a central location - adding the dependency manually to the surefire/failsafe classpath: liblocation – Alexander Pilch Jul 15 '14 at 19:44
  • The application is deployed in a clustered/shared hosting environment. We can only deploy the war and aren't allowed to change any infrastructure. – Alexander Pilch Jul 15 '14 at 19:46
  • I'd prefer a plain java connector and not one which forces us to create platform dependent artifacts by including some native libraries, especially if the performance of the connector is probably not a big issue. Even the jars are different in size, so I'm not sure if it would be possible to include just one jar and deploy the native library on the target system. – Alexander Pilch Jul 15 '14 at 19:54
  • You can bake in the appropriate files when you create the very last artifact, and have it "outside" while you develop. You need something that works in your IDE to avoid slowing development to a crawl. – Thorbjørn Ravn Andersen Jul 15 '14 at 20:12
  • The build uses classifier/profiles to create platform dependent artifacts. There are only 2 modules affected atm: the sap module and the war. We need those platform dependent builds, as maven drives our CI/deployment chain, which runs on linux. Baking in the dependency allows us to create a valid war, but the tests won't work during the build, as the artifact is missing. The current hacked state of the project works with all these constraints, but it is pretty ugly. The only clean solution I see would be SAP removing this check in the next version of their connector. – Alexander Pilch Jul 15 '14 at 20:34

1 Answers1

2

I had the same issue, and below is how I fixed it (in short work around it): 1. Run the command in command prompt

mvn install:install-file 
-Dfile=sapjco3.jar 
-DgroupId=com.company.sap 
-DartifactId=com.sap.conn.jco.sapjco 
-Dversion=1.0 
-Dpackaging=jar
  1. This will create a local artifact, or you can also create it in remote repository
  2. Download this dependency from maven as shown below:

    <dependency> <groupId>com.company.sap</groupId> <artifactId>com.sap.conn.jco.sapjco</artifactId> <version>1.0</version> </dependency>

This work around would avoid the sapjco3 error:

if (!jarname.equals("sapjco3.jar") 
&& !jarname.startsWith("com.sap.conn.jco") 
&& !jarname.equals("sapjco3_IDE.jar") 
&& Package.getPackage("org.apache.maven.surefire.booter") == null 
&& Package.getPackage("org.eclipse.jdt.internal.junit.runner") == null) {
    throw new ExceptionInInitializerError("Illegal JCo archive \"" + jarname + "\". It is not allowed to rename or repackage the original archive \"" + "sapjco3.jar" + "\".");
}
Sambit Swain
  • 131
  • 1
  • 13
  • Dear all, are we able to use provided scope for sap jco connector? if yes is there any example? Thanks in advance – stewchicken Aug 01 '22 at 07:19