Permalink
Browse files

Make M-. work in slime for temp mounted jars [IMMUTANT-70]

We just keep a map of every jar we tmp mount, then fix the urls for files within
those jars when they are requested.

@jcrossley: this one's for you my dear.
  • Loading branch information...
1 parent 4dbce6f commit 333b4e677e117cd356f15142428d9d4001c303f3 @tobias tobias committed Jun 8, 2012
@@ -0,0 +1,53 @@
+/*
+ * Copyright 2008-2012 Red Hat, Inc, and individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+
+package org.immutant.core;
+
+import java.io.File;
+import java.net.URL;
+import java.util.HashMap;
+
+import org.jboss.as.server.deployment.AttachmentKey;
+import org.jboss.msc.service.Service;
+import org.jboss.msc.service.StartContext;
+import org.jboss.msc.service.StartException;
+import org.jboss.msc.service.StopContext;
+
+public class JarMountMap extends HashMap<String, String> implements Service<JarMountMap> {
+ public static final AttachmentKey<JarMountMap> ATTACHMENT_KEY = AttachmentKey.create( JarMountMap.class );
+
+ @Override
+ public JarMountMap getValue() throws IllegalStateException, IllegalArgumentException {
+ return this;
+ }
+
+ @Override
+ public void start(StartContext context) throws StartException {
+ // TODO Auto-generated method stub
+
+ }
+
+ @Override
+ public void stop(StopContext context) {
+ // TODO Auto-generated method stub
+
+ }
+
+ private static final long serialVersionUID = 1L;
+}
@@ -32,27 +32,39 @@
*/
public class VFSStrippingClassLoader extends ClassLoader {
- public VFSStrippingClassLoader(ClassLoader parent) {
+ public VFSStrippingClassLoader(ClassLoader parent, JarMountMap mountMap) {
super( parent );
+ this.mountMap = mountMap;
}
@Override
public URL getResource(String name) {
URL url = getParent().getResource( name );
if (url != null && "vfs".equals( url.getProtocol() )) {
- try {
- URL nonVFSUrl = new URL( "file" + url.toExternalForm().substring( 3 ) );
- if ((new File( nonVFSUrl.toURI() )).exists()) {
- url = nonVFSUrl;
- }
+ try {
+ String urlAsString = url.toExternalForm();
+ int splitPoint = urlAsString.indexOf( ".jar/" ) + 5;
+ String jarPrefix = urlAsString.substring( 0, splitPoint );
+ String fileName = urlAsString.substring( splitPoint );
+ if (this.mountMap.containsKey( jarPrefix )) {
+ //translate resources within tmp mounted jars to the actual path. see IMMUTANT-70
+ url = new URL( "jar:" + this.mountMap.get( jarPrefix ) + "!/" + fileName );
+ } else {
+ URL nonVFSUrl = new URL( "file" + url.toExternalForm().substring( 3 ) );
+ if ((new File( nonVFSUrl.toURI() )).exists()) {
+ url = nonVFSUrl;
+ }
+ }
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (URISyntaxException e) {
e.printStackTrace();
}
}
-
+
return url;
}
+
+ private JarMountMap mountMap;
}
@@ -28,6 +28,7 @@
import org.immutant.core.ApplicationBootstrapUtils;
import org.immutant.core.ClojureMetaData;
import org.immutant.core.Immutant;
+import org.immutant.core.JarMountMap;
import org.immutant.core.as.CoreServices;
import org.jboss.as.server.deployment.Attachments;
import org.jboss.as.server.deployment.DeploymentPhaseContext;
@@ -59,6 +60,9 @@ public void deploy(DeploymentPhaseContext phaseContext) throws DeploymentUnitPro
File root = metaData.getRoot();
+ JarMountMap mountMap = new JarMountMap();
+ unit.putAttachment( JarMountMap.ATTACHMENT_KEY, mountMap );
+
try {
List<File> dependencyJars = ApplicationBootstrapUtils.getDependencies( root,
metaData.resolveDependencies(),
@@ -70,7 +74,7 @@ public void deploy(DeploymentPhaseContext phaseContext) throws DeploymentUnitPro
if (each.getName().matches( "^clojure(-\\d.\\d.\\d)?\\.jar$" )) {
clojureProvided = true;
}
- mount( each, unit );
+ mount( each, unit, mountMap );
}
if (!clojureProvided) {
@@ -81,12 +85,12 @@ public void deploy(DeploymentPhaseContext phaseContext) throws DeploymentUnitPro
// borrow the shipped clojure.jar
String jarPath = System.getProperty( "jboss.home.dir" ) + "/modules/org/immutant/core/main/clojure.jar";
- mount( new File( jarPath ), unit );
+ mount( new File( jarPath ), unit, mountMap );
}
//mount the runtime jar
String runtimePath = System.getProperty( "jboss.home.dir" ) + "/modules/org/immutant/core/main/immutant-runtime-impl.jar";
- mount( new File( runtimePath ), unit );
+ mount( new File( runtimePath ), unit, mountMap );
for(String each : ApplicationBootstrapUtils.resourceDirs( root, metaData.getLeinProfiles() )) {
final ResourceRoot childResource = new ResourceRoot( VFS.getChild( each ), null );
@@ -105,13 +109,16 @@ public void deploy(DeploymentPhaseContext phaseContext) throws DeploymentUnitPro
unit.putAttachment( Attachments.COMPOSITE_ANNOTATION_INDEX, new CompositeIndex( Collections.EMPTY_LIST ) );
}
- private void mount(File file, DeploymentUnit unit) throws IOException {
+ private void mount(File file, DeploymentUnit unit, JarMountMap mountMap) throws IOException {
VirtualFile mountPath = VFS.getChild( File.createTempFile( file.getName(), ".jar", tmpMountDir( unit ) ).toURI() );
log.debug( unit.getName() + ": mounting " + file );
final ResourceRoot childResource = new ResourceRoot( mountPath,
new MountHandle( VFS.mountZip( file, mountPath, TempFileProviderService.provider() ) ) );
ModuleRootMarker.mark( childResource );
unit.addToAttachmentList( Attachments.RESOURCE_ROOTS, childResource );
+
+ mountMap.put( mountPath.toURL().toExternalForm(), file.toURI().toURL().toExternalForm() );
+
}
private File tmpMountDir(DeploymentUnit unit) throws IOException {
@@ -20,6 +20,7 @@
package org.immutant.core.processors;
import org.immutant.core.ClojureMetaData;
+import org.immutant.core.JarMountMap;
import org.immutant.core.VFSStrippingClassLoader;
import org.immutant.core.as.CoreServices;
import org.immutant.runtime.ClojureRuntime;
@@ -57,7 +58,7 @@ public void deploy(DeploymentPhaseContext phaseContext) throws DeploymentUnitPro
// this won't happen in production, but helps testing
loader = this.getClass().getClassLoader();
}
- ClojureRuntime runtime = ClojureRuntime.newRuntime( new VFSStrippingClassLoader( loader ), deploymentUnit.getName() );
+ ClojureRuntime runtime = ClojureRuntime.newRuntime( new VFSStrippingClassLoader( loader, deploymentUnit.getAttachment( JarMountMap.ATTACHMENT_KEY ) ), deploymentUnit.getName() );
runtime.invoke( "immutant.registry/set-msc-registry", deploymentUnit.getServiceRegistry() );
deploymentUnit.putAttachment( ClojureRuntime.ATTACHMENT_KEY, runtime );

0 comments on commit 333b4e6

Please sign in to comment.